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()
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()
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()
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
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()
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)
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()
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()
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()
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 }