Exemplo n.º 1
0
    def compile(self, program: List['asm.Instruction']):
        if self.initial is not None:
            self.initial.compile(program)
            program.append(
                asm.DROP(self.initial.type.sizeof, self.initial.lineno))

        jmp_to_condition = None
        if self.condition is not None:
            jmp_to_condition = asm.JMP(-1, self.lineno)
            program.append(jmp_to_condition)

        addr_body = len(program)
        self.body.compile(program)

        if self.increment is not None:
            self.increment.compile(program)
            program.append(
                asm.DROP(self.increment.type.sizeof, self.increment.lineno))

        if self.condition is not None:
            assert jmp_to_condition is not None
            jmp_to_condition.addr = len(program)
            self.condition.compile(program)
            asm.add_cast(self.condition.type, symbols.TYPE_INT,
                         self.condition.lineno, program)
            program.append(asm.JT(addr_body, self.condition.lineno))
        else:
            program.append(asm.JMP(addr_body, self.lineno))
        addr_break = len(program)
        for brk in self._breaks:
            brk.addr = addr_break
        self._breaks.clear()
Exemplo n.º 2
0
    def compile(self, program: List['asm.Instruction']):
        func = self.current_function.symbol
        if self.value is not None:
            self.value.compile(program)
            # the returned expression must be implicitly cast to the function's expected return type
            asm.add_cast(self.value.type, func.ret_type, self.value.lineno,
                         program)

        program.append(
            asm.RETFP(func.args_size, func.ret_type.sizeof, self.lineno))
Exemplo n.º 3
0
 def compile(self, program: List['asm.Instruction'], as_rval: bool = True):
     assert as_rval, "expression cannot be used an lvalue"
     result_type = self.type
     self.operand_left.compile(program)
     asm.add_cast(self.operand_left.type, result_type,
                  self.operand_left.lineno, program)
     self.operand_right.compile(program)
     asm.add_cast(self.operand_right.type, result_type,
                  self.operand_right.lineno, program)
     program.append(
         self.instruction(asm.data_types[result_type], self.lineno))
Exemplo n.º 4
0
 def compile(self, program: List['asm.Instruction'], as_rval: bool = True):
     array_type = self.array_variable.type  # type: symbols.ArrayType
     elem_size = array_type.elem_type.sizeof
     self.array_variable.compile(program, as_rval=False)
     self.index_expression.compile(program)
     asm.add_cast(self.index_expression.type, symbols.TYPE_INT, self.lineno,
                  program)
     if elem_size != 1:
         program.append(asm.PUSHCT(elem_size, asm.INT, self.lineno))
         program.append(asm.MUL(asm.INT, self.lineno))
     program.append(asm.OFFSET(self.lineno))
     if as_rval:
         program.append(asm.LOAD(elem_size, self.lineno))
Exemplo n.º 5
0
    def compile(self, program: List['asm.Instruction'], as_rval: bool = True):
        assert as_rval, "expression cannot be used an lvalue"
        function_symbol = self.symbol_table.get_symbol(
            self.function_name)  # type: symbols.FunctionSymbol
        for arg_value, formal_arg in zip(reversed(self.args),
                                         reversed(function_symbol.args)):
            pass_by_val = not isinstance(
                arg_value.type,
                symbols.ArrayType)  # only arrays are passed by addres
            arg_value.compile(program, as_rval=pass_by_val)
            if pass_by_val:
                asm.add_cast(arg_value.type, formal_arg.type, arg_value.lineno,
                             program)

        if not isinstance(function_symbol, symbols.BuiltinSymbol):
            program.append(asm.CALL(function_symbol.offset, self.lineno))
        else:
            program.append(asm.CALLEXT(self.function_name, self.lineno))
Exemplo n.º 6
0
 def compile(self, program: List['asm.Instruction']):
     self.condition.compile(program)
     if self.body_if is not None:
         asm.add_cast(self.condition.type, symbols.TYPE_INT,
                      self.condition.lineno, program)
         jmp_else = asm.JF(-1, self.condition.lineno)
         program.append(jmp_else)
         self.body_if.compile(program)
         if self.body_else is not None:
             jmp_end = asm.JMP(-1, self.body_if.lineno)
             program.append(jmp_end)
             jmp_else.addr = len(program)
             self.body_else.compile(program)
             jmp_end.addr = len(program)
         else:
             jmp_else.addr = len(program)
     else:
         program.append(asm.DROP(self.condition.type.sizeof, self.lineno))
Exemplo n.º 7
0
 def compile(self, program: List['asm.Instruction'], as_rval: bool = True):
     assert as_rval, "expression cannot be used an lvalue"
     self.cast_expr.compile(program)
     asm.add_cast(self.cast_expr.type, self.type, self.lineno, program)