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); }
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) { 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 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); }
public override void GenerateCode(ILCodeGenerator cg) { Label trueLabel = cg.ILGenerator.DefineLabel(); Label falseLabel = cg.ILGenerator.DefineLabel(); ///evalúo el operando izquierdo LeftOperand.GenerateCode(cg); ///si fue true salto para el final de la operación cg.ILGenerator.Emit(OpCodes.Brtrue, trueLabel); ///evalúo el operando derecho RightOperand.GenerateCode(cg); ///si fue true salto para el final de la operación cg.ILGenerator.Emit(OpCodes.Brtrue, trueLabel); ///el resultado del | fue false cg.ILGenerator.Emit(OpCodes.Ldc_I4_0); ///salto para el false cg.ILGenerator.Emit(OpCodes.Br, falseLabel); ///marcamos el fin de la operación cg.ILGenerator.MarkLabel(trueLabel); ///pongo true en la pila cg.ILGenerator.Emit(OpCodes.Ldc_I4_1); ///marcamos el false cg.ILGenerator.MarkLabel(falseLabel); }
public void TestConditionMethods() { DynamicMethod dm; var gen = ILCodeGenerator.CreateDynamicMethodCodeGenerator( "TestConditionMethods", typeof(TestConditionMethodsDelegate), out dm); gen.IfGreaterThan( left1 => left1.LoadArgument(0), right1 => right1.LoadArgument(1)) .Load(1) .ElseIf(boolVal => boolVal.Equals( left2 => left2.LoadArgument(2), right2 => right2.LoadArgument(3))) .Load(2) .Else() .Load(3) .EndIf() .Ret(); var method = (TestConditionMethodsDelegate)dm.CreateDelegate(typeof(TestConditionMethodsDelegate)); var result = method(1, 2, 3, 4); Assert.AreEqual(3, result); result = method(5, 2, 3, 4); Assert.AreEqual(1, result); result = method(1, 2, 3, 3); Assert.AreEqual(2, result); }
public override void GenerateCode(ILCodeGenerator cg) { Label condLabel = cg.ILGenerator.DefineLabel(); Label endLabel = cg.ILGenerator.DefineLabel(); ///guardamos el label del fin del while cg.EndLoopLabelStack.Push(endLabel); ///marcamos la condición del while cg.ILGenerator.MarkLabel(condLabel); ///gen code del Condition Condition.GenerateCode(cg); ///si condition es false nos salimos del while cg.ILGenerator.Emit(OpCodes.Ldc_I4_0); cg.ILGenerator.Emit(OpCodes.Beq, endLabel); ///gen code del WhileBody WhileBody.GenerateCode(cg); ///volvemos a chequear la Condition cg.ILGenerator.Emit(OpCodes.Br, condLabel); ///marcamos el fin del while cg.ILGenerator.MarkLabel(endLabel); ///sacamos el label del fin del while cg.EndLoopLabelStack.Pop(); }
public void TestFieldPropertyMethods() { DynamicMethod dm; var gen = ILCodeGenerator.CreateDynamicMethodCodeGenerator( "TestFieldPropertyMethods", typeof(TestFieldPropertyMethodsDelegate), out dm); gen.StoreField(thisObj => thisObj.LoadArgument(0), typeof(TestClass).GetField("IntField"), val => val.Add( left => left.LoadField(thisObj2 => thisObj2.LoadArgument(0), typeof(TestClass).GetField("IntField")), right => right.Load(1))) .StoreProperty(thisObj => thisObj.LoadArgument(0), typeof(TestClass).GetProperty("StringProperty"), val2 => val2.Load("str")) .StoreProperty(thisObj => thisObj.LoadArgument(0), typeof(TestClass).GetProperty("WriteonlyStringValue"), val2 => val2.CallToString( typeof(int), val3 => val3.LoadStaticProperty( typeof(TestClass).GetProperty("ReadonlyIntValue", BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance)))) .Ret(); var method = (TestFieldPropertyMethodsDelegate)dm.CreateDelegate(typeof(TestFieldPropertyMethodsDelegate)); var obj = new TestClass(); method(obj); Assert.AreEqual(1, obj.IntField); Assert.AreEqual("str", obj.StringProperty); Assert.AreEqual(1, TestClass.ReadonlyIntValue); Assert.AreEqual("1", obj.GetWriteonlyStringValue()); }
public override void GenerateCode(ILCodeGenerator cg) { Label elseLabel = cg.ILGenerator.DefineLabel(); Label endLabel = cg.ILGenerator.DefineLabel(); ///gen code al Condition Condition.GenerateCode(cg); //si fue verdadera hago la parte del then en otro caso hago la parte del else cg.ILGenerator.Emit(OpCodes.Brfalse, elseLabel); ///gen code al ThenBody ThenBody.GenerateCode(cg); ///saltamos al fin de la instrucción cg.ILGenerator.Emit(OpCodes.Br, endLabel); ///marcamos el 'else' cg.ILGenerator.MarkLabel(elseLabel); ///gen code al ElseBody ElseBody.GenerateCode(cg); ///marcamos el fin de la instrucción cg.ILGenerator.MarkLabel(endLabel); }
public override void GenerateCode(ILCodeGenerator cg) { ExpressionNode currentExpression = null; for (int i = 0; i < ExpressionCount - 1; i++) { currentExpression = ExpressionAt(i); ///gen code a la currentExression currentExpression.GenerateCode(cg); ///si devuelve valor no lo usamos if (!currentExpression.NodeInfo.BuiltInType.IsCompatibleWith(BuiltInType.Void)) { cg.ILGenerator.Emit(OpCodes.Pop); } } ///gen code a la última expression if (ExpressionCount > 0) { currentExpression = ExpressionAt(ExpressionCount - 1); currentExpression.GenerateCode(cg); ///si alguna expression contiene break y retorna valor la última expression if (AnyExpressionContainsBreak && currentExpression.NodeInfo.BuiltInType.IsReturnType()) { cg.ILGenerator.Emit(OpCodes.Pop); } } }
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) { ///lo agregamos al contexto cg.ILContextTable.InsertILElement(ArrayId, new ILElementInfo { ILType = NodeInfo.ILType, ElementKind = SymbolKind.Type }); }
public override void GenerateCode(ILCodeGenerator cg) { ///gen code al ArithmeticOperationNode base.GenerateCode(cg); ///los dividimos cg.ILGenerator.Emit(OpCodes.Div); }
public override void GenerateCode(ILCodeGenerator cg) { ///gen code a UnaryOperationNode base.GenerateCode(cg); ///negamos el valor cg.ILGenerator.Emit(OpCodes.Neg); }
public override void GenerateCode(ILCodeGenerator cg) { ///gen code al ArithmeticOperationNode base.GenerateCode(cg); ///los multiplicamos cg.ILGenerator.Emit(OpCodes.Mul); }
public override void GenerateCode(ILCodeGenerator cg) { ///gen code al LeftOperand LeftOperand.GenerateCode(cg); ///gen code al RightOperand RightOperand.GenerateCode(cg); }
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) { //generamos la expresion a la que se le hace [] IndexedExpression.GenerateCode(cg); //generamos el indice Index.GenerateCode(cg); //cargamos el elemento del array if (LoadVariableInTheStack) { cg.ILGenerator.Emit(OpCodes.Ldelem, IndexedExpression.NodeInfo.ElementsType.ILType); } }
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 void CommitPendingGenerations(ILCodeGenerator cg, List <DeclarationNode> pendingDeclarations) { for (int i = 0; i < pendingDeclarations.Count; i++) { pendingDeclarations[i].GenerateCode(cg); } for (int i = 0; i < pendingDeclarations.Count; i++) { if (pendingDeclarations[i] is CallableDeclarationNode || pendingDeclarations[i] is RecordDeclarationNode) { pendingDeclarations[i].GenerateCode(cg); } } }
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); }
public override void GenerateCode(ILCodeGenerator cg) { Label falseLabel = cg.ILGenerator.DefineLabel(); ///gen code al Condition Condition.GenerateCode(cg); cg.ILGenerator.Emit(OpCodes.Ldc_I4_0); cg.ILGenerator.Emit(OpCodes.Ceq); cg.ILGenerator.Emit(OpCodes.Brtrue, falseLabel); ///gen code al ThenBody ThenBody.GenerateCode(cg); cg.ILGenerator.MarkLabel(falseLabel); }
public override void GenerateCode(ILCodeGenerator cg) { ///gen code al EqualityValueOperationNode base.GenerateCode(cg); if (LeftOperand.NodeInfo.BuiltInType.IsCompatibleWith(BuiltInType.Int)) { cg.ILGenerator.Emit(OpCodes.Ceq); } else { MethodInfo objectEquals = typeof(Object).GetMethod("Equals", new Type[] { typeof(object), typeof(object) }); cg.ILGenerator.Emit(OpCodes.Call, objectEquals); cg.ILGenerator.Emit(OpCodes.Ldc_I4_1); cg.ILGenerator.Emit(OpCodes.Ceq); } }
public void TestTryCatchMethods() { DynamicMethod dm; var gen = ILCodeGenerator.CreateDynamicMethodCodeGenerator( "TestTryCatchMethods", typeof(TestTryCatchMethodsDelegate), out dm); gen.Try() .IfEquals(left => left.LoadArgument(0), right => right.Load(1)) .Throw(typeof(ArgumentNullException), ex => ex.New(typeof(ArgumentNullException).GetConstructor(new[] { typeof(string) }), p1 => p1.Load("test"))) .Else() .Throw(typeof(ArgumentException), ex => ex.New(typeof(ArgumentException).GetConstructor(Type.EmptyTypes))) .EndIf() .Catch(typeof(ArgumentException)) .Rethrow() .Finally() .EndTry() .Ret(); var method = (TestTryCatchMethodsDelegate)dm.CreateDelegate(typeof(TestTryCatchMethodsDelegate)); Exception expected = null; try { method(1); } catch (ArgumentNullException ex) { expected = ex; } Assert.IsNotNull(expected); expected = null; try { method(2); } catch (ArgumentException ex) { expected = ex; } Assert.IsNotNull(expected); }
public override void GenerateCode(ILCodeGenerator cg) { cg.ILContextTable.InitNewContext(); DeclarationNode currentDeclaration; DeclarationType previousDeclarationType = DeclarationType.NONE; List <DeclarationNode> pendingDeclarations = new List <DeclarationNode>(); //chequeamos la semantica de C/U de las declaraciones for (int i = 0; i < LetDeclarationCount; i++) { currentDeclaration = GetLetDeclarationAt(i); if (GetDeclarationType(currentDeclaration) != previousDeclarationType && pendingDeclarations.Count > 0) { CommitPendingGenerations(cg, pendingDeclarations); pendingDeclarations.Clear(); } if (GetDeclarationType(currentDeclaration) == DeclarationType.VARIABLE) { currentDeclaration.GenerateCode(cg); //change VarDeclarationNode vdn = currentDeclaration as VarDeclarationNode; ListOfLocalDeclarations.Add(new KeyValuePair <LocalBuilder, FieldBuilder>(vdn.VariableLocalBuilder, vdn.VariableFieldBuilder)); } else { pendingDeclarations.Add(currentDeclaration); } previousDeclarationType = GetDeclarationType(currentDeclaration); } if (pendingDeclarations.Count > 0) { CommitPendingGenerations(cg, pendingDeclarations); pendingDeclarations.Clear(); } ExpressionSequence.GenerateCode(cg); cg.ILContextTable.CloseCurrentContext(); }
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) { ///gen code al RelationalOperationNode base.GenerateCode(cg); if (LeftOperand.NodeInfo.BuiltInType.IsCompatibleWith(BuiltInType.Int)) { cg.ILGenerator.Emit(OpCodes.Cgt); } else { MethodInfo method = typeof(string).GetMethod("Compare", new Type[] { typeof(string), typeof(string) }); cg.ILGenerator.Emit(OpCodes.Call, method); cg.ILGenerator.Emit(OpCodes.Ldc_I4_1); cg.ILGenerator.Emit(OpCodes.Ceq); } }
public void TestCallStringFormatMethod() { DynamicMethod dm; var gen = ILCodeGenerator.CreateDynamicMethodCodeGenerator( "TestCallStringFormatMethod", typeof(TestCallStringFormatMethodDelegate), out dm); gen.CallStringFormat( msg => msg.Load("{0}{1}{2}"), intVal => intVal.Box(typeof(int), box1 => box1.LoadArgument(0)), strVal => strVal.LoadArgument(1), test => test.LoadArgument(2)) .Ret(); var method = (TestCallStringFormatMethodDelegate)dm.CreateDelegate(typeof(TestCallStringFormatMethodDelegate)); var result = method(1, "2", new TestClass()); Assert.AreEqual(string.Format("{0}{1}{2}", 1, "2", new TestClass()), result); }
public override void GenCode(ICodeGenerator cg) { //obtenemos el functionSymbol var funSymbol = Scope.MappingDeclaration <FunctionSymbol>(Identifier); if (funSymbol.MethodBuilder == null) { //Creamos el metodo correspondiente a la funcion MethodBuilder function = cg.TypeBuilder.DefineMethod(Identifier + "_" + Scope.Id, MethodAttributes.Public | MethodAttributes.Static, ReturnType.PrimitiveType.ILType, Parameters.Select(i => i.FieldType.PrimitiveType.ILType).ToArray()); //Creamos los variables globales para cada uno de los parametros List <FieldBuilder> paramGlobals = new List <FieldBuilder>(); var fieldAttr = FieldAttributes.Public | FieldAttributes.Static; foreach (var item in Parameters) { paramGlobals.Add(cg.TypeBuilder.DefineField(item.Identifier + "_" + item.Scope.Id, item.FieldType.PrimitiveType.ILType, fieldAttr)); } //Rellenamos los campos del FunctionSymbol funSymbol.MethodBuilder = function; funSymbol.ParameterFieldBuilders = paramGlobals; } //Rellenamos los FieldSymbols con una referencia a al FieldBuilder correspondiente en el FunctionSymbol for (int i = 0; i < Parameters.Count; i++) { var field = Body.Scope.MappingDeclaration <FieldSymbol>(Parameters[i].Identifier); field.FieldBuilder = funSymbol.ParameterFieldBuilders[i]; //cg.GetGenerator.Emit(OpCodes.Ldarg, i+1); //cg.GetGenerator.Emit(OpCodes.Stsfld, funSymbol.ParameterFieldBuilders[i]); } //Creamos el ILCodeGenerator para la funcion y generamos su cuerpo var ilGen = funSymbol.MethodBuilder.GetILGenerator(); var funGen = new ILCodeGenerator(cg, ilGen); Body.GenCode(funGen); ilGen.Emit(OpCodes.Ret); }
private ILCode CreateCode(string moduleName, string typeName, AstNode exp) { if (Path.GetFileName(moduleName) != moduleName) { throw new Exception("can only output into current directory!"); } var name = new AssemblyName(Path.GetFileNameWithoutExtension(moduleName)); AssemblyBuilder asmb = AppDomain.CurrentDomain.DefineDynamicAssembly(name, AssemblyBuilderAccess.Save); ModuleBuilder modb = asmb.DefineDynamicModule(moduleName); TypeBuilder typeBuilder = modb.DefineType(typeName); MethodBuilder methMain = typeBuilder.DefineMethod("Main", MethodAttributes.Static, typeof(void), Type.EmptyTypes); var ilcode = new ILCode { Type = typeBuilder, Method = methMain, Module = modb }; init.CodeInfo = ilcode; init.GeneratePredifinedCode(); TypeBuilder nested = AddFunctionMainToCode(ilcode, methMain); ilcode.Type = nested; ILCodeGenerator codeGenerator = new ILCodeGenerator(ilcode); //generacion de codigos exp.Accept(codeGenerator); ILGenerator il = methMain.GetILGenerator(); il.Emit(OpCodes.Ret); nested.CreateType(); typeBuilder.CreateType(); modb.CreateGlobalFunctions(); asmb.SetEntryPoint(methMain); asmb.Save(moduleName); return(ilcode); }