def ret(class_name, command_number): output = COMMENT.format(command='return', name='', arg='') output += READ.format(address='LCL') output += STORE.format(address='ENDFRAME') output += _set_address_from_endframe(RETURN_ADDRESS, OFFSET_ENDFRAME[RETURN_ADDRESS]) output += READ_AND_DECREMENT_SP output += ADDRESS.format(address='ARG') output += FOLLOW_POINTER output += WRITE_TO_MEMORY_FROM_REGISTER output += READ.format(address='ARG') output += 'D=D+1\n' output += STORE.format(address='SP') for address in ['THAT', 'THIS', 'ARG', 'LCL']: output += _set_address_from_endframe(address, OFFSET_ENDFRAME[address]) output += ADDRESS.format(address=RETURN_ADDRESS) output += FOLLOW_POINTER output += JUMP return output
def push(class_name, command_number, memory_segment, value): address_offset = int(value) output = COMMENT.format(command='push', name=memory_segment, arg=value) output += ADDRESS.format( address=_get_base_address(class_name, memory_segment, address_offset)) if memory_segment == 'constant': output += LOAD_VALUE_TO_REGISTER elif memory_segment == 'static': output += FOLLOW_POINTER output += LOAD_VALUE_TO_REGISTER else: if memory_segment in MEMORY_SEGMENT_ADDRESSES: output += FOLLOW_POINTER # could be 'temp' or 'pointer' if address_offset != 0: output += _increment_memory(address_offset) output += FOLLOW_POINTER output += LOAD_VALUE_TO_REGISTER output += WRITE_AND_INCREMENT_SP return output
def call(class_name, command_number, function_name, argument_num): output = COMMENT.format(command='call', name=function_name, arg=argument_num) argument_num = int(argument_num) return_address = RETURN_ADDRESS_LABEL.format(class_name=class_name, command_number=command_number) output += ADDRESS.format(address=return_address) output += LOAD_VALUE_TO_REGISTER output += WRITE_AND_INCREMENT_SP for address in ['LCL', 'ARG', 'THIS', 'THAT']: output += READ.format(address=address) output += WRITE_AND_INCREMENT_SP output += READ.format(address='SP') output += SUBTRACT.format(value=5) if argument_num > 0: output += SUBTRACT.format(value=argument_num) output += STORE.format(address='ARG') output += READ.format(address='SP') output += STORE.format(address='LCL') output += GOTO.format(address=function_name) output += LABEL.format(address=return_address) return output
def bootstrap(): output = COMMENT.format(command='bootstrap', name='', arg='') output += ADDRESS.format(address='256') output += LOAD_VALUE_TO_REGISTER output += STORE.format(address='SP') output += call('bootstrap', 0, 'Sys.init', 0) return output
def function(class_name, command_number, function_name, local_variable_num): output = COMMENT.format(command='function', name=function_name, arg=local_variable_num) local_variable_num = int(local_variable_num) output += LABEL.format(address=function_name) for i in range(0, local_variable_num): output += ADDRESS.format(address='0') output += LOAD_VALUE_TO_REGISTER output += WRITE_AND_INCREMENT_SP return output
def pop(class_name, command_number, memory_segment, value): address_offset = int(value) output = COMMENT.format(command='pop', name=memory_segment, arg=address_offset) output += READ_AND_DECREMENT_SP output += ADDRESS.format( address=_get_base_address(class_name, memory_segment, address_offset)) if memory_segment == 'static': output += WRITE_TO_MEMORY_FROM_REGISTER else: if memory_segment == 'pointer': output += WRITE_TO_MEMORY_FROM_REGISTER elif memory_segment in MEMORY_SEGMENT_ADDRESSES: output += FOLLOW_POINTER # could be 'temp' or 'pointer' if address_offset != 0: output += _increment_memory(address_offset) output += WRITE_TO_MEMORY_FROM_REGISTER return output
def if_goto(class_name, command_number, label_name): output = COMMENT.format(command='if-goto', name=label_name, arg='') output += READ_AND_DECREMENT_SP output += ADDRESS.format(address=label_name) output += JUMP_IF_NOT return output