public void Visit(NotOperator not) { not.Right.Accept(this); var rightOperand = tacs.Last().Result; tacs.Add(Tac.Not(rightOperand, MakeNewTemp())); }
public void Visit(NegateOperator negate) { negate.Right.Accept(this); var rightOperand = tacs.Last().Result; tacs.Add(Tac.Negate(rightOperand, MakeNewTemp())); }
public void Visit(Program program) { // the init op code sets up the call stack, to read command line arguments var main = program.Definitions.Single(d => d.Name == "main"); tacs.Add(Tac.Init(main.Formals.Count)); // call main tacs.Add(Tac.BeginCall(main.Name, main.Formals.Count, "t0")); for (int i = 0; i < main.Formals.Count; i++) { tacs.Add(Tac.Param($"arg{i}")); } tacs.Add(Tac.Call("main", "t0")); // call print tacs.Add(Tac.BeginCall("print", 1, "t1")); tacs.Add(Tac.Param("t0")); tacs.Add(Tac.Call("print", "t1")); tacs.Add(Tac.Halt()); // declare print function tacs.Add(Tac.BeginFunc("print", 1)); tacs.Add(Tac.PrintVariable("arg0")); tacs.Add(Tac.EndFunc("print")); foreach (var definition in program.Definitions) { definition.Accept(this); } }
public void Visit(Body body) { foreach (var print in body.Prints) { print.Accept(this); } body.Expr.Accept(this); tacs.Add(Tac.Return(tacs.Last().Result)); }
public void Visit(TimesOperator times) { times.Left.Accept(this); var leftOperand = tacs.Last().Result; times.Right.Accept(this); var rightOperand = tacs.Last().Result; tacs.Add(Tac.Times(leftOperand, rightOperand, MakeNewTemp())); }
public void Visit(MinusOperator minus) { minus.Left.Accept(this); var leftOperand = tacs.Last().Result; minus.Right.Accept(this); var rightOperand = tacs.Last().Result; tacs.Add(Tac.Minus(leftOperand, rightOperand, MakeNewTemp())); }
public void Visit(DivideOperator divide) { divide.Left.Accept(this); var leftOperand = tacs.Last().Result; divide.Right.Accept(this); var rightOperand = tacs.Last().Result; tacs.Add(Tac.Divide(leftOperand, rightOperand, MakeNewTemp())); }
public void Visit(Print print) { print.Expr.Accept(this); var temp = tacs.Last().Result; var returnVariable = MakeNewTemp(); tacs.Add(Tac.BeginCall("print", 1, returnVariable)); tacs.Add(Tac.Param(temp)); tacs.Add(Tac.Call("print", returnVariable)); }
public void Visit(Definition definition) { // temps are local to the function so reset the counter for each func // (makes it easy to work out where the temp is stored in the stack frame) tempCounter = 0; Ast.SymbolTable.CurrentFunction = definition.Name; tacs.Add(Tac.BeginFunc(definition.Name, definition.Formals.Count)); definition.Body.Accept(this); tacs.Add(Tac.EndFunc(definition.Name)); }
public void Visit(IfThenElse ifthenelse) { var elseLabel = MakeNewLabel(); var endLabel = MakeNewLabel(); var resultVariable = MakeNewTemp(); ifthenelse.IfExpr.Accept(this); var ifoperand = tacs.Last().Result; tacs.Add(Tac.IfFalse(ifoperand, elseLabel)); ifthenelse.ThenExpr.Accept(this); tacs.Add(Tac.Assign(tacs.Last().Result, resultVariable)); tacs.Add(Tac.Goto(endLabel)); tacs.Add(Tac.Label(elseLabel, resultVariable)); ifthenelse.ElseExpr.Accept(this); tacs.Add(Tac.Assign(tacs.Last().Result, resultVariable)); tacs.Add(Tac.Label(endLabel, resultVariable)); }
public void Visit(EqualsOperator equals) { equals.Left.Accept(this); var leftOperand = tacs.Last().Result; equals.Right.Accept(this); var rightOperand = tacs.Last().Result; var result = MakeNewTemp(); var label1 = MakeNewLabel(); var label2 = MakeNewLabel(); tacs.Add(Tac.IfEqual(leftOperand, rightOperand, label1)); tacs.Add(Tac.Assign("0", result)); tacs.Add(Tac.Goto(label2)); tacs.Add(Tac.Label(label1, result)); tacs.Add(Tac.Assign("1", result)); tacs.Add(Tac.Label(label2, result)); }
public void Visit(LessThanOperator lessThan) { lessThan.Left.Accept(this); var leftOperand = tacs.Last().Result; lessThan.Right.Accept(this); var rightOperand = tacs.Last().Result; var result = MakeNewTemp(); var label1 = MakeNewLabel(); var label2 = MakeNewLabel(); tacs.Add(Tac.IfLessThan(leftOperand, rightOperand, label1)); tacs.Add(Tac.Assign("0", result)); tacs.Add(Tac.Goto(label2)); tacs.Add(Tac.Label(label1, result)); tacs.Add(Tac.Assign("1", result)); tacs.Add(Tac.Label(label2, result)); }
public void Visit(FunctionCall functionCall) { var args = new List <string>(); foreach (var actual in functionCall.Actuals) { actual.Expr.Accept(this); args.Add(tacs.Last().Result); } var returnValue = MakeNewTemp(); tacs.Add(Tac.BeginCall(functionCall.Name, functionCall.Actuals.Count, returnValue)); foreach (var arg in args) { tacs.Add(Tac.Param(arg)); } tacs.Add(Tac.Call(functionCall.Name, returnValue)); }
public void Visit(OrOperator or) { var trueLabel = MakeNewLabel(); var endLabel = MakeNewLabel(); or.Left.Accept(this); var leftOperand = tacs.Last().Result; tacs.Add(Tac.IfTrue(leftOperand, trueLabel)); or.Right.Accept(this); var rightOperand = tacs.Last().Result; tacs.Add(Tac.IfTrue(rightOperand, trueLabel)); var resultVariable = MakeNewTemp(); tacs.Add(Tac.Assign("0", resultVariable)); tacs.Add(Tac.Goto(endLabel)); tacs.Add(Tac.Label(trueLabel, resultVariable)); tacs.Add(Tac.Assign("1", resultVariable)); tacs.Add(Tac.Label(endLabel, resultVariable)); }
public void Visit(AndOperator and) { var falseLabel = MakeNewLabel(); var endLabel = MakeNewLabel(); and.Left.Accept(this); var leftOperand = tacs.Last().Result; tacs.Add(Tac.IfFalse(leftOperand, falseLabel)); and.Right.Accept(this); var rightOperand = tacs.Last().Result; tacs.Add(Tac.IfFalse(rightOperand, falseLabel)); var resultVariable = MakeNewTemp(); tacs.Add(Tac.Assign("1", resultVariable)); tacs.Add(Tac.Goto(endLabel)); tacs.Add(Tac.Label(falseLabel, resultVariable)); tacs.Add(Tac.Assign("0", resultVariable)); tacs.Add(Tac.Label(endLabel, resultVariable)); }
public void Visit(IntegerLiteral literal) { tacs.Add(Tac.Assign(literal.Value.ToString(), MakeNewTemp())); }
public void Visit(BooleanLiteral booleanLiteral) { var booleanValue = booleanLiteral.Value ? "1" : "0"; tacs.Add(Tac.Assign(booleanValue, MakeNewTemp())); }
public void Visit(Identifier identifier) { var arg = $"arg{Ast.SymbolTable.ArgumentNumber(identifier.Value)}"; tacs.Add(Tac.Assign(arg, MakeNewTemp())); }