public void CallNativeFunction(string name, Expression[] args) { ScriptNativeFunction function = ScriptNativeFunctionTable.Find(name); if (function == null) { throw new InvalidOperationException("Function not found"); } ScriptNativeFunctionAttribute functionAttribute = function.Method.GetCustomAttribute <ScriptNativeFunctionAttribute>(); ScriptNativeFunctionReturnAttribute[] returnTypes = function.Method.GetCustomAttributes <ScriptNativeFunctionReturnAttribute>(); ScriptNativeFunctionParameterAttribute[] parameterTypes = function.Method.GetCustomAttributes <ScriptNativeFunctionParameterAttribute>(); // return value들을 보관할 영역을 확보합니다. foreach (ScriptNativeFunctionReturnAttribute item in returnTypes) { AllocateN(DeclareVariable.SizeOf(item.Type), true); } Trace.Assert(parameterTypes.Length == args.Length); for (int i = 0; i < args.Length; i++) { Generate(args[i]); } binaryWriter.Write(ScriptInstruction.CallNativeFunction); binaryWriter.Write(functionAttribute.FunctionID); binaryWriter.Write(returnTypes.Length); binaryWriter.Write(parameterTypes.Length); AppendTextCode("<b>call_native</b> {0} [{1}]", functionAttribute.FunctionID, name); Pop(parameterTypes.Length); }
public void CallScriptFunction(string name, Expression[] args) { Function function = FindFunction(name); if (function == null) { throw new InvalidOperationException("Function not found"); } // return value들을 보관할 영역을 확보합니다. foreach (ScriptObjectType item in function.ReturnTypes) { AllocateN(DeclareVariable.SizeOf(item), true); } for (int i = 0; i < args.Length; i++) { Generate(args[i]); } binaryWriter.Write(ScriptInstruction.CallScriptFunction); string addressString = WriteAddress(function.BeginLabel); binaryWriter.Write(args.Length); AppendTextCode("<b>call</b> <a href=\"#{0}\">{0}</a> [{1}]", addressString, name); // 실행에서 Pop은 return에서 해주므로 여기서는 VS에서만 Pop해줍니다. PopVS(args.Length); }
public bool TryGetVariableOffsetFromVS(string name, out int stackIndex, out int localOffset, out int size) { List <List <DeclareVariable> > lvvs = localVariableVirtualStack; stackIndex = -1; localOffset = 0; size = 0; for (int i = lvvs.Count - 1; i >= 0; i--, stackIndex--) { List <DeclareVariable> items = lvvs[i]; if (items == null) { continue; } int k = items.Count - 1; bool found = false; for (k = items.Count - 1; k >= 0; k--) { DeclareVariable item = items[k]; if (item.Name == name) { size = DeclareVariable.SizeOf(item.Type); found = true; break; } } for (k = k - 1; k >= 0; k--) { localOffset += DeclareVariable.SizeOf(items[k].Type); } if (found) { return(true); } } return(false); }
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); } }