public void Compile(Generator generator, string outputFile) { // Generate compiletime environment var labels = _functionEnvironment.GetFunctionNames().ToDictionary(funName => funName, funName => Label.Fresh()); var compilationEnvironment = new CompilationEnvironment(labels); // Compile expression _expression.Compile(compilationEnvironment, generator); generator.Emit(Instruction.PrintI); generator.Emit(Instruction.Stop); // Compile functions foreach (var functionDefinition in _functionEnvironment.GetFunctions()) { compilationEnvironment = new CompilationEnvironment(labels); functionDefinition.Compile(compilationEnvironment, generator); } // Generate bytecode at and print to file generator.PrintCode(); var bytecode = generator.ToBytecode(); using (TextWriter writer = new StreamWriter(outputFile)) { foreach (var b in bytecode) { writer.Write(b); writer.Write(" "); } } }
public void Compile(CompilationEnvironment compilationEnvironment, Generator generator) { compilationEnvironment.DeclareLocal(_argument.Item1); // Formal argument name points to top of stack generator.Label(compilationEnvironment.GetFunctionLabel(_name)); _body.Compile(compilationEnvironment, generator); generator.Emit(new Return(1)); }
public override void Compile(CompilationEnvironment compilationEnvironment, Generator generator) { _e1.Compile(compilationEnvironment, generator); compilationEnvironment.PushTemporary(); _e2.Compile(compilationEnvironment, generator); switch (_op) { case Operator.Add: generator.Emit(Instruction.Add); break; case Operator.Div: generator.Emit(Instruction.Div); break; case Operator.Mul: generator.Emit(Instruction.Mul); break; case Operator.Sub: generator.Emit(Instruction.Sub); break; case Operator.Eq: generator.Emit(Instruction.Eq); break; case Operator.Ne: generator.Emit(Instruction.Eq); generator.Emit(Instruction.Not); break; case Operator.Ge: generator.Emit(Instruction.LT); generator.Emit(Instruction.Not); break; case Operator.Gt: generator.Emit(Instruction.Swap); generator.Emit(Instruction.LT); break; case Operator.Le: generator.Emit(Instruction.Swap); generator.Emit(Instruction.LT); generator.Emit(Instruction.Not); break; case Operator.Lt: generator.Emit(Instruction.LT); break; case Operator.And: generator.Emit(Instruction.Mul); break; case Operator.Or: generator.Emit(Instruction.Add); generator.Emit(new CstI(0)); generator.Emit(Instruction.Eq); generator.Emit(Instruction.Not); break; default: throw new InvalidOperationException(string.Format("Unknown binary operator: {0}", _op)); } compilationEnvironment.PopTemporary(); }
public void CompileVariable(Generator gen, string name) { var offset = 0; foreach (var variableName in _locals) { if (variableName == name) { gen.Emit(Instruction.GetSp); gen.Emit(new CstI(offset)); gen.Emit(Instruction.Sub); return; } offset++; } throw new InvalidOperationException("Undeclared variable: " + name); }
public override void Compile(CompilationEnvironment compilationEnvironment, Generator generator) { _expression.Compile(compilationEnvironment, generator); switch (_op) { case Operator.Not: generator.Emit(Instruction.Not); break; case Operator.Neg: generator.Emit(new CstI(0)); generator.Emit(Instruction.Swap); generator.Emit(Instruction.Sub); break; default: throw new InvalidOperationException(string.Format("Unknown unary operator: {0}", _op)); } }
static void Main(string[] args) { if (args.Length == 2) { var scanner = new Scanner(args[0]); var parser = new Parser(scanner); parser.Parse(); switch (args[1]) { case "run": Console.WriteLine(parser.program.Eval()); return; case "check": parser.program.Check(); return; case "compile": var gen = new Generator(); const string outputFile = "a.out"; parser.program.Compile(gen, outputFile); return; } } Console.WriteLine("Usage: Program <expression.txt> [run|check|compile]"); }
public override void Compile(CompilationEnvironment compilationEnvironment, Generator generator) { _arg.Compile(compilationEnvironment, generator); var label = compilationEnvironment.GetFunctionLabel(_name); generator.Emit(new Call(1, label)); }