From 44665654c8ffcc629aa07c382e7d2ac7b4ed8225 Mon Sep 17 00:00:00 2001 From: nub31 Date: Wed, 9 Jul 2025 20:44:20 +0200 Subject: [PATCH] bound types --- src/compiler/NubLang/Syntax/Binding/Binder.cs | 97 +++++++++++++------ .../NubLang/Syntax/Binding/DefinitionTable.cs | 16 +-- .../NubLang/Syntax/Binding/NubType.cs | 4 +- src/compiler/NubLang/Syntax/Parsing/Parser.cs | 2 +- 4 files changed, 80 insertions(+), 39 deletions(-) diff --git a/src/compiler/NubLang/Syntax/Binding/Binder.cs b/src/compiler/NubLang/Syntax/Binding/Binder.cs index 17972e2..3f4bcba 100644 --- a/src/compiler/NubLang/Syntax/Binding/Binder.cs +++ b/src/compiler/NubLang/Syntax/Binding/Binder.cs @@ -70,7 +70,7 @@ public sealed class Binder functions.Add(new BoundTraitFuncImpl(func.Tokens, func.Name, signature, body)); } - return new BoundTraitImpl(node.Tokens, node.Namespace, node.TraitType, node.ForType, functions); + return new BoundTraitImpl(node.Tokens, node.Namespace, BindType(node.TraitType), BindType(node.ForType), functions); } private BoundTrait BindTraitDefinition(TraitSyntax node) @@ -95,10 +95,10 @@ public sealed class Binder if (field.Value.HasValue) { - value = BindExpression(field.Value.Value, field.Type); + value = BindExpression(field.Value.Value, BindType(field.Type)); } - structFields.Add(new BoundStructField(field.Tokens, field.Index, field.Name, field.Type, value)); + structFields.Add(new BoundStructField(field.Tokens, field.Index, field.Name, BindType(field.Type), value)); } return new BoundStruct(node.Tokens, node.Namespace, node.Name, structFields); @@ -189,7 +189,7 @@ public sealed class Binder if (statement.ExplicitType.HasValue) { - type = statement.ExplicitType.Value; + type = BindType(statement.ExplicitType.Value); } var assignment = Optional.Empty(); @@ -269,7 +269,7 @@ public sealed class Binder var body = BindFuncBody(expression.Body, funcType.ReturnType, parameters); - return new BoundArrowFunc(expression.Tokens, new NubFuncType(funcType.ReturnType, parameters.Select(x => x.Type).ToList()), parameters, funcType.ReturnType, body); + return new BoundArrowFunc(expression.Tokens, new NubFuncType(parameters.Select(x => x.Type).ToList(), funcType.ReturnType), parameters, funcType.ReturnType, body); } private BoundArrayIndexAccess BindArrayIndexAccess(ArrayIndexAccessSyntax expression) @@ -281,7 +281,9 @@ public sealed class Binder private BoundArrayInitializer BindArrayInitializer(ArrayInitializerSyntax expression) { - return new BoundArrayInitializer(expression.Tokens, new NubArrayType(expression.ElementType), BindExpression(expression.Capacity, new NubPrimitiveType(PrimitiveTypeKind.U64)), expression.ElementType); + var capacity = BindExpression(expression.Capacity, new NubPrimitiveType(PrimitiveTypeKind.U64)); + var type = new NubArrayType(BindType(expression.ElementType)); + return new BoundArrayInitializer(expression.Tokens, type, capacity, BindType(expression.ElementType)); } private BoundBinaryExpression BindBinaryExpression(BinaryExpressionSyntax expression) @@ -334,7 +336,9 @@ public sealed class Binder var localFunc = localFuncs[0]; - var type = new NubFuncType(localFunc.Signature.ReturnType, localFunc.Signature.Parameters.Select(p => p.Type).ToList()); + var returnType = BindType(localFunc.Signature.ReturnType); + var parameterTypes = localFunc.Signature.Parameters.Select(p => BindType(p.Type)).ToList(); + var type = new NubFuncType(parameterTypes, returnType); return new BoundLocalFuncIdent(expression.Tokens, type, @namespace, expression.Name); } @@ -348,7 +352,9 @@ public sealed class Binder var externFunc = externFuncs[0]; - var type = new NubFuncType(externFunc.Signature.ReturnType, externFunc.Signature.Parameters.Select(p => p.Type).ToList()); + var returnType = BindType(externFunc.Signature.ReturnType); + var parameterTypes = externFunc.Signature.Parameters.Select(p => BindType(p.Type)).ToList(); + var type = new NubFuncType(parameterTypes, returnType); return new BoundExternFuncIdent(expression.Tokens, type, @namespace, expression.Name); } @@ -382,19 +388,21 @@ public sealed class Binder { var boundExpression = BindExpression(expression.Target); - var traitFuncImpls = _definitionTable.LookupTraitFuncImpl(boundExpression.Type, expression.Member).ToArray(); - if (traitFuncImpls.Length > 0) - { - if (traitFuncImpls.Length > 1) - { - throw new BindException(Diagnostic.Error($"Type {boundExpression.Type} implements multiple traits with the function {expression.Member}").Build()); - } - - var impl = traitFuncImpls[0]; - - var type = new NubFuncType(impl.Signature.ReturnType, impl.Signature.Parameters.Select(p => p.Type).ToList()); - return new BoundTraitImplFuncAccess(expression.Tokens, type, boundExpression, expression.Member); - } + // var traitFuncImpls = _definitionTable.LookupTraitFuncImpl(boundExpression.Type, expression.Member).ToArray(); + // if (traitFuncImpls.Length > 0) + // { + // if (traitFuncImpls.Length > 1) + // { + // throw new BindException(Diagnostic.Error($"Type {boundExpression.Type} implements multiple traits with the function {expression.Member}").Build()); + // } + // + // var impl = traitFuncImpls[0]; + // + // var returnType = BindType(impl.Signature.ReturnType); + // var parameterTypes = impl.Signature.Parameters.Select(p => BindType(p.Type)).ToList(); + // var type = new NubFuncType(parameterTypes, returnType); + // return new BoundTraitImplFuncAccess(expression.Tokens, type, boundExpression, expression.Member); + // } if (boundExpression.Type is NubCustomType customType) { @@ -418,7 +426,9 @@ public sealed class Binder var traitFunc = traitFuncs[0]; - var type = new NubFuncType(traitFunc.Signature.ReturnType, traitFunc.Signature.Parameters.Select(p => p.Type).ToList()); + var returnType = BindType(traitFunc.Signature.ReturnType); + var parameterTypes = traitFunc.Signature.Parameters.Select(p => BindType(p.Type)).ToList(); + var type = new NubFuncType(parameterTypes, returnType); return new BoundTraitFuncAccess(expression.Tokens, type, customType, boundExpression, expression.Member); } } @@ -443,7 +453,7 @@ public sealed class Binder var field = fields[0]; - return new BoundStructFieldAccess(expression.Tokens, field.Type, customType, boundExpression, expression.Member); + return new BoundStructFieldAccess(expression.Tokens, BindType(field.Type), customType, boundExpression, expression.Member); } } } @@ -453,7 +463,7 @@ public sealed class Binder private BoundStructInitializer BindStructInitializer(StructInitializerSyntax expression) { - if (expression.StructType is not NubCustomType structType) + if (expression.StructType is not CustomTypeSyntax structType) { throw new BindException(Diagnostic.Error($"Cannot initialize non-struct type {expression.StructType}").Build()); } @@ -488,10 +498,10 @@ public sealed class Binder throw new BindException(Diagnostic.Error($"Struct {structType} has multiple fields with the name {field}").Build()); } - initializers[field] = BindExpression(initializer, fields[0].Type); + initializers[field] = BindExpression(initializer, BindType(fields[0].Type)); } - return new BoundStructInitializer(expression.Tokens, structType, initializers); + return new BoundStructInitializer(expression.Tokens, (NubCustomType)BindType(structType), initializers); } private BoundUnaryExpression BindUnaryExpression(UnaryExpressionSyntax expression) @@ -536,10 +546,10 @@ public sealed class Binder foreach (var parameter in node.Parameters) { - parameters.Add(new BoundFuncParameter(parameter.Tokens, parameter.Name, parameter.Type)); + parameters.Add(new BoundFuncParameter(parameter.Tokens, parameter.Name, BindType(parameter.Type))); } - return new BoundFuncSignature(node.Tokens, parameters, node.ReturnType); + return new BoundFuncSignature(node.Tokens, parameters, BindType(node.ReturnType)); } private BoundBinaryOperator BindBinaryOperator(BinaryOperator op) @@ -600,6 +610,37 @@ public sealed class Binder _funcReturnTypes.Pop(); return body; } + + private NubType BindType(TypeSyntax node) + { + return node switch + { + ArrayTypeSyntax type => new NubArrayType(BindType(type.BaseType)), + CStringTypeSyntax => new NubCStringType(), + CustomTypeSyntax type => new NubCustomType(type.Namespace, type.Name), + FuncTypeSyntax type => new NubFuncType(type.Parameters.Select(BindType).ToList(), BindType(type.ReturnType)), + PointerTypeSyntax type => new NubPointerType(BindType(type.BaseType)), + PrimitiveTypeSyntax type => new NubPrimitiveType(type.SyntaxKind switch + { + PrimitiveTypeSyntaxKind.I64 => PrimitiveTypeKind.I64, + PrimitiveTypeSyntaxKind.I32 => PrimitiveTypeKind.I32, + PrimitiveTypeSyntaxKind.I16 => PrimitiveTypeKind.I16, + PrimitiveTypeSyntaxKind.I8 => PrimitiveTypeKind.I8, + PrimitiveTypeSyntaxKind.U64 => PrimitiveTypeKind.U64, + PrimitiveTypeSyntaxKind.U32 => PrimitiveTypeKind.U32, + PrimitiveTypeSyntaxKind.U16 => PrimitiveTypeKind.U16, + PrimitiveTypeSyntaxKind.U8 => PrimitiveTypeKind.U8, + PrimitiveTypeSyntaxKind.F64 => PrimitiveTypeKind.F64, + PrimitiveTypeSyntaxKind.F32 => PrimitiveTypeKind.F32, + PrimitiveTypeSyntaxKind.Bool => PrimitiveTypeKind.Bool, + _ => throw new ArgumentOutOfRangeException() + }), + StringTypeSyntax => new NubStringType(), + TemplateTypeSyntax templateTypeSyntax => throw new NotImplementedException(), + VoidTypeSyntax => new NubVoidType(), + _ => throw new ArgumentOutOfRangeException(nameof(node)) + }; + } } public record Variable(string Name, NubType Type); diff --git a/src/compiler/NubLang/Syntax/Binding/DefinitionTable.cs b/src/compiler/NubLang/Syntax/Binding/DefinitionTable.cs index fb2fc21..5d14b03 100644 --- a/src/compiler/NubLang/Syntax/Binding/DefinitionTable.cs +++ b/src/compiler/NubLang/Syntax/Binding/DefinitionTable.cs @@ -37,14 +37,14 @@ public class DefinitionTable return structNode.Fields.Where(x => x.Name == field); } - public IEnumerable LookupTraitFuncImpl(NubType forType, string name) - { - return _definitions - .OfType() - .Where(x => x.ForType == forType) - .SelectMany(x => x.Functions) - .Where(x => x.Name == name); - } + // public IEnumerable LookupTraitFuncImpl(NubType forType, string name) + // { + // return _definitions + // .OfType() + // .Where(x => x.ForType == forType) + // .SelectMany(x => x.Functions) + // .Where(x => x.Name == name); + // } public IEnumerable LookupTrait(string @namespace, string name) { diff --git a/src/compiler/NubLang/Syntax/Binding/NubType.cs b/src/compiler/NubLang/Syntax/Binding/NubType.cs index 48dff79..f40805a 100644 --- a/src/compiler/NubLang/Syntax/Binding/NubType.cs +++ b/src/compiler/NubLang/Syntax/Binding/NubType.cs @@ -95,9 +95,9 @@ public abstract class NubSimpleType : NubType #region Simple types -public class NubFuncType(NubType returnType, List parameters) : NubSimpleType +public class NubFuncType(List parameters, NubType returnType) : NubSimpleType { - public List Parameters { get; } = parameters; + public IReadOnlyList Parameters { get; } = parameters; public NubType ReturnType { get; } = returnType; public override StorageSize StorageSize => StorageSize.U64; diff --git a/src/compiler/NubLang/Syntax/Parsing/Parser.cs b/src/compiler/NubLang/Syntax/Parsing/Parser.cs index cde4229..ac83f8e 100644 --- a/src/compiler/NubLang/Syntax/Parsing/Parser.cs +++ b/src/compiler/NubLang/Syntax/Parsing/Parser.cs @@ -118,7 +118,7 @@ public sealed class Parser } } - var returnType = TryExpectSymbol(Symbol.Colon) ? ParseType() : new VoidTypeSyntax([Peek().GetValue()]); + var returnType = TryExpectSymbol(Symbol.Colon) ? ParseType() : new VoidTypeSyntax([GetTokens(startIndex).Last()]); return new FuncSignatureSyntax(GetTokens(startIndex), parameters, returnType); }