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 void EmitExternalFunctionSignature(FunctionIL function, Code code) { // I think external functions are supposed to not be mangled? var name = function.Symbol.Name.Text; var parameters = Convert(function.Parameters); var returnType = typeConverter.Convert(function.Symbol.ReturnDataType.Known()); code.FunctionDeclarations.AppendLine($"{returnType} {name}({parameters});"); }
private void EmitFunction(FunctionIL function, Code code) { var name = nameMangler.MangleName(function); var parameters = Convert(function.Parameters); var returnType = typeConverter.Convert(function.Symbol.ReturnDataType.Known()); // Write out the function declaration for C so we can call functions defined after others code.FunctionDeclarations.AppendLine($"{returnType} {name}({parameters});"); code.Definitions.DeclarationSeparatorLine(); code.Definitions.AppendLine($"{returnType} {name}({parameters})"); code.Definitions.BeginBlock(); controlFlowEmitter.Emit(function, code); code.Definitions.EndBlock(); }
public void EmitEntryPointAdapter(FunctionIL entryPoint, Code code) { if (entryPoint is null) { return; } code.Definitions.DeclarationSeparatorLine(); code.Definitions.AppendLine("// Entry Point Adapter"); code.Definitions.AppendLine("int32_t main(const int argc, char const * const * const argv)"); code.Definitions.BeginBlock(); var arguments = new List <string>(); foreach (var parameterType in entryPoint.Parameters.Select(p => p.DataType).Cast <ObjectType>()) { if (parameterType.ContainingNamespace == SystemConsole && parameterType.Name == "Console") { code.Definitions.AppendLine( "system__console__Console console = { &system__console__Console___vtable, malloc(sizeof(system__console__Console___Self)) };"); arguments.Add("system__console__Console___new__1(console)"); } else if (parameterType.ContainingNamespace == SystemConsole && parameterType.Name == "Arguments") { throw new NotImplementedException(); } else { throw new Exception($"Unexpected type for parameter to main: {parameterType}"); } } var joinedArguments = string.Join(", ", arguments); if (entryPoint.Symbol.ReturnDataType == DataType.Void) { code.Definitions.AppendLine($"{nameMangler.Mangle(entryPoint.Symbol)}({joinedArguments});"); code.Definitions.AppendLine("return 0;"); } else { code.Definitions.AppendLine($"return {nameMangler.Mangle(entryPoint.Symbol)}({joinedArguments})._value;"); } code.Definitions.EndBlock(); }
private static void Disassemble(FunctionIL function, AssemblyBuilder builder) { var parameters = FormatParameters(function.Parameters); builder.BeginLine("fn "); builder.Append(Convert(function.Symbol)); builder.Append("("); builder.Append(parameters); builder.Append(")"); builder.EndLine(); builder.BeginLine(builder.IndentCharacters); builder.Append("-> "); builder.EndLine(function.Symbol.ReturnDataType.ToString()); if (function.IL != null) { builder.BeginBlock(); Disassemble(function.IL, builder); builder.EndBlock(); } }
public string MangleName(FunctionIL function) { return(Mangle(function.Symbol)); }