コード例 #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);
        }
コード例 #2
0
        private void EmitType(ClassIL @class, Code code)
        {
            var typeName = nameMangler.MangleName(@class);

            // Struct Forward Declarations
            var selfType   = $"{typeName}___Self";
            var vtableType = $"{typeName}___VTable";
            var types      = code.TypeDeclarations;

            types.AppendLine($"typedef struct {selfType} {selfType};");
            types.AppendLine($"typedef struct {vtableType} {vtableType};");
            // Declare the full type because when it is used as a field, its
            // size will need to be known. However, order within struct
            // declarations is not defined.
            types.AppendLine($"typedef struct {typeName}");
            types.BeginBlock();
            types.AppendLine($"{vtableType} const* restrict _vtable;");
            types.AppendLine($"{selfType}* restrict _self;");
            types.EndBlockWith($"}} {typeName};");

            var structs = code.StructDeclarations;

            structs.AppendLine($"struct {selfType}");
            structs.BeginBlock();
            foreach (var field in @class.Members.OfType <FieldIL>())
            {
                var binding = field.Symbol.IsMutableBinding ? "var" : "let";
                structs.AppendLine($"// {binding} {field.Symbol.Name}: {field.DataType}");
                var fieldType = typeConverter.Convert(field.DataType.Known());
                var fieldName = nameMangler.MangleName(field);
                structs.AppendLine($"{fieldType} {fieldName};");
            }
            structs.EndBlockWithSemicolon();
            structs.AppendLine($"struct {vtableType}");
            structs.BeginBlock();
            foreach (var method in @class.Members.OfType <MethodDeclarationIL>())
            {
                var name       = nameMangler.MangleMethodName(method);
                var parameters = Convert(method.Parameters.Prepend(method.SelfParameter));
                var returnType = typeConverter.Convert(method.Symbol.ReturnDataType.Known());
                structs.AppendLine($"{returnType} (*{name})({parameters});");
            }
            structs.EndBlockWithSemicolon();

            var globals = code.StructDeclarations;

            globals.AppendLine($"const {vtableType} {typeName}___vtable = ({vtableType})");
            globals.BeginBlock();
            foreach (var method in @class.Members.OfType <MethodDeclarationIL>())
            {
                var fieldName    = nameMangler.MangleMethodName(method);
                var functionName = nameMangler.MangleName(method);
                globals.AppendLine($".{fieldName} = {functionName},");
            }
            globals.EndBlockWithSemicolon();
        }
コード例 #3
0
 public string MangleName(ClassIL @class)
 {
     return(Mangle(@class.Symbol));
 }