protected virtual BoundStatement RewriteBlockStatement(BoundBlockStatement node) { ImmutableArray <BoundStatement> .Builder builder = null; for (var i = 0; i < node.Statements.Length; i++) { var oldStatement = node.Statements[i]; var newStatement = RewriteStatement(oldStatement); if (newStatement != oldStatement) { if (builder == null) { builder = ImmutableArray.CreateBuilder <BoundStatement>(node.Statements.Length); for (var j = 0; j < i; j++) { builder.Add(node.Statements[j]); } } } if (builder != null) { builder.Add(newStatement); } } if (builder == null) { return(node); } return(new BoundBlockStatement(builder.MoveToImmutable())); }
protected override BoundStatement RewriteIfStatement(BoundIfStatement node) { if (node.ElseStatement is null) { var endLabel = CreateLabel(); var gotoIfFalse = new BoundConditionalGotoStatement(endLabel, node.Condition, jumpIfFalse: true, node.IsValid); var endLabelStmt = new BoundLabelStatement(endLabel, node.IsValid); var res = new BoundBlockStatement(ImmutableArray.Create <BoundStatement>(gotoIfFalse, node.Body, endLabelStmt), node.IsValid); return(RewriteStatement(res)); } else { var elseLabel = CreateLabel(); var endLabel = CreateLabel(); var gotoIfFalse = new BoundConditionalGotoStatement(elseLabel, node.Condition, jumpIfFalse: true, node.IsValid); var gotoEnd = new BoundGotoStatement(endLabel, node.IsValid); var elseLabelStmt = new BoundLabelStatement(elseLabel, node.IsValid); var endLabelStmt = new BoundLabelStatement(endLabel, node.IsValid); var res = new BoundBlockStatement(ImmutableArray.Create <BoundStatement>( gotoIfFalse, node.Body, gotoEnd, elseLabelStmt, node.ElseStatement, endLabelStmt ), node.IsValid); return(RewriteStatement(res)); } }
public Evaluator(BoundBlockStatement root, IDictionary <VariableSymbol, object> variables) { _root = root; _variables = variables; IndexLabels(); }
protected override BoundStatement RewriteWhileStatement(BoundWhileStatement node) { // while <condition> // <body> // // ---> // // goto check // continue: // <body> // check: // gotoTrue <condition> continue // break: // var checkLabel = GenerateLabel("Check"); var gotoCheck = new BoundGotoStatement(checkLabel); var continueLabelStatement = new BoundLabelStatement(node.ContinueLabel); var checkLabelStatement = new BoundLabelStatement(checkLabel); var gotoTrue = new BoundConditionalGotoStatement(node.ContinueLabel, node.Condition); var breakLabelStatement = new BoundLabelStatement(node.BreakLabel); var result = new BoundBlockStatement(ImmutableArray.Create <BoundStatement>( gotoCheck, continueLabelStatement, node.Body, checkLabelStatement, gotoTrue, breakLabelStatement )); return(RewriteStatement(result)); }
protected override BoundStatement RewriteWhileStatement(BoundWhileStatement node) { // while <condition> // <body> // // -----> // // goto continue // body: // <body> // continue: // gotoTrue <condition> body // break: var bodyLabel = GenerateLabel(); var continueLabel = node.ContinueLabel; var gotoContinue = new BoundGotoStatement(continueLabel); var bodyLabelStatement = new BoundLabelStatement(bodyLabel); var continueLabelStatement = new BoundLabelStatement(continueLabel); var gotoTrue = new BoundConditionalGotoStatement(bodyLabel, node.Condition, false); var breakLabelStatement = new BoundLabelStatement(node.BreakLabel); var result = new BoundBlockStatement(ImmutableArray.Create <BoundStatement>( gotoContinue, bodyLabelStatement, node.Body, continueLabelStatement, gotoTrue, breakLabelStatement)); return(RewriteStatement(result)); }
protected override BoundStatement RewriteForStatement(BoundForStatement node) { //For Statements are now all While Statements var variableDeclaration = new BoundVariableDeclaration(node.Variable, node.LowerBound); var variableExpression = new BoundVariableExpression(node.Variable); var upperBoundSymbol = new VariableSymbol("upperBound", true, typeof(int)); var upperBoundDeclaration = new BoundVariableDeclaration(upperBoundSymbol, node.UpperBound); var condition = new BoundBinaryExpression( variableExpression, BoundBinaryOperator.Bind(SyntaxKind.LessOrEqualsToken, typeof(int), typeof(int)), new BoundVariableExpression(upperBoundSymbol) ); var increment = new BoundExpressionStatement( new BoundAssignmentExpression( node.Variable, new BoundBinaryExpression( variableExpression, BoundBinaryOperator.Bind(SyntaxKind.PlusToken, typeof(int), typeof(int)), new BoundLiteralExpression(1) ) ) ); var whileBody = new BoundBlockStatement(ImmutableArray.Create <BoundStatement>(node.Body, increment)); var whileStatement = new BoundWhileStatement(condition, whileBody); var result = new BoundBlockStatement(ImmutableArray.Create <BoundStatement>( variableDeclaration, upperBoundDeclaration, whileStatement )); return(RewriteStatement(result)); }
public EvaluationResult Evaluate(Dictionary <VariableSymbol, object> variables) { ImmutableArray <Diagnostic> diagnostics = SyntaxTree.Diagnostics.Concat(GlobalScope.Diagnostics).ToImmutableArray(); if (diagnostics.Any()) { return(new EvaluationResult(diagnostics, null)); } BoundProgram program = Binder.BindProgram(GlobalScope); string appPath = Environment.GetCommandLineArgs()[0]; string appDirectory = Path.GetDirectoryName(appPath); string cfgPath = Path.Combine(appDirectory, "cfg.dot"); BoundBlockStatement cfgStatement = !program.Statement.Statements.Any() && program.Functions.Any() ? program.Functions.Last().Value : program.Statement; var cfg = ControlFlowGraph.Create(cfgStatement); using (StreamWriter streamWriter = new StreamWriter(cfgPath)) cfg.WriteTo(streamWriter); if (program.Diagnostics.Any()) { return(new EvaluationResult(program.Diagnostics.ToImmutableArray(), null)); } Evaluator evaluator = new Evaluator(program, variables); object value = evaluator.Evaluate(); return(new EvaluationResult(ImmutableArray <Diagnostic> .Empty, value)); }
protected override BoundStatement RewriteWhileStatement(BoundWhileStatement node) { // while <condition> <body> // --- to ---> // { // continue: // gotoFalse <condition> break // <body> // goto continue // break: // } var continueLabel = node.ContinueLabel; var breakLabel = node.BreakLabel; var continueStatement = new BoundLabelStatement(continueLabel); var gotoFalseStatement = new BoundConditionalGotoStatement(breakLabel, node.Condition, jumpIfTrue: false); var gotoContinue = new BoundGotoStatement(continueLabel); var breakStatement = new BoundLabelStatement(breakLabel); var result = new BoundBlockStatement( continueStatement, gotoFalseStatement, node.Body, gotoContinue, breakStatement); return(RewriteStatement(result)); }
protected override BoundStatement RewriteForStatement(BoundForStatement node) { /* * { * let upperBound = <UpperBound> * <variable> = <lowerBound> * while <variable> < <UpperBound> * { * <statement> * <variable> = <variable> + 1 * } * } */ var upperBoundSymbol = new VariableSymbol("upperBound", true, node.UpperBound.Type, true); var upperBoundDeclaration = new BoundVariableDeclaration(upperBoundSymbol, node.UpperBound); var upperBoundExpression = new BoundVariableExpression(upperBoundSymbol); var variableDeclaration = new BoundVariableDeclaration(node.Variable, node.LowerBound); // LowerBound shouldn't be rewriten? var variableExpression = new BoundVariableExpression(node.Variable); var conditionOperator = BoundBinaryOperator.Bind(SyntaxKind.LessToken, TypeSymbol.Int, TypeSymbol.Int); var condition = new BoundBinaryExpression(variableExpression, conditionOperator, upperBoundExpression); // UpperBound shouldn't be rewriten? var incrementOperator = BoundBinaryOperator.Bind(SyntaxKind.PlusToken, node.Variable.Type, TypeSymbol.Int); var increment = new BoundBinaryExpression(variableExpression, incrementOperator, new BoundLiteralExpression(1)); var incrementAssignment = new BoundAssignmentExpression(node.Variable, increment); var incrementStatement = new BoundExpressionStatement(incrementAssignment); var whileBlockStatement = new BoundBlockStatement(ImmutableArray.Create <BoundStatement>(node.Statement, incrementStatement)); var whileStatement = new BoundWhileStatement(condition, whileBlockStatement); var result = new BoundBlockStatement(ImmutableArray.Create <BoundStatement>(upperBoundDeclaration, variableDeclaration, whileStatement)); return(RewriteStatement(result)); }
protected override BoundStatement RewriteDoWhileStatement(BoundDoWhileStatement node) { // do // <body> // while <condition> // // -----> // // continue: // <body> // gotoTrue <condition> continue // var continueLabelStatement = new BoundLabelStatement(node.ContinueLabel); var gotoTrue = new BoundConditionalGotoStatement(node.ContinueLabel, node.Condition); var breakLabelStatement = new BoundLabelStatement(node.BreakLabel); var result = new BoundBlockStatement(ImmutableArray.Create <BoundStatement>( continueLabelStatement, node.Body, gotoTrue, breakLabelStatement )); return(RewriteStatement(result)); }
/// <inheritdoc/> protected override BoundStatement RewriteForInfiniteStatement(BoundForInfiniteStatement node) { // for // <body> // // ----> // // { // continue: // <body> // goto continue // break: // } var continueLabelStatement = new BoundLabelStatement(node.ContinueLabel); var gotoContinue = new BoundGotoStatement(node.ContinueLabel); var breakLabelStatement = new BoundLabelStatement(node.BreakLabel); var result = new BoundBlockStatement(ImmutableArray.Create <BoundStatement>( continueLabelStatement, node.Body, gotoContinue, breakLabelStatement)); return(RewriteStatement(result)); }
private void EvaluateBlockStatement(BoundBlockStatement node) { foreach (var statement in node.Statements) { EvaluateStatement(statement); } }
protected override BoundStatement RewriteWhileStatement(BoundWhileStatement node) { // goto continue // body: // <body> // continue: // goto body if <condition> // break: var bodyLabel = CreateLabel(); var gotoContinue = new BoundGotoStatement(node.ContinueLabel, node.IsValid); var gotoBody = new BoundConditionalGotoStatement(bodyLabel, node.Condition, jumpIfFalse: false, node.IsValid); var continueLabelStmt = new BoundLabelStatement(node.ContinueLabel, node.IsValid); var bodyLabelStmt = new BoundLabelStatement(bodyLabel, node.IsValid); var breakLabelStmt = new BoundLabelStatement(node.BreakLabel, node.IsValid); var res = new BoundBlockStatement(ImmutableArray.Create <BoundStatement>( gotoContinue, bodyLabelStmt, node.Body, continueLabelStmt, gotoBody, breakLabelStmt ), node.IsValid); return(RewriteStatement(res)); }
protected override BoundStatement RewriteIfStatement(BoundIfStatement node) { if (node.ElseStatement == null) { var endLabel = GenerateLabel("EndIf"); var gotoFalse = new BoundConditionalGotoStatement(endLabel, node.Condition, false); var endLabelStatement = new BoundLabelStatement(endLabel); var result = new BoundBlockStatement(ImmutableArray.Create <BoundStatement>( gotoFalse, node.ThenStatement, endLabelStatement )); return(RewriteStatement(result)); } else { var endLabel = GenerateLabel("EndIf"); var elseLabel = GenerateLabel("IfElse"); var gotoFalse = new BoundConditionalGotoStatement(elseLabel, node.Condition, false); var gotoEndStatement = new BoundGotoStatement(endLabel); var elseLabelStatement = new BoundLabelStatement(elseLabel); var endLabelStatement = new BoundLabelStatement(endLabel); var result = new BoundBlockStatement(ImmutableArray.Create <BoundStatement>( gotoFalse, node.ThenStatement, gotoEndStatement, elseLabelStatement, node.ElseStatement, endLabelStatement )); return(RewriteStatement(result)); } }
private object EvaluateStatement(BoundBlockStatement body) { var labelToIndex = new Dictionary <BoundLabel, int>(); for (var i = 0; i < body.Statements.Length; i++) { if (body.Statements[i] is BoundLabelStatement l) { labelToIndex.Add(l.Label, i + 1); } } var index = 0; while (index < body.Statements.Length) { var s = body.Statements[index]; switch (s.Kind) { case BoundNodeKind.VariableDeclaration: EvaluateVariableDeclaration((BoundVariableDeclaration)s); index++; break; case BoundNodeKind.ExpressionStatement: EvaluateExpressionStatement((BoundExpressionStatement)s); index++; break; case BoundNodeKind.GotoStatement: var gs = (BoundGotoStatement)s; index = labelToIndex[gs.Label]; break; case BoundNodeKind.ConditionalGotoStatement: var cgs = (BoundConditionalGotoStatement)s; var condition = (bool)EvaluateExpression(cgs.Condition); if (condition == cgs.JumpIfTrue) { index = labelToIndex[cgs.Label]; } else { index++; } break; case BoundNodeKind.LabelStatement: index++; break; default: throw new Exception($"Unexpected node {s.Kind}"); } } return(_lastValue); }
protected override BoundStatement RewriteIfStatement(BoundIfStatement node) { if (node.ElseStatement == null) { // if <condition> // <then> // // ----> // // gotoFalse <condition> end // <then> // end: // var endLabel = GenerateLabel(); var gotoFalse = new BoundConditionalGotoStatement(endLabel, node.Condition, false); var endLabelStatement = new BoundLabelStatement(endLabel); var result = new BoundBlockStatement(ImmutableArray.Create <BoundStatement>(gotoFalse, node.ThenStatement, endLabelStatement)); return(RewriteStatement(result)); } else { // if <condition> // <then> // else // <else> // // ----> // // gotoFalse <condition> else // <then> // goto end // else: // <else> // end: var elseLabel = GenerateLabel(); var endLabel = GenerateLabel(); var gotoFalse = new BoundConditionalGotoStatement(elseLabel, node.Condition, false); var gotoEndStatement = new BoundGotoStatement(endLabel); var elseLabelStatement = new BoundLabelStatement(elseLabel); var endLabelStatement = new BoundLabelStatement(endLabel); var result = new BoundBlockStatement(ImmutableArray.Create <BoundStatement>( gotoFalse, node.ThenStatement, gotoEndStatement, elseLabelStatement, node.ElseStatement, endLabelStatement )); return(RewriteStatement(result)); } }
protected override BoundStatement RewriteForStatement(BoundForStatement node) { /* * for <var> = <lower> to <upper> * <body> * * -----> * { * var <var> = <lower> * let upperBound = <upper> * while (<var> <= <upperBound>) * { * <body> * <var> = <var> + 1 * } * } */ // var <var> = <lower> var variableDeclaration = new BoundVariableDeclaration(node.Variable, node.LowerBound); // let upperBound = <upper> var upperBoundSymbol = new VariableSymbol("upperBound", true, TypeSymbol.Int); var upperBoundDeclaration = new BoundVariableDeclaration(upperBoundSymbol, node.UpperBound); // <var> var variableExpression = new BoundVariableExpression(node.Variable); //<var> <= <upperBound> var condition = new BoundBinaryExpression( variableExpression, BoundBinaryOperator.Bind(SyntaxKind.LessOrEqualsToken, TypeSymbol.Int, TypeSymbol.Int), new BoundVariableExpression(upperBoundSymbol) ); // <var> = <var> + 1 var increment = new BoundExpressionStatement( new BoundAssignmentExpression( node.Variable, new BoundBinaryExpression( variableExpression, BoundBinaryOperator.Bind(SyntaxKind.PlusToken, TypeSymbol.Int, TypeSymbol.Int), new BoundLiteralExpression(1) ) ) ); var whileBlock = new BoundBlockStatement(ImmutableArray.Create(node.Body, increment)); var whileStatement = new BoundWhileStatement(condition, whileBlock); var result = new BoundBlockStatement(ImmutableArray.Create <BoundStatement>( variableDeclaration, upperBoundDeclaration, whileStatement)); return(RewriteStatement(result)); }
protected override BoundStatement RewriteForStatement(BoundForStatement node) { // for <var> = <lower> to <upper> // <body> // // ----> // { // var <var> = <lower> // let upperBound = <upper> // while (<var> <= upperBound) // { // <body> // continue: // <var> = <var> + 1 // } // } var variableDeclaration = new BoundVariableDeclaration(node.Variable, node.LowerBound); var variableExpression = new BoundVariableExpression(node.Variable); var upperBoundSymbol = new LocalVariableSymbol("upperBound", true, TypeSymbol.Int); var upperBoundDeclaration = new BoundVariableDeclaration(upperBoundSymbol, node.UpperBound); var condition = new BoundBinaryExpression( variableExpression, BoundBinaryOperator.Bind(SyntaxKind.LessOrEqualsToken, TypeSymbol.Int, TypeSymbol.Int), new BoundVariableExpression(upperBoundSymbol) ); var continueLabelStatement = new BoundLabelStatement(node.ContinueLabel); var increment = new BoundExpressionStatement( new BoundAssignmentExpression( node.Variable, new BoundBinaryExpression( variableExpression, BoundBinaryOperator.Bind(SyntaxKind.PlusToken, TypeSymbol.Int, TypeSymbol.Int), new BoundLiteralExpression(1) ) ) ); var whileBody = new BoundBlockStatement( ImmutableArray.Create <BoundStatement>( node.Body, continueLabelStatement, increment ) ); var whileStatement = new BoundWhileStatement(condition, whileBody, node.BreakLabel, GenerateLabel()); var result = new BoundBlockStatement( ImmutableArray.Create <BoundStatement>( variableDeclaration, upperBoundDeclaration, whileStatement ) ); return(RewriteStatement(result)); }
protected override BoundStatement RewriteConditionalStatement(BoundConditionalStatement node) { if (node.ElseStatement is null) { // if <condition> <then> // --- to ---> // { // gotoFalse <condition> end // <then> // end: // } var endLabel = GenerateLabel("end"); var gotoFalse = new BoundConditionalGotoStatement(endLabel, node.Condition, false); var endLabelStatement = new BoundLabelStatement(endLabel); var result = new BoundBlockStatement( gotoFalse, node.ThenStatement, endLabelStatement); return(RewriteStatement(result)); } else { // if <condition> <then> else <else> // --- to ---> // { // gotoFalse <condition> else // <then> // goto end // else: // <else> // end: // } var endLabel = GenerateLabel("end"); var elseLabel = GenerateLabel("else"); var gotoFalse = new BoundConditionalGotoStatement(elseLabel, node.Condition, false); var gotoEnd = new BoundGotoStatement(endLabel); var elseLabelStatement = new BoundLabelStatement(elseLabel); var endLabelStatement = new BoundLabelStatement(endLabel); var result = new BoundBlockStatement( gotoFalse, node.ThenStatement, gotoEnd, elseLabelStatement, node.ElseStatement, endLabelStatement); return(RewriteStatement(result)); } }
protected override BoundStatement RewriteForStatement(BoundForStatement node) { var initializer = new BoundExpressionStatement(node.Initializer); var loop = new BoundExpressionStatement(node.Loop); var continueLabelStatement = new BoundLabelStatement(node.ContinueLabel); var whileBlock = new BoundBlockStatement(ImmutableArray.Create <BoundStatement>(node.Body, continueLabelStatement, loop)); var whileStatement = new BoundWhileStatement(node.Condition, whileBlock, node.BreakLabel, GenerateLabel()); var result = new BoundBlockStatement(ImmutableArray.Create <BoundStatement>(initializer, whileStatement)); return(RewriteStatement(result)); }
private static void WriteBoundBlockStatement(this IndentedTextWriter writer, BoundBlockStatement node) { writer.ColorWrite("{"); writer.Indent += 4; foreach (var n in node.Statements) { writer.WriteLine(); writer.WriteBoundNode(n); } writer.Indent -= 4; writer.WriteLine(); writer.ColorWrite("}"); }
protected override BoundStatement RewriteForToStatement(BoundForToStatement node) { // for <var> = <lower> to <upper> <body> // --- to ---> // { // var <var> = <lower> // let upperBound = <upper> // while <var> <= upperBound // <body> // continue: // <var> = <var> + 1 // } var variableDeclaration = new BoundVariableDeclarationStatement(node.Variable, node.LowerBound); var upperBoundSymbol = new LocalVariableSymbol("upperBound", true, TypeSymbol.Int); var upperBoundDeclaration = new BoundVariableDeclarationStatement(upperBoundSymbol, node.UpperBound); var upperBoundExpression = new BoundVariableExpression(upperBoundSymbol); var condition = new BoundBinaryExpression( new BoundVariableExpression(node.Variable), BoundBinaryOperator.Bind(Lexing.TokenKind.LessOrEquals, TypeSymbol.Int, TypeSymbol.Int), upperBoundExpression); var increment = new BoundExpressionStatement( new BoundAssignmentExpression( node.Variable, new BoundBinaryExpression( new BoundVariableExpression(node.Variable), BoundBinaryOperator.Bind(Lexing.TokenKind.Plus, TypeSymbol.Int, TypeSymbol.Int), new BoundLiteralExpression(1)))); var whileBlock = new BoundBlockStatement( node.Body, increment); var whileStatement = new BoundWhileStatement(condition, whileBlock, node.BreakLabel, node.ContinueLabel); var result = new BoundBlockStatement( variableDeclaration, upperBoundDeclaration, whileStatement); return(RewriteStatement(result)); }
private static BoundBlockStatement RemoveDeadCode(BoundBlockStatement node) { var controlFlow = ControlFlowGraph.Create(node); var reachableStatements = new HashSet <BoundStatement>(controlFlow.Blocks.SelectMany(b => b.Statements)); var builder = node.Statements.ToBuilder(); for (var i = builder.Count - 1; i >= 0; i--) { if (!reachableStatements.Contains(builder[i])) { builder.RemoveAt(i); } } return(new BoundBlockStatement(node.Syntax, builder.ToImmutable())); }
protected override BoundStatement RewriteDoWhileStatement(BoundDoWhileStatement node) { var continueLabelStmt = new BoundLabelStatement(node.ContinueLabel, node.IsValid); var breakLabelStmt = new BoundLabelStatement(node.BreakLabel, node.IsValid); var gotoContinue = new BoundConditionalGotoStatement(node.ContinueLabel, node.Condition, jumpIfFalse: false, node.IsValid); var res = new BoundBlockStatement(ImmutableArray.Create <BoundStatement>( continueLabelStmt, node.Body, gotoContinue, breakLabelStmt ), node.IsValid); return(RewriteStatement(res)); }
protected override BoundStatement RewriteDoWhileStatement(BoundDoWhileStatement node) { var bodyLabel = GenerateLabel(); var bodyLabelStatement = new BoundLabelStatement(bodyLabel); var continueLabelStatement = new BoundLabelStatement(node.ContinueLabel); var gotoTrue = new BoundConditionalGotoStatement(bodyLabel, node.Condition); var breakLabelStatement = new BoundLabelStatement(node.BreakLabel); var result = new BoundBlockStatement(ImmutableArray.Create <BoundStatement>( bodyLabelStatement, node.Body, continueLabelStatement, gotoTrue, breakLabelStatement )); return(RewriteStatement(result)); }
protected override BoundStatement RewriteWhileStatement(BoundWhileStatement node) { /* * check: * gotoIfFalse <condition> end * <statement> * goto check * end: */ var checkLabelStatement = new BoundLabelStatement(GenerateLabel()); var endLabelStatement = new BoundLabelStatement(GenerateLabel()); var gotoIfFalseStatement = new BoundConditionalGotoStatement(endLabelStatement.Label, node.Condition, false); var gotoCheckStatement = new BoundGotoStatement(checkLabelStatement.Label); var statements = ImmutableArray.Create <BoundStatement>(checkLabelStatement, gotoIfFalseStatement, node.Statement, gotoCheckStatement, endLabelStatement); var result = new BoundBlockStatement(statements); return(RewriteStatement(result)); }
private object EvaluateCallExpression(BoundCallExpression node) { if (node.Function == BuiltinFunctions.Input) { return(Console.ReadLine()); } else if (node.Function == BuiltinFunctions.Print) { string message = (string)EvaluateExpression(node.Arguments[0]); Console.WriteLine(message); return(null); } else if (node.Function == BuiltinFunctions.Rnd) { int max = (int)EvaluateExpression(node.Arguments[0]); if (random == null) { random = new Random(); } return(random.Next(max)); } else { Dictionary <VariableSymbol, object> localVars = new Dictionary <VariableSymbol, object>(); for (int i = 0; i < node.Arguments.Length; i++) { ParameterSymbol parameter = node.Function.Parameters[i]; object value = EvaluateExpression(node.Arguments[i]); localVars.Add(parameter, value); } locals.Push(localVars); BoundBlockStatement statement = program.Functions[node.Function]; object result = EvaluateStatement(statement); locals.Pop(); return(result); } }
private void EmitFunctionBody(FunctionSymbol function, BoundBlockStatement body) { var method = _methods[function]; _locals.Clear(); var ilProcessor = method.Body.GetILProcessor(); foreach (var statement in body.Statements) { EmitStatement(ilProcessor, statement); } // HACK: We should make sure that our bound tree has explicit returns. if (function.Type == TypeSymbol.Void) { ilProcessor.Emit(OpCodes.Ret); } method.Body.OptimizeMacros(); }
protected override BoundStatement RewriteForStatement(BoundForStatement node) { var condition = node.Condition; var continueLabelStatement = new BoundLabelStatement(node.ContinueLabel); var increment = new BoundExpressionStatement( node.Action ); var whileBody = new BoundBlockStatement(ImmutableArray.Create <BoundStatement>( node.Body, continueLabelStatement, increment) ); var whileStatement = new BoundWhileStatement(condition, whileBody, node.BreakLabel, GenerateLabel()); var result = new BoundBlockStatement(ImmutableArray.Create <BoundStatement>( node.Variable, whileStatement )); return(RewriteStatement(result)); }
protected override BoundStatement RewriteDoWhileStatement(BoundDoWhileStatement node) { BoundLabel bodyLabel = GenerateLabel(); BoundLabel endLabel = new BoundLabel("End"); BoundLabelStatement bodyLabelStatement = new BoundLabelStatement(bodyLabel); BoundLabelStatement continueLabelStatement = new BoundLabelStatement(node.ContinueLabel); BoundConditionalGotoStatement gotoTrue = new BoundConditionalGotoStatement(bodyLabel, node.Condition, true); BoundLabelStatement breakLabelStatement = new BoundLabelStatement(node.BreakLabel); BoundLabelStatement endLabelStatement = new BoundLabelStatement(endLabel); BoundBlockStatement result = new BoundBlockStatement(ImmutableArray.Create <BoundStatement>( bodyLabelStatement, node.Body, continueLabelStatement, gotoTrue, breakLabelStatement, endLabelStatement )); return(RewriteStatement(result)); }