def binary_comp(comp): return concat( decr_sp(), load_stack_top_into_d(), decr_sp(), ['@SP', 'A=M', 'D=M-D'], if_else( comparator=comp, true_block=['@SP', 'A=M', 'M=-1'], # recall: in HW -1 represents true, 0 false false_block=['@SP', 'A=M', 'M=0']), incr_sp())
def pop_heap(segment, index): return concat( load_constant_into_d(index), [f'@{segment}', 'D=M+D'], # load addr into D ['@R13', 'M=D'], # store addr into mem decr_sp(), load_stack_top_into_d(), ['@R13', 'A=M', 'M=D'])
def func_return(): return concat( decr_sp(), load_stack_top_into_d(), ['@ARG', 'A=M', 'M=D'], # *ARG = D ['@ARG', 'D=M', '@SP', 'M=D+1'], # SP = ARG + 1 unpack_stack_frame(), ['@R13', 'A=M', '0;JMP'] # JMP *R13 )
def unary_op(op): return concat(decr_sp(), ['@SP', 'A=M', f'M={op}M'], incr_sp())
def binary_op(op): return concat(decr_sp(), load_stack_top_into_d(), decr_sp(), ['@SP', 'A=M', f'M=M{op}D'], incr_sp())
def cond_goto(labelname): return concat(decr_sp(), load_stack_top_into_d(), [f'@{labelname}', 'D;JNE'])
def pop_static(_, index): varname = get_static_varname(index) return concat(decr_sp(), load_stack_top_into_d(), [f'@{varname}', 'M=D'])
def pop_temp(_, index): addr = get_temp_addr(index) return concat(decr_sp(), load_stack_top_into_d(), [f'@{addr}', 'M=D'])
def pop_pointer(_, val): segment = get_pointer_segment(val) return concat(decr_sp(), load_stack_top_into_d(), [f'@{segment}', 'M=D'])