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)); } }
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)); }