Beispiel #1
0
 def endproc(self, quad):
     debug('endproc')
     current_scope = self.CallStack.pop()
     self.ip = current_scope.return_addr
     self._newstack = None
     del current_scope  # vacuous statement but makes me feel good
     debug()
Beispiel #2
0
 def equals(self, quad):
     debug("equals")
     left_operand = self.get_value(quad[1])
     right_operand = self.get_value(quad[2])
     result = left_operand == right_operand
     self.set_value(quad[3], result)
     debug()
Beispiel #3
0
 def gosub(self, quad):
     debug('gosub')
     sf = self._newstack
     self.CallStack.push(sf)
     sf.set_return_addr(self.ip)
     self.ip = int(quad[3]) - 1  # minus 1 because next() adds one
     debug()
Beispiel #4
0
 def check(operator, left_operand: DType, right_operand: DType) -> DType:
     result = SemanticCube._check(operator, left_operand, right_operand)
     nintCompiler.debug((operator, left_operand, right_operand))
     if result == DType.ERROR:
         raise Exception('Type mismatch: No baila mija con el señor',
                         left_operand, right_operand)
     return result
Beispiel #5
0
 def param(self, quad):
     debug('param')
     current_scope = self.CallStack.peek()
     assert current_scope is not None, "No callstack"
     param = self.get_value(quad[1])
     address = quad[3]
     assert self._newstack is not None
     self._newstack.set_value(address, param)
     debug()
Beispiel #6
0
 def get_value(self, address):
     if is_constant(address):
         debug(address, "is_constant")
         return self.ConstTable[address]
     elif is_temp(address):
         return self.Temp.get_val(address)
     elif is_global(address):  # TODO: we could probably remove this now
         return self._GlobalMemory.get_val(address)
     return self.CallStack.peek().get_val(address)
Beispiel #7
0
    def expand_active_record(self, quad):
        debug("ERA")
        func_name = quad[1]

        assert func_name in self.FunDir, "No function"

        size_map = self.FunDir[func_name]

        # Create the AR
        sf = StackFrame(func_name, size_map)

        # Add it to the callstack
        # self.CallStack.push(sf)
        self._newstack = sf
        debug()
Beispiel #8
0
 def add(self, quad):
     debug("add")
     debug(quad)
     left_operand = self.get_value(quad[1])
     right_operand = self.get_value(quad[2])
     result = left_operand + right_operand
     self.set_value(quad[3], result)
     debug()
Beispiel #9
0
 def assign(self, quad):
     debug("assign")
     debug(quad)
     if self._returns_value:
         # Second param is function
         self._returns_value = False
         func = self.FunDir[quad[1]]
         assert 'value' in func, "Function should have a value because it is non-void"
         value = func['value']
     else:
         value = self.get_value(quad[1])
     assert value is not None
     target_address = quad[3]
     self.set_value(target_address, value)
     debug()
Beispiel #10
0
    def __init__(self, filename: str):
        super().__init__()
        self.ip = 0  # Instruction pointer
        self.quads = []
        self.ConstTable = dict()

        # Memcounts
        self._memcount_temp = 0
        self._memcount_global = 0

        self._returns_value = False
        self._newstack = None

        self.load_data(filename)
        self._total_quads = len(self.quads)

        assert self._memcount_global != 0 and self._memcount_temp != 0, "No data read for global or temp counts from bytecode"

        if debug_mode == 'debug':
            debug("========== QUADS ===========")
            for quad in self.quads:
                debug(quad)
            debug()
            debug()

        # TODO: Create memory sections here
        self.Temp = Memory(self._memcount_temp)
        self._GlobalMemory = Memory(self._memcount_global)
        self.CallStack = Stack()  # Local memory
        self.CallStack.push(self._GlobalMemory)

        # Instruction set
        self.nintIS = {

            # Arithmetic
            Operator.ASSIGN: self.assign,
            Operator.ADD: self.add,
            Operator.SUB: self.sub,
            Operator.MULT: self.mult,
            Operator.DIV: self.div,

            # Relops
            Operator.GT: self.gt,
            Operator.GTE: self.gte,
            Operator.LT: self.lt,
            Operator.LTE: self.lte,
            Operator.EQUAL: self.equals,
            Operator.NEQ: self.neq,

            # Boolean comparisons
            Operator.AND: self.bool_and,
            Operator.OR: self.bool_or,

            # GOTOs
            Operator.GOTO: self.goto,
            Operator.GOTOF: self.gotoF,
            Operator.GOTOV: self.gotoV,

            # Functions
            Operator.GOSUB: self.gosub,
            Operator.PARAM: self.param,
            Operator.ERA: self.expand_active_record,
            Operator.ENDPROC: self.endproc,
            Operator.RETURN: self.return_proc,
            Operator.PRINT: self._print
        }