public void Compile(string path) { AppDomain domain = System.Threading.Thread.GetDomain(); AssemblyName name = new AssemblyName(); name.Name = "Sharp Code Assembly"; AssemblyBuilder assemblyBuilder = domain.DefineDynamicAssembly(name, AssemblyBuilderAccess.Save); ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule(m_Module.Name, m_Module.Name + ".exe", true); // // Создаем глобальные переменные // TypeBuilder globalBuilder = moduleBuilder.DefineType("Global"); m_Globals = new SymbolTable(); foreach (Statement statement in m_Module.Body.Statements) { if (statement is Variable) { Variable variable = statement as Variable; System.Type type = variable.Type.ToSystemType(); FieldBuilder field = globalBuilder.DefineField(variable.Name, type, FieldAttributes.Public | FieldAttributes.Static); m_Globals.Add(variable.Name, SymbolType.Variable, statement, field); } } globalBuilder.CreateType(); // // Строим функции // m_Module.Body.SymbolTable = m_Globals; BuildFunctionStubs(m_Module.Body, moduleBuilder); foreach (Function function in m_Module.Body.Functions) { BuildFunction(function); } // // Создаем точку входа (функция main) // MethodBuilder mainBuilder = moduleBuilder.DefineGlobalMethod("Main", MethodAttributes.Public | MethodAttributes.Static, typeof(void), null); ILGenerator mainIL = mainBuilder.GetILGenerator(); m_Module.Body.Statements.Add(new CallStatement(null, "main")); EmitBody(mainIL, m_Module.Body, true); moduleBuilder.CreateGlobalFunctions(); assemblyBuilder.SetEntryPoint(mainBuilder.GetBaseDefinition()); assemblyBuilder.Save(m_Module.Name + ".exe"); System.IO.File.Move(m_Module.Name + ".exe", path); }
private void BuildSymbolTable(SymbolTable parent, Body body) { if (body.Structures != null) foreach (Structure structure in body.Structures) parent.Add(structure).SyntaxObject = structure; if (body.Functions != null) { foreach (Function function in body.Functions) { parent.Add(function).SyntaxObject = function; function.Body.SymbolTable = new SymbolTable(); BuildSymbolTable(function.Body.SymbolTable, function.Body); } } if (body.Statements != null) { foreach (Statement statement in body.Statements) { if (statement is Variable) parent.Add(statement as Variable).SyntaxObject = statement; } } }