Пример #1
0
        private MethodBuilder not(ILCodeGenerator cg)
        {
            ILElementInfo notFunction = cg.ILContextTable.GetDefinedVarOrFunction("not");

            ///si ya fue definido
            if (!Object.Equals(notFunction, null))
            {
                return(notFunction.MethodBuilder);
            }

            MethodBuilder not  = cg.Program.DefineMethod("not", MethodAttributes.Private | MethodAttributes.Static, typeof(int), new Type[] { typeof(int) });
            ILGenerator   body = not.GetILGenerator();

            body.Emit(OpCodes.Ldarg_0);
            body.Emit(OpCodes.Ldc_I4_0);
            body.Emit(OpCodes.Ceq);
            body.Emit(OpCodes.Ret);

            ///lo agregamos a las funciones
            cg.ILContextTable.InsertPredefinedCallable("not", new ILElementInfo {
                MethodBuilder = not
            });

            return(not);
        }
Пример #2
0
        private MethodBuilder concat(ILCodeGenerator cg)
        {
            ILElementInfo concatFunction = cg.ILContextTable.GetDefinedVarOrFunction("concat");

            ///si ya fue definido
            if (!Object.Equals(concatFunction, null))
            {
                return(concatFunction.MethodBuilder);
            }

            MethodBuilder concat = cg.Program.DefineMethod("concat", MethodAttributes.Private | MethodAttributes.Static, typeof(string), new Type[] { typeof(string), typeof(string) });
            ILGenerator   body   = concat.GetILGenerator();

            body.Emit(OpCodes.Ldarg_0);
            body.Emit(OpCodes.Ldarg_1);
            body.Emit(OpCodes.Call, typeof(string).GetMethod("Concat", new Type[] { typeof(string), typeof(string) }));
            body.Emit(OpCodes.Ret);

            ///lo agregamos a las funciones
            cg.ILContextTable.InsertPredefinedCallable("concat", new ILElementInfo {
                MethodBuilder = concat
            });

            return(concat);
        }
        public override void GenerateCode(ILCodeGenerator cg)
        {
            Type variableType;

            variableType = inferredParche.ILType;

            VariableLocalBuilder = cg.ILGenerator.DeclareLocal(variableType);

            string       varName = string.Format("{0}{1}", VariableName, cg.ILContextTable.ContextNumber);
            FieldBuilder fd      = cg.Program.DefineField(varName, variableType, FieldAttributes.Private | FieldAttributes.Static);

            VariableFieldBuilder = fd;

            cg.ILContextTable.InsertILElement(VariableName, new ILElementInfo {
                FieldBuilder = fd, ILType = variableType, ElementKind = SymbolKind.Variable
            });

            ILElementInfo varInfo = cg.ILContextTable.GetDefinedVarOrFunction(VariableName);

            cg.ILGenerator.Emit(OpCodes.Ldsfld, varInfo.FieldBuilder);
            cg.ILGenerator.Emit(OpCodes.Stloc, VariableLocalBuilder);

            InitExpression.GenerateCode(cg);

            ///este usa el static field porque el campo es estático
            cg.ILGenerator.Emit(OpCodes.Stsfld, varInfo.FieldBuilder);
        }
Пример #4
0
        private MethodBuilder getchar(ILCodeGenerator cg)
        {
            ILElementInfo getcharFunction = cg.ILContextTable.GetDefinedVarOrFunction("getchar");

            ///si ya fue definido
            if (!Object.Equals(getcharFunction, null))
            {
                return(getcharFunction.MethodBuilder);
            }

            MethodBuilder getchar = cg.Program.DefineMethod("getchar", MethodAttributes.Private | MethodAttributes.Static, typeof(string), System.Type.EmptyTypes);
            ILGenerator   body    = getchar.GetILGenerator();

            LocalBuilder local = body.DeclareLocal(typeof(ConsoleKeyInfo));

            body.Emit(OpCodes.Call, typeof(Console).GetMethod("ReadKey", System.Type.EmptyTypes));
            body.Emit(OpCodes.Stloc, local);
            body.Emit(OpCodes.Ldloca_S, local);
            body.Emit(OpCodes.Call, typeof(ConsoleKeyInfo).GetProperty("KeyChar").GetGetMethod());
            body.Emit(OpCodes.Call, typeof(Char).GetMethod("ToString", new Type[] { typeof(char) }));
            body.Emit(OpCodes.Ret);

            ///lo agregamos a las funciones
            cg.ILContextTable.InsertPredefinedCallable("getchar", new ILElementInfo {
                MethodBuilder = getchar
            });
            return(getchar);
        }
        public override void GenerateCode(ILCodeGenerator cg)
        {
            ILElementInfo ile        = cg.ILContextTable.GetDefinedType(RecordId);
            Type          recordType = ile.ILType;

            List <Type> fieldsType = new List <Type>();

            foreach (var fieldElement in NodeInfo.Fields)
            {
                fieldsType.Add(fieldElement.Value.ILType);
            }
            foreach (var fieldExpression in Fields)
            {
                fieldExpression.Value.GenerateCode(cg);
            }

            //ConstructorInfo constructor = recordType.GetConstructor(fieldsType.ToArray());

            ///le pedimos el constructor que no tiene parámetros
            ConstructorInfo constructor = recordType.GetConstructors()[0];

            cg.ILGenerator.Emit(OpCodes.Newobj, constructor);

            NodeInfo.ILType = ile.TypeBuilder;
        }
        public override void GenerateCode(ILCodeGenerator cg)
        {
            DotedExpression.GenerateCode(cg);

            if (LoadVariableInTheStack)
            {
                ILElementInfo ile = cg.ILContextTable.GetDefinedType(RecordName);
                FieldInfo     fi  = ile.TypeBuilder.GetField(ID);
                cg.ILGenerator.Emit(OpCodes.Ldfld, fi);
            }
        }
Пример #7
0
        public override void GenerateCode(ILCodeGenerator cg)
        {
            ILElementInfo varTypeInfo  = cg.ILContextTable.GetDefinedType(VarTypeId);
            Type          variableType = null;

            if (varTypeInfo.TypeBuilder != null)
            {
                variableType = varTypeInfo.TypeBuilder;
            }
            else if (varTypeInfo.ILType != null)
            {
                variableType = varTypeInfo.ILType;
            }
            else if (InitExpression is NilConstantNode)
            {
                variableType = typeof(string);
            }
            else
            {
                variableType = NodeInfo.ILType;
            }

            if (InitExpression is ArrayCreationNode)
            {
                variableType = InitExpression.NodeInfo.ILType;
            }

            VariableLocalBuilder = cg.ILGenerator.DeclareLocal(variableType);

            string       varName = string.Format("{0}{1}", VariableName, cg.ILContextTable.ContextNumber);
            FieldBuilder fd      = cg.Program.DefineField(varName, variableType, FieldAttributes.Private | FieldAttributes.Static);

            //change
            VariableFieldBuilder = fd;

            cg.ILContextTable.InsertILElement(VariableName, new ILElementInfo {
                FieldBuilder = fd, ILType = variableType, ElementKind = SymbolKind.Variable
            });

            ILElementInfo variableElementInfo = cg.ILContextTable.GetDefinedVarOrFunction(VariableName);

            cg.ILGenerator.Emit(OpCodes.Ldsfld, variableElementInfo.FieldBuilder);
            cg.ILGenerator.Emit(OpCodes.Stloc, VariableLocalBuilder);

            InitExpression.GenerateCode(cg);

            //este usa el static field porque el campo es estatico
            cg.ILGenerator.Emit(OpCodes.Stsfld, variableElementInfo.FieldBuilder);
        }
Пример #8
0
        private MethodBuilder chr(ILCodeGenerator cg)
        {
            ILElementInfo chrFunction = cg.ILContextTable.GetDefinedVarOrFunction("chr");

            ///si ya fue definido
            if (!Object.Equals(chrFunction, null))
            {
                return(chrFunction.MethodBuilder);
            }

            MethodBuilder chr  = cg.Program.DefineMethod("chr", MethodAttributes.Private | MethodAttributes.Static, typeof(string), new Type[] { typeof(int) });
            ILGenerator   body = chr.GetILGenerator();

            Label outOfRangeLabel = body.DefineLabel();
            Label endLabel        = body.DefineLabel();

            ///si i es mayor que 127
            body.Emit(OpCodes.Ldarg_0);
            body.Emit(OpCodes.Ldc_I4, 127);
            body.Emit(OpCodes.Bgt, outOfRangeLabel);

            ///si i es menor que 0
            body.Emit(OpCodes.Ldarg_0);
            body.Emit(OpCodes.Ldc_I4_0);
            body.Emit(OpCodes.Blt, outOfRangeLabel);


            body.Emit(OpCodes.Ldarg_0);
            body.Emit(OpCodes.Call, typeof(Convert).GetMethod("ToChar", new Type[] { typeof(int) }));
            body.Emit(OpCodes.Call, typeof(Char).GetMethod("ToString", new Type[] { typeof(char) }));

            ///saltamos al fin del proceso
            body.Emit(OpCodes.Br, endLabel);

            ///hubo index out of range
            body.MarkLabel(outOfRangeLabel);
            body.Emit(OpCodes.Ldstr, "Integer i is out of range");
            body.ThrowException(typeof(IndexOutOfRangeException));

            body.MarkLabel(endLabel);
            body.Emit(OpCodes.Ret);

            ///lo agregamos a las funciones
            cg.ILContextTable.InsertPredefinedCallable("chr", new ILElementInfo {
                MethodBuilder = chr
            });
            return(chr);
        }
Пример #9
0
        private MethodBuilder ord(ILCodeGenerator cg)
        {
            ILElementInfo ordFunction = cg.ILContextTable.GetDefinedVarOrFunction("ord");

            ///si ya fue definido
            if (!Object.Equals(ordFunction, null))
            {
                return(ordFunction.MethodBuilder);
            }

            MethodBuilder ord  = cg.Program.DefineMethod("ord", MethodAttributes.Private | MethodAttributes.Static, typeof(int), new Type[] { typeof(string) });
            ILGenerator   body = ord.GetILGenerator();

            Label stringEmptyLabel = body.DefineLabel();
            Label endLabel         = body.DefineLabel();

            ///verificamos que no sea el string nulo o vacío
            body.Emit(OpCodes.Ldarg_0);
            body.Emit(OpCodes.Call, typeof(string).GetMethod("IsNullOrEmpty", new Type[] { typeof(string) }));
            body.Emit(OpCodes.Brtrue, stringEmptyLabel);

            ///0 es el índice del 1er char
            body.Emit(OpCodes.Ldarg_0);
            body.Emit(OpCodes.Ldc_I4_0);

            ///llamamos al get_Chars
            MethodInfo getChars = typeof(string).GetMethod("get_Chars", new Type[] { typeof(int) });

            body.Emit(OpCodes.Callvirt, getChars);
            body.Emit(OpCodes.Br, endLabel);

            ///si era el string nulo o vacío cargamos -1 en la pila
            body.MarkLabel(stringEmptyLabel);
            body.Emit(OpCodes.Ldc_I4, -1);

            ///fin del metodo
            body.MarkLabel(endLabel);
            body.Emit(OpCodes.Ret);

            ///lo agregamos a las funciones
            cg.ILContextTable.InsertPredefinedCallable("ord", new ILElementInfo {
                MethodBuilder = ord
            });
            return(ord);
        }
        public override void GenerateCode(ILCodeGenerator cg)
        {
            if (firstPass)
            {
                TypeBuilder tb = cg.Module.DefineType(RecordId + cg.ILContextTable.ContextNumber);
                cg.ILContextTable.InsertILElement(RecordId, new ILElementInfo {
                    TypeBuilder = tb, ILType = tb, ElementKind = SymbolKind.Type
                });
                recordParche.ILType = tb;
                firstPass           = false;
            }
            else
            {
                ILElementInfo ile = cg.ILContextTable.GetDefinedType(RecordId);

                FieldBuilder fbTmp;
                List <Type>  fieldsILType = new List <Type>();
                for (int i = 0; i < FieldsCount; i++)
                {
                    fbTmp = ile.TypeBuilder.DefineField(Fields[i].Key, realFields[i].Type.ILType, FieldAttributes.Public);
                    ile.FieldsOfContainerClass.Add(fbTmp);
                    fieldsILType.Add(realFields[i].Type.ILType);
                }

                ConstructorBuilder ctor   = ile.TypeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, fieldsILType.ToArray());
                ILGenerator        cgCtor = ctor.GetILGenerator();
                cgCtor.Emit(OpCodes.Ldarg_0);
                cgCtor.Emit(OpCodes.Call, typeof(object).GetConstructor(System.Type.EmptyTypes));
                for (int i = 0; i < Fields.Count; i++)
                {
                    cgCtor.Emit(OpCodes.Ldarg_0);
                    cgCtor.Emit(OpCodes.Ldarg, i + 1);
                    cgCtor.Emit(OpCodes.Stfld, ile.FieldsOfContainerClass[i]);
                }
                cgCtor.Emit(OpCodes.Ret);
                ile.TypeBuilder.CreateType();
            }
        }
Пример #11
0
        private MethodBuilder getline(ILCodeGenerator cg)
        {
            ILElementInfo getlineFunction = cg.ILContextTable.GetDefinedVarOrFunction("getline");

            ///si ya fue definido
            if (!Object.Equals(getlineFunction, null))
            {
                return(getlineFunction.MethodBuilder);
            }

            MethodBuilder getline = cg.Program.DefineMethod("getline", MethodAttributes.Private | MethodAttributes.Static, typeof(string), new Type[0]);
            ILGenerator   body    = getline.GetILGenerator();

            body.Emit(OpCodes.Call, typeof(Console).GetMethod("ReadLine"));
            body.Emit(OpCodes.Ret);

            ///lo agregamos a las funciones
            cg.ILContextTable.InsertPredefinedCallable("getline", new ILElementInfo {
                MethodBuilder = getline
            });

            return(getline);
        }
Пример #12
0
        public override void GenerateCode(ILCodeGenerator cg)
        {
            ILElementInfo lValue = cg.ILContextTable.GetDefinedVarOrFunction(VariableName);

            NodeInfo.ILType = lValue.ILType;

            if (LoadVariableInTheStack)
            {
                if (!Object.Equals(lValue.ParameterBuilder, null))
                {
                    int index = lValue.ParameterBuilder.Position - 1;
                    cg.ILGenerator.Emit(OpCodes.Ldarg, index);
                }
                else if (!Object.Equals(lValue.FieldBuilder, null))
                {
                    cg.ILGenerator.Emit(OpCodes.Ldsfld, lValue.FieldBuilder);
                }
                else if (!Object.Equals(lValue.LocalBuilder, null))
                {
                    cg.ILGenerator.Emit(OpCodes.Ldloc, lValue.LocalBuilder);
                }
            }
        }
Пример #13
0
        private MethodBuilder printi(ILCodeGenerator cg)
        {
            ILElementInfo printiProcedure = cg.ILContextTable.GetDefinedVarOrFunction("printi");

            ///si ya fue definido
            if (!Object.Equals(printiProcedure, null))
            {
                return(printiProcedure.MethodBuilder);
            }

            MethodBuilder printi = cg.Program.DefineMethod("printi", MethodAttributes.Private | MethodAttributes.Static, typeof(void), new Type[] { typeof(int) });
            ILGenerator   body   = printi.GetILGenerator();

            body.Emit(OpCodes.Ldarg_0);
            body.Emit(OpCodes.Call, typeof(Console).GetMethod("Write", new Type[] { typeof(int) }));
            body.Emit(OpCodes.Ret);

            ///lo agregamos a las funciones
            cg.ILContextTable.InsertPredefinedCallable("printi", new ILElementInfo {
                MethodBuilder = printi
            });
            return(printi);
        }
Пример #14
0
        private MethodBuilder flush(ILCodeGenerator cg)
        {
            ILElementInfo flushProcedure = cg.ILContextTable.GetDefinedVarOrFunction("flush");

            ///si ya fue definido
            if (!Object.Equals(flushProcedure, null))
            {
                return(flushProcedure.MethodBuilder);
            }

            MethodBuilder flush = cg.Program.DefineMethod("flush", MethodAttributes.Private | MethodAttributes.Static, typeof(void), System.Type.EmptyTypes);
            ILGenerator   body  = flush.GetILGenerator();

            body.Emit(OpCodes.Call, typeof(Console).GetProperty("Out").GetGetMethod());
            body.Emit(OpCodes.Callvirt, typeof(TextWriter).GetMethod("Flush", System.Type.EmptyTypes));
            body.Emit(OpCodes.Ret);

            ///lo agregamos a las funciones
            cg.ILContextTable.InsertPredefinedCallable("flush", new ILElementInfo {
                MethodBuilder = flush
            });
            return(flush);
        }
        public override void GenerateCode(ILCodeGenerator cg)
        {
            LValue.LoadVariableInTheStack = false;
            LValue.GenerateCode(cg);
            LValue.LoadVariableInTheStack = true;

            //generamos Expression
            Expression.GenerateCode(cg);

            if (LValue is LValueIdNode)
            {
                LValueIdNode  id  = LValue as LValueIdNode;
                ILElementInfo ile = cg.ILContextTable.GetDefinedVarOrFunction(id.VariableName);

                if (!Object.Equals(ile.FieldBuilder, null))
                {
                    cg.ILGenerator.Emit(OpCodes.Stsfld, ile.FieldBuilder);
                }
                else if (!Object.Equals(ile.LocalBuilder, null))
                {
                    cg.ILGenerator.Emit(OpCodes.Stloc, ile.LocalBuilder);
                }
            }
            else if (LValue is ArrayIndexAccessNode)
            {
                ArrayIndexAccessNode arrayElement = LValue as ArrayIndexAccessNode;
                cg.ILGenerator.Emit(OpCodes.Stelem, arrayElement.NodeInfo.Type.ILType);
            }
            else
            {
                RecordDotAccessNode recordAccess = (LValue as RecordDotAccessNode);
                ILElementInfo       ile          = cg.ILContextTable.GetDefinedType(recordAccess.RecordName);
                FieldInfo           fi           = ile.TypeBuilder.GetField(recordAccess.ID);
                cg.ILGenerator.Emit(OpCodes.Stfld, fi);
            }
        }
Пример #16
0
        private MethodBuilder exit(ILCodeGenerator cg)
        {
            ILElementInfo exitProcedure = cg.ILContextTable.GetDefinedVarOrFunction("exit");

            ///si ya fue definido
            if (!Object.Equals(exitProcedure, null))
            {
                return(exitProcedure.MethodBuilder);
            }

            MethodBuilder exit = cg.Program.DefineMethod("exit", MethodAttributes.Private | MethodAttributes.Static, typeof(void), new Type[] { typeof(int) });
            ILGenerator   body = exit.GetILGenerator();

            body.Emit(OpCodes.Ldarg_0);
            body.Emit(OpCodes.Call, typeof(Environment).GetMethod("Exit", new Type[] { typeof(int) }));
            body.Emit(OpCodes.Ret);

            ///lo agregamos a las funciones
            cg.ILContextTable.InsertPredefinedCallable("exit", new ILElementInfo {
                MethodBuilder = exit
            });

            return(exit);
        }
Пример #17
0
        private MethodBuilder size(ILCodeGenerator cg)
        {
            ILElementInfo sizeFunction = cg.ILContextTable.GetDefinedVarOrFunction("size");

            ///si ya fue definido
            if (!Object.Equals(sizeFunction, null))
            {
                return(sizeFunction.MethodBuilder);
            }

            MethodBuilder size = cg.Program.DefineMethod("size", MethodAttributes.Private | MethodAttributes.Static, typeof(int), new Type[] { typeof(string) });
            ILGenerator   body = size.GetILGenerator();

            body.Emit(OpCodes.Ldarg_0);
            body.Emit(OpCodes.Call, typeof(string).GetProperty("Length").GetGetMethod());
            body.Emit(OpCodes.Ret);

            ///lo agregamos a las funciones
            cg.ILContextTable.InsertPredefinedCallable("size", new ILElementInfo {
                MethodBuilder = size
            });

            return(size);
        }
Пример #18
0
        public override void GenerateCode(ILCodeGenerator cg)
        {
            ///el for crea su scope(en IL)
            cg.ILGenerator.BeginScope();

            ///creamos un nuevo contexto
            cg.ILContextTable.InitNewContext();

            ///definimos los labels necesarios en el ciclo
            Label forCondLabel = cg.ILGenerator.DefineLabel();
            Label forEndLabel  = cg.ILGenerator.DefineLabel();

            ///guardamos el label a donde vamos a saltar
            cg.EndLoopLabelStack.Push(forEndLabel);

            ///declaramos la variable local de iteracion del for
            ILElementInfo forloopVariable = cg.ILContextTable.InsertILElement(LoopVariable, new ILElementInfo
            {
                LocalBuilder = cg.ILGenerator.DeclareLocal(typeof(int)),
                ElementKind  = SymbolKind.Variable
            });

            ///declaramamos una varaible que representa a EndIndex
            ILElementInfo endLoopVariable = cg.ILContextTable.InsertILElement("endLoopVariable", new ILElementInfo
            {
                LocalBuilder = cg.ILGenerator.DeclareLocal(typeof(int)),
                ElementKind  = SymbolKind.Variable
            });

            ///generamos la expresion de fin y la almacenamos
            EndIndex.GenerateCode(cg);
            cg.ILGenerator.Emit(OpCodes.Ldc_I4_1);
            cg.ILGenerator.Emit(OpCodes.Add);
            cg.ILGenerator.Emit(OpCodes.Stloc, endLoopVariable.LocalBuilder);

            ///generamos la expresion de inicializacion y lo almacenamos
            StartIndex.GenerateCode(cg);
            cg.ILGenerator.Emit(OpCodes.Stloc, forloopVariable.LocalBuilder);

            ///condition del for
            cg.ILGenerator.MarkLabel(forCondLabel);

            cg.ILGenerator.Emit(OpCodes.Ldloc, forloopVariable.LocalBuilder);
            cg.ILGenerator.Emit(OpCodes.Ldloc, endLoopVariable.LocalBuilder);

            ///si no se cumple la condition, saltamos al fin del ciclo
            cg.ILGenerator.Emit(OpCodes.Clt);
            cg.ILGenerator.Emit(OpCodes.Brfalse, forEndLabel);

            ///generamos el codigo del cuerpo
            ForBody.GenerateCode(cg);

            ///incrementamos la variable del ciclo
            cg.ILGenerator.Emit(OpCodes.Ldloc, forloopVariable.LocalBuilder);
            cg.ILGenerator.Emit(OpCodes.Ldc_I4_1);
            cg.ILGenerator.Emit(OpCodes.Add);
            cg.ILGenerator.Emit(OpCodes.Stloc, forloopVariable.LocalBuilder);

            ///saltamos a la condicion del for
            cg.ILGenerator.Emit(OpCodes.Br, forCondLabel);

            ///ponemos la variable de fin de ciclo
            cg.ILGenerator.MarkLabel(forEndLabel);

            ///sacamos el label guardado
            cg.EndLoopLabelStack.Pop();

            ///cerramos el contexto
            cg.ILContextTable.CloseCurrentContext();

            ///cerramos el scope del for(en IL)
            cg.ILGenerator.EndScope();
        }
Пример #19
0
        public override void GenerateCode(ILCodeGenerator cg)
        {
            ///gen code a los argumentos
            for (int i = 1; i <= ArgsCount; i++)
            {
                ArgAt(i).GenerateCode(cg);
            }

            switch (CallableId)
            {
            case "print":
                cg.ILGenerator.Emit(OpCodes.Call, print(cg));
                //print(cg);
                break;

            case "printi":
                cg.ILGenerator.Emit(OpCodes.Call, printi(cg));
                //printi(cg);
                break;

            case "flush":
                cg.ILGenerator.Emit(OpCodes.Call, flush(cg));
                //flush(cg);
                break;

            case "getchar":
                cg.ILGenerator.Emit(OpCodes.Call, getchar(cg));
                //getchar(cg);
                break;

            case "ord":
                cg.ILGenerator.Emit(OpCodes.Call, ord(cg));
                //ord(cg);
                break;

            case "chr":
                cg.ILGenerator.Emit(OpCodes.Call, chr(cg));
                //chr(cg);
                break;

            case "size":
                cg.ILGenerator.Emit(OpCodes.Call, size(cg));
                //size(cg);
                break;

            case "substring":
                cg.ILGenerator.Emit(OpCodes.Call, substring(cg));
                //substring(cg);
                break;

            case "concat":
                cg.ILGenerator.Emit(OpCodes.Call, concat(cg));
                //concat(cg);
                break;

            case "not":
                cg.ILGenerator.Emit(OpCodes.Call, not(cg));
                //not(cg);
                break;

            case "exit":
                cg.ILGenerator.Emit(OpCodes.Call, exit(cg));
                //exit(cg);
                break;

            case "getline":
                cg.ILGenerator.Emit(OpCodes.Call, getline(cg));
                //getline(cg);
                break;

            case "printline":
                cg.ILGenerator.Emit(OpCodes.Call, printline(cg));
                //printline(cg);
                break;

            default:
                ILElementInfo ile = cg.ILContextTable.GetDefinedVarOrFunction(CallableId);
                cg.ILGenerator.Emit(OpCodes.Call, ile.MethodBuilder);
                break;
            }
        }
        public override void GenerateCode(ILCodeGenerator cg)
        {
            if (FirstPass)
            {
                if (this is FunctionDeclarationNode)
                {
                    ILElementInfo returnILElementInfo = cg.ILContextTable.GetDefinedType((this as FunctionDeclarationNode).ReturnType);
                    returnILType = returnILElementInfo.ILType;

                    if (Object.Equals(returnILType, null))
                    {
                        returnILType = (this as FunctionDeclarationNode).functionParche.ILType;
                    }
                }

                for (int i = 0; i < ILTypes.Count; i++)
                {
                    if (Object.Equals(ILTypes[i], null))
                    {
                        ILTypes[i] = parametersType[i].Type.ILType;
                    }
                }

                ///creamos un método estático en la clase Program
                string        callableName = string.Format("{0}{1}", CallableId, cg.ILContextTable.ContextNumber);
                MethodBuilder callable     = cg.Program.DefineMethod(callableName, MethodAttributes.Private | MethodAttributes.Static, returnILType, ILTypes.ToArray());

                ///lo insertamos el la tabla de contextos
                cg.ILContextTable.InsertILElement(CallableId, new ILElementInfo {
                    MethodBuilder = callable, ElementKind = SymbolKind.Function
                });

                ///ya no va a ser la 1era pasada
                FirstPass = false;
            }
            else
            {
                ILElementInfo callable = cg.ILContextTable.GetDefinedVarOrFunction(CallableId);

                MethodBuilder callableBuilder = callable.MethodBuilder;

                ILGenerator tmpIL = cg.ILGenerator;
                cg.ILGenerator = callableBuilder.GetILGenerator();

                ///creamos un nuevo contexto
                cg.ILContextTable.InitNewContext();

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

                ///creamos los parámetros y variables en la clase Program
                for (int i = 0; i < Parameters.Count; i++)
                {
                    ParameterBuilder pb = callableBuilder.DefineParameter(i + 1, ParameterAttributes.None, Parameters[i].Key);

                    string       parameterName = string.Format("{0}{1}", Parameters[i].Key, cg.ILContextTable.ContextNumber);
                    FieldBuilder fb            = cg.Program.DefineField(parameterName, ILTypes[i], FieldAttributes.Public | FieldAttributes.Static);
                    cg.ILContextTable.InsertILElement(Parameters[i].Key, new ILElementInfo {
                        FieldBuilder = fb, ElementKind = SymbolKind.Variable
                    });
                }

                //salvamos los valores de las variables de la clase
                for (int i = 0; i < Parameters.Count; i++)
                {
                    localSaving.Add(cg.ILGenerator.DeclareLocal(ILTypes[i]));
                    callable = cg.ILContextTable.GetDefinedVarOrFunction(Parameters[i].Key);
                    cg.ILGenerator.Emit(OpCodes.Ldsfld, callable.FieldBuilder);
                    cg.ILGenerator.Emit(OpCodes.Stloc, localSaving[i]);
                }

                ///cargando los argumentos
                for (int i = 0; i < Parameters.Count; i++)
                {
                    callable = cg.ILContextTable.GetDefinedVarOrFunction(Parameters[i].Key);
                    cg.ILGenerator.Emit(OpCodes.Ldarg, i);
                    cg.ILGenerator.Emit(OpCodes.Stsfld, callable.FieldBuilder);
                }

                ///gen code al body de la función o procedimiento
                CallableBody.GenerateCode(cg);

                bool         isFunction  = this is FunctionDeclarationNode;
                LocalBuilder returnValue = null;

                ///en caso de ser función
                if (isFunction)
                {
                    returnValue = cg.ILGenerator.DeclareLocal(returnILType);
                    cg.ILGenerator.Emit(OpCodes.Stloc, returnValue);
                }

                ///restauramos los valores de las variables de la clase
                for (int i = 0; i < Parameters.Count; i++)
                {
                    callable = cg.ILContextTable.GetDefinedVarOrFunction(Parameters[i].Key);
                    cg.ILGenerator.Emit(OpCodes.Ldloc, localSaving[i]);
                    cg.ILGenerator.Emit(OpCodes.Stsfld, callable.FieldBuilder);
                }
                List <KeyValuePair <LocalBuilder, FieldBuilder> > localvars = CallableBody.GetLocalVariableDeclarations();
                foreach (var item in localvars)
                {
                    cg.ILGenerator.Emit(OpCodes.Ldloc, item.Key);
                    cg.ILGenerator.Emit(OpCodes.Stsfld, item.Value);
                }


                ///destruimos el contexto de la función o procedimiento
                cg.ILContextTable.CloseCurrentContext();

                ///si es función ponemos en el tope de la pila el valor de retorno
                if (isFunction)
                {
                    cg.ILGenerator.Emit(OpCodes.Ldloc, returnValue);
                }

                ///emitimos el return de la función
                cg.ILGenerator.Emit(OpCodes.Ret);

                ///restauramos el ILGenerator del cg
                cg.ILGenerator = tmpIL;
            }
        }