Beispiel #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);
        }
        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();
        }
Beispiel #4
0
        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();
            }
        }
Beispiel #6
0
 public string MangleName(FunctionIL function)
 {
     return(Mangle(function.Symbol));
 }