Fahad/MCG-CS/CodeGenerator.cs
changeset 45 7545b1bc1514
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Fahad/MCG-CS/CodeGenerator.cs	Wed Nov 12 12:24:26 2014 +0000
@@ -0,0 +1,874 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+// Added
+using System.Reflection;
+using System.Reflection.Emit;
+using System.IO;
+
+public sealed class CodeGenerator
+{
+    
+    Dictionary<string, System.Reflection.Emit.LocalBuilder> tblIdentifier;
+    Dictionary<string, System.Reflection.Emit.LocalBuilder> tblArguments;
+    TypeBuilder _typeBuilder = null;
+    System.Reflection.Emit.ILGenerator _ILGenerator = null;
+    MemberInfo WriteLine = typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) });
+
+    #region Statement
+    public CodeGenerator(Statement statement, string fileName)
+    {
+        string strFileName = Path.GetFileNameWithoutExtension(fileName);
+
+        #region Define Assembly
+        //AssemblyName _AssemblyName = new AssemblyName(Path.GetFileNameWithoutExtension(fileName));
+        AssemblyName _AssemblyName = new AssemblyName(strFileName);
+        AppDomain currentDomain = AppDomain.CurrentDomain;
+        AssemblyBuilder _AssemblyBuilder = currentDomain.DefineDynamicAssembly(_AssemblyName, AssemblyBuilderAccess.Save);
+        #endregion
+
+        #region Define Module
+        ModuleBuilder _ModuleBuilder = _AssemblyBuilder.DefineDynamicModule(fileName);
+        #endregion
+        
+        _typeBuilder = _ModuleBuilder.DefineType("CodeGenerator");
+        MethodBuilder _MethodBuilder = _typeBuilder.DefineMethod
+            ("Main", 
+            MethodAttributes.Static, 
+            typeof(void), 
+            System.Type.EmptyTypes);
+
+        _ILGenerator = _MethodBuilder.GetILGenerator();
+        tblIdentifier = new Dictionary<string, System.Reflection.Emit.LocalBuilder>();
+        tblArguments = new Dictionary<string, System.Reflection.Emit.LocalBuilder>();
+
+        // CIL generation
+        GenerateStatement(statement);
+
+        _ILGenerator.Emit(OpCodes.Ret);
+        _typeBuilder.CreateType();
+        _ModuleBuilder.CreateGlobalFunctions();
+        _AssemblyBuilder.SetEntryPoint(_MethodBuilder);
+        _AssemblyBuilder.Save(fileName);
+        tblIdentifier = null;
+        _ILGenerator = null; 
+    }
+
+    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 ExceptionHandler(string strException) 
+    {
+        throw new Exception(strException);
+    }
+
+    public void SaveIdentifier(string IdentifierName, System.Type IdentifierType)
+    {
+        if (tblIdentifier.ContainsKey(IdentifierName))
+        {
+            LocalBuilder locb = tblIdentifier[IdentifierName];
+
+            if (locb.LocalType == IdentifierType)
+            {
+                _ILGenerator.Emit(OpCodes.Stloc, tblIdentifier[IdentifierName]);
+            }
+            else
+            {
+                ExceptionHandler("'" + IdentifierName + "' is of type " + locb.LocalType.Name + " but saving in different type " + IdentifierType.Name);
+            }
+        }
+        else
+        {
+            ExceptionHandler("variable not declared '" + IdentifierName + "'");
+        }
+    }
+
+    public void GenerateExpression(Expression _expression, System.Type expressionType)
+    {
+        System.Type typeOfExpression;
+
+        if (_expression is AlphaNumericValue)
+        {
+            typeOfExpression = typeof(string);
+            _ILGenerator.Emit(OpCodes.Ldstr, ((AlphaNumericValue)_expression).Value);
+        }
+        else if (_expression is NumericValue)
+        {
+            typeOfExpression = typeof(int);
+            _ILGenerator.Emit(OpCodes.Ldc_I4, ((NumericValue)_expression).Value);
+        }
+        
+        else if (_expression is ArithmaticExpression) 
+        {
+            typeOfExpression = GetExpressionType(_expression);
+
+            ArithmaticExpression arithmaticExpression = (ArithmaticExpression)_expression;
+            GenerateExpression(arithmaticExpression.Left, GetExpressionType(arithmaticExpression.Left));
+            GenerateExpression(arithmaticExpression.Right, GetExpressionType(arithmaticExpression.Right));
+            if (arithmaticExpression.Operand == ArithmaticOperands.Add) 
+            {
+                _ILGenerator.Emit(OpCodes.Add);
+            }
+            else if (arithmaticExpression.Operand == ArithmaticOperands.Subtract) 
+            {
+                _ILGenerator.Emit(OpCodes.Sub);
+            }
+            else if (arithmaticExpression.Operand == ArithmaticOperands.Multiply) 
+            {
+                _ILGenerator.Emit(OpCodes.Mul);
+            }
+            else if (arithmaticExpression.Operand == ArithmaticOperands.Division) 
+            {
+                _ILGenerator.Emit(OpCodes.Div);
+            }
+        }
+        
+        
+        else if (_expression is Identifier)
+        {
+            string identifier = ((Identifier)_expression).IdentifierName;
+            typeOfExpression = GetExpressionType(_expression);
+
+            if (!tblIdentifier.ContainsKey(identifier))
+            {
+                ExceptionHandler("undeclared variable '" + identifier + "'");
+            }
+
+            _ILGenerator.Emit(OpCodes.Ldloc, tblIdentifier[identifier]);
+        }
+        
+        else
+        {
+            ExceptionHandler("can't generate " + _expression.GetType().Name);
+            typeOfExpression = null;
+        }
+
+        if (typeOfExpression != expressionType)
+        {
+            if (typeOfExpression == typeof(int) &&
+                expressionType == typeof(string))
+            {
+                _ILGenerator.Emit(OpCodes.Box, typeof(int));
+                _ILGenerator.Emit(OpCodes.Callvirt, typeof(object).GetMethod("ToString"));
+            }
+            else
+            {
+                ExceptionHandler("can't convert " + typeOfExpression.Name + " to " + expressionType.Name);
+            }
+        }
+
+    }
+
+    public System.Type GetExpressionType(Expression _expression)
+    {
+        if (_expression is AlphaNumericValue)
+        {
+            return typeof(string);
+        }
+        else if (_expression is NumericValue)
+        {
+            return typeof(int);
+        }
+        else if (_expression is Identifier)
+        {
+            Identifier var = (Identifier)_expression;
+            if (tblIdentifier.ContainsKey(var.IdentifierName))
+            {
+                LocalBuilder locb = tblIdentifier[var.IdentifierName];
+                return locb.LocalType;
+            }
+            else
+            {
+                ExceptionHandler("variable not declared '" + var.IdentifierName + "'");
+                return null;
+            }
+        }
+        else if (_expression is ArithmaticExpression) 
+        {
+            return typeof(ArithmaticExpression);
+        }
+        else
+        {
+            ExceptionHandler("type cannot be generated for " + _expression.GetType().Name);
+            return null;
+        }
+    }
+
+    #endregion
+
+    #region Method
+
+    System.Reflection.Emit.ILGenerator _ILMethod = null;
+    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);
+        }
+    }
+
+    public void SaveIdentifierMethod(string IdentifierName, System.Type IdentifierType)
+    {
+        if (tblIdentifier.ContainsKey(IdentifierName))
+        {
+            LocalBuilder locb = tblIdentifier[IdentifierName];
+
+            if (locb.LocalType == IdentifierType)
+            {
+                _ILMethod.Emit(OpCodes.Stloc, tblIdentifier[IdentifierName]);
+            }
+            else
+            {
+                ExceptionHandler("'" + IdentifierName + "' is of type " + locb.LocalType.Name + " but saving in different type " + IdentifierType.Name);
+            }
+        }
+        else
+        {
+            ExceptionHandler("variable not declared '" + IdentifierName + "'");
+        }
+    }
+
+    public void DeclareArgument() { }
+
+    public void GenerateExpressionMethod(Expression _expression, System.Type expressionType)
+    {
+        System.Type typeOfExpression;
+
+        if (_expression is AlphaNumericValue)
+        {
+            typeOfExpression = typeof(string);
+            _ILMethod.Emit(OpCodes.Ldstr, ((AlphaNumericValue)_expression).Value);
+        }
+        else if (_expression is NumericValue)
+        {
+            typeOfExpression = typeof(int);
+            _ILMethod.Emit(OpCodes.Ldc_I4, ((NumericValue)_expression).Value);
+        }
+
+        else if (_expression is ArithmaticExpression)
+        {
+            typeOfExpression = GetExpressionTypeMethod(_expression);
+
+            ArithmaticExpression arithmaticExpression = (ArithmaticExpression)_expression;
+            GenerateExpressionMethod(arithmaticExpression.Left, GetExpressionTypeMethod(arithmaticExpression.Left));
+            GenerateExpressionMethod(arithmaticExpression.Right, GetExpressionTypeMethod(arithmaticExpression.Right));
+            if (arithmaticExpression.Operand == ArithmaticOperands.Add)
+            {
+                _ILMethod.Emit(OpCodes.Add);
+            }
+            else if (arithmaticExpression.Operand == ArithmaticOperands.Subtract)
+            {
+                _ILMethod.Emit(OpCodes.Sub);
+            }
+            else if (arithmaticExpression.Operand == ArithmaticOperands.Multiply)
+            {
+                _ILMethod.Emit(OpCodes.Mul);
+            }
+            else if (arithmaticExpression.Operand == ArithmaticOperands.Division)
+            {
+                _ILMethod.Emit(OpCodes.Div);
+            }
+        }
+
+
+        else if (_expression is Identifier)
+        {
+            string identifier = ((Identifier)_expression).IdentifierName;
+            typeOfExpression = GetExpressionTypeMethod(_expression);
+
+            if (!tblIdentifier.ContainsKey(identifier) && !tblArguments.ContainsKey(identifier))
+            {
+                ExceptionHandler("undeclared variable '" + identifier + "'");
+            }
+
+            if (tblIdentifier.ContainsKey(identifier))
+                _ILMethod.Emit(OpCodes.Ldloc, tblIdentifier[identifier]);
+            else
+                _ILMethod.Emit(OpCodes.Ldloc, tblArguments[identifier]);
+        }
+
+        else
+        {
+            ExceptionHandler("can't generate " + _expression.GetType().Name);
+            typeOfExpression = null;
+        }
+
+        if (typeOfExpression != expressionType)
+        {
+            if (typeOfExpression == typeof(int) &&
+                expressionType == typeof(string))
+            {
+                _ILMethod.Emit(OpCodes.Box, typeof(int));
+                _ILMethod.Emit(OpCodes.Callvirt, typeof(object).GetMethod("ToString"));
+            }
+            else
+            {
+                ExceptionHandler("can't convert " + typeOfExpression.Name + " to " + expressionType.Name);
+            }
+        }
+
+    }
+
+    public System.Type GetExpressionTypeMethod(Expression _expression)
+    {
+        if (_expression is AlphaNumericValue)
+        {
+            return typeof(string);
+        }
+        else if (_expression is NumericValue)
+        {
+            return typeof(int);
+        }
+        else if (_expression is Identifier)
+        {
+            Identifier var = (Identifier)_expression;
+            if (tblIdentifier.ContainsKey(var.IdentifierName))
+            {
+                LocalBuilder locb = tblIdentifier[var.IdentifierName];
+                return locb.LocalType;
+            }
+            else if (tblArguments.ContainsKey(var.IdentifierName))
+            {
+                LocalBuilder locb = tblArguments[var.IdentifierName];
+                return locb.LocalType;
+            }
+            else
+            {
+                ExceptionHandler("variable not declared '" + var.IdentifierName + "'");
+                return null;
+            }
+        }
+        else if (_expression is ArithmaticExpression)
+        {
+            return typeof(ArithmaticExpression);
+        }
+        else
+        {
+            ExceptionHandler("type cannot be generated for " + _expression.GetType().Name);
+            return null;
+        }
+    }    
+    #endregion
+}
+