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); }
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); }
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); } }
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); }
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); }
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(); } }
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); }
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); } } }
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); }
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); } }
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); }
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); }
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(); }
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; } }