protected virtual ICfgNode Build(IfThen ifThen) { ifThen.Condition.Accept(this); var condition = Result; ifThen.Body?.Accept(this); var body = Result; if (condition == null && body == null) { return(null); } return(Emit.If(condition ?? ifThen.Condition, body ?? ifThen.Body)); }
private Statement ParseStatement() { Statement parsedStatement; if (currentToken == listTokens.Count) { ExceptionHandler("statement was expected before end of file"); } if (listTokens[currentToken].Equals("print")) { currentToken++; Write _Write = new Write(); _Write.Expression = ParseExpression(); parsedStatement = _Write; } else if (listTokens[currentToken].Equals("var")) { currentToken++; DeclareVariable _DeclareVariable = new DeclareVariable(); if (currentToken < listTokens.Count && listTokens[currentToken] is string) { _DeclareVariable.Identifier = (string)listTokens[currentToken]; } else { ExceptionHandler("variable name was expected after 'var'"); } currentToken++; if (currentToken == listTokens.Count || listTokens[currentToken].ToString() != Lexer.Tokens.EqualTo.ToString()) { ExceptionHandler("= sign was expected after 'var identifier'"); } currentToken++; _DeclareVariable.Expression = ParseExpression(); parsedStatement = _DeclareVariable; } else if (listTokens[currentToken].Equals("call")) { currentToken++; CallFunction _CallFunction = new CallFunction(); if (currentToken < listTokens.Count && listTokens[currentToken] is string) { _CallFunction.FunctionName = (string)listTokens[currentToken]; } else { ExceptionHandler("function name is expected after 'call'"); } currentToken++; _CallFunction.Parameter1 = ParseExpression(); //index++; if (currentToken == listTokens.Count || listTokens[currentToken].ToString() != Lexer.Tokens.Comma.ToString()) { ExceptionHandler("',' sign was expected after first parameter"); } currentToken++; _CallFunction.Parameter2 = ParseExpression(); //index++; if (currentToken == listTokens.Count || listTokens[currentToken].ToString() != Lexer.Tokens.Comma.ToString()) { ExceptionHandler("',' sign was expected after second parameter"); } currentToken++; _CallFunction.Parameter3 = ParseExpression(); //index++; if (currentToken == listTokens.Count || listTokens[currentToken].ToString() != Lexer.Tokens.Terminator.ToString()) { ExceptionHandler("';' sign was expected after third parameter"); } parsedStatement = _CallFunction; } else if (listTokens[currentToken].Equals("string") || listTokens[currentToken].Equals("numeric") || listTokens[currentToken].Equals("void")) { DeclareFunction _DeclareFunction = new DeclareFunction(); _DeclareFunction.ReturnType = listTokens[currentToken].ToString(); currentToken++; if (currentToken < listTokens.Count && listTokens[currentToken] is string) { _DeclareFunction.FunctionName = (string)listTokens[currentToken]; } else { ExceptionHandler("function name is expected after return type"); } currentToken++; if (listTokens[currentToken].Equals("var")) { currentToken++; DeclareVariable _DeclareVariable = new DeclareVariable(); if (currentToken < listTokens.Count && listTokens[currentToken] is string) { _DeclareVariable.Identifier = (string)listTokens[currentToken]; } else { ExceptionHandler("variable name was expected after 'var'"); } currentToken++; if (currentToken == listTokens.Count || listTokens[currentToken].ToString() != Lexer.Tokens.EqualTo.ToString()) { ExceptionHandler("= sign was expected after 'var identifier'"); } currentToken++; _DeclareVariable.Expression = ParseExpression(); _DeclareFunction.Parameter1 = _DeclareVariable; } currentToken++; if (listTokens[currentToken].Equals("var")) { currentToken++; DeclareVariable _DeclareVariable = new DeclareVariable(); if (currentToken < listTokens.Count && listTokens[currentToken] is string) { _DeclareVariable.Identifier = (string)listTokens[currentToken]; } else { ExceptionHandler("variable name was expected after 'var'"); } currentToken++; if (currentToken == listTokens.Count || listTokens[currentToken].ToString() != Lexer.Tokens.EqualTo.ToString()) { ExceptionHandler("= sign was expected after 'var identifier'"); } currentToken++; _DeclareVariable.Expression = ParseExpression(); _DeclareFunction.Parameter2 = _DeclareVariable; } currentToken++; if (listTokens[currentToken].Equals("var")) { currentToken++; DeclareVariable _DeclareVariable = new DeclareVariable(); if (currentToken < listTokens.Count && listTokens[currentToken] is string) { _DeclareVariable.Identifier = (string)listTokens[currentToken]; } else { ExceptionHandler("variable name was expected after 'var'"); } currentToken++; if (currentToken == listTokens.Count || listTokens[currentToken].ToString() != Lexer.Tokens.EqualTo.ToString()) { ExceptionHandler("= sign was expected after 'var identifier'"); } currentToken++; _DeclareVariable.Expression = ParseExpression(); _DeclareFunction.Parameter3 = _DeclareVariable; } if (currentToken == listTokens.Count || !listTokens[currentToken].Equals("begin")) { ExceptionHandler("expected 'begin' after input parameters"); } currentToken++; _DeclareFunction.Body = ParseStatement(); parsedStatement = _DeclareFunction; if (currentToken == listTokens.Count || !listTokens[currentToken].Equals("endfunc")) { ExceptionHandler("unterminated function', 'endfunc' expected at the end"); } currentToken++; } else if (listTokens[currentToken].Equals("read")) { currentToken++; ReadInput _ReadInput = new ReadInput(); if (currentToken < listTokens.Count && listTokens[currentToken] is string) { _ReadInput.Identifier = (string)listTokens[currentToken++]; parsedStatement = _ReadInput; } else { ExceptionHandler("variable name is expected after 'read'"); parsedStatement = null; } } // IfThenElse ifThenElse = new IfThenElse(); // RelationalExpression relExpr = new RelationalExpression(); // relExpr.Left = ParseExpression(); // if (listTokens[index] == Scanner.EqualTo) // relExpr.Operand = RelationalOperands.EqualTo; // else if (listTokens[index] == Scanner.LessThan) // relExpr.Operand = RelationalOperands.LessThan; // else if (listTokens[index] == Scanner.GreaterThan) // relExpr.Operand = RelationalOperands.GreaterThan; // else // { // ExceptionHandler("expected relational operand"); // } // index++; // relExpr.Right = ParseExpression(); // ifThenElse.If = relExpr; // index++; // ifThenElse.Then = ParseStatement(); // parsedStatement = ifThenElse; // //index++; else if (listTokens[this.currentToken].Equals("while")) { currentToken++; While _while = new While(); _while.LeftExpression = ParseExpression(); if (listTokens[currentToken].ToString() == Lexer.Tokens.EqualTo.ToString()) { _while.Operand = RelationalOperands.EqualTo; } else if (listTokens[currentToken].ToString() == Lexer.Tokens.LessThan.ToString()) { _while.Operand = RelationalOperands.LessThan; } else if (listTokens[currentToken].ToString() == Lexer.Tokens.GreaterThan.ToString()) { _while.Operand = RelationalOperands.GreaterThan; } currentToken++; _while.RightExpression = ParseExpression(); if (currentToken == listTokens.Count || !listTokens[currentToken].Equals("do")) { ExceptionHandler("expected 'do' after while"); } currentToken++; _while.Body = ParseStatement(); parsedStatement = _while; if (currentToken == listTokens.Count || !listTokens[currentToken].Equals("endwhile")) { ExceptionHandler("unterminated 'while', endwhile expected at the end"); } currentToken++; } else if (listTokens[this.currentToken].Equals("if")) { currentToken++; IfThen _IfThen = new IfThen(); _IfThen.LeftExpression = ParseExpression(); if (listTokens[currentToken].ToString() == Lexer.Tokens.EqualTo.ToString()) { _IfThen.Operand = RelationalOperands.EqualTo; } else if (listTokens[currentToken].ToString() == Lexer.Tokens.LessThan.ToString()) { _IfThen.Operand = RelationalOperands.LessThan; } else if (listTokens[currentToken].ToString() == Lexer.Tokens.GreaterThan.ToString()) { _IfThen.Operand = RelationalOperands.GreaterThan; } currentToken++; _IfThen.RightExpression = ParseExpression(); if (currentToken == listTokens.Count || !listTokens[currentToken].Equals("then")) { ExceptionHandler("expected 'then' after if"); } currentToken++; _IfThen.ThenBody = ParseStatement(); if (currentToken == listTokens.Count || !listTokens[currentToken].Equals("else")) { ExceptionHandler("'else' is expected"); } currentToken++; _IfThen.ElseBody = ParseStatement(); parsedStatement = _IfThen; if (currentToken == listTokens.Count || !listTokens[currentToken].Equals("endif")) { ExceptionHandler("unterminated 'if', endif expected at the end"); } currentToken++; } else if (listTokens[currentToken].Equals("for")) { currentToken++; For _For = new For(); if (currentToken < listTokens.Count && listTokens[currentToken] is string) { _For.Identifier = (string)listTokens[currentToken]; } else { ExceptionHandler("expected identifier after 'for'"); } currentToken++; if (currentToken == listTokens.Count || listTokens[currentToken].ToString() != Lexer.Tokens.EqualTo.ToString()) { ExceptionHandler("for missing '='"); } currentToken++; _For.From = ParseExpression(); if (currentToken == listTokens.Count || !listTokens[currentToken].Equals("to")) { ExceptionHandler("expected 'to' after for"); } currentToken++; _For.To = ParseExpression(); if (currentToken == listTokens.Count || !listTokens[currentToken].Equals("do")) { ExceptionHandler("expected 'do' after from expression in for loop"); } currentToken++; _For.Body = ParseStatement(); parsedStatement = _For; if (currentToken == listTokens.Count || !listTokens[currentToken].Equals("end")) { ExceptionHandler("unterminated 'for' loop body"); } currentToken++; } else if (listTokens[currentToken] is string) { // assignment Assignment _Assignment = new Assignment(); _Assignment.Identifier = (string)listTokens[currentToken++]; if (currentToken == listTokens.Count || listTokens[currentToken].ToString() != Lexer.Tokens.EqualTo.ToString()) { ExceptionHandler("expected '='"); } currentToken++; _Assignment.Expression = ParseExpression(); parsedStatement = _Assignment; } else { ExceptionHandler("parse error at token " + currentToken + ": " + listTokens[currentToken]); parsedStatement = null; } if (currentToken < listTokens.Count && listTokens[currentToken].ToString() == Lexer.Tokens.Terminator.ToString()) { currentToken++; if (currentToken < listTokens.Count && !listTokens[currentToken].Equals("end") && !listTokens[currentToken].Equals("else") && !listTokens[currentToken].Equals("endif") && !listTokens[currentToken].Equals("endwhile") && !listTokens[currentToken].Equals("endfunc")) { StatementSequence sequence = new StatementSequence(); sequence.Left = parsedStatement; sequence.Right = ParseStatement(); parsedStatement = sequence; } } return(parsedStatement); }
public void GenerateStatement(Statement _statement) { if (_statement is StatementSequence) { StatementSequence _StatementSequence = (StatementSequence)_statement; GenerateStatement(_StatementSequence.Left); GenerateStatement(_StatementSequence.Right); } else if (_statement is DeclareVariable) { // declare a variable in symbol table DeclareVariable declare = (DeclareVariable)_statement; tblIdentifier[declare.Identifier] = _ILGenerator.DeclareLocal(GetExpressionType(declare.Expression)); // set the initial value Assignment assign = new Assignment(); assign.Identifier = declare.Identifier; assign.Expression = declare.Expression; GenerateStatement(assign); } else if (_statement is Assignment) { Assignment assign = (Assignment)_statement; GenerateExpression(assign.Expression, GetExpressionType(assign.Expression)); if (GetExpressionType(assign.Expression) == typeof(ArithmaticExpression)) { SaveIdentifier(assign.Identifier, typeof(Int32)); } else { SaveIdentifier(assign.Identifier, GetExpressionType(assign.Expression)); } } else if (_statement is DeclareFunction) { GenerateStatementMethod(_statement); } else if (_statement is Write) { // for print keyword, call .net method for printscreen GenerateExpression(((Write)_statement).Expression, typeof(string)); _ILGenerator.Emit(OpCodes.Call, typeof(System.Console).GetMethod("WriteLine", new System.Type[] { typeof(string) })); } else if (_statement is ReadInput) { // call the readline method and parse input method _ILGenerator.Emit(OpCodes.Call, typeof(System.Console).GetMethod("ReadLine", BindingFlags.Public | BindingFlags.Static, null, new System.Type[] { }, null)); _ILGenerator.Emit(OpCodes.Call, typeof(int).GetMethod("Parse", BindingFlags.Public | BindingFlags.Static, null, new System.Type[] { typeof(string) }, null)); // store the input value in local builder SaveIdentifier(((ReadInput)_statement).Identifier, typeof(int)); } else if (_statement is IfThenElse) { //IfThenElse ifThenElse = (IfThenElse)stmt; //RelationalExpression relExpr = (RelationalExpression)ifThenElse.If; //// if, left side only //il.Emit(OpCodes.Stloc, symbolTable[relExpr.Left.ToString()]); //Label lblIf = il.DefineLabel(); //il.Emit(OpCodes.Br, lblIf); //// then //Label lblThen = il.DefineLabel(); //il.MarkLabel(lblThen); } else if (_statement is While) { While _while = (While)_statement; Label lblTest = _ILGenerator.DefineLabel(); Label lblEnd = _ILGenerator.DefineLabel(); if (_while.Operand == RelationalOperands.GreaterThan) { _ILGenerator.MarkLabel(lblTest); GenerateExpression(_while.LeftExpression, typeof(int)); GenerateExpression(_while.RightExpression, typeof(int)); _ILGenerator.Emit(OpCodes.Cgt); _ILGenerator.Emit(OpCodes.Brfalse, lblEnd); GenerateStatement(_while.Body); _ILGenerator.Emit(OpCodes.Br, lblTest); _ILGenerator.MarkLabel(lblEnd); } else if (_while.Operand == RelationalOperands.EqualTo) { _ILGenerator.MarkLabel(lblTest); GenerateExpression(_while.LeftExpression, typeof(int)); GenerateExpression(_while.RightExpression, typeof(int)); _ILGenerator.Emit(OpCodes.Ceq); _ILGenerator.Emit(OpCodes.Brfalse, lblEnd); GenerateStatement(_while.Body); _ILGenerator.Emit(OpCodes.Br, lblTest); _ILGenerator.MarkLabel(lblEnd); } else if (_while.Operand == RelationalOperands.LessThan) { _ILGenerator.MarkLabel(lblTest); GenerateExpression(_while.LeftExpression, typeof(int)); GenerateExpression(_while.RightExpression, typeof(int)); _ILGenerator.Emit(OpCodes.Clt); _ILGenerator.Emit(OpCodes.Brfalse, lblEnd); GenerateStatement(_while.Body); _ILGenerator.Emit(OpCodes.Br, lblTest); _ILGenerator.MarkLabel(lblEnd); } } else if (_statement is IfThen) { #region //////Label body = il.DefineLabel(); //////il.Emit(OpCodes.Ldc_I4, 1000); /* * // var x = 0; * // if x < 5 then * // print "less than 5"; * // endif; * * IfThen ifThen = (IfThen)stmt; * // jump to test * * * // **test** if x LessThan 5? (do the test) * il.MarkLabel(test); * GenExpr(ifThen.LeftExpression, typeof(int)); * */ //Label greaterThan = il.DefineLabel(); //IfThen ifThen = (IfThen)stmt; //GenExpr(ifThen.LeftExpression, typeof(int)); //GenExpr(ifThen.RightExpression, typeof(int)); //if (ifThen.Operand == RelationalOperands.GreaterThan) //{ // //} #endregion IfThen ifThen = (IfThen)_statement; Label lblElse = _ILGenerator.DefineLabel(); Label lblEnd = _ILGenerator.DefineLabel(); #region GreaterThan if (ifThen.Operand == RelationalOperands.GreaterThan) { GenerateExpression(ifThen.LeftExpression, typeof(int)); GenerateExpression(ifThen.RightExpression, typeof(int)); _ILGenerator.Emit(OpCodes.Cgt); _ILGenerator.Emit(OpCodes.Brfalse, lblElse); GenerateStatement(ifThen.ThenBody); _ILGenerator.Emit(OpCodes.Br, lblEnd); _ILGenerator.MarkLabel(lblElse); GenerateStatement(ifThen.ElseBody); _ILGenerator.MarkLabel(lblEnd); } #endregion #region EqualTo else if (ifThen.Operand == RelationalOperands.EqualTo) { GenerateExpression(ifThen.LeftExpression, typeof(int)); GenerateExpression(ifThen.RightExpression, typeof(int)); _ILGenerator.Emit(OpCodes.Ceq); _ILGenerator.Emit(OpCodes.Brfalse, lblElse); GenerateStatement(ifThen.ThenBody); _ILGenerator.Emit(OpCodes.Br, lblEnd); _ILGenerator.MarkLabel(lblElse); GenerateStatement(ifThen.ElseBody); _ILGenerator.MarkLabel(lblEnd); } #endregion #region LessThan else if (ifThen.Operand == RelationalOperands.LessThan) { GenerateExpression(ifThen.LeftExpression, typeof(int)); GenerateExpression(ifThen.RightExpression, typeof(int)); _ILGenerator.Emit(OpCodes.Clt); _ILGenerator.Emit(OpCodes.Brfalse, lblElse); GenerateStatement(ifThen.ThenBody); _ILGenerator.Emit(OpCodes.Br, lblEnd); _ILGenerator.MarkLabel(lblElse); GenerateStatement(ifThen.ElseBody); _ILGenerator.MarkLabel(lblEnd); } #endregion #region /* * Label gtTrue = il.DefineLabel(); * Label gtFalse = il.DefineLabel(); * * */ #endregion } else if (_statement is For) { // example: // for x = 0 to 100 do // print "hello"; // end; // x = 0 For forLoop = (For)_statement; Assignment assign = new Assignment(); assign.Identifier = forLoop.Identifier; assign.Expression = forLoop.From; GenerateStatement(assign); // jump to the test Label test = _ILGenerator.DefineLabel(); _ILGenerator.Emit(OpCodes.Br, test); // body statement Label body = _ILGenerator.DefineLabel(); _ILGenerator.MarkLabel(body); GenerateStatement(forLoop.Body); // increase x _ILGenerator.Emit(OpCodes.Ldloc, tblIdentifier[forLoop.Identifier]); _ILGenerator.Emit(OpCodes.Ldc_I4, 1); _ILGenerator.Emit(OpCodes.Add); SaveIdentifier(forLoop.Identifier, typeof(int)); // check if x is equal to 100 _ILGenerator.MarkLabel(test); _ILGenerator.Emit(OpCodes.Ldloc, tblIdentifier[forLoop.Identifier]); GenerateExpression(forLoop.To, typeof(int)); _ILGenerator.Emit(OpCodes.Blt, body); } else { ExceptionHandler("unable to generate " + _statement.GetType().Name); } }
public void GenerateStatementMethod(Statement _statement) { #region Statement if (_statement is StatementSequence) { StatementSequence _StatementSequence = (StatementSequence)_statement; GenerateStatementMethod(_StatementSequence.Left); GenerateStatementMethod(_StatementSequence.Right); } #endregion #region Declare Variable else if (_statement is DeclareVariable) { // declare a variable in symbol table DeclareVariable declare = (DeclareVariable)_statement; tblIdentifier[declare.Identifier] = _ILMethod.DeclareLocal(GetExpressionTypeMethod(declare.Expression)); // set the initial value Assignment assign = new Assignment(); assign.Identifier = declare.Identifier; assign.Expression = declare.Expression; GenerateStatementMethod(assign); } #endregion #region Assignment else if (_statement is Assignment) { Assignment assign = (Assignment)_statement; GenerateExpressionMethod(assign.Expression, GetExpressionTypeMethod(assign.Expression)); if (GetExpressionTypeMethod(assign.Expression) == typeof(ArithmaticExpression)) { SaveIdentifierMethod(assign.Identifier, typeof(Int32)); } else { SaveIdentifierMethod(assign.Identifier, GetExpressionTypeMethod(assign.Expression)); } } #endregion else if (_statement is DeclareFunction) { DeclareFunction _DeclareFunction = (DeclareFunction)_statement; string strFunctionName = _DeclareFunction.FunctionName; Type ParameterType1 = GetExpressionTypeMethod(_DeclareFunction.Parameter1.Expression); Type ParameterType2 = GetExpressionTypeMethod(_DeclareFunction.Parameter2.Expression); Type ParameterType3 = GetExpressionTypeMethod(_DeclareFunction.Parameter3.Expression); Type[] InputParameters = { ParameterType1, ParameterType2, ParameterType3 }; Type ReturnType = typeof(void); if (_DeclareFunction.ReturnType == "void") { ReturnType = typeof(void); } else if (_DeclareFunction.ReturnType == "string") { ReturnType = typeof(string); } else if (_DeclareFunction.ReturnType == "numeric") { ReturnType = typeof(int); } //FieldBuilder Parameter1 = _typeBuilder.DefineField(_DeclareFunction.Parameter1.Identifier, ParameterType1, FieldAttributes.Private); //FieldBuilder Parameter2 = _typeBuilder.DefineField(_DeclareFunction.Parameter2.Identifier, ParameterType2, FieldAttributes.Private); //FieldBuilder Parameter3 = _typeBuilder.DefineField(_DeclareFunction.Parameter3.Identifier, ParameterType3, FieldAttributes.Private); MethodBuilder NewMethod = _typeBuilder.DefineMethod (strFunctionName, MethodAttributes.Static, ReturnType, InputParameters); //ParameterBuilder poolRefBuilder = NewMethod.DefineParameter(1, ParameterAttributes.In, _DeclareFunction.Parameter1.Identifier); _ILMethod = NewMethod.GetILGenerator(); //tblArguments[_DeclareFunction.Parameter0.Identifier] = _ILMethod. tblArguments[_DeclareFunction.Parameter1.Identifier] = _ILMethod.DeclareLocal(ParameterType1); GenerateExpressionMethod(_DeclareFunction.Parameter1.Expression, ParameterType1); //_ILMethod.Emit(OpCodes.Starg, 0); tblArguments[_DeclareFunction.Parameter1.Identifier] = _ILMethod.DeclareLocal(ParameterType2); GenerateExpressionMethod(_DeclareFunction.Parameter1.Expression, ParameterType2); //_ILMethod.Emit(OpCodes.Starg, 1); tblArguments[_DeclareFunction.Parameter2.Identifier] = _ILMethod.DeclareLocal(ParameterType3); GenerateExpressionMethod(_DeclareFunction.Parameter2.Expression, ParameterType3); //_ILMethod.Emit(OpCodes.Starg, 2); //GenerateStatementMethod(_DeclareFunction.Body); //_ILMethod.Emit(OpCodes.Ret); } #region write-read else if (_statement is Write) { // for print keyword, call .net method for printscreen GenerateExpressionMethod(((Write)_statement).Expression, typeof(string)); _ILMethod.Emit(OpCodes.Call, typeof(System.Console).GetMethod("WriteLine", new System.Type[] { typeof(string) })); } else if (_statement is ReadInput) { // call the readline method and parse input method _ILMethod.Emit(OpCodes.Call, typeof(System.Console).GetMethod("ReadLine", BindingFlags.Public | BindingFlags.Static, null, new System.Type[] { }, null)); _ILMethod.Emit(OpCodes.Call, typeof(int).GetMethod("Parse", BindingFlags.Public | BindingFlags.Static, null, new System.Type[] { typeof(string) }, null)); // store the input value in local builder SaveIdentifierMethod(((ReadInput)_statement).Identifier, typeof(int)); } #endregion #region While else if (_statement is While) { While _while = (While)_statement; Label lblTest = _ILMethod.DefineLabel(); Label lblEnd = _ILMethod.DefineLabel(); if (_while.Operand == RelationalOperands.GreaterThan) { _ILMethod.MarkLabel(lblTest); GenerateExpressionMethod(_while.LeftExpression, typeof(int)); GenerateExpressionMethod(_while.RightExpression, typeof(int)); _ILMethod.Emit(OpCodes.Cgt); _ILMethod.Emit(OpCodes.Brfalse, lblEnd); GenerateStatementMethod(_while.Body); _ILMethod.Emit(OpCodes.Br, lblTest); _ILMethod.MarkLabel(lblEnd); } else if (_while.Operand == RelationalOperands.EqualTo) { _ILMethod.MarkLabel(lblTest); GenerateExpressionMethod(_while.LeftExpression, typeof(int)); GenerateExpressionMethod(_while.RightExpression, typeof(int)); _ILMethod.Emit(OpCodes.Ceq); _ILMethod.Emit(OpCodes.Brfalse, lblEnd); GenerateStatementMethod(_while.Body); _ILMethod.Emit(OpCodes.Br, lblTest); _ILMethod.MarkLabel(lblEnd); } else if (_while.Operand == RelationalOperands.LessThan) { _ILMethod.MarkLabel(lblTest); GenerateExpressionMethod(_while.LeftExpression, typeof(int)); GenerateExpressionMethod(_while.RightExpression, typeof(int)); _ILMethod.Emit(OpCodes.Clt); _ILMethod.Emit(OpCodes.Brfalse, lblEnd); GenerateStatementMethod(_while.Body); _ILMethod.Emit(OpCodes.Br, lblTest); _ILMethod.MarkLabel(lblEnd); } } #endregion #region If-Then else if (_statement is IfThen) { IfThen ifThen = (IfThen)_statement; Label lblElse = _ILMethod.DefineLabel(); Label lblEnd = _ILMethod.DefineLabel(); #region GreaterThan if (ifThen.Operand == RelationalOperands.GreaterThan) { GenerateExpressionMethod(ifThen.LeftExpression, typeof(int)); GenerateExpressionMethod(ifThen.RightExpression, typeof(int)); _ILMethod.Emit(OpCodes.Cgt); _ILMethod.Emit(OpCodes.Brfalse, lblElse); GenerateStatementMethod(ifThen.ThenBody); _ILMethod.Emit(OpCodes.Br, lblEnd); _ILMethod.MarkLabel(lblElse); GenerateStatementMethod(ifThen.ElseBody); _ILMethod.MarkLabel(lblEnd); } #endregion #region EqualTo else if (ifThen.Operand == RelationalOperands.EqualTo) { GenerateExpressionMethod(ifThen.LeftExpression, typeof(int)); GenerateExpressionMethod(ifThen.RightExpression, typeof(int)); _ILMethod.Emit(OpCodes.Ceq); _ILMethod.Emit(OpCodes.Brfalse, lblElse); GenerateStatementMethod(ifThen.ThenBody); _ILMethod.Emit(OpCodes.Br, lblEnd); _ILMethod.MarkLabel(lblElse); GenerateStatementMethod(ifThen.ElseBody); _ILMethod.MarkLabel(lblEnd); } #endregion #region LessThan else if (ifThen.Operand == RelationalOperands.LessThan) { GenerateExpressionMethod(ifThen.LeftExpression, typeof(int)); GenerateExpressionMethod(ifThen.RightExpression, typeof(int)); _ILMethod.Emit(OpCodes.Clt); _ILMethod.Emit(OpCodes.Brfalse, lblElse); GenerateStatementMethod(ifThen.ThenBody); _ILMethod.Emit(OpCodes.Br, lblEnd); _ILMethod.MarkLabel(lblElse); GenerateStatementMethod(ifThen.ElseBody); _ILMethod.MarkLabel(lblEnd); } #endregion } #endregion #region for else if (_statement is For) { For forLoop = (For)_statement; Assignment assign = new Assignment(); assign.Identifier = forLoop.Identifier; assign.Expression = forLoop.From; GenerateStatementMethod(assign); Label test = _ILMethod.DefineLabel(); _ILMethod.Emit(OpCodes.Br, test); Label body = _ILMethod.DefineLabel(); _ILMethod.MarkLabel(body); GenerateStatementMethod(forLoop.Body); _ILMethod.Emit(OpCodes.Ldloc, tblIdentifier[forLoop.Identifier]); _ILMethod.Emit(OpCodes.Ldc_I4, 1); _ILMethod.Emit(OpCodes.Add); SaveIdentifierMethod(forLoop.Identifier, typeof(int)); _ILMethod.MarkLabel(test); _ILMethod.Emit(OpCodes.Ldloc, tblIdentifier[forLoop.Identifier]); GenerateExpressionMethod(forLoop.To, typeof(int)); _ILMethod.Emit(OpCodes.Blt, body); } #endregion else { ExceptionHandler("unable to generate " + _statement.GetType().Name); } }
protected virtual IExpression CompileExpressionNode(IExpressionNodeFactory factory, ParseTreeNode astNode) { switch (astNode.Term.Name) { case "Number": var num = TypeNormalizer.EnsureType <double>(astNode.Token.Value); return(factory.CreateLiteral(num)); case "String": var str = TypeNormalizer.EnsureType <string>(astNode.Token.Value); return(factory.CreateLiteral(str)); case "Boolean": var bln = TypeNormalizer.EnsureType <bool>(astNode.Token.Value); return(factory.CreateLiteral(bln)); case "Identifier": var variable = astNode.Token.Value; if (variable != null) { return(factory.CreateVariable(variable.ToString())); } break; case "Expr": if (astNode.ChildNodes.Count == 3 && astNode.ChildNodes[1].Term is SymbolTerminal) { IExpression left = CompileExpressionNode(factory, astNode.ChildNodes[0]); IExpression right = CompileExpressionNode(factory, astNode.ChildNodes[2]); return(factory.CreateBinaryOperator(astNode.ChildNodes[1].Term.Name, left, right)); } if (astNode.ChildNodes.Count == 2 && astNode.ChildNodes[0].Term is SymbolTerminal) { IExpression arg = CompileExpressionNode(factory, astNode.ChildNodes[1]); return(factory.CreateUnaryOperator(astNode.ChildNodes[0].Term.Name, arg)); } if (astNode.ChildNodes.Count == 2 && astNode.ChildNodes[1].Term is SymbolTerminal) { IExpression arg = CompileExpressionNode(factory, astNode.ChildNodes[0]); return(factory.CreateUnaryOperator(astNode.ChildNodes[1].Term.Name, arg)); } break; case "QualifiedName": var parts = new List <string>(); if (astNode.ChildNodes.Count == 2) { return(new QualifiedName(new[] { astNode.ChildNodes[1].Token.ValueString })); } //Condition ought to be impossible if (astNode.ChildNodes.Count != 3) { throw new Exception("Malformed QualifiedName - should have 3 child nodes"); } ExtractQualifiedName(astNode, parts); return(new QualifiedName(parts.ToArray())); case "FunctionExpression": string functionName = (astNode.ChildNodes[0].Token.ValueString); var args = new IExpression[astNode.ChildNodes[1].ChildNodes.Count]; for (int i = 0; i < astNode.ChildNodes[1].ChildNodes.Count; i++) { args[i] = CompileExpressionNode(factory, astNode.ChildNodes[1].ChildNodes[i]); } return(factory.CreateFunction(functionName, args)); case "IfThen": IExpression condition = CompileExpressionNode(factory, astNode.ChildNodes[1]); IExpression trueExpr = CompileExpressionNode(factory, astNode.ChildNodes[3]); IExpression falseExpr = null; if (astNode.ChildNodes.Count == 6) { falseExpr = CompileExpressionNode(factory, astNode.ChildNodes[5]); } var func = new IfThen(); if (falseExpr != null) { func.AcceptArguments(condition, trueExpr, falseExpr); } else { func.AcceptArguments(condition, trueExpr); } return(func); case "ArrayExpression": IExpression context = CompileExpressionNode(factory, astNode.ChildNodes[0]); IExpression index = CompileExpressionNode(factory, astNode.ChildNodes[1]); var indexer = new ItemAtIndex(); indexer.AcceptArguments(context, index); return(indexer); } return(null); }
// don't call base protected override IExpression CompileExpressionNode(IExpressionNodeFactory factory, ParseTreeNode astNode) { switch (astNode.Term.Name) { case "Number": var num = TypeNormalizer.EnsureType <double>(astNode.Token.Value); return(factory.CreateLiteral(num)); case "String": var str = TypeNormalizer.EnsureType <string>(astNode.Token.Value); return(factory.CreateLiteral(str)); case "Boolean": var bln = TypeNormalizer.EnsureType <bool>(astNode.Token.Value); return(factory.CreateLiteral(bln)); case "Identifier": var variable = astNode.Token.Value; if (variable != null) { return(factory.CreateVariable(variable.ToString())); } break; case "Symbol": var str_1 = TypeNormalizer.EnsureType <string>(astNode.Token.Value); return(factory.CreateLiteral(str_1)); case "UserSectionStmt": return(factory.CreateFunction(astNode.ChildNodes[2].Token.Text, null)); case "GlobalSectionStmt": return(factory.CreateLiteral(this.SinglePage.EvaluatePropertyPath(astNode.ChildNodes[2].Token.Text))); case "ParameterSectionStmt": return(CompileExpressionNode(factory, astNode.ChildNodes[2])); case "FieldsSectionStmt": //return CompileExpressionNode (factory,astNode.ChildNodes[2]); IExpression l = CompileExpressionNode(factory, astNode.ChildNodes[2]); return(factory.CreateFunction(astNode.ChildNodes[0].Token.Text, l)); case "ParExpr": return(CompileExpressionNode(factory, astNode.ChildNodes[0])); case "BinExpr": if (astNode.ChildNodes.Count == 3 && astNode.ChildNodes[1].Term is SymbolTerminal) { IExpression left = CompileExpressionNode(factory, astNode.ChildNodes[0]); IExpression right = CompileExpressionNode(factory, astNode.ChildNodes[2]); return(factory.CreateBinaryOperator(astNode.ChildNodes[1].Term.Name, left, right)); } if (astNode.ChildNodes.Count == 2 && astNode.ChildNodes[0].Term is SymbolTerminal) { IExpression arg = CompileExpressionNode(factory, astNode.ChildNodes[1]); return(factory.CreateUnaryOperator(astNode.ChildNodes[0].Term.Name, arg)); } if (astNode.ChildNodes.Count == 2 && astNode.ChildNodes[1].Term is SymbolTerminal) { IExpression arg = CompileExpressionNode(factory, astNode.ChildNodes[0]); return(factory.CreateUnaryOperator(astNode.ChildNodes[1].Term.Name, arg)); } break; case "QualifiedName": var parts = new List <string>(); if (astNode.ChildNodes.Count == 2) { return(new QualifiedName(new[] { astNode.ChildNodes[1].Token.ValueString })); } /* * //Condition ought to be impossible * if (astNode.ChildNodes.Count != 3 ) * throw new Exception("Malformed QualifiedName - should have 3 child nodes"); */ if (astNode.ChildNodes.Count == 1) { return(CompileExpressionNode(factory, astNode.ChildNodes[0])); } SimpleExpressionLanguageCompiler.ExtractQualifiedName(astNode, parts); return(new QualifiedName(parts.ToArray())); case "FunctionExpression": IExpression [] args = null; string functionName = (astNode.ChildNodes[0].ChildNodes[0].Token.ValueString); if (astNode.ChildNodes.Count == 1) { args = new IExpression[astNode.ChildNodes[0].ChildNodes[0].ChildNodes.Count]; } else { args = new IExpression[astNode.ChildNodes[1].ChildNodes.Count]; for (int i = 0; i < astNode.ChildNodes[1].ChildNodes.Count; i++) { args[i] = CompileExpressionNode(factory, astNode.ChildNodes[1].ChildNodes[i]); } } return(factory.CreateFunction(functionName, args)); case "IfThen": IExpression condition = CompileExpressionNode(factory, astNode.ChildNodes[1].ChildNodes[0]); IExpression trueExpr = CompileExpressionNode(factory, astNode.ChildNodes[3]); // IExpression falseExpr = CompileExpressionNode(factory, astNode.ChildNodes[3]); IExpression falseExpr = null; if (astNode.ChildNodes.Count == 6) { falseExpr = CompileExpressionNode(factory, astNode.ChildNodes[5]); } var func = new IfThen(); if (falseExpr != null) { func.AcceptArguments(condition, trueExpr, falseExpr); } else { func.AcceptArguments(condition, trueExpr); } return(func); /* * case "ArrayExpression": * IExpression context = CompileExpressionNode(factory, astNode.ChildNodes[0]); * IExpression index = CompileExpressionNode(factory, astNode.ChildNodes[1]); * var indexer = new ItemAtIndex(); * indexer.AcceptArguments(context, index); * return indexer; * */ } return(null); }
public IfThenElse(IfThen ifThen, IStep @else) { _ifThen = ifThen; _else = @else; }
public void Visit(IfThen ifThen) => Result = Build(ifThen);
public virtual void Visit(IfThen ifThen) { ifThen.Condition.Accept(this); ifThen.Body?.Accept(this); }
public bool Parse(Lexer lexer, Token token, Attributes attributes) { var successfullyParsed = true; Expression condition = null; try { ValidateToken(token, TokenType.ConditionalIf); var expressionAttributes = Attributes.Create(attributes.ToArray()); successfullyParsed &= ParserFactory.GetExpressionParser().Parse(lexer, lexer.GetNextToken(), expressionAttributes); // SEM: La condición en un IF no puede ser una expresión nula. if (expressionAttributes.ContainsAttribute("EXP")) { condition = expressionAttributes["EXP"] as Expression; // SEM: La condición en un IF no puede ser una expresión nula. if (condition != null) { // SEM: La condición en un IF sólo puede ser una expresión booleana if (condition.Type != DataType.Boolean) { LogTypeExpressionInvalid(token, DataType.Boolean, DataType.Integer); successfullyParsed = false; } } else { LogNullExpression(token, DataType.Boolean); successfullyParsed = false; } } else { LogNullExpression(token, DataType.Boolean); successfullyParsed = false; } ValidateToken(lexer.GetCurrentToken(), TokenType.ConditionalThen); var thenBodyAttributes = Attributes.Create(attributes["ENVS"], "ENVS"); var thenStatements = new Statements(); thenBodyAttributes.AddAttribute(thenStatements, "STMS"); successfullyParsed &= ParserFactory.GetBodyParser().Parse(lexer, lexer.GetNextToken(), thenBodyAttributes); token = lexer.GetCurrentToken(); if (token.Is(TokenType.ConditionalEnd)) { ValidateToken(lexer.GetNextToken(), TokenType.EndOfInstruction); var tree = new IfThen(); tree.Condition = condition; tree.Statements = thenStatements; attributes.AddAttribute(tree, "IF"); } else if (token.Is(TokenType.ConditionalElse)) { var elseBodyAttributes = Attributes.Create(attributes["ENVS"], "ENVS"); var elseStatements = new Statements(); elseBodyAttributes.AddAttribute(elseStatements, "STMS"); successfullyParsed &= ParserFactory.GetBodyParser().Parse(lexer, lexer.GetNextToken(), elseBodyAttributes); ValidateToken(lexer.GetCurrentToken(), TokenType.ConditionalEnd); ValidateToken(lexer.GetNextToken(), TokenType.EndOfInstruction); var tree = new IfThenElse(); tree.Condition = condition; tree.Then = thenStatements; tree.Else = elseStatements; attributes.AddAttribute(tree, "IF"); } } catch (Exception ex) { successfullyParsed = false; Logger(ex.Message); ErrorRecovery(lexer); } return(successfullyParsed); }
protected virtual IExpression CompileExpressionNode(IExpressionNodeFactory factory, ParseNode astNode) { switch (astNode.Token.Type) { case TokenType.Atom: if (astNode.Nodes[0].Token.Type == TokenType.BROPEN) { return(CompileExpressionNode(factory, astNode.Nodes[1])); } return(CompileExpressionNode(factory, astNode.Nodes[0])); case TokenType.NUMBER: case TokenType.INTEGER: var num = TypeNormalizer.EnsureType <double>(astNode.Token.Text); return(factory.CreateLiteral(num)); case TokenType.STRING: var str = TypeNormalizer.EnsureType <string>(astNode.Token.Text.Replace("\"", String.Empty)); return(factory.CreateLiteral(str)); case TokenType.TRUE: case TokenType.FALSE: var bln = TypeNormalizer.EnsureType <bool>(astNode.Token.Text); return(factory.CreateLiteral(bln)); case TokenType.NULL: return(null); case TokenType.BooleanExpr: case TokenType.CompareExpr: case TokenType.AddExpr: case TokenType.MultExpr: case TokenType.PowerExpr: return(CompileBinaryOperator(factory, astNode)); case TokenType.QualifiedName: return(CompileQualifiedName(factory, null, Select(astNode.Nodes, TokenType.Identifier), 0)); case TokenType.Conditional: var pieces = Select(astNode.Nodes, TokenType.BooleanExpr); IExpression condition = CompileExpressionNode(factory, pieces[0]); IExpression trueExpr = CompileExpressionNode(factory, pieces[1]); IExpression falseExpr = (pieces.Count == 3) ? CompileExpressionNode(factory, pieces[2]) : null; var func = new IfThen(); if (falseExpr != null) { func.AcceptArguments(condition, trueExpr, falseExpr); } else { func.AcceptArguments(condition, trueExpr); } return(func); case TokenType.UnaryExpr: string token = astNode.Nodes[0].Token.Text; IExpression left = CompileBinaryOperator(factory, astNode.Nodes[1]); return(factory.CreateUnaryOperator(token, left)); } return(null); }