Beispiel #1
0
        private LinkerResult ExtractDeclaringExportTypesFromNode(ASTNode node, Domain domain)
        {
            switch (node)
            {
            case NamespaceDirectiveNode namespaceDirective:
                Domain sub      = domain.First <NamespaceDomain>(namespaceDirective.Name.FullName);
                var    newTypes = new List <LinkingType>();
                foreach (var subNode in namespaceDirective.Body.Nodes)
                {
                    var r = this.ExtractDeclaringExportTypesFromNode(subNode, sub);
                    if (!r)
                    {
                        return(r);
                    }
                    else
                    {
                        foreach (var subType in r.types)
                        {
                            subType.FullName = $"{namespaceDirective.Name.FullName}.{subType.FullName}";
                            newTypes.Add(subType);
                        }
                    }
                }
                return(new LinkerResult(new CompileResult(true), newTypes));

            case ClassDeclNode classDecl:
                var classType    = domain.First <ClassType>(classDecl.LocalClassName);
                var classLnkType = new LinkingType(classDecl.LocalClassName, 0);
                List <LinkingType> classDeclTypes = new List <LinkingType>()
                {
                    classLnkType
                };
                foreach (var subClass in classDecl.Classes)
                {
                    var subClassResult = this.ExtractDeclaringExportTypesFromNode(subClass, classType);
                    if (!subClassResult)
                    {
                        return(subClassResult);
                    }
                    else
                    {
                        foreach (var subClassType in subClassResult.types)
                        {
                            subClassType.FullName = $"{classDecl.LocalClassName}+{subClassType.FullName}";
                        }
                    }
                }
                foreach (var method in classType.Methods)
                {
                    if (method.Value is ExternalFunctionType externalFunction)
                    {
                        var methodResult = this.LinkExternalMethod(classType, method.Value.Origin, externalFunction, classLnkType);
                        if (!methodResult)
                        {
                            return(methodResult);
                        }
                    }
                    else
                    {
                        if (method.Value.Origin.GetHint(CompileHintType.PointerHint) is CompileHint ptrHint)
                        {
                            classLnkType.MethodPtrs.Add(method.Key, new LinkInternalPtr((ulong)ptrHint.Args[0]));
                        }
                        else
                        {
                            return(new LinkerResult(false));
                        }
                    }
                }
                foreach (var field in classType.Fields)
                {
                    classLnkType.FieldPtrs.Add(field.Key, classLnkType.SizeInMemory);
                    if (field.Value is ValueType vType)
                    {
                        classLnkType.SizeInMemory += vType.Size;
                    }
                    else if (field.Value is ReferenceType rType)
                    {
                        classLnkType.SizeInMemory += 8;
                    }
                    else
                    {
                        throw new NotImplementedException();
                    }
                }
                return(new LinkerResult(classDeclTypes));

            case FuncDeclNode funcDeclNode when !funcDeclNode.HasBody:
                /*var funcResult = this.LinkExternalMethod(null, funcDeclNode, null, null);
                 * if (!funcResult) {
                 *  return funcResult;
                 * }*/
                return(new LinkerResult(true));

            default:
                return(new LinkerResult(true));
            }
        }
Beispiel #2
0
        private LinkerResult LinkExternalMethod(ClassType klass, FuncDeclNode funcDecl, ExternalFunctionType type, LinkingType lnkType)
        {
            // Get best external match
            var external = klass is null?this.GetDllFunction(type.Name) : this.GetDllFunction(klass.Name, type.Name);

            // Make sure there's an external to bind to
            if (!external.HasValue)
            {
                return(new LinkerResult(false));
            }
            else
            {
                DllFunction func = external.Value;
                if (lnkType is not null)
                {
                    lnkType.MethodPtrs.Add(type.Name, this.m_bindings.Register(func));
                }
            }

            // Return true (Fails by following bail-out-fast, so when reaching this point it's always success)
            return(new LinkerResult(true));
        }