NOP :
POP_N_ELEMS (0) : 
POP_N_ELEMS POP_VALUE : POP_N_ELEMS ($1a + 1)
POP_VALUE POP_VALUE : POP_N_ELEMS (2)
POP_VALUE POP_N_ELEMS : POP_N_ELEMS ($2a + 1)
POP_N_ELEMS POP_N_ELEMS : POP_N_ELEMS ($1a + $2a)
POP_N_ELEMS(1) : POP_VALUE

MARK MARK: MARK2

ASSIGN_GLOBAL POP_VALUE : ASSIGN_GLOBAL_AND_POP($1a)
ASSIGN_LOCAL  POP_VALUE : ASSIGN_LOCAL_AND_POP($1a)
CALL_LFUN POP_VALUE : CALL_LFUN_AND_POP($1a)
APPLY POP_VALUE : APPLY_AND_POP($1a)
MARK APPLY : MARK_APPLY($2a)
MARK_APPLY POP_VALUE : MARK_APPLY_POP($1a)
NUMBER(0) : CONST0
NUMBER(1) : CONST1
NUMBER(-1) : CONST_1
NUMBER (0x7fffffff) : BIGNUM
CONST0 NEGATE : CONST0
CONST1 NEGATE : CONST_1
CONST_1 NEGATE : CONST1
NUMBER NEGATE : NEG_NUMBER($1a)
NUMBER [$1a < 0] : NEG_NUMBER (-$1a)
NEG_NUMBER NEGATE : NUMBER ($1a)
NEGATE NEGATE :
COMPL COMPL :
NEGATE CONST_1 ADD : COMPL
NEGATE CONST1 SUBTRACT : COMPL
CONST0 ASSIGN_LOCAL_AND_POP : CLEAR_LOCAL($2a)
CLEAR_LOCAL NUMBER(0) ASSIGN_LOCAL_AND_POP ($1a) : CLEAR_LOCAL($1a)
CLEAR_LOCAL NUMBER(0) ASSIGN_LOCAL_AND_POP ($1a+1) : CLEAR_2_LOCAL($1a)

CONST_1 MULTIPLY : NEGATE
#CONST0 MULTIPLY : POP_VALUE CONST0
CONST1 MULTIPLY : 
#NUMBER MULTIPLY [count_bits($1a)==1]: NUMBER(my_log2($1a)) LSH

CONST_1 DIVIDE : NEGATE
CONST1 DIVIDE : 
#NUMBER DIVIDE [count_bits($1a)==1]: NUMBER(my_log2($1a)) RSH

CONST0 SUBTRACT:
CONST0 XOR:
CONST_1 XOR: COMPL
EQ CONST0: NOT
CONST0 RETURN: RETURN_0
CONST1 RETURN: RETURN_1
INC POP_VALUE: INC_AND_POP
POST_INC POP_VALUE: INC_AND_POP
DEC POP_VALUE: DEC_AND_POP
POST_DEC POP_VALUE: DEC_AND_POP
NOT BRANCH_WHEN_NON_ZERO: BRANCH_WHEN_ZERO($2a)
NOT BRANCH_WHEN_ZERO: BRANCH_WHEN_NON_ZERO($2a)

BRANCH !LABEL : BRANCH($1a)
RETURN !LABEL : RETURN
RETURN_0 !LABEL : RETURN_0
BRANCH LABEL ($1a) : LABEL ($1a)

LOCAL_LVALUE INC : INC_LOCAL ($1a)
LOCAL_LVALUE POST_INC : POST_INC_LOCAL ($1a)
LOCAL_LVALUE INC_AND_POP : INC_LOCAL_AND_POP ($1a)
INC_LOCAL POP_VALUE : INC_LOCAL_AND_POP ($1a)
POST_INC_LOCAL POP_VALUE : INC_LOCAL_AND_POP ($1a)

LOCAL_LVALUE DEC : DEC_LOCAL ($1a)
LOCAL_LVALUE POST_DEC : POST_DEC_LOCAL ($1a)
LOCAL_LVALUE DEC_AND_POP : DEC_LOCAL_AND_POP ($1a)
DEC_LOCAL POP_VALUE : DEC_LOCAL_AND_POP ($1a)
POST_DEC_LOCAL POP_VALUE : DEC_LOCAL_AND_POP ($1a)

ASSIGN_LOCAL_AND_POP LOCAL ($1a) : ASSIGN_LOCAL ($1a)
ASSIGN_LOCAL_AND_POP LOCAL ($1a) RETURN : RETURN
ASSIGN_GLOBAL_AND_POP GLOBAL ($1a) : ASSIGN_GLOBAL ($1a)
DEC_LOCAL_AND_POP LOCAL ($1a) : DEC_LOCAL ($1a)
INC_LOCAL_AND_POP LOCAL ($1a) : INC_LOCAL ($1a)

GLOBAL_LVALUE INC_AND_POP GLOBAL($1a): GLOBAL_LVALUE($1a) INC
GLOBAL_LVALUE DEC_AND_POP GLOBAL($1a): GLOBAL_LVALUE($1a) DEC

CONST1 BRANCH_WHEN_ZERO:
CONST0 BRANCH_WHEN_ZERO: BRANCH($2a)
CONST1 BRANCH_WHEN_NON_ZERO: BRANCH($2a)
CONST0 BRANCH_WHEN_NON_ZERO: 

EQ BRANCH_WHEN_NON_ZERO: BRANCH_WHEN_EQ ($2a)
NE BRANCH_WHEN_NON_ZERO: BRANCH_WHEN_NE ($2a)
LT BRANCH_WHEN_NON_ZERO: BRANCH_WHEN_LT ($2a)
GT BRANCH_WHEN_NON_ZERO: BRANCH_WHEN_GT ($2a)
LE BRANCH_WHEN_NON_ZERO: BRANCH_WHEN_LE ($2a)
GE BRANCH_WHEN_NON_ZERO: BRANCH_WHEN_GE ($2a)

EQ BRANCH_WHEN_ZERO: BRANCH_WHEN_NE ($2a)
NE BRANCH_WHEN_ZERO: BRANCH_WHEN_EQ ($2a)
LT BRANCH_WHEN_ZERO: BRANCH_WHEN_GE ($2a)
GT BRANCH_WHEN_ZERO: BRANCH_WHEN_LE ($2a)
LE BRANCH_WHEN_ZERO: BRANCH_WHEN_GT ($2a)
GE BRANCH_WHEN_ZERO: BRANCH_WHEN_LT ($2a)

EQ LOR: EQ_OR ($2a)
EQ LAND: EQ_AND ($2a)

EQ NOT: NE
NE NOT: EQ
LT NOT: GE
GT NOT: LE
LE NOT: GT
GE NOT: LT

LOCAL LOCAL [$2a<256 && $3o != F_SIZEOF && $3o != F_INDEX ]: 2_LOCALS ($1a) BYTE ($2a)
MARK LOCAL [ $3o != F_SIZEOF && $3o != F_INDEX ]: MARK_AND_LOCAL ($2a)
LOCAL SIZEOF: SIZEOF_LOCAL ($1a)
STRING INDEX: STRING_INDEX ($1a)
LOCAL INDEX: LOCAL_INDEX ($1a)
CONST0 INDEX: POS_INT_INDEX (0)
CONST_1 INDEX: NEG_INT_INDEX (1)
CONST1 INDEX: POS_INT_INDEX (1)

NUMBER [$1a < 0] INDEX: NEG_INT_INDEX (-$1a)
NUMBER [$1a >= 0] INDEX: POS_INT_INDEX ($1a)
NEG_NUMBER [$1a >= 0] INDEX: NEG_INT_INDEX ($1a)
NEG_NUMBER [$1a < 0] INDEX: POS_INT_INDEX (-$1a)

BRANCH_WHEN_ZERO BRANCH LABEL ($1a): BRANCH_WHEN_NON_ZERO($2a) LABEL($1a)
BRANCH_WHEN_NON_ZERO BRANCH LABEL ($1a): BRANCH_WHEN_ZERO($2a) LABEL($1a)

BRANCH_WHEN_EQ BRANCH LABEL ($1a) : BRANCH_WHEN_NE($2a) LABEL($1a)
BRANCH_WHEN_NE BRANCH LABEL ($1a) : BRANCH_WHEN_EQ($2a) LABEL($1a)

BRANCH_WHEN_LT BRANCH LABEL ($1a) : BRANCH_WHEN_GE($2a) LABEL($1a)
BRANCH_WHEN_GE BRANCH LABEL ($1a) : BRANCH_WHEN_LT($2a) LABEL($1a)

BRANCH_WHEN_LE BRANCH LABEL ($1a) : BRANCH_WHEN_GT($2a) LABEL($1a)
BRANCH_WHEN_GT BRANCH LABEL ($1a) : BRANCH_WHEN_LE($2a) LABEL($1a)


CONST0 ADD: ADD_INT (0)
CONST1 ADD: ADD_INT (1)
CONST_1 ADD: ADD_NEG_INT (1)
NUMBER [$1a >= 0] ADD : ADD_INT ($1a)
NUMBER [$1a < 0] ADD : ADD_NEG_INT (-$1a)

CONST0 SUBTRACT: ADD_INT (0)
CONST1 SUBTRACT: ADD_NEG_INT (-1)
CONST_1 SUBTRACT: ADD_INT (1)
NUMBER [$1a >= 0] SUBTRACT : ADD_NEG_INT ($1a)
NUMBER [$1a < 0] SUBTRACT : ADD_INT (-$1a)

LTOSVAL2 ADD ASSIGN_AND_POP : ADD_TO_AND_POP
LTOSVAL ADD ASSIGN_AND_POP : ADD_TO_AND_POP
