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 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); } }