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