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); }
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(); }
public string MangleName(ConstructorIL constructor) { return(Mangle(constructor.Symbol)); }