Ejemplo n.º 1
0
        private DeclarationIL Build(IDeclaration declaration, ISymbolTree symbolTree)
        {
            if (declarationsIL.TryGetValue(declaration.Symbol, out var declarationIL))
            {
                return(declarationIL);
            }

            switch (declaration)
            {
            default:
                throw ExhaustiveMatch.Failed(declaration);

            case IFunctionDeclaration function:
            {
                var il = ilFactory.CreateGraph(function);
                declarationIL = new FunctionIL(false, false, function.Symbol, BuildParameters(function.Parameters), il);
                break;
            }

            case IAssociatedFunctionDeclaration associatedFunction:
            {
                var il = ilFactory.CreateGraph(associatedFunction);
                declarationIL = new FunctionIL(false, true, associatedFunction.Symbol, BuildParameters(associatedFunction.Parameters), il);
                break;
            }

            case IConcreteMethodDeclaration method:
            {
                var il = ilFactory.CreateGraph(method);
                declarationIL = new MethodDeclarationIL(method.Symbol, BuildParameter(method.SelfParameter), BuildParameters(method.Parameters), il);
                break;
            }

            case IAbstractMethodDeclaration method:
            {
                declarationIL = new MethodDeclarationIL(method.Symbol, BuildParameter(method.SelfParameter), BuildParameters(method.Parameters), null);
                break;
            }

            case IConstructorDeclaration constructor:
            {
                var il                   = ilFactory.CreateGraph(constructor);
                var parameters           = BuildConstructorParameters(constructor);
                var fieldInitializations = BuildFieldInitializations(constructor);
                declarationIL = new ConstructorIL(constructor.Symbol, parameters, fieldInitializations, il);
                break;
            }

            case IFieldDeclaration fieldDeclaration:
                declarationIL = new FieldIL(fieldDeclaration.Symbol);
                break;

            case IClassDeclaration classDeclaration:
                declarationIL = new ClassIL(classDeclaration.Symbol,
                                            BuildClassMembers(classDeclaration, symbolTree));
                break;
            }
            declarationsIL.Add(declaration.Symbol, declarationIL);
            return(declarationIL);
        }
Ejemplo n.º 2
0
        private DeclarationIL?BuildDefaultConstructor(
            IClassDeclaration classDeclaration,
            ISymbolTree symbolTree)
        {
            var constructorSymbol = classDeclaration.DefaultConstructorSymbol;

            if (constructorSymbol is null)
            {
                return(null);
            }

            if (declarationsIL.TryGetValue(constructorSymbol, out var declaration))
            {
                return(declaration);
            }

            var selfParameterSymbol = symbolTree.Children(constructorSymbol).OfType <SelfParameterSymbol>().Single();
            var selfParameter       = new SelfParameterIL(selfParameterSymbol);
            var parameters          = selfParameter.Yield().ToFixedList <ParameterIL>();

            var graph = new ControlFlowGraphBuilder(classDeclaration.File);

            graph.AddSelfParameter(selfParameterSymbol);
            var block = graph.NewBlock();

            block.End(new ReturnVoidInstruction(classDeclaration.NameSpan, Scope.Outer));

            //var il = new ControlFlowGraphBuilder(classDeclaration.File);
            //il.AddSelfParameter(selfType);
            //var block = il.NewBlock();
            //block.End(classDeclaration.NameSpan, Scope.Outer);

            var defaultConstructor = new ConstructorIL(// TODO how to get a name
                constructorSymbol,
                parameters, FixedList <FieldInitializationIL> .Empty, graph.Build());

            //defaultConstructor.ControlFlowOld.InsertedDeletes = new InsertedDeletes();
            declarationsIL.Add(constructorSymbol, defaultConstructor);
            return(defaultConstructor);
        }
        private void EmitConstructor(ConstructorIL constructor, Code code)
        {
            // Don't emit constructors without control flow, they are generic
            // TODO need to handle better
            if (constructor.IL is null)
            {
                return;
            }

            var name       = nameMangler.MangleName(constructor);
            var parameters = Convert(constructor.Parameters);
            var returnType = typeConverter.Convert(constructor.Symbol.ContainingSymbol.DeclaresDataType.Known());

            // Write out the function declaration for C so we can call functions defined after others
            code.FunctionDeclarations.AppendLine($"// {constructor.Symbol}");
            code.FunctionDeclarations.AppendLine($"{returnType} {name}({parameters});");

            code.Definitions.DeclarationSeparatorLine();
            code.Definitions.AppendLine($"// {constructor.Symbol}");
            code.Definitions.AppendLine($"{returnType} {name}({parameters})");
            code.Definitions.BeginBlock();
            controlFlowEmitter.Emit(constructor, code);
            code.Definitions.EndBlock();
        }
Ejemplo n.º 4
0
 public string MangleName(ConstructorIL constructor)
 {
     return(Mangle(constructor.Symbol));
 }