def visitWhileStmt(self, ctx: DecafParser.WhileStmtContext): self.enterScope('whileblock' + str(self.anonCounter)) self.anonCounter += 1 whileNode = ICNode('while') code = [] conditionlabel = self.gen_label() elselabel = self.gen_label() expr = self.visit(ctx.expression()) condition = expr.lt self.free_temporal(condition) code.append(conditionlabel) code += expr.code code.append('IFNOT ' + condition + ' goto ' + elselabel) whileblock = self.visit(ctx.block()) code += whileblock.code code.append('goto ' + conditionlabel) code.append(elselabel) whileNode.code = code self.exitScope() return whileNode
def visitBlock(self, ctx: DecafParser.BlockContext): blockNode = ICNode('none') code = [] for statement in ctx.statement(): v = self.visitStatement(statement) code += v.code if v else [] blockNode.code = code return blockNode
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 visitReturnStmt(self, ctx: DecafParser.ReturnStmtContext): expr = self.visit(ctx.expression()) returnNode = ICNode('return') code = [] code += expr.code code.append(self.gen_code(RETURN_REGISTER, expr.lt, '', '')) self.free_temporal(expr.lt) code.append('BX LR') returnNode.code = code return returnNode
def visitAssignStmt(self, ctx: DecafParser.AssignStmtContext): destination = self.visit(ctx.left) right = self.visit(ctx.right) loc = destination assignNode = ICNode('=', left=destination, right=right) code = [] code += right.code if not isinstance(destination, str): code += destination.code loc = destination.lt code.append(self.gen_code(loc, right.lt, '', '')) self.free_temporal(right.lt) assignNode.code = code return assignNode
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 visitIfStmt(self, ctx: DecafParser.IfStmtContext): self.enterScope('ifblock' + str(self.anonCounter)) self.anonCounter += 1 ifNode = ICNode('if') code = [] elselabel = self.gen_label() expr = self.visit(ctx.expression()) condition = expr.lt self.free_temporal(condition) code += expr.code code.append('IFNOT ' + condition + ' goto ' + elselabel) ifblock = self.visit(ctx.ifblock) code += ifblock.code if ctx.elseblock: endlabel = self.gen_label() code.append('goto ' + endlabel) code.append(elselabel) elseblock = self.visit(ctx.elseblock) code += elseblock.code code.append(endlabel) else: code.append(elselabel) ifNode.code = code self.exitScope() return ifNode
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
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 visitBool_literal(self, ctx: DecafParser.Bool_literalContext): if ctx.getText() == 'true': return ICNode(None, lt='1') return ICNode(None, lt='0')
def visitChar_literal(self, ctx: DecafParser.Char_literalContext): return ICNode(None, lt=ctx.getText())