Пример #1
0
def decode(singlefile):
    print(singlefile)
    with open(singlefile, 'r') as f:
        name = os.path.basename(singlefile).split('.')[0]
        asmname = os.path.join(os.path.dirname(singlefile), "%s.asm" % name)
        asm = open(asmname, 'w')
        print(asmname)
        print()
        n = 0
        while True:
            line = f.readline()
            if line == '':
                break
            line = parser.removeun(line)
            if line == '':
                continue
            n += 1
            line = parser.removeun(line)
            command = line.split()[0]
            ctype = parser.commandType(command)
            a1 = parser.arg1(line, ctype)
            if ctype == 'C_ARITHMETIC':
                code = writeArithmetic(command)
                if command in ['eq', 'gt', 'lt']:
                    code = code % (n, n, n, n, n, n, n)
            elif ctype == 'C_PUSH' or ctype == "C_POP":
                a2 = parser.arg2(line)
                code = writepushpop(name, command, a1, a2)
            asm.write("%s\n" % code)
        asm.close()
Пример #2
0
    def getASM(self, parser, code_writer):
        CT = parser.commandType()
        if CT == parser.C_ARITHMETIC:
#            print(parser.arg1())
            code_writer.writeArithmetic(parser.arg1())
        elif CT == parser.C_PUSH or CT == parser.C_POP:
#            print (parser.arg1(), parser.arg2())
            code_writer.writePushPop(CT, parser.arg1(), parser.arg2())
        elif CT == parser.C_LABEL:
#            print(parser.arg1())
            code_writer.writeLabel(parser.arg1())
        elif CT == parser.C_GOTO:
#            print(parser.arg1())
            code_writer.writeGoTo(parser.arg1())
        elif CT == parser.C_IF:
#            print(parser.arg1())
            code_writer.writeIf(parser.arg1())
        elif CT == parser.C_RETURN:
#            print("return")
            code_writer.writeReturn()
        elif CT == parser.C_FUNCTION:
#            print(parser.arg1(), parser.arg2())
            code_writer.writeFunction(parser.arg1(), parser.arg2())
        elif CT == parser.C_CALL:
#            print(parser.arg1(), parser.arg2())
            code_writer.writeCall(parser.arg1(), parser.arg2())
Пример #3
0
def write_push_pop():
    base = arg1()
    if base == 'static':
        f.write('@16' + '\n')
        f.write('D=A' + '\n')
    elif base == 'local':
        f.write('@LCL' + '\n')
        f.write('D=M' + '\n')
    elif base == 'argument':
        f.write('@ARG' + '\n')
        f.write('D=M' + '\n')
    elif base == 'this':
        f.write('@THIS' + '\n')
        f.write('D=M' + '\n')
    elif base == 'that':
        f.write('@THAT' + '\n')
        f.write('D=M' + '\n')
    elif base == 'constant':
        f.write('@SP' + '\n')
        f.write('D=A' + '\n')
    elif base == 'temp':
        f.write('@5' + '\n')
        f.write('D=A' + '\n')
    f.write('@R13' + '\n')
    f.write('M=D' + '\n')

    index = arg2()
    f.write('@' + index + '\n')
    f.write('D=A' + '\n')
    f.write('@R13' + '\n')
    f.write('M=M+D' + '\n')

    command = command_type()
    if command == 'C_PUSH':
        f.write('D=M' + '\n')
        if base != 'constant':
            f.write('A=D' + '\n')
            f.write('D=M' + '\n')
        f.write('@SP' + '\n')
        f.write('M=M+1' + '\n')
        f.write('A=M-1' + '\n')
        f.write('M=D' + '\n')
    else:  # (if command == 'C_POP')
        f.write('@SP' + '\n')
        f.write('M=M-1' + '\n')
        f.write('A=M+1' + '\n')
        f.write('D=M' + '\n')
        f.write('@R13' + '\n')
        f.write('A=M' + '\n')
        f.write('M=D' + '\n')
Пример #4
0
def write_push_pop () :
  base = arg1()
  if base == 'static' :
    f.write('@16' + '\n')
    f.write('D=A' + '\n')
  elif base == 'local' :
    f.write('@LCL' + '\n')
    f.write('D=M' + '\n')
  elif base == 'argument' :
    f.write('@ARG' + '\n')
    f.write('D=M' + '\n')
  elif base == 'this' :
    f.write('@THIS' + '\n')
    f.write('D=M' + '\n')
  elif base == 'that' :
    f.write('@THAT' + '\n')
    f.write('D=M' + '\n')
  elif base == 'constant' :
    f.write('@SP' + '\n')
    f.write('D=A' + '\n')
  elif base == 'temp' :
    f.write('@5' + '\n')
    f.write('D=A' + '\n')
  f.write('@R13' + '\n')
  f.write('M=D' + '\n')

  index = arg2()
  f.write('@' + index + '\n')
  f.write('D=A' + '\n')
  f.write('@R13' + '\n')
  f.write('M=M+D' + '\n')

  command = command_type()
  if command == 'C_PUSH' :
    f.write('D=M' + '\n')
    if base != 'constant' :
      f.write('A=D' + '\n')
      f.write('D=M' + '\n')
    f.write('@SP' + '\n')
    f.write('M=M+1' + '\n')
    f.write('A=M-1' + '\n')
    f.write('M=D' + '\n')
  else : # (if command == 'C_POP')
    f.write('@SP' + '\n')
    f.write('M=M-1' + '\n')
    f.write('A=M+1' + '\n')
    f.write('D=M' + '\n')
    f.write('@R13' + '\n')
    f.write('A=M' + '\n')
    f.write('M=D' + '\n')
Пример #5
0
def write_arithmetic():
    command = arg1()
    # (if command operates on single value)
    if command == 'not' or command == 'neg':
        f.write('@SP' + '\n')
        f.write('A=M' + '\n')
        if command == 'not':
            f.write('M=!M' + '\n')
        else:
            f.write('M=-M' + '\n')

    else:  # (if command operates on two values)
        f.write('@SP' + '\n')
        f.write('M=M-1' + '\n')
        f.write('A=M+1' + '\n')
        f.write('D=M' + '\n')
        f.write('A=A-1' + '\n')

        if command == 'add':
            f.write('M=M+D' + '\n')
        elif command == 'sub':
            f.write('M=M-D' + '\n')
        elif command == 'and':
            f.write('M=M&D' + '\n')
        elif command == 'or':
            f.write('M=M|D' + '\n')

        else:  # (if operation is comparative)
            f.write('D=M-D' + '\n')
            global set_true_count, continue_count
            f.write('@SET_TRUE.' + str(set_true_count) + '\n')
            if command == 'eq':
                f.write('D;JEQ' + '\n')
            if command == 'gt':
                f.write('D;JGT' + '\n')
            if command == 'lt':
                f.write('D;JLT' + '\n')
            f.write('@SP' + '\n')
            f.write('A=M' + '\n')
            f.write('M=0' + '\n')
            f.write('@CONTINUE.' + str(continue_count) + '\n')
            f.write('0;JMP' + '\n')
            f.write('(SET_TRUE.' + str(set_true_count) + ')' + '\n')
            f.write('@SP' + '\n')
            f.write('A=M' + '\n')
            f.write('M=1' + '\n')
            f.write('(CONTINUE.' + str(continue_count) + ')' + '\n')
            set_true_count += 1
            continue_count += 1
Пример #6
0
def write_arithmetic () :
  command = arg1()
  # (if command operates on single value)
  if command == 'not' or command == 'neg' : 
    f.write('@SP' + '\n')
    f.write('A=M' + '\n')
    if command =='not' :
      f.write('M=!M' + '\n')
    else :
      f.write('M=-M' + '\n')

  else : # (if command operates on two values)
    f.write('@SP' + '\n')
    f.write('M=M-1' + '\n')
    f.write('A=M+1' + '\n')
    f.write('D=M' + '\n')
    f.write('A=A-1' + '\n')

    if command == 'add' :
      f.write('M=M+D' + '\n')
    elif command == 'sub' :
      f.write('M=M-D' + '\n')
    elif command == 'and' :
      f.write('M=M&D' + '\n')
    elif command == 'or' :
      f.write('M=M|D' + '\n')

    else : # (if operation is comparative)
      f.write('D=M-D' + '\n')
      global set_true_count, continue_count
      f.write('@SET_TRUE.' + str(set_true_count) + '\n')
      if command == 'eq' :
        f.write('D;JEQ' + '\n')
      if command == 'gt' :
        f.write('D;JGT' + '\n')
      if command == 'lt' :
        f.write('D;JLT' + '\n')
      f.write('@SP' + '\n')
      f.write('A=M' + '\n')
      f.write('M=0' + '\n')
      f.write('@CONTINUE.' + str(continue_count) + '\n')
      f.write('0;JMP' + '\n')
      f.write('(SET_TRUE.' + str(set_true_count) + ')' + '\n')
      f.write('@SP' + '\n')
      f.write('A=M' + '\n')
      f.write('M=1' + '\n')
      f.write('(CONTINUE.' + str(continue_count) + ')' + '\n')
      set_true_count += 1
      continue_count += 1