Beispiel #1
0
        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);
        }
Beispiel #2
0
        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);
            }
        }
Beispiel #3
0
 void IDefinitionBuilder.Build(IAstDefinition ast, IMemberDefinition parentDefinition, DefinitionBuildingContext context)
 {
     this.Build((TAstDefinition)ast, (TParentDefinition)parentDefinition, context);
 }
Beispiel #4
0
 public abstract void Build(TAstDefinition ast, TParentDefinition parentDefinition, DefinitionBuildingContext context);
Beispiel #5
0
        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);
        }
Beispiel #6
0
        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);
        }
Beispiel #7
0
        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);
        }
Beispiel #8
0
 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)));
     }
 }
Beispiel #9
0
        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);
        }