示例#1
0
 def compile_pop(cls, segment, offset, vm_command_context):
     pop_to_d = [
         '@SP',
         'A=M-1',
         'D=M',
         '@SP',
         'M=M-1'
     ]
     if is_pointer_type(segment):
         return lines_of(
             '@{}'.format(get_base_address(segment)),
             'D=M',
             '@{}'.format(offset),
             'D=D+A',
             '@R15',
             'M=D',
             *pop_to_d,
             '@R15',
             'A=M',
             'M=D')
     elif is_direct_type(segment):
         return lines_of(
             *pop_to_d,
             '@{}'.format(get_base_address(segment) + int(offset)),
             'M=D')
     elif is_static_type(segment):
         vm_filename, _ = vm_command_context
         return lines_of(
             *pop_to_d,
             '@{}'.format(cls.make_static_variable(vm_filename, offset)),
             'M=D')
     else:
         raise NotImplementedError('Unsupported segment {}'.format(segment))
示例#2
0
 def compile_push(cls, segment, offset, vm_command_context):
     push_from_d = [
         '@SP',
         'A=M',
         'M=D',
         'D=A+1',
         '@SP',
         'M=D'
     ]
     if is_virtual_type(segment):
         return lines_of(
             '@{}'.format(offset),
             'D=A',
             *push_from_d)
     elif is_static_type(segment):
         vm_filename, _ = vm_command_context
         return lines_of(
             '@{}'.format(cls.make_static_variable(vm_filename, offset)),
             'D=M',
             *push_from_d)
     elif is_pointer_type(segment):
         return lines_of(
             '@{}'.format(get_base_address(segment)),
             'D=M',
             '@{}'.format(offset),
             'A=D+A',
             'D=M',
             *push_from_d)
     elif is_direct_type(segment):
         return lines_of(
             '@{}'.format(get_base_address(segment) + int(offset)),
             'D=M',
             *push_from_d)
     else:
         raise NotImplementedError('Unknown segment {}'.format(segment))
示例#3
0
 def compile_if_goto(cls, label, vm_command_context):
     # note that this pops from the stack
     return lines_of(
         '@SP',
         'AM=M-1',
         'D=M',
         '@{}'.format(cls.symbol_from_label(vm_command_context, label)),
         'D;JNE')
示例#4
0
 def compile_or(cls):
     return lines_of(
         '@SP',
         'A=M-1',
         'D=M',
         'A=A-1',
         'M=D|M',
         'D=A+1',
         '@SP',
         'M=D')
示例#5
0
 def compile_sub(cls):
     return lines_of(
         '@SP',
         'A=M-1',
         'D=M',
         'A=A-1',
         'M=M-D',
         'D=A+1',
         '@SP',
         'M=D')
示例#6
0
 def compile_eq(cls, vm_command_context, callcount):
     eq_true_symbol = cls.make_order_symbol(
         vm_command_context, 'EQ_TRUE', callcount)
     eq_end_symbol = cls.make_order_symbol(
         vm_command_context, 'EQ_END', callcount)
     return lines_of(
         *cls.diff_top2_to_d,
         '@{}'.format(eq_true_symbol),
         'D;JEQ',
         'D=0',
         '@{}'.format(eq_end_symbol),
         '0;JMP',
         '({})'.format(eq_true_symbol),
         'D=-1',
         '({})'.format(eq_end_symbol),
         *cls.push_compare_value)
示例#7
0
 def compile_lt(cls, vm_command_context, callcount):
     lt_true_symbol = cls.make_order_symbol(
         vm_command_context, 'LT_TRUE', callcount)
     lt_end_symbol = cls.make_order_symbol(
         vm_command_context, 'LT_END', callcount)
     return lines_of(
         *cls.diff_top2_to_d,
         '@{}'.format(lt_true_symbol),
         'D;JLT',
         'D=0',
         '@{}'.format(lt_end_symbol),
         '0;JMP',
         '({})'.format(lt_true_symbol),
         'D=-1',
         '({})'.format(lt_end_symbol),
         *cls.push_compare_value)
示例#8
0
 def compile_return(cls, vm_command_context):
     decrement_old_lcl_and_store_value_in_d = ["@R13", "M=M-1", "A=M", "D=M"]
     return lines_of(
         # store value of ARG in R15
         "@ARG",
         "D=M",
         "@R15",
         "M=D",
         # revert LCL, THAT, THIS, ARG from
         # LCL, storing original LCL in R13
         "@LCL",
         "D=M",
         "@R13",
         "M=D",
         *decrement_old_lcl_and_store_value_in_d,
         "@THAT",
         "M=D",
         *decrement_old_lcl_and_store_value_in_d,
         "@THIS",
         "M=D",
         *decrement_old_lcl_and_store_value_in_d,
         "@ARG",
         "M=D",
         *decrement_old_lcl_and_store_value_in_d,
         "@LCL",
         "M=D",
         # store return address in R14
         *decrement_old_lcl_and_store_value_in_d,
         "@R14",
         "M=D",
         # push computed value, reset stack pointer
         "@SP",
         "A=M-1",
         "D=M",
         "@R15",
         "A=M",
         "M=D",
         "@R15",
         "D=M",
         "@SP",
         "M=D+1",
         # retrieve return value, jump
         "@R14",
         "A=M",
         "0;JMP"
     )
示例#9
0
 def compile_call(cls, callee, n_args, vm_command_context, callcount):
     return_symbol = "{}$RETURN_{}".format(namespace(*vm_command_context), callcount)
     reposition_arg_loop_symbol = "{}$REPOSITION_ARG_{}".format(namespace(*vm_command_context), callcount)
     push_from_d = ["@SP", "A=M", "M=D", "D=A+1", "@SP", "M=D"]
     return lines_of(
         "@{}".format(return_symbol),
         "D=A",
         *push_from_d,
         "@LCL",
         "D=M",
         *push_from_d,
         "@ARG",
         "D=M",
         *push_from_d,
         "@THIS",
         "D=M",
         *push_from_d,
         "@THAT",
         "D=M",
         *push_from_d,
         # reposition LCL
         "@SP",
         "D=M",
         "@LCL",
         "M=D",
         # reposition ARG; ARG = SP - n_args - 5
         "@ARG",
         "M=D",
         "@{}".format(int(n_args) + 5),
         "D=A",
         "({})".format(reposition_arg_loop_symbol),
         "@ARG",
         "M=M-1",
         "@{}".format(reposition_arg_loop_symbol),
         "D=D-1;JNE",
         # jump to callee
         "@{}".format(namespace(vm_command_context[0], callee)),
         "0;JMP",
         "({})".format(return_symbol)
     )
示例#10
0
 def compile_function(cls, function, n_locals, vm_command_context):
     init_locals_symbol = "{}$INIT_LOCALS".format(namespace(*vm_command_context))
     if int(n_locals):
         initialize_locals = [
             "@{}".format(n_locals),
             "D=A",
             "@R13",
             "M=D",
             "({})".format(init_locals_symbol),
             "@SP",
             "D=M",
             "M=M+1",
             "A=D",
             "M=0",
             "@R13",
             "MD=M-1",
             "@{}".format(init_locals_symbol),
             "D;JNE",
         ]
     else:
         initialize_locals = []
     return lines_of("({})".format(namespace(*vm_command_context)), *initialize_locals)
示例#11
0
 def bootstrap(cls, file_h):
     """Sets the stack pointer to 256, calls Sys.init, adds halting loop."""
     bootstrap_halt_loop = "BOOTSTRAP_HALT_LOOP"
     file_h.write(lines_of("@256", "D=A", "@SP", "M=D") + "\n")
     file_h.write(cls.compile_call("Sys.init", "0", ("", None)) + "\n")
     file_h.write(lines_of("({})".format(bootstrap_halt_loop), "@{}".format(bootstrap_halt_loop), "0;JMP") + "\n")
示例#12
0
 def compile_goto(cls, label, vm_command_context):
     return lines_of(
         '@{}'.format(cls.symbol_from_label(vm_command_context, label)),
         '0;JMP')
示例#13
0
 def compile_label(cls, label, vm_command_context):
     return lines_of(
         '({})'.format(cls.symbol_from_label(vm_command_context, label)))
示例#14
0
 def compile_not(cls):
     return lines_of(
         '@SP',
         'A=M-1',
         'D=M',
         'M=!M')
示例#15
0
 def compile_neg(cls):
     return lines_of(
         '@SP',
         'A=M-1',
         'D=M',
         'M=-M')