def visitLocation(self, ctx: DecafParser.LocationExprContext, struct=None): var_name = ctx.name.text scope = self.scopes.peek() var, scopeName = scope.lookup(var_name) tokenEXPR = ctx.expr tokenLOC = ctx.loc locNode = ICNode('location') if not tokenEXPR and not tokenLOC: locNode.lt = self.get_location(scopeName, var.offset) return locNode #We have a list elif tokenEXPR and not tokenLOC: size = scope.typeTable.getSize(var.stype) # EZ index is a number if (index := ctx.expr.getText()).isnumeric(): locNode.lt = self.get_location(scopeName, var.offset + size * int(index)) return locNode # Index is an expression code = [] expr = self.visit(tokenEXPR) # 2 new temporals, to compute the new offset new_temp = self.get_temporal() new_temp2 = self.get_temporal() # if expression is a location, we get a string, if not we get an ICNode location = expr if not isinstance(expr, str): code += expr.code location = expr.lt self.free_temporal(expr.lt) code.append(self.gen_code(new_temp, location, '*', size)) code.append(self.gen_code(new_temp2, new_temp, '+', var.offset)) self.free_temporal(new_temp) self.free_temporal(new_temp2) locNode.code = code locNode.lt = self.get_location(scopeName, new_temp2) return locNode
def visitNegationExpr(self, ctx: DecafParser.NegativeExprContext): t = self.visit(ctx.expression) new_temp = self.get_temporal() code = [] negated = ICNode('!', right=t) code += t.code code.append(new_temp + ' = NOT ' + t.lt) self.free_temporal(t.lt) negated.code = code negated.lt = new_temp return negated
def visitMethodCall(self, ctx: DecafParser.MethodCallExprContext): methodCallNode = ICNode('call') code = [] method_label = str(ctx.ID()) scope = self.scopes.peek() method = scope.typeExists(method_label, 'method') for argument in ctx.arg(): argNode = self.visitArg(argument) code += argNode.code code.append('PushParam ' + argNode.lt) self.free_temporal(argNode.lt) code.append('LCall ' + method_label) code.append('PopParams ' + str(method.size)) methodCallNode.lt = RETURN_REGISTER methodCallNode.code = code return methodCallNode
def visitRelationOp(self, ctx: DecafParser.RelationOpContext): op = ctx.op.getText() left_node = self.visit(ctx.left) right_node = self.visit(ctx.right) self.free_temporal(left_node.lt) self.free_temporal(right_node.lt) rel = ICNode(op, right_node, left_node) code = [] code += left_node.code code += right_node.code new_temp = self.get_temporal() code.append(self.gen_code(new_temp, left_node.lt, op, right_node.lt)) rel.code = code rel.lt = new_temp return rel
def visitArithOp(self, ctx: DecafParser.ArithOpContext): op = ctx.op.getText() left_node = self.visit(ctx.left) right_node = self.visit(ctx.right) self.free_temporal(left_node.lt) self.free_temporal(right_node.lt) arith = ICNode(op, right_node, left_node) code = [] code += left_node.code code += right_node.code new_temp = self.get_temporal() code.append(self.gen_code(new_temp, left_node.lt, op, right_node.lt)) arith.code = code arith.lt = new_temp return arith
def visitEqualityOp(self, ctx: DecafParser.EqualityOpContext): op = ctx.op.getText() left_node = self.visit(ctx.left) right_node = self.visit(ctx.right) self.free_temporal(left_node.lt) self.free_temporal(right_node.lt) eq = ICNode(op, right_node, left_node) code = [] code += left_node.code code += right_node.code new_temp = self.get_temporal() code.append(self.gen_code(new_temp, left_node.lt, op, right_node.lt)) eq.code = code eq.lt = new_temp return eq