public void Compile(AstRoot root, Stream toStream, CompilationArguments arguments) { Argument.RequireNotNull("toStream", toStream); Argument.RequireNotNull("root", root); Argument.RequireNotNull("arguments", arguments); var assembly = AssemblyDefinition.CreateAssembly( new AssemblyNameDefinition(arguments.AssemblyName, arguments.AssemblyVersion), arguments.AssemblyName, arguments.Target == CompilationTarget.Console ? ModuleKind.Console : ModuleKind.Dll ); var module = assembly.MainModule; var context = new DefinitionBuildingContext(module, this.referenceProviders); foreach (var typeAst in root.Descendants<AstTypeDefinition>()) { DefineType(module, typeAst, context); } context.ClearDebt(); foreach (var type in module.Types) { foreach (var method in type.Methods) { CompileMethod(method, context.GetAst(method), context); } } assembly.Write(toStream); }
private void CompileMethod(MethodDefinition method, AstMethodDefinitionBase methodAst, DefinitionBuildingContext parentContext) { var body = method.Body.GetILProcessor(); var context = new CilCompilationContext(method, methodAst, (e, c) => CompileCil(body, e, c), parentContext); foreach (var element in methodAst.Body) { CompileCil(body, element, context); } }
void IDefinitionBuilder.Build(IAstDefinition ast, IMemberDefinition parentDefinition, DefinitionBuildingContext context) { this.Build((TAstDefinition)ast, (TParentDefinition)parentDefinition, context); }
public abstract void Build(TAstDefinition ast, TParentDefinition parentDefinition, DefinitionBuildingContext context);
private void DefineType(ModuleDefinition module, Ast.Definitions.AstTypeDefinition typeAst, DefinitionBuildingContext context) { var type = new TypeDefinition("", typeAst.Name, TypeAttributes.Public | ToTypeAttribute(typeAst.DefinitionType)) { BaseType = module.Import(typeof(object)) }; module.Types.Add(type); foreach (var memberAst in typeAst.Members) { DefineMember(type, memberAst, context); } context.MapDefinition(typeAst, type); }
private void DefineMember(TypeDefinition type, IAstDefinition memberAst, DefinitionBuildingContext context) { var builder = this.builders.SingleOrDefault(c => c.CanBuild(memberAst, type)); if (builder == null) throw new NotImplementedException("LightCompiler: No DefinitionBuilder for " + memberAst + " under " + type + "."); builder.Build(memberAst, type, context); }
private void DefineFunction(TypeDefinition type, AstMethodDefinitionBase methodAst, DefinitionBuildingContext context) { MethodDefinition method; if (methodAst is Ast.Definitions.AstFunctionDefinition) { var functionAst = methodAst as AstFunctionDefinition; var attributes = MethodAttributes.Public; if (methodAst.Compilation.Static) attributes |= MethodAttributes.Static; var returnType = context.ConvertReference(functionAst.ReturnType, returnNullIfFailed: true); method = new MethodDefinition(functionAst.Name, attributes, returnType ?? CecilHelper.GetVoidType(type.Module)); if (returnType == null) context.AddDebt(() => method.ReturnType = context.ConvertReference(functionAst.ReturnType)); if (methodAst.Compilation.EntryPoint) type.Module.EntryPoint = method; } else if (methodAst is Ast.Definitions.AstConstructorDefinition) { method = CecilHelper.CreateConstructor(type); method.Attributes |= MethodAttributes.Public; } else { throw new NotImplementedException("LightCompiler.CompileFunction: cannot compile " + methodAst + "."); } type.Methods.Add(method); context.MapDefinition(methodAst, method); DefineParameters(method, methodAst, context); }
private void DefineParameters(MethodDefinition method, AstMethodDefinitionBase methodAst, DefinitionBuildingContext context) { foreach (var parameter in methodAst.Parameters) { method.Parameters.Add(new ParameterDefinition(parameter.Name, ParameterAttributes.None, context.ConvertReference(parameter.Type))); } }
private void DefineMember(TypeDefinition type, IAstDefinition memberAst, DefinitionBuildingContext context) { var functionAst = memberAst as AstMethodDefinitionBase; if (functionAst != null) { DefineFunction(type, functionAst, context); return; } var builder = this.builders.SingleOrDefault(c => c.CanBuild(memberAst, type)); if (builder == null) throw new NotImplementedException("LightCompiler: No DefinitionBuilder for " + memberAst + " under " + type + "."); builder.Build(memberAst, type, context); }