/// <summary> /// Compiles the current syntax tree into a compilation result. /// </summary> /// <returns>An emit result.</returns> public EmitResult Emit() { var syntaxDiagnostics = SyntaxTree.Diagnostics.Concat(GlobalScope.Diagnostics).ToImmutableArray(); if (syntaxDiagnostics.Any()) { return(new EmitResult(success: false, syntaxDiagnostics)); } var program = Binder.BindProgram(GlobalScope); if (program.Diagnostics.Any()) { return(new EmitResult(success: false, program.Diagnostics.ToImmutableArray())); } var emitDiagnostics = EmitAssembly(program); if (emitDiagnostics.Any()) { return(new EmitResult(success: false, emitDiagnostics)); } return(new EmitResult(success: true, diagnostics: ImmutableArray <Diagnostic> .Empty)); }
/// <summary> /// Evaluates the current compilation provided a symbol table with actual values. /// </summary> /// <param name="variables">The symbol table with actual values.</param> /// <returns>An evaluation result.</returns> public EvaluationResult Evaluate(Dictionary <VariableSymbol, object> variables) { var diagnostics = SyntaxTree.Diagnostics.Concat(GlobalScope.Diagnostics).ToImmutableArray(); if (diagnostics.Any()) { return(new EvaluationResult(diagnostics, null)); } var program = Binder.BindProgram(GlobalScope); var appPath = Environment.GetCommandLineArgs()[0]; var appDirectory = Path.GetDirectoryName(appPath); var cfgPath = Path.Combine(appDirectory, "cfg.dot"); var cfgStatement = !program.Statement.Statements.Any() && program.Functions.Any() ? program.Functions.Last().Value : program.Statement; var cfg = ControlFlowGraph.Create(cfgStatement); using (var streamWriter = new StreamWriter(cfgPath)) { cfg.WriteTo(streamWriter); } if (program.Diagnostics.Any()) { return(new EvaluationResult(program.Diagnostics.ToImmutableArray(), null)); } var evaluator = new Evaluator(program, variables); var value = evaluator.Evaluate(); return(new EvaluationResult(ImmutableArray <Diagnostic> .Empty, value)); }
/// <summary> /// Emits a tree for this program to the specified writer. /// </summary> /// <param name="writer">The writer.</param> public void EmitTree(TextWriter writer) { var program = Binder.BindProgram(GlobalScope); if (program.Statement.Statements.Any()) { program.Statement.WriteTo(writer); } else { foreach (var functionBody in program.Functions) { if (!GlobalScope.Functions.Contains(functionBody.Key)) { continue; } functionBody.Key.WriteTo(writer); functionBody.Value.WriteTo(writer); } } }