EndScope() public method

public EndScope ( ) : void
return void
コード例 #1
0
      internal override void TranslateToIL(ILGenerator il, Type rtype){
        //This assumes that rtype == Void.class
        this.context.EmitLineInfo(il);
        Globals.ScopeStack.Push(new WithObject(Globals.ScopeStack.Peek(), new JSObject(null, false)));
        bool savedInsideProtectedRegion = compilerGlobals.InsideProtectedRegion;
        compilerGlobals.InsideProtectedRegion = true;
        Label lab = il.DefineLabel();
        compilerGlobals.BreakLabelStack.Push(lab);
        compilerGlobals.ContinueLabelStack.Push(lab);
        this.obj.TranslateToIL(il, Typeob.Object);
        this.EmitILToLoadEngine(il);
        il.Emit(OpCodes.Call, CompilerGlobals.jScriptWithMethod); // JScriptWith returns the with object as an 'Object' (used by the debugger EE)
        
        // define a local named 'with()' that the debugger EE will use to bind to the with object
        LocalBuilder withObj = null;
        if (context.document.debugOn){
          il.BeginScope(); // used by the debugger to mark a with block 
          withObj = il.DeclareLocal(Typeob.Object);
          withObj.SetLocalSymInfo("with()");
          il.Emit(OpCodes.Stloc, withObj);
        }else
          il.Emit(OpCodes.Pop);

        il.BeginExceptionBlock();
        this.block.TranslateToILInitializer(il);
        this.block.TranslateToIL(il, Typeob.Void);
        il.BeginFinallyBlock();
        if (context.document.debugOn){
          // null the local used by the debugger EE
          il.Emit(OpCodes.Ldnull);
          il.Emit(OpCodes.Stloc, withObj);
        }
        this.EmitILToLoadEngine(il);
        il.Emit(OpCodes.Call, CompilerGlobals.popScriptObjectMethod);
        il.Emit(OpCodes.Pop);
        il.EndExceptionBlock();
        if (context.document.debugOn)
          il.EndScope(); // used by the debugger to mark a with block 
        il.MarkLabel(lab);
        compilerGlobals.BreakLabelStack.Pop();
        compilerGlobals.ContinueLabelStack.Pop();
        compilerGlobals.InsideProtectedRegion = savedInsideProtectedRegion;
        Globals.ScopeStack.Pop();
      }
コード例 #2
0
ファイル: try.cs プロジェクト: ArildF/masters
 internal override void TranslateToIL(ILGenerator il, Type rtype){
   //This assumes that rtype == Void.class.
   bool savedInsideProtectedRegion = compilerGlobals.InsideProtectedRegion;
   compilerGlobals.InsideProtectedRegion = true;
   compilerGlobals.BreakLabelStack.Push(compilerGlobals.BreakLabelStack.Peek(0));
   compilerGlobals.ContinueLabelStack.Push(compilerGlobals.ContinueLabelStack.Peek(0));
   il.BeginExceptionBlock(); 
   if (this.finally_block != null){
     if (this.finallyHasControlFlowOutOfIt)
       il.BeginExceptionBlock();
     if (this.handler != null) 
       il.BeginExceptionBlock();
   }
   this.body.TranslateToIL(il, Typeob.Void);
   if (this.tryEndContext != null)
     this.tryEndContext.EmitLineInfo(il);
   if (this.handler != null){
     if (this.type == null){
       il.BeginCatchBlock(typeof(Exception));
       this.handler.context.EmitLineInfo(il);
       this.EmitILToLoadEngine(il);
       il.Emit(OpCodes.Call, CompilerGlobals.jScriptExceptionValueMethod);
     }else{
       Type filterType = this.type.ToType();
       if (typeof(Exception).IsAssignableFrom(filterType)){
         il.BeginCatchBlock(filterType);
         this.handler.context.EmitLineInfo(il);
       }
       else{
         il.BeginExceptFilterBlock();
         this.handler.context.EmitLineInfo(il);
         this.EmitILToLoadEngine(il);
         il.Emit(OpCodes.Call, CompilerGlobals.jScriptExceptionValueMethod);
         il.Emit(OpCodes.Isinst, filterType);
         il.Emit(OpCodes.Ldnull);
         il.Emit(OpCodes.Cgt_Un);
         il.BeginCatchBlock(null);
         this.EmitILToLoadEngine(il);
         il.Emit(OpCodes.Call, CompilerGlobals.jScriptExceptionValueMethod);
         Convert.Emit(this, il, Typeob.Object, filterType);
       }
     }
     Object tok = this.field is JSVariableField ? ((JSVariableField)this.field).GetMetaData() : this.field;
     if (tok is LocalBuilder)
       il.Emit(OpCodes.Stloc, (LocalBuilder)tok);
     else if (tok is FieldInfo)
       il.Emit(OpCodes.Stsfld, (FieldInfo)tok);
     else
       Convert.EmitLdarg(il, (short)tok);
     if (this.handler_scope != null){
       if (!this.handler_scope.isKnownAtCompileTime){ //I.e. eval or nested func
         this.EmitILToLoadEngine(il);
         il.Emit(OpCodes.Ldstr, this.fieldName);
         ConstantWrapper.TranslateToILInt(il, this.handler_scope.scopeId);
         il.Emit(OpCodes.Call, typeof(Try).GetMethod("PushHandlerScope"));
         Globals.ScopeStack.Push(this.handler_scope);
       }
       il.BeginScope(); // so that we can emit local scoped information for the handler variable
       if (this.context.document.debugOn)
         this.handler_scope.EmitLocalInfoForFields(il);
     }
     this.handler.TranslateToIL(il, Typeob.Void);
     if (this.handler_scope != null){
       il.EndScope(); 
       if (!this.handler_scope.isKnownAtCompileTime){ //I.e. eval or nested func
         this.EmitILToLoadEngine(il);
         il.Emit(OpCodes.Call, CompilerGlobals.popScriptObjectMethod);
         il.Emit(OpCodes.Pop);
         Globals.ScopeStack.Pop();
       }
     }
     il.EndExceptionBlock();
   }
   if (this.finally_block != null){
     bool savedInsideFinally = compilerGlobals.InsideFinally;
     int savedFinallyStackTop = compilerGlobals.FinallyStackTop;
     compilerGlobals.InsideFinally = true;
     compilerGlobals.FinallyStackTop = compilerGlobals.BreakLabelStack.Size();
     il.BeginFinallyBlock();
     this.finally_block.TranslateToIL(il, Typeob.Void);
     il.EndExceptionBlock();
     compilerGlobals.InsideFinally = savedInsideFinally;
     compilerGlobals.FinallyStackTop = savedFinallyStackTop;
     if (this.finallyHasControlFlowOutOfIt){
       il.BeginCatchBlock(typeof(BreakOutOfFinally));
       il.Emit(OpCodes.Ldfld, typeof(BreakOutOfFinally).GetField("target"));
       // don't need to go to 0 in the loop because 0 is the outmost block (i.e. function body)
       // and that would generate a JIT assert because the jump is sometimes outside the function
       for (int i = compilerGlobals.BreakLabelStack.Size()-1, n = i; i > 0; i--){
         il.Emit(OpCodes.Dup);
         ConstantWrapper.TranslateToILInt(il, i);
         Label lab = il.DefineLabel();
         il.Emit(OpCodes.Blt_S, lab);
         il.Emit(OpCodes.Pop);
         if (savedInsideFinally && i < savedFinallyStackTop)
           il.Emit(OpCodes.Rethrow);
         else
           il.Emit(OpCodes.Leave, (Label)compilerGlobals.BreakLabelStack.Peek(n-i));
         il.MarkLabel(lab);
       }
       il.Emit(OpCodes.Pop);
       il.BeginCatchBlock(typeof(ContinueOutOfFinally));
       il.Emit(OpCodes.Ldfld, typeof(ContinueOutOfFinally).GetField("target"));
       // don't need to go to 0 in the loop because 0 is the outmost block (i.e. function body)
       for (int i = compilerGlobals.ContinueLabelStack.Size()-1, n = i; i > 0; i--){
         il.Emit(OpCodes.Dup);
         ConstantWrapper.TranslateToILInt(il, i);
         Label lab = il.DefineLabel();
         il.Emit(OpCodes.Blt_S, lab);
         il.Emit(OpCodes.Pop);
         if (savedInsideFinally && i < savedFinallyStackTop)
           il.Emit(OpCodes.Rethrow);
         else
           il.Emit(OpCodes.Leave, (Label)compilerGlobals.ContinueLabelStack.Peek(n-i));
         il.MarkLabel(lab);
       }
       il.Emit(OpCodes.Pop);
       ScriptObject scope = Globals.ScopeStack.Peek();
       while (scope != null && !(scope is FunctionScope))
         scope = scope.GetParent();
       if (scope != null && !savedInsideFinally){
         il.BeginCatchBlock(typeof(ReturnOutOfFinally));
         il.Emit(OpCodes.Pop);
         il.Emit(OpCodes.Leave, ((FunctionScope)scope).owner.returnLabel);
       }
       il.EndExceptionBlock();
     }
   }
   compilerGlobals.InsideProtectedRegion = savedInsideProtectedRegion;
   compilerGlobals.BreakLabelStack.Pop();
   compilerGlobals.ContinueLabelStack.Pop();
 }
コード例 #3
0
 internal override void TranslateToIL(ILGenerator il, Type rtype)
 {
     base.context.EmitLineInfo(il);
     base.Globals.ScopeStack.Push(new WithObject(base.Globals.ScopeStack.Peek(), new JSObject(null, false)));
     bool insideProtectedRegion = base.compilerGlobals.InsideProtectedRegion;
     base.compilerGlobals.InsideProtectedRegion = true;
     Label item = il.DefineLabel();
     base.compilerGlobals.BreakLabelStack.Push(item);
     base.compilerGlobals.ContinueLabelStack.Push(item);
     this.obj.TranslateToIL(il, Typeob.Object);
     base.EmitILToLoadEngine(il);
     il.Emit(OpCodes.Call, CompilerGlobals.jScriptWithMethod);
     LocalBuilder local = null;
     if (base.context.document.debugOn)
     {
         il.BeginScope();
         local = il.DeclareLocal(Typeob.Object);
         local.SetLocalSymInfo("with()");
         il.Emit(OpCodes.Stloc, local);
     }
     else
     {
         il.Emit(OpCodes.Pop);
     }
     il.BeginExceptionBlock();
     this.block.TranslateToILInitializer(il);
     this.block.TranslateToIL(il, Typeob.Void);
     il.BeginFinallyBlock();
     if (base.context.document.debugOn)
     {
         il.Emit(OpCodes.Ldnull);
         il.Emit(OpCodes.Stloc, local);
     }
     base.EmitILToLoadEngine(il);
     il.Emit(OpCodes.Call, CompilerGlobals.popScriptObjectMethod);
     il.Emit(OpCodes.Pop);
     il.EndExceptionBlock();
     if (base.context.document.debugOn)
     {
         il.EndScope();
     }
     il.MarkLabel(item);
     base.compilerGlobals.BreakLabelStack.Pop();
     base.compilerGlobals.ContinueLabelStack.Pop();
     base.compilerGlobals.InsideProtectedRegion = insideProtectedRegion;
     base.Globals.ScopeStack.Pop();
 }
コード例 #4
0
 public override void Compile(ILGenerator il)
 {
     SymbolTable.PushScope();
     il.BeginScope();
     EmitDebugInfo(il, 0, true);
     if (Options.Debug) {
         il.Emit(OpCodes.Nop); //To step correctly
     }
     if (Variables != null) {
         Variables.Compile(il);
     }
     Statements.Compile(il);
     il.EndScope();
     SymbolTable.PopScope();
     EmitDebugInfo(il, 1, true);
 }
コード例 #5
0
ファイル: Program.cs プロジェクト: GunioRobot/Project-Mizu
        static void HandleStatement(Mizu.Parser.ParseNode stmt, ILGenerator ILgen, ref List<LocalBuilderEx> locals, out bool err)
        {
            switch (stmt.Token.Type)
            {
                case Parser.TokenType.VarStatement:
                    {
                        #region VAR
                        int i = 0;
                        while (i != stmt.Nodes.Count - 1)
                        {
                            var token = stmt.Nodes[i];

                            if (IsDebug)
                            {
                                int sline = 0, scol = 0;

                                FindLineAndCol(code, stmt.Token.StartPos, ref sline, ref scol);

                                int eline = 0, ecol = 0;

                                FindLineAndCol(code, stmt.Token.EndPos, ref eline, ref ecol);

                                ILgen.MarkSequencePoint(doc, sline, scol, eline, ecol);
                            }

                            if (token.Token.Type == TokenType.IDENTIFIER) //If its a var declaration.
                            {
                                if (locals.Find(it => it.Name == token.Token.Text) == null)
                                {
                                    var set = stmt.Nodes[i + 1];
                                    if (set.Token.Type == TokenType.SET)
                                    {
                                        i += 1;
                                        var next = stmt.Nodes[i + 1];
                                        if (next.Token.Type == TokenType.NUMBER) //Integers
                                        {
                                            //Declares a variable and leaves a reference to it.

                                            LocalBuilderEx local = new LocalBuilderEx();
                                            local.VariableType = typeof(int);
                                            local.Base = ILgen.DeclareLocal(local.VariableType);

                                            if (IsDebug) local.Base.SetLocalSymInfo(token.Token.Text); //Set variable name for debug info.

                                            ILgen.Emit(OpCodes.Ldc_I4, int.Parse(next.Token.Text)); //Sets the number
                                            ILgen.Emit(OpCodes.Stloc, (LocalBuilder)local.Base); //Assigns the number to the variable.

                                            local.Name = token.Token.Text;
                                            local.Type = LocalType.Var;

                                            locals.Add(local); //Remembers the variable.
                                            i += 1;
                                        }
                                        else if (next.Token.Type == TokenType.FLOAT)
                                        {
                                            //Declares a variable and leaves a reference to it.

                                            LocalBuilderEx local = new LocalBuilderEx();
                                            local.VariableType = typeof(float);
                                            local.Base = ILgen.DeclareLocal(local.VariableType);

                                            if (IsDebug) local.Base.SetLocalSymInfo(token.Token.Text); //Set variable name for debug info.

                                            ILgen.Emit(OpCodes.Ldc_R4, float.Parse(next.Token.Text)); //Sets the number
                                            ILgen.Emit(OpCodes.Stloc, (LocalBuilder)local.Base); //Assigns the number to the variable.

                                            local.Name = token.Token.Text;
                                            local.Type = LocalType.Var;

                                            locals.Add(local); //Remembers the variable.
                                            i += 1;
                                        }
                                        else if (next.Token.Type == TokenType.UPPER)
                                        {
                                            //A variable that reads from stdin (Console.ReadLne)
                                            //Declares a variable and leaves a reference to it.

                                            LocalBuilderEx local = new LocalBuilderEx();

                                            local.VariableType = typeof(int);

                                            local.Base = ILgen.DeclareLocal(local.VariableType);

                                            local.Name = token.Token.Text;
                                            local.Type = LocalType.Var;

                                            if (IsDebug) local.Base.SetLocalSymInfo(token.Token.Text); //Set variable name for debug info.

                                            try
                                            {
                                                //If theres a WAVEY symbol, print the variable name.
                                                var wavey = stmt.Nodes[i + 2];
                                                ILgen.Emit(OpCodes.Ldstr, local.Name + " = ");
                                                ILgen.Emit(OpCodes.Call, typeof(Console).GetMethod("Write", new Type[] { typeof(string) }));
                                                i += 1;
                                            }
                                            catch (Exception) { }

                                            ILgen.Emit(OpCodes.Call, typeof(Console).GetMethod("ReadLine")); //Sets the number from STDIN.

                                            ILgen.Emit(OpCodes.Call, typeof(Convert).GetMethod("ToInt32", new Type[] { typeof(string) })); //Parses it into an integer.
                                            ILgen.Emit(OpCodes.Stloc, (LocalBuilder)local.Base); //Assigns the number to the variable.

                                            locals.Add(local); //Remembers the variable.
                                            i += 1;
                                        }
                                        else if (next.Token.Type == TokenType.COMMA)
                                        {
                                            //An array.

                                            dynamic info = GetLineAndCol(code, stmt.Token.StartPos);

                                            Console.Error.WriteLine("Error: Static arrays are not supported at this time. Line: {0}, Col: {1}", info.Line, info.Col);
                                            err = true;
                                            return;
                                        }
                                        else
                                        {
                                            #region Iterating Variable
                                            //Its a range
                                            var lowNum = stmt.Nodes[i + 2]; //Name is mis-informing. This is really the first number.
                                            var highNum = stmt.Nodes[i + 5]; //Same ^^, this is the second number.

                                            LocalBuilderEx local = new LocalBuilderEx();

                                            local.LoopHigh = int.Parse(highNum.Token.Text);
                                            local.LoopLow = int.Parse(lowNum.Token.Text);

                                            local.Name = token.Token.Text;
                                            local.Type = LocalType.LoopVar;
                                            local.VariableType = typeof(int);

                                            var looplab = ILgen.DefineLabel();

                                            ILgen.BeginScope();
                                            local.Base = ILgen.DeclareLocal(local.VariableType);

                                            local.LoopLabel = looplab;

                                            if (IsDebug) local.Base.SetLocalSymInfo(token.Token.Text); //Set variable name for debug info.

                                            ILgen.Emit(OpCodes.Ldc_I4, local.LoopLow); //Sets the number
                                            ILgen.Emit(OpCodes.Stloc, (LocalBuilder)local.Base); //Assigns the number to the variable.

                                            ILgen.MarkLabel(looplab);
                                            //this is where the IL will execute.

                                            local.LoopAction = () =>
                                            {

                                                //Updates the iterator by 1
                                                ILgen.Emit(OpCodes.Ldloc, local.Base);
                                                ILgen.Emit(OpCodes.Ldc_I4_1);

                                                if (local.LoopLow < local.LoopHigh)
                                                {
                                                    ILgen.Emit(OpCodes.Add); //Loop up
                                                    local.LoopDirection = LoopDirectionEnum.Up;
                                                }
                                                else if (local.LoopLow > local.LoopHigh)
                                                {
                                                    ILgen.Emit(OpCodes.Sub); //Loop down.
                                                    local.LoopDirection = LoopDirectionEnum.Down;
                                                }
                                                else
                                                {
                                                    dynamic info = GetLineAndCol(code, stmt.Token.StartPos);

                                                    Console.Error.WriteLine("Error: Variable '{0}' should be set as {1}. In this case, looping is not allowed. Line: {2}, Col: {3}", local.Name, local.LoopLow.ToString(), info.Line, info.Col);
                                                    return true; //Abort because of error.
                                                }

                                                ILgen.Emit(OpCodes.Stloc, (LocalBuilder)local.Base);
                                                ILgen.EndScope();
                                                return false;
                                            };

                                            locals.Add(local); //Remembers the variable.

                                            i += 6;
                                            #endregion
                                        }
                                    }
                                }
                                else
                                {
                                    //Report an error and stop compile process.

                                    dynamic info = GetLineAndCol(code, stmt.Token.StartPos);

                                    err = true;
                                    Console.Error.WriteLine("Error: '{0}' already exist! Line: {1}, Col: {2}", token.Token.Text, info.Line, info.Col);
                                    return;
                                }
                            }
                        }
                        break;
                        #endregion
                    }
                case TokenType.PrintStatement:
                    {
                        #region Printing
                        if (IsDebug)
                        {
                            int sline = 0, scol = 0;

                            FindLineAndCol(code, stmt.Token.StartPos, ref sline, ref scol);

                            int eline = 0, ecol = 0;

                            FindLineAndCol(code, stmt.Token.EndPos, ref eline, ref ecol);

                            ILgen.MarkSequencePoint(doc, sline, scol, eline, ecol);
                        }

                        ///Generates output by making a print statement.
                        var period = stmt.Nodes[0];
                        var outpt = stmt.Nodes[1];
                        switch (outpt.Token.Type)
                        {
                            case TokenType.IDENTIFIER:
                                {
                                    //Prints a variable.
                                    LocalBuilderEx local = locals.Find(it => it.Name == outpt.Token.Text);

                                    if (local == null)
                                    {
                                        dynamic info = GetLineAndCol(code, stmt.Token.StartPos);

                                        err = true;
                                        Console.Error.WriteLine("Error: '{0}' doesn't exist! Line: {1}, Col: {2}", outpt.Token.Text, info.Line, info.Col);
                                        return;
                                    }

                                    ILgen.Emit(OpCodes.Ldloc, local.Base);

                                    ILgen.Emit(OpCodes.Call, typeof(Convert).GetMethod("ToString", new Type[] { local.VariableType })); //Converts the integer to a string.

                                    ILgen.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) })); //Prints the newly formed string.
                                    break;
                                }
                            case TokenType.FLOAT:
                            case TokenType.NUMBER:
                                {
                                    //Prints a integer or float (decimal) number.
                                    if (outpt.Token.Type == TokenType.NUMBER) //if its a integer
                                    {
                                        ILgen.Emit(OpCodes.Ldc_I4, int.Parse(outpt.Token.Text));

                                        ILgen.Emit(OpCodes.Call, typeof(Convert).GetMethod("ToString", new Type[] { typeof(int) })); //Converts the integer to a string.
                                    }
                                    else
                                    {
                                        //Otherwise, its a float (decimal).
                                        ILgen.Emit(OpCodes.Ldc_R4, float.Parse(outpt.Token.Text));

                                        ILgen.Emit(OpCodes.Call, typeof(Convert).GetMethod("ToString", new Type[] { typeof(float) })); //Converts the integer to a string.
                                    }

                                    ILgen.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) })); //Prints the newly formed string.
                                    break;
                                }
                            case TokenType.STRING:
                                {
                                    //Prints just a plain string. See the next case for a format string.

                                    string formt = outpt.Token.Text.Substring(1); formt = formt.Remove(formt.Length - 1); //Removes surrounding quotes.

                                    ILgen.Emit(OpCodes.Ldstr, formt); //Loads the string onto the stack

                                    ILgen.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) })); //Prints the newly formed string.
                                    break;
                                }
                            case TokenType.SIN:
                                {

                                    //Prints a format string

                                    ParseNode formtnd = stmt.Nodes[2];

                                    string formt = formtnd.Token.Text.Substring(1); formt = formt.Remove(formt.Length - 1); //Removes surrounding quotes.

                                    ILgen.Emit(OpCodes.Ldstr, formt); //Loads the format string.

                                    int arrymax = (stmt.Nodes.Count / 2 - 1);
                                    ILgen.Emit(OpCodes.Ldc_I4, arrymax);
                                    ILgen.Emit(OpCodes.Newarr, typeof(string));

                                    int arry_i = 0;

                                    for (int i = 3; i < stmt.Nodes.Count; i++)
                                    {
                                        if (stmt.Nodes[i].Token.Type == TokenType.WHITESPACE)
                                        {
                                            if (stmt.Nodes.Count - 1 == i)
                                                break;

                                            continue;
                                        }
                                        else if (stmt.Nodes[i].Token.Type == TokenType.PERIOD)
                                        {
                                            break;
                                        }
                                        else
                                        {
                                            ParseNode nd = stmt.Nodes[i];

                                            ILgen.Emit(OpCodes.Dup);
                                            ILgen.Emit(OpCodes.Ldc_I4, arry_i);

                                            switch (nd.Token.Type)
                                            {
                                                case TokenType.IDENTIFIER:
                                                    {
                                                        LocalBuilderEx local = locals.Find(it => it.Name == nd.Token.Text);

                                                        if (local == null)
                                                        {
                                                            err = true;
                                                            Console.Error.WriteLine("Error: '{0}' doesn't exist!", nd.Token.Text);
                                                            return;
                                                        }

                                                        ILgen.Emit(OpCodes.Ldloc, local.Base);
                                                        ILgen.Emit(OpCodes.Call, typeof(Convert).GetMethod("ToString", new Type[] { typeof(int) }));
                                                        break;
                                                    }
                                                case TokenType.NUMBER:
                                                    {
                                                        ILgen.Emit(OpCodes.Ldc_I4, int.Parse(nd.Token.Text));
                                                        ILgen.Emit(OpCodes.Call, typeof(Convert).GetMethod("ToString", new Type[] { typeof(int) }));
                                                        break;
                                                    }
                                            }

                                            ILgen.Emit(OpCodes.Stelem_Ref);

                                            arry_i += 1;

                                        }
                                    }

                                    ILgen.Emit(OpCodes.Call,
                                        typeof(System.String).GetMethod("Format",
                                            new Type[] { typeof(string), typeof(string[]) }));

                                    ILgen.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) })); //Prints the newly formed string.
                                    break;
                                }
                        }
                        break;
                        #endregion
                    }
                case TokenType.EvalStatement:
                    {
                        #region EvalStatement
                        var identifier = stmt.Nodes[1];
                        var expr = stmt.Nodes[3];

                        LocalBuilderEx local = new LocalBuilderEx();

                        //Check if a variable of the same name exist.
                        LocalBuilderEx lct = locals.Find(it => it.Name == identifier.Token.Text);
                        if (lct != null)
                        {
                            //Variable exist, stop compiling.
                            dynamic info = GetLineAndCol(code, stmt.Token.StartPos);

                            Console.Error.WriteLine("Error: {0} variable already exist! Line: {1}, Col: {2}", identifier.Token.Text, info.Line, info.Col);

                            if (lct.Type == LocalType.LoopVar)
                                Console.Error.WriteLine("- Error: Iterating variables are readonly!");

                            err = true;
                            return;
                        }

                        if (!NoEval)
                        {
                            #region Eval using Mizu.Lib.Evaluator

                            local.VariableType = typeof(int);

                            local.Base = ILgen.DeclareLocal(local.VariableType); //Sets the number

                            var exprstr = "";
                            bool localsadded = false;

                            List<LocalBuilder> tmplocals = new List<LocalBuilder>();

                            foreach (LocalBuilderEx lc in locals)
                            {

                                ILgen.Emit(OpCodes.Ldstr, "var " + lc.Name + "={0}");

                                ILgen.Emit(OpCodes.Ldloc, (LocalBuilder)lc.Base);

                                ILgen.Emit(OpCodes.Call,
                                    typeof(Convert).GetMethod("ToString", new Type[] { typeof(int) }));

                                ILgen.Emit(OpCodes.Call,
                                    typeof(System.String).GetMethod("Format",
                                    new Type[] { typeof(string), typeof(string) }));

                                LocalBuilder lb = ILgen.DeclareLocal(typeof(string));
                                ILgen.Emit(OpCodes.Stloc, lb);

                                tmplocals.Add(lb);

                                localsadded = true;
                            }

                            //Creates an array to store all of the variables for the String.Concat call.
                            int arrymax = (tmplocals.Count * 2) + 1;
                            ILgen.Emit(OpCodes.Ldc_I4, arrymax);
                            ILgen.Emit(OpCodes.Newarr, typeof(string));

                            int arry_i = 0;

                            if (localsadded)
                            {
                                foreach (LocalBuilder tmploc in tmplocals)
                                {
                                    ILgen.Emit(OpCodes.Dup);
                                    ILgen.Emit(OpCodes.Ldc_I4, arry_i);
                                    ILgen.Emit(OpCodes.Ldloc, tmploc);
                                    ILgen.Emit(OpCodes.Stelem_Ref);

                                    arry_i += 1;

                                    ILgen.Emit(OpCodes.Dup);
                                    ILgen.Emit(OpCodes.Ldc_I4, arry_i);
                                    ILgen.Emit(OpCodes.Ldstr, ";");
                                    ILgen.Emit(OpCodes.Stelem_Ref);

                                    arry_i += 1;
                                }
                            }

                            ILgen.Emit(OpCodes.Dup);
                            ILgen.Emit(OpCodes.Ldc_I4, arry_i);

                            exprstr += GenerateExprStr(expr);
                            ILgen.Emit(OpCodes.Ldstr, exprstr);

                            ILgen.Emit(OpCodes.Stelem_Ref);
                            arry_i += 1;

                            ILgen.Emit(OpCodes.Call,
                                typeof(System.String).GetMethod("Concat",
                                         new Type[] { typeof(string[]) }));

                            ILgen.Emit(OpCodes.Call, typeof(Mizu.Lib.Evaluator.Evaluator).GetMethod("Eval"));

                            ILgen.Emit(OpCodes.Call, typeof(Convert).GetMethod("ToInt32", new Type[] { typeof(string) })); //Parses it into an integer.

                            ILgen.Emit(OpCodes.Stloc, (LocalBuilder)local.Base); //Assigns the number to the variable.
                            #endregion
                        }
                        else
                        {
                            if (ExprStrHasVar(expr))
                            {
                                HandleMathExpr(ILgen, locals, expr);

                                local.VariableType = typeof(float);

                                local.Base = ILgen.DeclareLocal(local.VariableType); //Sets the number;
                            }
                            else
                            {
                                //Optimize. If the equation is constant, might as well calculate the result and place it in the code.

                                var res = Mizu.Lib.Evaluator.Evaluator.Eval(GenerateExprStr(expr));

                                if (res.Contains("."))
                                {
                                    local.VariableType = typeof(float);

                                    local.Base = ILgen.DeclareLocal(local.VariableType); //Sets the number

                                    ILgen.Emit(OpCodes.Ldc_R4, float.Parse(res));
                                }
                                else
                                {
                                    local.VariableType = typeof(int);

                                    local.Base = ILgen.DeclareLocal(local.VariableType); //Sets the number

                                    ILgen.Emit(OpCodes.Ldc_I4, int.Parse(res));
                                }
                            }
                            ILgen.Emit(OpCodes.Stloc, (LocalBuilder)local.Base); //Assigns the number to the variable.
                        }

                        if (IsDebug) local.Base.SetLocalSymInfo(identifier.Token.Text);

                        local.Name = identifier.Token.Text;
                        local.Type = LocalType.Var;

                        locals.Add(local); //Remembers the variable.

                        break;
                        #endregion
                    }
                case TokenType.MathCMDStatement:
                    {
                        #region MathCommandStatement
                        var cmd = stmt.Nodes[0];
                        var input = stmt.Nodes[2];
                        var local = locals.Find(it => it.Name == input.Token.Text);
                        if (local != null)
                        {
                            if (IsDebug)
                            {
                                int sline = 0, scol = 0;

                                FindLineAndCol(code, cmd.Token.StartPos, ref sline, ref scol);

                                int eline = 0, ecol = 0;

                                FindLineAndCol(code, cmd.Token.EndPos, ref eline, ref ecol);

                                ILgen.MarkSequencePoint(doc, sline, scol, eline, ecol);

                            }

                            switch (cmd.Token.Type)
                            {
                                case TokenType.SQRT:
                                    {
                                        ILgen.Emit(OpCodes.Ldloca, local.Base);
                                        ILgen.Emit(OpCodes.Call, typeof(Math).GetMethod("Sqrt"));
                                        ILgen.Emit(OpCodes.Stloc, (LocalBuilder)local.Base);
                                        break;
                                    }
                                case TokenType.SIN:
                                    {
                                        ILgen.Emit(OpCodes.Ldloca, local.Base);
                                        ILgen.Emit(OpCodes.Call, typeof(Math).GetMethod("Sin"));
                                        ILgen.Emit(OpCodes.Stloc, (LocalBuilder)local.Base);
                                        break;
                                    }
                                case TokenType.ABS:
                                    {
                                        ILgen.Emit(OpCodes.Ldloca, local.Base);
                                        ILgen.Emit(OpCodes.Call, typeof(Math).GetMethod("Abs", new Type[] { typeof(int) }));
                                        ILgen.Emit(OpCodes.Stloc, (LocalBuilder)local.Base);
                                        break;
                                    }
                                case TokenType.TAN:
                                    {
                                        ILgen.Emit(OpCodes.Ldloca, local.Base);
                                        ILgen.Emit(OpCodes.Call, typeof(Math).GetMethod("Tan"));
                                        ILgen.Emit(OpCodes.Stloc, (LocalBuilder)local.Base);
                                        break;
                                    }
                                case TokenType.COS:
                                    {
                                        ILgen.Emit(OpCodes.Ldloca, local.Base);
                                        ILgen.Emit(OpCodes.Call, typeof(Math).GetMethod("Cos"));
                                        ILgen.Emit(OpCodes.Stloc, (LocalBuilder)local.Base);
                                        break;
                                    }
                            }

                        }
                        else
                        {
                            //Report an error and stop compile process.

                            dynamic info = GetLineAndCol(code, stmt.Token.StartPos);

                            err = true;
                            Console.Error.WriteLine("Error: '{0}' doesn't exist! Line: {1}, Col: {2}", input.Token.Text, info.Line, info.Col);
                            return;
                        }

                        break;
                        #endregion
                    }
                case TokenType.BlockedStatement:
                    {
                        //Due to parser limitations, I have to handle this token in order for both the if blocks and the switch blocks to begin with [.
                        HandleStatement(stmt.Nodes[1], ILgen, ref locals, out err);
                        break;
                    }
                case TokenType.IfStatement: //If block
                    {
                        #region If Statement
                        bool hasElse = false;

                        var left = stmt.Nodes[0];
                        var com = stmt.Nodes[1];
                        var right = stmt.Nodes[2];

                        if (IsDebug)
                        {
                            int sline = 0, scol = 0;

                            FindLineAndCol(code, left.Token.StartPos, ref sline, ref scol);

                            int eline = 0, ecol = 0;

                            FindLineAndCol(code, right.Token.EndPos, ref eline, ref ecol);

                            ILgen.MarkSequencePoint(doc, sline, scol, eline, ecol);
                        }

                        var bodies = stmt.Nodes.FindAll(it => it.Token.Type == TokenType.Statements);

                        hasElse = bodies.Count == 2;

                        //Load the 'left' hand type onto the stack.
                        HandleDataToken(ILgen, locals, left, out err);

                        //Load the 'right' hand type to the stack.
                        HandleDataToken(ILgen, locals, right, out err);

                        //Load the 'comparison' function onto the stack.

                        HandleDataToken(ILgen, locals, com, out err);

                        Label endofifblock = ILgen.DefineLabel();

                        Label ifbodyloc = ILgen.DefineLabel();

                        Label elsebodyloc = ILgen.DefineLabel();

                        if (!hasElse)
                        {
                            //No else block.
                            ILgen.Emit(OpCodes.Brfalse, endofifblock);
                        }
                        else
                        {
                            //Has an else block.

                            //ILgen.Emit(OpCodes.Brtrue, ifbodyloc);
                            //ILgen.Emit(OpCodes.Brtrue, ifbodyloc);
                            ILgen.Emit(OpCodes.Brfalse, elsebodyloc);
                            //ILgen.Emit(OpCodes.Br, ifbodyloc);
                        }

                        // Handle the first body of an if statement.

                        ILgen.MarkLabel(ifbodyloc);
                        ILgen.BeginScope();
                        var ifbody = bodies[0];

                        List<LocalBuilderEx> ifbody_locals = new List<LocalBuilderEx>();
                        locals.ForEach((it) => ifbody_locals.Add(it));

                        foreach (ParseNode pn in ifbody.Nodes)
                        {
                            bool iferr = false;
                            HandleStatement(pn.Nodes[0], ILgen, ref ifbody_locals, out iferr);

                            if (iferr)
                            {
                                err = true;
                                return;
                            }
                        }

                        ILgen.Emit(OpCodes.Br, endofifblock);
                        ILgen.EndScope();

                        //Handle the else bit (if any)
                        if (hasElse)
                        {
                            ILgen.MarkLabel(elsebodyloc);
                            ILgen.BeginScope();

                            var elsebody = bodies[1];

                            List<LocalBuilderEx> elsebody_locals = new List<LocalBuilderEx>();
                            locals.ForEach((it) => elsebody_locals.Add(it));

                            foreach (ParseNode pn in elsebody.Nodes)
                            {
                                bool elerr = false;
                                HandleStatement(pn.Nodes[0], ILgen, ref elsebody_locals, out elerr);

                                if (elerr)
                                {
                                    err = true;
                                    return;
                                }
                            }

                            ILgen.Emit(OpCodes.Br, endofifblock);
                            ILgen.EndScope();

                        }

                        ILgen.MarkLabel(endofifblock);

                        break;
                        #endregion
                    }
                case TokenType.SwitchStatement: //Switch block
                    {
                        #region Switch Statement
                        Label endofswitch = ILgen.DefineLabel();
                        SwitchCaseInfo defaultcase = new SwitchCaseInfo()
                        {
                            Label = ILgen.DefineLabel()
                        };

                        List<SwitchCaseInfo> caselist = new List<SwitchCaseInfo>();

                        bool hasDefault = false;

                        var ident = stmt.Nodes[1];

                        var compar = new Comparison<ParseNode>((node1, node2) =>
                        {
                            try
                            {
                                if (node1 == node2)
                                {
                                    return 0;
                                }
                                else if (node1.Nodes[0].Token.Type == TokenType.NUMBER)
                                {
                                    return -1;
                                }
                                else
                                {
                                    return 1;
                                }
                            }
                            catch (Exception)
                            {
                                return 0;
                            }
                        });

                        var cases = stmt.Nodes.FindAll(it => it.Token.Type == TokenType.SwitchCaseStatement);
                        cases.Sort(compar);

                        var addedcases = new List<int>();

                        if (IsDebug)
                        {
                            int sline = 0, scol = 0;

                            FindLineAndCol(code, ident.Token.StartPos, ref sline, ref scol);

                            int eline = 0, ecol = 0;

                            FindLineAndCol(code, ident.Token.EndPos, ref eline, ref ecol);

                            ILgen.MarkSequencePoint(doc, sline, scol, eline, ecol);
                        }

                        foreach (ParseNode casen in cases)
                        {
                            SwitchCaseInfo caseinfo = new SwitchCaseInfo();

                            var casename = casen.Nodes[0];
                            if (casename.Token.Text == "*")
                            {
                                defaultcase.Node = casen;
                                defaultcase.CaseName = casename;
                                defaultcase.CaseType = SwitchCase_TypeEnum.Default;

                                if (hasDefault == true)
                                {
                                    //Report an error and stop compile process.
                                    err = true;

                                    dynamic info = GetLineAndCol(code, stmt.Token.StartPos);

                                    Console.Error.WriteLine("Error: Switch block already has a default case. Line: {0}, Col: {1}", info.Line, info.Col);
                                    return;
                                }

                                hasDefault = true;
                            }
                            else
                            {
                                caseinfo.Number = int.Parse(casen.Nodes[0].Token.Text);
                                caseinfo.CaseType = SwitchCase_TypeEnum.Number;
                                caseinfo.CaseName = casename;
                                caseinfo.Node = casen;
                                caseinfo.Label = ILgen.DefineLabel();

                                if (addedcases.Contains(caseinfo.Number))
                                {
                                    err = true;

                                    dynamic info = GetLineAndCol(code, stmt.Token.StartPos);

                                    Console.Error.WriteLine("Error: Switch block already has a case for '{0}'. Line: {1}, Col: {2}",caseinfo.Number, info.Line, info.Col);
                                    return;
                                }

                                addedcases.Add(caseinfo.Number);

                                caselist.Add(caseinfo);
                            }
                        }

                        foreach (SwitchCaseInfo cse in caselist)
                        {
                            //Build the instruction table.
                            if (cse.CaseType == SwitchCase_TypeEnum.Number)
                            {
                                HandleDataToken(ILgen, locals, ident, out err); //Load identifier.

                                HandleDataToken(ILgen, locals, cse.CaseName, out err); //Loads the number.

                                ILgen.Emit(OpCodes.Ceq);
                                ILgen.Emit(OpCodes.Brtrue, cse.Label);
                            }
                            else
                            {
                                ILgen.Emit(OpCodes.Br, defaultcase.Label);
                            }
                        }

                        if (hasDefault == false)
                        {
                            //Report an error and stop compile process.
                            err = true;

                            dynamic info = GetLineAndCol(code, stmt.Token.StartPos);

                            Console.Error.WriteLine("Error: Switch block doesn't have a default case. Line: {0}, Col: {1}", info.Line, info.Col);
                            return;
                        }

                        ///Handle default case

                        var dcase = defaultcase.Node;

                        ILgen.BeginScope();

                        List<LocalBuilderEx> d_locals = new List<LocalBuilderEx>();
                        locals.ForEach((it) => d_locals.Add(it));

                        var dstmts = dcase.Nodes.Find(it => it.Token.Type == TokenType.Statements);

                        ILgen.MarkLabel(defaultcase.Label);
                        foreach (ParseNode pn in dstmts.Nodes)
                        {
                            HandleStatement(pn.Nodes[0], ILgen, ref d_locals, out err);
                        }

                        ILgen.EndScope();
                        ILgen.Emit(OpCodes.Br, endofswitch); //Jumps out of switvch at the end of the method.

                        ////

                        foreach (SwitchCaseInfo inner in caselist)
                        {
                            ILgen.BeginScope();

                            List<LocalBuilderEx> tmp_locals = new List<LocalBuilderEx>();
                            locals.ForEach((it) => tmp_locals.Add(it));

                            var stmts = inner.Node.Nodes.Find(it => it.Token.Type == TokenType.Statements);

                            ILgen.MarkLabel(inner.Label);

                            bool ierr = false;

                            foreach (ParseNode pn in stmts.Nodes)
                            {
                                HandleStatement(pn.Nodes[0], ILgen, ref tmp_locals, out ierr);
                            }

                            if (ierr)
                            {
                                err = true;
                                return;
                            }

                            ILgen.EndScope();
                            ILgen.Emit(OpCodes.Br, endofswitch); //Jumps out of switvch at the end of the method.
                        }

                        ILgen.MarkLabel(endofswitch);
                        break;
                        #endregion
                    }
                default:
                    {
                        //Report an error and stop compile process.
                        err = true;

                        dynamic info = GetLineAndCol(code, stmt.Token.StartPos);

                        Console.Error.WriteLine("Error: Unsupported statement: {0}. Line: {1}, Col: {2}", stmt.Text, info.Line, info.Col);
                        return;
                    }
            }
            err = false;
        }
コード例 #6
0
ファイル: Emitter.cs プロジェクト: ForNeVeR/BetterFuck
 /// <summary>
 /// Produces BetterFuck finalization code for Main method in target assembly.
 /// </summary>
 /// <param name="ilGenerator"></param>
 private static void ProduceFinalCode(ILGenerator ilGenerator)
 {
     ilGenerator.Emit(OpCodes.Ret);
     ilGenerator.EndScope();
 }
コード例 #7
0
        public override void GenerateCode(ILGenerator codeGenerator, TypeBuilder typeBuilder, ModuleBuilder moduleBuilder)
        {
            Type elementType = Environment.GetCLRType(((ArrayType)ReturnType).ElementsType);

            codeGenerator.BeginScope();
            Label forStart = codeGenerator.DefineLabel();
            Label forEnd = codeGenerator.DefineLabel();
            LocalBuilder lengthBuilder = codeGenerator.DeclareLocal(typeof(int));
            LocalBuilder i = codeGenerator.DeclareLocal(typeof(int));
            codeGenerator.Emit(OpCodes.Ldc_I4_M1);
            codeGenerator.Emit(OpCodes.Stloc, i);

            SizeExp.GenerateCode(codeGenerator, typeBuilder, moduleBuilder);
            codeGenerator.Emit(OpCodes.Stloc, lengthBuilder);
            codeGenerator.Emit(OpCodes.Ldloc, lengthBuilder);
            codeGenerator.Emit(OpCodes.Newarr, elementType);

            codeGenerator.MarkLabel(forStart);

            // i++
            codeGenerator.Emit(OpCodes.Dup);
            codeGenerator.Emit(OpCodes.Ldloc, i);
            codeGenerator.Emit(OpCodes.Ldc_I4_1);
            codeGenerator.Emit(OpCodes.Add);
            codeGenerator.Emit(OpCodes.Stloc, i);
            codeGenerator.Emit(OpCodes.Ldloc, i);

            // if i >= lengthBuilder goto END
            codeGenerator.Emit(OpCodes.Ldloc, lengthBuilder);
            codeGenerator.Emit(OpCodes.Bge, forEnd);

            // Stack:   arrayRef / i / obj / Stelem
            codeGenerator.Emit(OpCodes.Ldloc, i);
            InitialValueExp.GenerateCode(codeGenerator, typeBuilder, moduleBuilder);
            codeGenerator.Emit(OpCodes.Stelem, elementType);

            codeGenerator.Emit(OpCodes.Br, forStart);

            codeGenerator.MarkLabel(forEnd);

            codeGenerator.Emit(OpCodes.Pop);
            codeGenerator.EndScope();
        }
コード例 #8
0
ファイル: ArrayNode.cs プロジェクト: oisbel/TigerCompiler
        public override void GenCode(TypeBuilder tb, MethodBuilder mb, ILGenerator cg)
        {
            Type elementType;
            if (Value.ReturnType.Name == "nil")
                elementType = Compiler.SearchType(Name);
            else
                elementType = Compiler.SearchType(Value.ReturnType.Name);

            Type tipoArray = elementType.MakeArrayType();//int[]

            LocalBuilder array = cg.DeclareLocal(tipoArray);//int[]array
            Length.GenCode(tb, mb, cg);

            cg.Emit(OpCodes.Dup);
            cg.Emit(OpCodes.Newarr, elementType);//int[5]
            cg.Emit(OpCodes.Stloc, array);//array=int[5]

            LocalBuilder extremoIntervalo = cg.DeclareLocal(typeof(int));
            cg.Emit(OpCodes.Stloc, extremoIntervalo);//guarda el tamnno del array

            cg.BeginScope();//crea un nuevo scope que al final se cierrra
            LocalBuilder value = cg.DeclareLocal(elementType);

            //comienzo a llenar el array..es un for cuando lo desemsamblo
            System.Reflection.Emit.Label star = cg.DefineLabel();
            System.Reflection.Emit.Label end = cg.DefineLabel();

            LocalBuilder i = cg.DeclareLocal(typeof(int));
            cg.Emit(OpCodes.Ldc_I4_0);
            cg.Emit(OpCodes.Stloc, i);

            cg.MarkLabel(star);
            cg.Emit(OpCodes.Ldloc, i);
            cg.Emit(OpCodes.Ldloc, extremoIntervalo);
            cg.Emit(OpCodes.Bge, end);

            Value.GenCode(tb, mb, cg);
            cg.Emit(OpCodes.Stloc, value);

            cg.Emit(OpCodes.Ldloc, array);
            cg.Emit(OpCodes.Ldloc, i);
            cg.Emit(OpCodes.Ldloc, value);

            cg.Emit(OpCodes.Stelem, value.LocalType);

            cg.Emit(OpCodes.Ldc_I4_1);
            cg.Emit(OpCodes.Ldloc, i);
            cg.Emit(OpCodes.Add);
            cg.Emit(OpCodes.Stloc, i);
            cg.Emit(OpCodes.Br, star);

            cg.MarkLabel(end);

            cg.EndScope();
            cg.Emit(OpCodes.Ldloc, array);
        }
コード例 #9
0
ファイル: CodeGen.cs プロジェクト: mirhagk/IronTuring
        private void GenStmt(ParseTreeNode stmt, ILGenerator il, SymbolTable symbolTable, Label? exitScope = null)
        {
            if (stmt.Term.Name == "program")
            {
                if (stmt.ChildNodes.Count > 0)
                {
                    this.GenStmt(stmt.ChildNodes[0].ChildNodes[0], il, symbolTable);
                    this.GenStmt(stmt.ChildNodes[1], il, symbolTable);
                }
            }
            else if (stmt.Term.Name == "variableDeclaration")
            {
                Type localType;
                // declare a local
                if (stmt.ChildNodes[2].Term.Name == "typeSpecifier")
                {
                    localType = this.TypeOfTypeDeclaration(stmt.ChildNodes[2].ChildNodes[0]);
                }
                else
                {
                    localType = TypeOfExpr(stmt.ChildNodes[2].ChildNodes[1], symbolTable);
                }
                Action<string> generateAssign = null;
                ParseTreeNode assign = stmt.ChildNodes.Where(x => x.Term.Name == "setEqual").SingleOrDefault();
                // set the initial value
                if (assign != null)
                {
                    generateAssign = new Action<string>(name =>
                    {
                        this.GenExpr(assign.ChildNodes[1], symbolTable.Locals[name].LocalType, il, symbolTable);
                        symbolTable.Store(name, TypeOfExpr(assign.ChildNodes[1], symbolTable), il);
                    });
                }
                var variableIden = stmt.ChildNodes[1];
                while (true)
                {
                    string name = variableIden.ChildNodes[0].Token.ValueString;
                    symbolTable.AddLocal(name, il.DeclareLocal(localType));
                    if (generateAssign != null)
                        generateAssign(name);

                    if (variableIden.ChildNodes.Count < 2)
                        break;
                    variableIden = variableIden.ChildNodes[1];
                }
            }
            else if (stmt.Term.Name == "io")
            {
                if (stmt.ChildNodes[0].Token.ValueString == "put")
                {
                    //the first argument is always there, until we can build a proper AST this'll have to do
                    ParseTreeNode argItem = stmt.ChildNodes[1];
                    this.GenExpr(argItem.ChildNodes[0], typeof(string), il, symbolTable);
                    il.Emit(OpCodes.Call, typeof(System.Console).GetMethod("Write", new System.Type[] { typeof(string) }));
                    argItem = stmt.ChildNodes[2];
                    while (true)
                    {
                        if (argItem.ChildNodes.Count == 0)
                            break;
                        this.GenExpr(argItem.ChildNodes[0].ChildNodes[0], typeof(string), il, symbolTable);
                        il.Emit(OpCodes.Call, typeof(System.Console).GetMethod("Write", new System.Type[] { typeof(string) }));
                        argItem = argItem.ChildNodes[1];
                    }
                    if (stmt.ChildNodes[3].ChildNodes.Count == 0)//put a newline character if there is no ...
                        il.Emit(OpCodes.Call, typeof(System.Console).GetMethod("WriteLine", new System.Type[] { }));
                }
                else if (stmt.ChildNodes[0].Token.ValueString == "get")
                {
                    foreach (var argument in stmt.ChildNodes[1].ChildNodes)
                    {
                        //switch(symbolTable.TypeOfVar(
                        il.Emit(OpCodes.Call, typeof(System.Console).GetMethod("ReadLine", new System.Type[] { }));
                        symbolTable.Store(argument.Token.ValueString, typeof(string), il);
                    }
                }
            }
            else if (stmt.Term.Name == "assignment")
            {

                if (stmt.ChildNodes[0].Term.Name == "functionCall")//if we see this as a function call, we know that's not true, and it's actually an array (which is kinda the same thing in turing)
                {
                    string arrayName = stmt.ChildNodes[0].ChildNodes[0].Token.ValueString;
                    if (symbolTable.TypeOfVar(arrayName).IsArray)
                    {
                        symbolTable.PushVar(arrayName, il);
                        if (stmt.ChildNodes[0].ChildNodes[1].ChildNodes.Count > 1)
                            throw new NotImplementedException("Multi-Dimensional arrays are not yet supported");

                        this.GenExpr(stmt.ChildNodes[0].ChildNodes[1].ChildNodes[0], typeof(int), il, symbolTable);
                        this.GenExpr(stmt.ChildNodes[1].ChildNodes[1], TypeOfExpr(stmt.ChildNodes[1].ChildNodes[1], symbolTable), il, symbolTable);

                        il.Emit(OpCodes.Stelem, symbolTable.TypeOfVar(arrayName).GetElementType());
                    }
                    else
                        throw new NotSupportedException(String.Format("Non-array identifier used like an array: {0}", arrayName));
                }
                else
                {
                    this.GenExpr(stmt.ChildNodes[1].ChildNodes[1], TypeOfExpr(stmt.ChildNodes[1].ChildNodes[1], symbolTable), il, symbolTable);
                    string ident = stmt.ChildNodes[0].Token.ValueString;
                    symbolTable.Store(ident, TypeOfExpr(stmt.ChildNodes[1].ChildNodes[1], symbolTable), il);
                }
            }
            else if (stmt.Term.Name == "functionDefinition")
            {
                string functionName = stmt.ChildNodes[0].ChildNodes[1].Token.ValueString;

                SymbolTable localSymbols = new SymbolTable(symbolTable);
                foreach (var parameter in symbolTable.functionTable[functionName].arguments)
                {
                    localSymbols.AddParameter(parameter.argName, parameter.argType);
                }

                var ilMeth = symbolTable.functionTable[functionName].GetILGenerator();
                GenStmt(stmt.ChildNodes[1], ilMeth, localSymbols);
                ilMeth.Emit(OpCodes.Ret);
            }
            else if (stmt.Term.Name == "result")
            {
                GenExpr(stmt.ChildNodes[1], TypeOfExpr(stmt.ChildNodes[1], symbolTable), il, symbolTable);
                var result = il.DeclareLocal(TypeOfExpr(stmt.ChildNodes[1], symbolTable));
                il.Emit(OpCodes.Stloc, result);
                il.Emit(OpCodes.Ldloc, result);
                il.Emit(OpCodes.Ret, result);
            }
            else if (stmt.Term.Name == "functionCall" | stmt.Term.Name == "memberCall")
            {
                GenExpr(stmt, null, il, symbolTable);
            }
            else if (stmt.Term.Name == "ifBlock")
            {
                Label ifTrue = il.DefineLabel();
                Label ifFalse = il.DefineLabel();
                Label endLabel = il.DefineLabel();

                GenExpr(stmt.ChildNodes[0], typeof(bool), il, symbolTable);//expression to check if true
                il.Emit(OpCodes.Brtrue, ifTrue);//if true then jump to true block
                il.Emit(OpCodes.Br, ifFalse);//otherwise jump to false block

                il.MarkLabel(ifTrue);//true block
                GenStmt(stmt.ChildNodes[1], il, symbolTable);
                il.Emit(OpCodes.Br, endLabel);//jump to after false block

                il.MarkLabel(ifFalse);//false block
                if (stmt.ChildNodes[2].ChildNodes.Count > 0)//then there's an else-if, this takes place in the else section
                {
                    ParseTreeNode elseBlockStmt = stmt.ChildNodes[2];//Turn the elsif to an inner if statement
                    elseBlockStmt.ChildNodes.Add(stmt.ChildNodes[3]);//Move the optional else statement to the inner if statement
                    elseBlockStmt.Term.Name = "ifBlock";

                    GenStmt(elseBlockStmt, il, symbolTable);
                }
                else if (stmt.ChildNodes[3].ChildNodes.Count > 0)
                    GenStmt(stmt.ChildNodes[3].ChildNodes[0], il, symbolTable);//generate expresson for false section, otherwise the label will be at the same spot as the end

                il.MarkLabel(endLabel);//the end of the if statement
            }
            else if (stmt.Term.Name == "loop")
            {
                Label beginLoop = il.DefineLabel();
                Label endLoop = il.DefineLabel();
                il.MarkLabel(beginLoop);
                GenStmt(stmt.ChildNodes[0], il, symbolTable, endLoop);
                il.Emit(OpCodes.Br, beginLoop);
                il.MarkLabel(endLoop);
            }
            else if (stmt.Term.Name == "forLoop")
            {
                il.BeginScope();

                Label beginLoop = il.DefineLabel();
                Label endLoop = il.DefineLabel();
                LocalBuilder i = il.DeclareLocal(typeof(int));
                string identName = stmt.ChildNodes[1].Token.ValueString;
                symbolTable.AddLocal(identName, i);
                symbolTable.AddLocal("___endLoop", il.DeclareLocal(typeof(int)));
                if (stmt.ChildNodes[2].ChildNodes.Count == 1)//then an identifier is used as a range, or char. We just fail for now
                    throw new NotImplementedException();
                else
                {
                    GenExpr(stmt.ChildNodes[2].ChildNodes[0], typeof(int), il, symbolTable);
                    symbolTable.Store(identName, typeof(int), il);
                    GenExpr(stmt.ChildNodes[2].ChildNodes[1], typeof(int), il, symbolTable);
                    symbolTable.Store("___endLoop", typeof(int), il);
                }
                il.MarkLabel(beginLoop);
                GenStmt(stmt.ChildNodes[4], il, symbolTable, endLoop);
                symbolTable.PushVar(identName, il);
                il.Emit(OpCodes.Ldc_I4_1);
                if (stmt.ChildNodes[3].ChildNodes.Count > 0)//then there is a decreasing statement, so do decreasing
                    il.Emit(OpCodes.Sub);
                else
                    il.Emit(OpCodes.Add);
                il.Emit(OpCodes.Dup);
                symbolTable.Store(identName, typeof(int), il);
                symbolTable.PushVar("___endLoop", il);

                if (stmt.ChildNodes[3].ChildNodes.Count > 0)//then there is a decreasing statement, so do decreasing
                    il.Emit(OpCodes.Bge, beginLoop);
                else
                    il.Emit(OpCodes.Ble, beginLoop);
                il.MarkLabel(endLoop);
                symbolTable.RemoveLocal(identName);
                symbolTable.RemoveLocal("___endLoop");

                il.EndScope();
            }
            else
            {
                throw new System.Exception("don't know how to gen a " + stmt.Term.Name);
            }
        }