Fahad/MCG-CS/CodeGenerator.cs
changeset 45 7545b1bc1514
equal deleted inserted replaced
44:a751aa1ee4f7 45:7545b1bc1514
       
     1 using System;
       
     2 using System.Collections.Generic;
       
     3 using System.Text;
       
     4 // Added
       
     5 using System.Reflection;
       
     6 using System.Reflection.Emit;
       
     7 using System.IO;
       
     8 
       
     9 public sealed class CodeGenerator
       
    10 {
       
    11     
       
    12     Dictionary<string, System.Reflection.Emit.LocalBuilder> tblIdentifier;
       
    13     Dictionary<string, System.Reflection.Emit.LocalBuilder> tblArguments;
       
    14     TypeBuilder _typeBuilder = null;
       
    15     System.Reflection.Emit.ILGenerator _ILGenerator = null;
       
    16     MemberInfo WriteLine = typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) });
       
    17 
       
    18     #region Statement
       
    19     public CodeGenerator(Statement statement, string fileName)
       
    20     {
       
    21         string strFileName = Path.GetFileNameWithoutExtension(fileName);
       
    22 
       
    23         #region Define Assembly
       
    24         //AssemblyName _AssemblyName = new AssemblyName(Path.GetFileNameWithoutExtension(fileName));
       
    25         AssemblyName _AssemblyName = new AssemblyName(strFileName);
       
    26         AppDomain currentDomain = AppDomain.CurrentDomain;
       
    27         AssemblyBuilder _AssemblyBuilder = currentDomain.DefineDynamicAssembly(_AssemblyName, AssemblyBuilderAccess.Save);
       
    28         #endregion
       
    29 
       
    30         #region Define Module
       
    31         ModuleBuilder _ModuleBuilder = _AssemblyBuilder.DefineDynamicModule(fileName);
       
    32         #endregion
       
    33         
       
    34         _typeBuilder = _ModuleBuilder.DefineType("CodeGenerator");
       
    35         MethodBuilder _MethodBuilder = _typeBuilder.DefineMethod
       
    36             ("Main", 
       
    37             MethodAttributes.Static, 
       
    38             typeof(void), 
       
    39             System.Type.EmptyTypes);
       
    40 
       
    41         _ILGenerator = _MethodBuilder.GetILGenerator();
       
    42         tblIdentifier = new Dictionary<string, System.Reflection.Emit.LocalBuilder>();
       
    43         tblArguments = new Dictionary<string, System.Reflection.Emit.LocalBuilder>();
       
    44 
       
    45         // CIL generation
       
    46         GenerateStatement(statement);
       
    47 
       
    48         _ILGenerator.Emit(OpCodes.Ret);
       
    49         _typeBuilder.CreateType();
       
    50         _ModuleBuilder.CreateGlobalFunctions();
       
    51         _AssemblyBuilder.SetEntryPoint(_MethodBuilder);
       
    52         _AssemblyBuilder.Save(fileName);
       
    53         tblIdentifier = null;
       
    54         _ILGenerator = null; 
       
    55     }
       
    56 
       
    57     public void GenerateStatement(Statement _statement)
       
    58     {
       
    59         if (_statement is StatementSequence)
       
    60         {
       
    61             StatementSequence _StatementSequence = (StatementSequence)_statement;
       
    62             GenerateStatement(_StatementSequence.Left);
       
    63             GenerateStatement(_StatementSequence.Right);
       
    64         }
       
    65 
       
    66         else if (_statement is DeclareVariable)
       
    67         {
       
    68             // declare a variable in symbol table
       
    69             DeclareVariable declare = (DeclareVariable)_statement;
       
    70             tblIdentifier[declare.Identifier] = 
       
    71                 _ILGenerator.DeclareLocal(GetExpressionType(declare.Expression));
       
    72 
       
    73             // set the initial value
       
    74             Assignment assign = new Assignment();
       
    75             assign.Identifier = declare.Identifier;
       
    76             assign.Expression = declare.Expression;
       
    77             GenerateStatement(assign);
       
    78         }
       
    79 
       
    80         else if (_statement is Assignment)
       
    81         {
       
    82             Assignment assign = (Assignment)_statement;
       
    83             GenerateExpression(assign.Expression, 
       
    84                 GetExpressionType(assign.Expression));
       
    85             if (GetExpressionType(assign.Expression) == typeof(ArithmaticExpression))
       
    86             {
       
    87                 SaveIdentifier(assign.Identifier, typeof(Int32));
       
    88             }
       
    89             else 
       
    90             {
       
    91                 SaveIdentifier(assign.Identifier, 
       
    92                     GetExpressionType(assign.Expression));
       
    93             }
       
    94             
       
    95         }
       
    96 
       
    97         else if (_statement is DeclareFunction) 
       
    98         {
       
    99             GenerateStatementMethod(_statement);
       
   100         }
       
   101 
       
   102         else if (_statement is Write)
       
   103         {
       
   104             // for print keyword, call .net method for printscreen
       
   105             GenerateExpression(((Write)_statement).Expression,
       
   106                 typeof(string));
       
   107             _ILGenerator.Emit(OpCodes.Call,
       
   108                 typeof(System.Console).GetMethod("WriteLine",
       
   109                 new System.Type[] { typeof(string) }));
       
   110         }
       
   111 
       
   112         else if (_statement is ReadInput)
       
   113         {
       
   114             // call the readline method and parse input method
       
   115             _ILGenerator.Emit(OpCodes.Call,
       
   116                 typeof(System.Console).GetMethod("ReadLine",
       
   117                 BindingFlags.Public | BindingFlags.Static,
       
   118                 null, new System.Type[] { }, null));
       
   119             _ILGenerator.Emit(OpCodes.Call,
       
   120                 typeof(int).GetMethod("Parse",
       
   121                 BindingFlags.Public | BindingFlags.Static,
       
   122                 null, new System.Type[] { typeof(string) }, null));
       
   123             // store the input value in local builder
       
   124             SaveIdentifier(((ReadInput)_statement).Identifier, typeof(int));
       
   125         }
       
   126         else if (_statement is IfThenElse)
       
   127         {
       
   128 
       
   129             //IfThenElse ifThenElse = (IfThenElse)stmt;
       
   130             //RelationalExpression relExpr = (RelationalExpression)ifThenElse.If;
       
   131             //// if, left side only
       
   132             //il.Emit(OpCodes.Stloc, symbolTable[relExpr.Left.ToString()]);
       
   133             //Label lblIf = il.DefineLabel();
       
   134             //il.Emit(OpCodes.Br, lblIf);
       
   135             //// then
       
   136             //Label lblThen = il.DefineLabel();
       
   137             //il.MarkLabel(lblThen);
       
   138 
       
   139         }
       
   140 
       
   141         else if (_statement is While)
       
   142         {
       
   143             While _while = (While)_statement;
       
   144             Label lblTest = _ILGenerator.DefineLabel();
       
   145             Label lblEnd = _ILGenerator.DefineLabel();
       
   146 
       
   147             if (_while.Operand == RelationalOperands.GreaterThan)
       
   148             {
       
   149                 _ILGenerator.MarkLabel(lblTest);
       
   150                 GenerateExpression(_while.LeftExpression, typeof(int));
       
   151                 GenerateExpression(_while.RightExpression, typeof(int));
       
   152                 _ILGenerator.Emit(OpCodes.Cgt);
       
   153                 _ILGenerator.Emit(OpCodes.Brfalse, lblEnd);
       
   154                 GenerateStatement(_while.Body);
       
   155                 _ILGenerator.Emit(OpCodes.Br, lblTest);
       
   156 
       
   157                 _ILGenerator.MarkLabel(lblEnd);
       
   158             }
       
   159             else if (_while.Operand == RelationalOperands.EqualTo)
       
   160             {
       
   161                 _ILGenerator.MarkLabel(lblTest);
       
   162                 GenerateExpression(_while.LeftExpression, typeof(int));
       
   163                 GenerateExpression(_while.RightExpression, typeof(int));
       
   164                 _ILGenerator.Emit(OpCodes.Ceq);
       
   165                 _ILGenerator.Emit(OpCodes.Brfalse, lblEnd);
       
   166                 GenerateStatement(_while.Body);
       
   167                 _ILGenerator.Emit(OpCodes.Br, lblTest);
       
   168 
       
   169                 _ILGenerator.MarkLabel(lblEnd);
       
   170             }
       
   171             else if (_while.Operand == RelationalOperands.LessThan)
       
   172             {
       
   173                 _ILGenerator.MarkLabel(lblTest);
       
   174                 GenerateExpression(_while.LeftExpression, typeof(int));
       
   175                 GenerateExpression(_while.RightExpression, typeof(int));
       
   176                 _ILGenerator.Emit(OpCodes.Clt);
       
   177                 _ILGenerator.Emit(OpCodes.Brfalse, lblEnd);
       
   178                 GenerateStatement(_while.Body);
       
   179                 _ILGenerator.Emit(OpCodes.Br, lblTest);
       
   180 
       
   181                 _ILGenerator.MarkLabel(lblEnd);
       
   182             }
       
   183         }
       
   184         else if (_statement is IfThen)
       
   185         {
       
   186             #region
       
   187             //////Label body = il.DefineLabel();
       
   188 
       
   189             //////il.Emit(OpCodes.Ldc_I4, 1000);
       
   190 
       
   191 
       
   192 
       
   193             /*
       
   194             // var x = 0;
       
   195             // if x < 5 then
       
   196             //    print "less than 5";
       
   197             // endif;
       
   198 
       
   199             IfThen ifThen = (IfThen)stmt;
       
   200             // jump to test
       
   201             
       
   202 
       
   203             // **test** if x LessThan 5? (do the test)
       
   204             il.MarkLabel(test);
       
   205             GenExpr(ifThen.LeftExpression, typeof(int));
       
   206             
       
   207             */
       
   208 
       
   209             //Label greaterThan = il.DefineLabel();
       
   210 
       
   211             //IfThen ifThen = (IfThen)stmt;
       
   212             //GenExpr(ifThen.LeftExpression, typeof(int));
       
   213             //GenExpr(ifThen.RightExpression, typeof(int));
       
   214             //if (ifThen.Operand == RelationalOperands.GreaterThan) 
       
   215             //{
       
   216             //    
       
   217             //}
       
   218             #endregion
       
   219 
       
   220             IfThen ifThen = (IfThen)_statement;
       
   221             Label lblElse = _ILGenerator.DefineLabel();
       
   222             Label lblEnd = _ILGenerator.DefineLabel();
       
   223 
       
   224             #region GreaterThan
       
   225             if (ifThen.Operand == RelationalOperands.GreaterThan)
       
   226             {
       
   227                 GenerateExpression(ifThen.LeftExpression, typeof(int));
       
   228                 GenerateExpression(ifThen.RightExpression, typeof(int));
       
   229                 _ILGenerator.Emit(OpCodes.Cgt);
       
   230                 _ILGenerator.Emit(OpCodes.Brfalse, lblElse);
       
   231                 GenerateStatement(ifThen.ThenBody);
       
   232                 _ILGenerator.Emit(OpCodes.Br, lblEnd);
       
   233 
       
   234                 _ILGenerator.MarkLabel(lblElse);
       
   235                 GenerateStatement(ifThen.ElseBody);
       
   236 
       
   237                 _ILGenerator.MarkLabel(lblEnd);
       
   238             }
       
   239             #endregion
       
   240             #region EqualTo
       
   241             else if (ifThen.Operand == RelationalOperands.EqualTo)
       
   242             {
       
   243                 GenerateExpression(ifThen.LeftExpression, typeof(int));
       
   244                 GenerateExpression(ifThen.RightExpression, typeof(int));
       
   245                 _ILGenerator.Emit(OpCodes.Ceq);
       
   246                 _ILGenerator.Emit(OpCodes.Brfalse, lblElse);
       
   247                 GenerateStatement(ifThen.ThenBody);
       
   248                 _ILGenerator.Emit(OpCodes.Br, lblEnd);
       
   249 
       
   250                 _ILGenerator.MarkLabel(lblElse);
       
   251                 GenerateStatement(ifThen.ElseBody);
       
   252 
       
   253                 _ILGenerator.MarkLabel(lblEnd);
       
   254             }
       
   255             #endregion
       
   256             #region LessThan
       
   257             else if (ifThen.Operand == RelationalOperands.LessThan)
       
   258             {
       
   259                 GenerateExpression(ifThen.LeftExpression, typeof(int));
       
   260                 GenerateExpression(ifThen.RightExpression, typeof(int));
       
   261                 _ILGenerator.Emit(OpCodes.Clt);
       
   262                 _ILGenerator.Emit(OpCodes.Brfalse, lblElse);
       
   263                 GenerateStatement(ifThen.ThenBody);
       
   264                 _ILGenerator.Emit(OpCodes.Br, lblEnd);
       
   265 
       
   266                 _ILGenerator.MarkLabel(lblElse);
       
   267                 GenerateStatement(ifThen.ElseBody);
       
   268 
       
   269                 _ILGenerator.MarkLabel(lblEnd);
       
   270             }
       
   271             #endregion
       
   272 
       
   273             #region
       
   274             /*
       
   275             Label gtTrue = il.DefineLabel();
       
   276             Label gtFalse = il.DefineLabel();
       
   277             
       
   278             
       
   279              */
       
   280             #endregion
       
   281 
       
   282         }
       
   283         else if (_statement is For)
       
   284         {
       
   285             // example: 
       
   286             // for x = 0 to 100 do
       
   287             //   print "hello";
       
   288             // end;
       
   289 
       
   290             // x = 0
       
   291             For forLoop = (For)_statement;
       
   292             Assignment assign = new Assignment();
       
   293             assign.Identifier = forLoop.Identifier;
       
   294             assign.Expression = forLoop.From;
       
   295             GenerateStatement(assign);
       
   296             // jump to the test
       
   297             Label test = _ILGenerator.DefineLabel();
       
   298             _ILGenerator.Emit(OpCodes.Br, test);
       
   299 
       
   300             // body statement
       
   301             Label body = _ILGenerator.DefineLabel();
       
   302             _ILGenerator.MarkLabel(body);
       
   303             GenerateStatement(forLoop.Body);
       
   304 
       
   305             // increase x
       
   306             _ILGenerator.Emit(OpCodes.Ldloc, tblIdentifier[forLoop.Identifier]);
       
   307             _ILGenerator.Emit(OpCodes.Ldc_I4, 1);
       
   308             _ILGenerator.Emit(OpCodes.Add);
       
   309             SaveIdentifier(forLoop.Identifier, typeof(int));
       
   310 
       
   311             // check if x is equal to 100
       
   312             _ILGenerator.MarkLabel(test);
       
   313             _ILGenerator.Emit(OpCodes.Ldloc, tblIdentifier[forLoop.Identifier]);
       
   314             GenerateExpression(forLoop.To, typeof(int));
       
   315             _ILGenerator.Emit(OpCodes.Blt, body);
       
   316         }
       
   317 
       
   318         else
       
   319         {
       
   320             ExceptionHandler("unable to generate " + _statement.GetType().Name);
       
   321         }
       
   322     }
       
   323 
       
   324     public void ExceptionHandler(string strException) 
       
   325     {
       
   326         throw new Exception(strException);
       
   327     }
       
   328 
       
   329     public void SaveIdentifier(string IdentifierName, System.Type IdentifierType)
       
   330     {
       
   331         if (tblIdentifier.ContainsKey(IdentifierName))
       
   332         {
       
   333             LocalBuilder locb = tblIdentifier[IdentifierName];
       
   334 
       
   335             if (locb.LocalType == IdentifierType)
       
   336             {
       
   337                 _ILGenerator.Emit(OpCodes.Stloc, tblIdentifier[IdentifierName]);
       
   338             }
       
   339             else
       
   340             {
       
   341                 ExceptionHandler("'" + IdentifierName + "' is of type " + locb.LocalType.Name + " but saving in different type " + IdentifierType.Name);
       
   342             }
       
   343         }
       
   344         else
       
   345         {
       
   346             ExceptionHandler("variable not declared '" + IdentifierName + "'");
       
   347         }
       
   348     }
       
   349 
       
   350     public void GenerateExpression(Expression _expression, System.Type expressionType)
       
   351     {
       
   352         System.Type typeOfExpression;
       
   353 
       
   354         if (_expression is AlphaNumericValue)
       
   355         {
       
   356             typeOfExpression = typeof(string);
       
   357             _ILGenerator.Emit(OpCodes.Ldstr, ((AlphaNumericValue)_expression).Value);
       
   358         }
       
   359         else if (_expression is NumericValue)
       
   360         {
       
   361             typeOfExpression = typeof(int);
       
   362             _ILGenerator.Emit(OpCodes.Ldc_I4, ((NumericValue)_expression).Value);
       
   363         }
       
   364         
       
   365         else if (_expression is ArithmaticExpression) 
       
   366         {
       
   367             typeOfExpression = GetExpressionType(_expression);
       
   368 
       
   369             ArithmaticExpression arithmaticExpression = (ArithmaticExpression)_expression;
       
   370             GenerateExpression(arithmaticExpression.Left, GetExpressionType(arithmaticExpression.Left));
       
   371             GenerateExpression(arithmaticExpression.Right, GetExpressionType(arithmaticExpression.Right));
       
   372             if (arithmaticExpression.Operand == ArithmaticOperands.Add) 
       
   373             {
       
   374                 _ILGenerator.Emit(OpCodes.Add);
       
   375             }
       
   376             else if (arithmaticExpression.Operand == ArithmaticOperands.Subtract) 
       
   377             {
       
   378                 _ILGenerator.Emit(OpCodes.Sub);
       
   379             }
       
   380             else if (arithmaticExpression.Operand == ArithmaticOperands.Multiply) 
       
   381             {
       
   382                 _ILGenerator.Emit(OpCodes.Mul);
       
   383             }
       
   384             else if (arithmaticExpression.Operand == ArithmaticOperands.Division) 
       
   385             {
       
   386                 _ILGenerator.Emit(OpCodes.Div);
       
   387             }
       
   388         }
       
   389         
       
   390         
       
   391         else if (_expression is Identifier)
       
   392         {
       
   393             string identifier = ((Identifier)_expression).IdentifierName;
       
   394             typeOfExpression = GetExpressionType(_expression);
       
   395 
       
   396             if (!tblIdentifier.ContainsKey(identifier))
       
   397             {
       
   398                 ExceptionHandler("undeclared variable '" + identifier + "'");
       
   399             }
       
   400 
       
   401             _ILGenerator.Emit(OpCodes.Ldloc, tblIdentifier[identifier]);
       
   402         }
       
   403         
       
   404         else
       
   405         {
       
   406             ExceptionHandler("can't generate " + _expression.GetType().Name);
       
   407             typeOfExpression = null;
       
   408         }
       
   409 
       
   410         if (typeOfExpression != expressionType)
       
   411         {
       
   412             if (typeOfExpression == typeof(int) &&
       
   413                 expressionType == typeof(string))
       
   414             {
       
   415                 _ILGenerator.Emit(OpCodes.Box, typeof(int));
       
   416                 _ILGenerator.Emit(OpCodes.Callvirt, typeof(object).GetMethod("ToString"));
       
   417             }
       
   418             else
       
   419             {
       
   420                 ExceptionHandler("can't convert " + typeOfExpression.Name + " to " + expressionType.Name);
       
   421             }
       
   422         }
       
   423 
       
   424     }
       
   425 
       
   426     public System.Type GetExpressionType(Expression _expression)
       
   427     {
       
   428         if (_expression is AlphaNumericValue)
       
   429         {
       
   430             return typeof(string);
       
   431         }
       
   432         else if (_expression is NumericValue)
       
   433         {
       
   434             return typeof(int);
       
   435         }
       
   436         else if (_expression is Identifier)
       
   437         {
       
   438             Identifier var = (Identifier)_expression;
       
   439             if (tblIdentifier.ContainsKey(var.IdentifierName))
       
   440             {
       
   441                 LocalBuilder locb = tblIdentifier[var.IdentifierName];
       
   442                 return locb.LocalType;
       
   443             }
       
   444             else
       
   445             {
       
   446                 ExceptionHandler("variable not declared '" + var.IdentifierName + "'");
       
   447                 return null;
       
   448             }
       
   449         }
       
   450         else if (_expression is ArithmaticExpression) 
       
   451         {
       
   452             return typeof(ArithmaticExpression);
       
   453         }
       
   454         else
       
   455         {
       
   456             ExceptionHandler("type cannot be generated for " + _expression.GetType().Name);
       
   457             return null;
       
   458         }
       
   459     }
       
   460 
       
   461     #endregion
       
   462 
       
   463     #region Method
       
   464 
       
   465     System.Reflection.Emit.ILGenerator _ILMethod = null;
       
   466     public void GenerateStatementMethod(Statement _statement)
       
   467     {
       
   468         #region Statement
       
   469         if (_statement is StatementSequence)
       
   470         {
       
   471             StatementSequence _StatementSequence = (StatementSequence)_statement;
       
   472             GenerateStatementMethod(_StatementSequence.Left);
       
   473             GenerateStatementMethod(_StatementSequence.Right);
       
   474         }
       
   475         #endregion
       
   476 
       
   477         #region Declare Variable
       
   478         else if (_statement is DeclareVariable)
       
   479         {
       
   480             // declare a variable in symbol table
       
   481             DeclareVariable declare = (DeclareVariable)_statement;
       
   482             tblIdentifier[declare.Identifier] =
       
   483                 _ILMethod.DeclareLocal(GetExpressionTypeMethod(declare.Expression));
       
   484 
       
   485             // set the initial value
       
   486             Assignment assign = new Assignment();
       
   487             assign.Identifier = declare.Identifier;
       
   488             assign.Expression = declare.Expression;
       
   489             GenerateStatementMethod(assign);
       
   490         }
       
   491         #endregion
       
   492 
       
   493         #region Assignment
       
   494         else if (_statement is Assignment)
       
   495         {
       
   496             Assignment assign = (Assignment)_statement;
       
   497             GenerateExpressionMethod(assign.Expression, GetExpressionTypeMethod(assign.Expression));
       
   498             if (GetExpressionTypeMethod(assign.Expression) == typeof(ArithmaticExpression))
       
   499             {
       
   500                 SaveIdentifierMethod(assign.Identifier, typeof(Int32));
       
   501             }
       
   502             else
       
   503             {
       
   504                 SaveIdentifierMethod(assign.Identifier,
       
   505                     GetExpressionTypeMethod(assign.Expression));
       
   506             }
       
   507 
       
   508         }
       
   509         #endregion
       
   510 
       
   511         else if (_statement is DeclareFunction)
       
   512         {
       
   513             DeclareFunction _DeclareFunction = (DeclareFunction)_statement;
       
   514 
       
   515             string strFunctionName = _DeclareFunction.FunctionName;
       
   516 
       
   517             Type ParameterType1 = GetExpressionTypeMethod(_DeclareFunction.Parameter1.Expression);
       
   518             Type ParameterType2 = GetExpressionTypeMethod(_DeclareFunction.Parameter2.Expression);
       
   519             Type ParameterType3 = GetExpressionTypeMethod(_DeclareFunction.Parameter3.Expression);
       
   520             Type[] InputParameters = { ParameterType1, ParameterType2, ParameterType3 };
       
   521             
       
   522             Type ReturnType = typeof(void);
       
   523             if(_DeclareFunction.ReturnType == "void")
       
   524                 ReturnType = typeof(void);
       
   525             else if (_DeclareFunction.ReturnType == "string")
       
   526                 ReturnType = typeof(string);
       
   527             else if (_DeclareFunction.ReturnType == "numeric")
       
   528                 ReturnType = typeof(int);
       
   529 
       
   530             
       
   531 
       
   532             //FieldBuilder Parameter1 = _typeBuilder.DefineField(_DeclareFunction.Parameter1.Identifier, ParameterType1, FieldAttributes.Private);
       
   533             //FieldBuilder Parameter2 = _typeBuilder.DefineField(_DeclareFunction.Parameter2.Identifier, ParameterType2, FieldAttributes.Private);
       
   534             //FieldBuilder Parameter3 = _typeBuilder.DefineField(_DeclareFunction.Parameter3.Identifier, ParameterType3, FieldAttributes.Private);            
       
   535             
       
   536             MethodBuilder NewMethod = 
       
   537                 _typeBuilder.DefineMethod
       
   538                 (strFunctionName,
       
   539                 MethodAttributes.Static,
       
   540                 ReturnType,
       
   541                 InputParameters);
       
   542 
       
   543             //ParameterBuilder poolRefBuilder = NewMethod.DefineParameter(1, ParameterAttributes.In, _DeclareFunction.Parameter1.Identifier);
       
   544 
       
   545             _ILMethod = NewMethod.GetILGenerator();
       
   546 
       
   547 
       
   548             //tblArguments[_DeclareFunction.Parameter0.Identifier] = _ILMethod.
       
   549 
       
   550             tblArguments[_DeclareFunction.Parameter1.Identifier] = _ILMethod.DeclareLocal(ParameterType1);
       
   551             GenerateExpressionMethod(_DeclareFunction.Parameter1.Expression, ParameterType1);
       
   552             //_ILMethod.Emit(OpCodes.Starg, 0);
       
   553 
       
   554             tblArguments[_DeclareFunction.Parameter1.Identifier] = _ILMethod.DeclareLocal(ParameterType2);
       
   555             GenerateExpressionMethod(_DeclareFunction.Parameter1.Expression, ParameterType2);
       
   556             //_ILMethod.Emit(OpCodes.Starg, 1);
       
   557 
       
   558             tblArguments[_DeclareFunction.Parameter2.Identifier] = _ILMethod.DeclareLocal(ParameterType3);
       
   559             GenerateExpressionMethod(_DeclareFunction.Parameter2.Expression, ParameterType3);
       
   560             //_ILMethod.Emit(OpCodes.Starg, 2);
       
   561 
       
   562             //GenerateStatementMethod(_DeclareFunction.Body);
       
   563             //_ILMethod.Emit(OpCodes.Ret);
       
   564         }
       
   565 
       
   566         #region write-read
       
   567         else if (_statement is Write)
       
   568         {
       
   569             // for print keyword, call .net method for printscreen
       
   570             GenerateExpressionMethod(((Write)_statement).Expression,
       
   571                 typeof(string));
       
   572             _ILMethod.Emit(OpCodes.Call,
       
   573                 typeof(System.Console).GetMethod("WriteLine",
       
   574                 new System.Type[] { typeof(string) }));
       
   575         }
       
   576 
       
   577         else if (_statement is ReadInput)
       
   578         {
       
   579             // call the readline method and parse input method
       
   580             _ILMethod.Emit(OpCodes.Call,
       
   581                 typeof(System.Console).GetMethod("ReadLine",
       
   582                 BindingFlags.Public | BindingFlags.Static,
       
   583                 null, new System.Type[] { }, null));
       
   584             _ILMethod.Emit(OpCodes.Call,
       
   585                 typeof(int).GetMethod("Parse",
       
   586                 BindingFlags.Public | BindingFlags.Static,
       
   587                 null, new System.Type[] { typeof(string) }, null));
       
   588             // store the input value in local builder
       
   589             SaveIdentifierMethod(((ReadInput)_statement).Identifier, typeof(int));
       
   590         }
       
   591         #endregion
       
   592 
       
   593         #region While
       
   594         else if (_statement is While)
       
   595         {
       
   596             While _while = (While)_statement;
       
   597             Label lblTest = _ILMethod.DefineLabel();
       
   598             Label lblEnd = _ILMethod.DefineLabel();
       
   599 
       
   600             if (_while.Operand == RelationalOperands.GreaterThan)
       
   601             {
       
   602                 _ILMethod.MarkLabel(lblTest);
       
   603                 GenerateExpressionMethod(_while.LeftExpression, typeof(int));
       
   604                 GenerateExpressionMethod(_while.RightExpression, typeof(int));
       
   605                 _ILMethod.Emit(OpCodes.Cgt);
       
   606                 _ILMethod.Emit(OpCodes.Brfalse, lblEnd);
       
   607                 GenerateStatementMethod(_while.Body);
       
   608                 _ILMethod.Emit(OpCodes.Br, lblTest);
       
   609 
       
   610                 _ILMethod.MarkLabel(lblEnd);
       
   611             }
       
   612             else if (_while.Operand == RelationalOperands.EqualTo)
       
   613             {
       
   614                 _ILMethod.MarkLabel(lblTest);
       
   615                 GenerateExpressionMethod(_while.LeftExpression, typeof(int));
       
   616                 GenerateExpressionMethod(_while.RightExpression, typeof(int));
       
   617                 _ILMethod.Emit(OpCodes.Ceq);
       
   618                 _ILMethod.Emit(OpCodes.Brfalse, lblEnd);
       
   619                 GenerateStatementMethod(_while.Body);
       
   620                 _ILMethod.Emit(OpCodes.Br, lblTest);
       
   621 
       
   622                 _ILMethod.MarkLabel(lblEnd);
       
   623             }
       
   624             else if (_while.Operand == RelationalOperands.LessThan)
       
   625             {
       
   626                 _ILMethod.MarkLabel(lblTest);
       
   627                 GenerateExpressionMethod(_while.LeftExpression, typeof(int));
       
   628                 GenerateExpressionMethod(_while.RightExpression, typeof(int));
       
   629                 _ILMethod.Emit(OpCodes.Clt);
       
   630                 _ILMethod.Emit(OpCodes.Brfalse, lblEnd);
       
   631                 GenerateStatementMethod(_while.Body);
       
   632                 _ILMethod.Emit(OpCodes.Br, lblTest);
       
   633 
       
   634                 _ILMethod.MarkLabel(lblEnd);
       
   635             }
       
   636         }
       
   637         #endregion
       
   638 
       
   639         #region If-Then
       
   640         else if (_statement is IfThen)
       
   641         {
       
   642             IfThen ifThen = (IfThen)_statement;
       
   643             Label lblElse = _ILMethod.DefineLabel();
       
   644             Label lblEnd = _ILMethod.DefineLabel();
       
   645 
       
   646             #region GreaterThan
       
   647             if (ifThen.Operand == RelationalOperands.GreaterThan)
       
   648             {
       
   649                 GenerateExpressionMethod(ifThen.LeftExpression, typeof(int));
       
   650                 GenerateExpressionMethod(ifThen.RightExpression, typeof(int));
       
   651                 _ILMethod.Emit(OpCodes.Cgt);
       
   652                 _ILMethod.Emit(OpCodes.Brfalse, lblElse);
       
   653                 GenerateStatementMethod(ifThen.ThenBody);
       
   654                 _ILMethod.Emit(OpCodes.Br, lblEnd);
       
   655 
       
   656                 _ILMethod.MarkLabel(lblElse);
       
   657                 GenerateStatementMethod(ifThen.ElseBody);
       
   658 
       
   659                 _ILMethod.MarkLabel(lblEnd);
       
   660             }
       
   661             #endregion
       
   662             #region EqualTo
       
   663             else if (ifThen.Operand == RelationalOperands.EqualTo)
       
   664             {
       
   665                 GenerateExpressionMethod(ifThen.LeftExpression, typeof(int));
       
   666                 GenerateExpressionMethod(ifThen.RightExpression, typeof(int));
       
   667                 _ILMethod.Emit(OpCodes.Ceq);
       
   668                 _ILMethod.Emit(OpCodes.Brfalse, lblElse);
       
   669                 GenerateStatementMethod(ifThen.ThenBody);
       
   670                 _ILMethod.Emit(OpCodes.Br, lblEnd);
       
   671 
       
   672                 _ILMethod.MarkLabel(lblElse);
       
   673                 GenerateStatementMethod(ifThen.ElseBody);
       
   674 
       
   675                 _ILMethod.MarkLabel(lblEnd);
       
   676             }
       
   677             #endregion
       
   678             #region LessThan
       
   679             else if (ifThen.Operand == RelationalOperands.LessThan)
       
   680             {
       
   681                 GenerateExpressionMethod(ifThen.LeftExpression, typeof(int));
       
   682                 GenerateExpressionMethod(ifThen.RightExpression, typeof(int));
       
   683                 _ILMethod.Emit(OpCodes.Clt);
       
   684                 _ILMethod.Emit(OpCodes.Brfalse, lblElse);
       
   685                 GenerateStatementMethod(ifThen.ThenBody);
       
   686                 _ILMethod.Emit(OpCodes.Br, lblEnd);
       
   687 
       
   688                 _ILMethod.MarkLabel(lblElse);
       
   689                 GenerateStatementMethod(ifThen.ElseBody);
       
   690 
       
   691                 _ILMethod.MarkLabel(lblEnd);
       
   692             }
       
   693             #endregion
       
   694         }
       
   695         #endregion
       
   696 
       
   697         #region for
       
   698         else if (_statement is For)
       
   699         {
       
   700             For forLoop = (For)_statement;
       
   701             Assignment assign = new Assignment();
       
   702             assign.Identifier = forLoop.Identifier;
       
   703             assign.Expression = forLoop.From;
       
   704             GenerateStatementMethod(assign);
       
   705             
       
   706             Label test = _ILMethod.DefineLabel();
       
   707             _ILMethod.Emit(OpCodes.Br, test);
       
   708 
       
   709             Label body = _ILMethod.DefineLabel();
       
   710             _ILMethod.MarkLabel(body);
       
   711             GenerateStatementMethod(forLoop.Body);
       
   712 
       
   713             _ILMethod.Emit(OpCodes.Ldloc, tblIdentifier[forLoop.Identifier]);
       
   714             _ILMethod.Emit(OpCodes.Ldc_I4, 1);
       
   715             _ILMethod.Emit(OpCodes.Add);
       
   716             SaveIdentifierMethod(forLoop.Identifier, typeof(int));
       
   717 
       
   718             _ILMethod.MarkLabel(test);
       
   719             _ILMethod.Emit(OpCodes.Ldloc, tblIdentifier[forLoop.Identifier]);
       
   720             GenerateExpressionMethod(forLoop.To, typeof(int));
       
   721             _ILMethod.Emit(OpCodes.Blt, body);
       
   722         }
       
   723         #endregion
       
   724 
       
   725         else
       
   726         {
       
   727             ExceptionHandler("unable to generate " + _statement.GetType().Name);
       
   728         }
       
   729     }
       
   730 
       
   731     public void SaveIdentifierMethod(string IdentifierName, System.Type IdentifierType)
       
   732     {
       
   733         if (tblIdentifier.ContainsKey(IdentifierName))
       
   734         {
       
   735             LocalBuilder locb = tblIdentifier[IdentifierName];
       
   736 
       
   737             if (locb.LocalType == IdentifierType)
       
   738             {
       
   739                 _ILMethod.Emit(OpCodes.Stloc, tblIdentifier[IdentifierName]);
       
   740             }
       
   741             else
       
   742             {
       
   743                 ExceptionHandler("'" + IdentifierName + "' is of type " + locb.LocalType.Name + " but saving in different type " + IdentifierType.Name);
       
   744             }
       
   745         }
       
   746         else
       
   747         {
       
   748             ExceptionHandler("variable not declared '" + IdentifierName + "'");
       
   749         }
       
   750     }
       
   751 
       
   752     public void DeclareArgument() { }
       
   753 
       
   754     public void GenerateExpressionMethod(Expression _expression, System.Type expressionType)
       
   755     {
       
   756         System.Type typeOfExpression;
       
   757 
       
   758         if (_expression is AlphaNumericValue)
       
   759         {
       
   760             typeOfExpression = typeof(string);
       
   761             _ILMethod.Emit(OpCodes.Ldstr, ((AlphaNumericValue)_expression).Value);
       
   762         }
       
   763         else if (_expression is NumericValue)
       
   764         {
       
   765             typeOfExpression = typeof(int);
       
   766             _ILMethod.Emit(OpCodes.Ldc_I4, ((NumericValue)_expression).Value);
       
   767         }
       
   768 
       
   769         else if (_expression is ArithmaticExpression)
       
   770         {
       
   771             typeOfExpression = GetExpressionTypeMethod(_expression);
       
   772 
       
   773             ArithmaticExpression arithmaticExpression = (ArithmaticExpression)_expression;
       
   774             GenerateExpressionMethod(arithmaticExpression.Left, GetExpressionTypeMethod(arithmaticExpression.Left));
       
   775             GenerateExpressionMethod(arithmaticExpression.Right, GetExpressionTypeMethod(arithmaticExpression.Right));
       
   776             if (arithmaticExpression.Operand == ArithmaticOperands.Add)
       
   777             {
       
   778                 _ILMethod.Emit(OpCodes.Add);
       
   779             }
       
   780             else if (arithmaticExpression.Operand == ArithmaticOperands.Subtract)
       
   781             {
       
   782                 _ILMethod.Emit(OpCodes.Sub);
       
   783             }
       
   784             else if (arithmaticExpression.Operand == ArithmaticOperands.Multiply)
       
   785             {
       
   786                 _ILMethod.Emit(OpCodes.Mul);
       
   787             }
       
   788             else if (arithmaticExpression.Operand == ArithmaticOperands.Division)
       
   789             {
       
   790                 _ILMethod.Emit(OpCodes.Div);
       
   791             }
       
   792         }
       
   793 
       
   794 
       
   795         else if (_expression is Identifier)
       
   796         {
       
   797             string identifier = ((Identifier)_expression).IdentifierName;
       
   798             typeOfExpression = GetExpressionTypeMethod(_expression);
       
   799 
       
   800             if (!tblIdentifier.ContainsKey(identifier) && !tblArguments.ContainsKey(identifier))
       
   801             {
       
   802                 ExceptionHandler("undeclared variable '" + identifier + "'");
       
   803             }
       
   804 
       
   805             if (tblIdentifier.ContainsKey(identifier))
       
   806                 _ILMethod.Emit(OpCodes.Ldloc, tblIdentifier[identifier]);
       
   807             else
       
   808                 _ILMethod.Emit(OpCodes.Ldloc, tblArguments[identifier]);
       
   809         }
       
   810 
       
   811         else
       
   812         {
       
   813             ExceptionHandler("can't generate " + _expression.GetType().Name);
       
   814             typeOfExpression = null;
       
   815         }
       
   816 
       
   817         if (typeOfExpression != expressionType)
       
   818         {
       
   819             if (typeOfExpression == typeof(int) &&
       
   820                 expressionType == typeof(string))
       
   821             {
       
   822                 _ILMethod.Emit(OpCodes.Box, typeof(int));
       
   823                 _ILMethod.Emit(OpCodes.Callvirt, typeof(object).GetMethod("ToString"));
       
   824             }
       
   825             else
       
   826             {
       
   827                 ExceptionHandler("can't convert " + typeOfExpression.Name + " to " + expressionType.Name);
       
   828             }
       
   829         }
       
   830 
       
   831     }
       
   832 
       
   833     public System.Type GetExpressionTypeMethod(Expression _expression)
       
   834     {
       
   835         if (_expression is AlphaNumericValue)
       
   836         {
       
   837             return typeof(string);
       
   838         }
       
   839         else if (_expression is NumericValue)
       
   840         {
       
   841             return typeof(int);
       
   842         }
       
   843         else if (_expression is Identifier)
       
   844         {
       
   845             Identifier var = (Identifier)_expression;
       
   846             if (tblIdentifier.ContainsKey(var.IdentifierName))
       
   847             {
       
   848                 LocalBuilder locb = tblIdentifier[var.IdentifierName];
       
   849                 return locb.LocalType;
       
   850             }
       
   851             else if (tblArguments.ContainsKey(var.IdentifierName))
       
   852             {
       
   853                 LocalBuilder locb = tblArguments[var.IdentifierName];
       
   854                 return locb.LocalType;
       
   855             }
       
   856             else
       
   857             {
       
   858                 ExceptionHandler("variable not declared '" + var.IdentifierName + "'");
       
   859                 return null;
       
   860             }
       
   861         }
       
   862         else if (_expression is ArithmaticExpression)
       
   863         {
       
   864             return typeof(ArithmaticExpression);
       
   865         }
       
   866         else
       
   867         {
       
   868             ExceptionHandler("type cannot be generated for " + _expression.GetType().Name);
       
   869             return null;
       
   870         }
       
   871     }    
       
   872     #endregion
       
   873 }
       
   874