private void CreateTypes(ref TranslationUnitData transUnit) { var idPool = Environment !.IdPool; foreach (ref var astUnit in transUnit.AstUnits.Span) { foreach (var nm in astUnit.Ast.Namespaces) { ArrayPointer <byte> namespaceName; using (var nameArr = nm.NamespaceName.ToPooledChars()) namespaceName = idPool.GetIdentifier(nameArr); var namespaceBuilder = EnvironmentBuilder !.GetOrCreateNamespace(namespaceName); foreach (var type in nm.Contents) { switch (type) { case ES_AstClassDefinition classDef: CreateTypes_Aggregate(ref transUnit, namespaceBuilder, ES_TypeTag.Class, classDef); break; case ES_AstStructDefinition structDef: CreateTypes_Aggregate(ref transUnit, namespaceBuilder, ES_TypeTag.Struct, structDef); break; case ES_AstEnumDefinition enumDef: { var typeName = Environment !.IdPool.GetIdentifier(enumDef.Name.Text.Span); if (namespaceBuilder.CheckTypeExists(typeName, null) != null) { errorList.Add(ES_FrontendErrors.GenTypeAlreadyDefined( namespaceBuilder.NamespaceData.NamespaceNameString, enumDef.Name.Text.Span.GetPooledString(), enumDef.Name )); break; } var builder = namespaceBuilder.GetOrCreateEnum(enumDef.AccessModifier, typeName, transUnit.Name); EnvironmentBuilder !.PointerAstMap.Add((IntPtr)builder.EnumData, enumDef); break; } case ES_AstFunctionDefinition: // Functions are handled in a pass of their own. break; default: throw new NotImplementedException("Node type not implemented yet."); } } } } }
private void CreateTypes_Aggregate( ref TranslationUnitData transUnit, ES_NamespaceData.Builder namespaceBuilder, ES_TypeTag type, ES_AstAggregateDefinition typeDef ) { var namespaceName = namespaceBuilder.NamespaceData.NamespaceName; var typeName = Environment !.IdPool.GetIdentifier(typeDef.Name.Text.Span); if (namespaceBuilder.CheckTypeExists(typeName, null) != null) { errorList.Add(ES_FrontendErrors.GenTypeAlreadyDefined( namespaceBuilder.NamespaceData.NamespaceNameString, typeDef.Name.Text.Span.GetPooledString(), typeDef.Name )); return; } ES_TypeInfo *typeData = null; if (type == ES_TypeTag.Class) { var classBuilder = namespaceBuilder.GetOrCreateClass(typeDef.AccessModifier, typeName, transUnit.Name); typeData = &classBuilder.ClassData->TypeInfo; } else if (type == ES_TypeTag.Struct) { var structBuilder = namespaceBuilder.GetOrCreateStruct(typeDef.AccessModifier, typeName, transUnit.Name); typeData = &structBuilder.StructData->TypeInfo; } else { Debug.Fail("Not implemented/supported."); } EnvironmentBuilder !.PointerAstMap.Add((IntPtr)typeData, typeDef); }
private bool TypeSizing_AnalyzeCycles([NotNull] ES_TypeInfo *type) { switch (type->TypeTag) { case ES_TypeTag.Struct: case ES_TypeTag.Class: break; case ES_TypeTag.Void: case ES_TypeTag.Bool: case ES_TypeTag.Int: case ES_TypeTag.Float: case ES_TypeTag.Function: case ES_TypeTag.Enum: case ES_TypeTag.Interface: case ES_TypeTag.Reference: case ES_TypeTag.Const: case ES_TypeTag.Immutable: case ES_TypeTag.Array: return(false); default: throw new NotImplementedException("Type not implemented yet."); } var hasCycles = false; foreach (var memberAddr in type->MembersList.MembersList.Span) { var member = memberAddr.Address; if (member->MemberType != ES_MemberType.Field) { continue; } if (member->Flags.HasFlag(ES_MemberFlags.Static)) { continue; } var field = (ES_MemberData_Variable *)member; if (TypeSizing_AnalyzeCycles_Traverse(field->Type, type)) { if (!EnvironmentBuilder !.PointerAstMap.TryGetValue((IntPtr)field, out var astNode)) { Debug.Fail("PointerAstMap is missing field mappings."); } var fieldAstNode = astNode as ES_AstMemberVarDefinition; Debug.Assert(fieldAstNode is not null); errorList.Add(ES_FrontendErrors.GenFieldCausesCycle( member->Name.GetPooledString(ES_Encodings.Identifier), type->Name.GetNameAsTypeString(), fieldAstNode.Name )); hasCycles = true; } } return(hasCycles); }