protected override BoundStatement RewriteWhileStatement(BoundWhileStatement node) { // while <condition> // <bode> // // -----> // // goto continue // <body> // continue: // gotoTrue <condition> body // Break // var gotoContinue = new BoundGotoStatment(node.ContinueLabel); var bodyLabelStatement = new BoundLabelStatement(node.BodyLabel); var continueLabelStatement = new BoundLabelStatement(node.ContinueLabel); var gotoTrue = new BoundConditionalGotoStatment(node.BodyLabel, node.Condition); var breakLabelStatement = new BoundLabelStatement(node.BreakLabel); var result = new BoundBlockStatemnet(ImmutableArray.Create <BoundStatement>( gotoContinue, bodyLabelStatement, node.Body, continueLabelStatement, gotoTrue, breakLabelStatement )); return(RewriteStatement(result)); }
protected override BoundStatement RewriteIfStatement(BoundIfStatement node) { if (node.ElseStatement == null) { // if <condition> // <then> // // ----> // // gotoFalse <condition> end // <then> // end: var endLabel = GenerateLabel(); var gotoFalse = new BoundConditionalGotoStatment(endLabel, node.Condition, false); var endLabelStatement = new BoundLabelStatement(endLabel); var result = new BoundBlockStatemnet(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 BoundConditionalGotoStatment(elseLabel, node.Condition, false); var gotoEndStatement = new BoundGotoStatment(endLabel); var elseLabelStatement = new BoundLabelStatement(elseLabel); var endLabelStatement = new BoundLabelStatement(endLabel); var result = new BoundBlockStatemnet(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> // while (<var> <= <upper>) // { // <body> // <var> = <var> + 1 // } // } var variableDeclaration = new BoundVeriableDeclaration(node.Variable, node.LowerBound); var variableExpression = new BoundVariableExpression(node.Variable); var upperBoundSybmle = new VariableSymble("upperBound", true, typeof(int)); var upperBoundDeclaration = new BoundVeriableDeclaration(upperBoundSybmle, node.UpperBound); var condition = new BoundBinaryExpression( variableExpression, BoundBinaryOperator.Bind(SyntaxKind.LessOrEqualToken, typeof(int), typeof(int)), new BoundVariableExpression(upperBoundSybmle) ); var increment = new BoundExpressionStatemnet( new BoundAssignmentExpression( node.Variable, new BoundBinaryExpression( variableExpression, BoundBinaryOperator.Bind(SyntaxKind.PlusToken, typeof(int), typeof(int)), new BoundLiteralExpression(1) ) ) ); var whileBody = new BoundBlockStatemnet(ImmutableArray.Create <BoundStatement>(node.Body, increment)); var whileStatement = new BoundWhileStatement(condition, whileBody); var result = new BoundBlockStatemnet(ImmutableArray.Create <BoundStatement>( variableDeclaration, upperBoundDeclaration, whileStatement)); return(RewriteStatement(result)); }
protected override BoundStatement RewriteWhileStatement(BoundWhileStatement node) { // while <condition> // <bode> // // -----> // // goto check // continue: // <body> // check: // gotoTrue <condition> continue // end: // var continueLabel = GenerateLabel(); var checkLabel = GenerateLabel(); var endLabel = GenerateLabel(); var gotoCheck = new BoundGotoStatment(checkLabel); var continueLabelStatement = new BoundLabelStatement(continueLabel); var checkLabelStatement = new BoundLabelStatement(checkLabel); var gotoTrue = new BoundConditionalGotoStatment(continueLabel, node.Condition); var endLabelStatement = new BoundLabelStatement(endLabel); var result = new BoundBlockStatemnet(ImmutableArray.Create <BoundStatement>( gotoCheck, continueLabelStatement, node.Body, checkLabelStatement, gotoTrue, endLabelStatement )); return(RewriteStatement(result)); }
protected override BoundStatement RewriteForStatement(BoundForStatement node) { // for <var> = <lower> to <upper> by <incriment> // <body> // // ----> // // { // var <var> = <lower> // while (<var> <= <upper>) // { // <body> // continue: // <var> = <var> + 1 // } // } var variableDeclaration = new BoundVeriableDeclaration(node.Variable, node.LowerBound); var variableExpression = new BoundVariableExpression(node.Variable); var upperBoundSybmle = new LocalVariableSymbol("upperBound", true, TypeSymbol.Int); var upperBoundDeclaration = new BoundVeriableDeclaration(upperBoundSybmle, node.UpperBound); var condition = new BoundBinaryExpression( variableExpression, BoundBinaryOperator.Bind(SyntaxKind.LessOrEqualToken, TypeSymbol.Int, TypeSymbol.Int), new BoundVariableExpression(upperBoundSybmle) ); var Ittertator = node.Itterator; var Operator = SyntaxKind.PlusToken; if (Ittertator == null) { Ittertator = new BoundLiteralExpression(1); } var continueLabelStatement = new BoundLabelStatement(node.ContinueLabel); var increment = new BoundExpressionStatemnet( new BoundAssignmentExpression( node.Variable, new BoundBinaryExpression( variableExpression, BoundBinaryOperator.Bind(Operator, TypeSymbol.Int, TypeSymbol.Int), Ittertator ) ) ); var whileBody = new BoundBlockStatemnet(ImmutableArray.Create <BoundStatement>( node.Body, continueLabelStatement, increment) ); var whileStatement = new BoundWhileStatement(condition, whileBody, node.BodyLabel, node.BreakLabel, GenerateLabel()); var result = new BoundBlockStatemnet(ImmutableArray.Create <BoundStatement>( variableDeclaration, upperBoundDeclaration, whileStatement)); return(RewriteStatement(result)); }
public Evaluator(BoundBlockStatemnet root, Dictionary <VariableSymble, object> variables) { _root = root; _variables = variables; }
private object EvaluateStatement(BoundBlockStatemnet body) { var labeleToIndex = new Dictionary <BoundLabel, int>(); for (var i = 0; i < body.Statements.Length; i++) { if (body.Statements[i] is BoundLabelStatement l) { labeleToIndex.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((BoundVeriableDeclaration)s); index++; break; case BoundNodeKind.ExpressionStatement: EvaluateExpressiontatement((BoundExpressionStatemnet)s); index++; break; case BoundNodeKind.GotoStatment: var gs = (BoundGotoStatment)s; index = labeleToIndex[gs.Label]; break; case BoundNodeKind.ConditionalGotoStatment: var cgs = (BoundConditionalGotoStatment)s; var condition = (bool)EvaluateExpression(cgs.Condition); if (condition == cgs.JumpIfTrue) { index = labeleToIndex[cgs.Label]; } else { index++; } break; case BoundNodeKind.LabelStatement: index++; break; case BoundNodeKind.ReturnStatement: var rs = (BoundReturnStatement)s; _lastValue = rs.Expression == null ? null : EvaluateExpression(rs.Expression); return(_lastValue); default: throw new Exception($"Unexpected node {s.Kind}"); } } return(_lastValue); }