From 1eeeb67d88e837314879dc4640e240a11c6d2e50 Mon Sep 17 00:00:00 2001 From: nub31 Date: Fri, 12 Sep 2025 17:31:40 +0200 Subject: [PATCH] ... --- .../NubLang/Generation/QBE/QBEGenerator.cs | 50 ++++++------------- compiler/NubLang/Modules/Module.cs | 42 ++++++++++------ compiler/NubLang/Modules/ModuleRepository.cs | 26 +++++++--- compiler/NubLang/TypeChecking/TypeChecker.cs | 10 ++-- 4 files changed, 69 insertions(+), 59 deletions(-) diff --git a/compiler/NubLang/Generation/QBE/QBEGenerator.cs b/compiler/NubLang/Generation/QBE/QBEGenerator.cs index 8bf00dc..277bff3 100644 --- a/compiler/NubLang/Generation/QBE/QBEGenerator.cs +++ b/compiler/NubLang/Generation/QBE/QBEGenerator.cs @@ -46,19 +46,16 @@ public class QBEGenerator foreach (var structType in _structTypes) { EmitStructType(structType); - _writer.NewLine(); } foreach (var structDef in _definitions.OfType()) { EmitStructDefinition(structDef); - _writer.NewLine(); } foreach (var funcDef in _definitions.OfType()) { EmitFuncDefinition(funcDef); - _writer.NewLine(); } // foreach (var structDef in _definitions.OfType().Where(x => x.InterfaceImplementations.Count > 0)) @@ -408,19 +405,14 @@ public class QBEGenerator private void EmitStructDefinition(StructNode structDef) { - // _writer.WriteLine($"export function {StructCtorName(_module.Name, structDef.Name)}() {{"); - // _writer.WriteLine("@start"); - // _writer.Indented($"%struct =l alloc8 {SizeOf(type)}"); - // // todo(nub31): Finish constructor - // _writer.Indented("ret %struct"); - // _writer.WriteLine("}"); + // todo(nub31): Find a way do run the initializers from other modules where the definition is not available. + // A constructor is probably the answer foreach (var function in structDef.Functions) { _labelIndex = 0; _tmpIndex = 0; - _writer.NewLine(); _writer.Write("export function "); if (function.Signature.ReturnType is not VoidTypeNode) @@ -453,14 +445,14 @@ public class QBEGenerator private void EmitStructType(StructTypeNode structType) { - _writer.WriteLine($"type {StructTypeName(structType.Module, structType.Name)} = {{ "); + _writer.Write($"type {StructTypeName(structType.Module, structType.Name)} = {{ "); foreach (var field in structType.Fields) { - _writer.Indented($"{StructDefQBEType(field.Type)},"); + _writer.Write($"{StructDefQBEType(field.Type)},"); } - _writer.WriteLine("}"); + _writer.WriteLine(" }"); return; string StructDefQBEType(TypeNode type) @@ -1367,55 +1359,45 @@ public class QBEGenerator throw new UnreachableException($"Member '{member}' not found in struct"); } - #region Naming utilities - private string TmpName() { - return $"%t{++_tmpIndex}"; + return $"%t.{++_tmpIndex}"; } private string LabelName() { - return $"@l{++_labelIndex}"; + return $"@l.{++_labelIndex}"; } private string CStringName() { - return $"$cstring{++_cStringLiteralIndex}"; + return $"$cstr.{++_cStringLiteralIndex}"; } private string StringName() { - return $"$string{++_stringLiteralIndex}"; + return $"$str.{++_stringLiteralIndex}"; } - private string FuncName(string module, string name, string? externSymbol) + private static string FuncName(string module, string name, string? externSymbol) { - var symbol = externSymbol ?? $"{module}.{name}"; - return "$" + symbol; + return $"${externSymbol ?? $"{module}.{name}"}"; } - private string StructTypeName(string module, string name) + private static string StructTypeName(string module, string name) { return $":{module}.{name}"; } - private string StructFuncName(string module, string structName, string funcName) + private static string StructFuncName(string module, string structName, string funcName) { - return $"${module}.{structName}_func.{funcName}"; + return $"${module}.{structName}.func.{funcName}"; } - private string StructCtorName(string module, string structName) + private static string StructVtableName(string module, string structName) { - return $"${module}.{structName}_ctor"; + return $"${module}.{structName}.vtable"; } - - private string StructVtableName(string module, string structName) - { - return $"${module}.{structName}_vtable"; - } - - #endregion } public class StringLiteral(string value, string name) diff --git a/compiler/NubLang/Modules/Module.cs b/compiler/NubLang/Modules/Module.cs index f0f349a..26ff5f1 100644 --- a/compiler/NubLang/Modules/Module.cs +++ b/compiler/NubLang/Modules/Module.cs @@ -4,45 +4,55 @@ namespace NubLang.Modules; public class Module { - private readonly List _structs = []; - private readonly List _interfaces = []; - private readonly List _functions = []; + private readonly List _structs = []; + private readonly List _interfaces = []; + private readonly List _functions = []; - public void RegisterStruct(bool exported, string name, List fields) + public void RegisterStruct(bool exported, string name, List fields, List functions) { - _structs.Add(new ModuleStructType(exported, name, fields)); + _structs.Add(new ModuleStruct(exported, name, fields, functions)); } - public void RegisterInterface(bool exported, string name) + public void RegisterInterface(bool exported, string name, List functions) { - _interfaces.Add(new ModuleInterfaceType(exported, name)); + _interfaces.Add(new ModuleInterface(exported, name, functions)); } - public void RegisterFunction(bool exported, string name, string? externSymbol, FuncTypeSyntax type) + public void RegisterFunction(bool exported, string name, string? externSymbol, List parameters, TypeSyntax returnType) { - _functions.Add(new ModuleFuncType(exported, name, externSymbol, type)); + _functions.Add(new ModuleFunction(exported, name, externSymbol, parameters, returnType)); } - public List StructTypes(bool includePrivate) + public List StructTypes(bool includePrivate) { return _structs.Where(x => x.Exported || includePrivate).ToList(); } - public List InterfaceTypes(bool includePrivate) + public List InterfaceTypes(bool includePrivate) { return _interfaces.Where(x => x.Exported || includePrivate).ToList(); } - public List Functions(bool includePrivate) + public List Functions(bool includePrivate) { return _functions.Where(x => x.Exported || includePrivate).ToList(); } } -public record ModuleStructTypeField(string Name, TypeSyntax Type, bool HasDefaultValue); +public record ModuleStructField(string Name, TypeSyntax Type, bool HasDefaultValue); -public record ModuleStructType(bool Exported, string Name, List Fields); +public record ModuleStructFunctionParameter(string Name, TypeSyntax Type); -public record ModuleInterfaceType(bool Exported, string Name); +public record ModuleStructFunction(string Name, List Parameters, TypeSyntax ReturnType); -public record ModuleFuncType(bool Exported, string Name, string? ExternSymbol, FuncTypeSyntax FuncType); \ No newline at end of file +public record ModuleStruct(bool Exported, string Name, List Fields, List Functions); + +public record ModuleInterfaceFunctionParameter(string Name, TypeSyntax Type); + +public record ModuleInterfaceFunction(string Name, List Parameters, TypeSyntax ReturnType); + +public record ModuleInterface(bool Exported, string Name, List Functions); + +public record ModuleFunctionParameter(string Name, TypeSyntax Type); + +public record ModuleFunction(bool Exported, string Name, string? ExternSymbol, List Parameters, TypeSyntax ReturnType); \ No newline at end of file diff --git a/compiler/NubLang/Modules/ModuleRepository.cs b/compiler/NubLang/Modules/ModuleRepository.cs index 6e43263..67ba1f0 100644 --- a/compiler/NubLang/Modules/ModuleRepository.cs +++ b/compiler/NubLang/Modules/ModuleRepository.cs @@ -24,20 +24,34 @@ public class ModuleRepository { case FuncSyntax funcDef: { - var parameters = funcDef.Signature.Parameters.Select(x => x.Type).ToList(); - var type = new FuncTypeSyntax([], parameters, funcDef.Signature.ReturnType); - module.RegisterFunction(funcDef.Exported, funcDef.Name, funcDef.ExternSymbol, type); + var parameters = funcDef.Signature.Parameters.Select(x => new ModuleFunctionParameter(x.Name, x.Type)).ToList(); + module.RegisterFunction(funcDef.Exported, funcDef.Name, funcDef.ExternSymbol, parameters, funcDef.Signature.ReturnType); break; } case StructSyntax structDef: { - var fields = structDef.Fields.Select(x => new ModuleStructTypeField(x.Name, x.Type, x.Value.HasValue)).ToList(); - module.RegisterStruct(structDef.Exported, structDef.Name, fields); + var fields = structDef.Fields.Select(x => new ModuleStructField(x.Name, x.Type, x.Value.HasValue)).ToList(); + + var functions = new List(); + foreach (var function in structDef.Functions) + { + var parameters = function.Signature.Parameters.Select(x => new ModuleStructFunctionParameter(x.Name, x.Type)).ToList(); + functions.AddRange(new ModuleStructFunction(function.Name, parameters, function.Signature.ReturnType)); + } + + module.RegisterStruct(structDef.Exported, structDef.Name, fields, functions); break; } case InterfaceSyntax interfaceDef: { - module.RegisterInterface(interfaceDef.Exported, interfaceDef.Name); + var functions = new List(); + foreach (var function in interfaceDef.Functions) + { + var parameters = function.Signature.Parameters.Select(x => new ModuleInterfaceFunctionParameter(x.Name, x.Type)).ToList(); + functions.AddRange(new ModuleInterfaceFunction(function.Name, parameters, function.Signature.ReturnType)); + } + + module.RegisterInterface(interfaceDef.Exported, interfaceDef.Name, functions); break; } default: diff --git a/compiler/NubLang/TypeChecking/TypeChecker.cs b/compiler/NubLang/TypeChecking/TypeChecker.cs index e0d413d..d36107f 100644 --- a/compiler/NubLang/TypeChecking/TypeChecker.cs +++ b/compiler/NubLang/TypeChecking/TypeChecker.cs @@ -366,7 +366,9 @@ public sealed class TypeChecker if (function != null) { - return new FuncIdentifierNode(ResolveType(function.FuncType), _syntaxTree.Metadata.ModuleName, expression.Name, function.ExternSymbol); + var parameters = function.Parameters.Select(x => ResolveType(x.Type)).ToList(); + var type = new FuncTypeNode(parameters, ResolveType(function.ReturnType)); + return new FuncIdentifierNode(type, _syntaxTree.Metadata.ModuleName, expression.Name, function.ExternSymbol); } throw new TypeCheckerException(Diagnostic.Error($"Symbol {expression.Name} not found").At(expression).Build()); @@ -385,7 +387,9 @@ public sealed class TypeChecker var function = module.Functions(includePrivate).FirstOrDefault(x => x.Name == expression.Name); if (function != null) { - return new FuncIdentifierNode(ResolveType(function.FuncType), expression.Module, expression.Name, function.ExternSymbol); + var parameters = function.Parameters.Select(x => ResolveType(x.Type)).ToList(); + var type = new FuncTypeNode(parameters, ResolveType(function.ReturnType)); + return new FuncIdentifierNode(type, expression.Module, expression.Name, function.ExternSymbol); } throw new TypeCheckerException(Diagnostic.Error($"No exported symbol {expression.Name} not found in module {expression.Module}").At(expression).Build()); @@ -558,7 +562,7 @@ public sealed class TypeChecker result.Fields.AddRange(fields); // todo(nub31): Functions and interface implementations - + _referencedStructTypes.Add(result); return result; }