bound types

This commit is contained in:
nub31
2025-07-09 20:44:20 +02:00
parent a0b7b9026c
commit 8a5dd88446
4 changed files with 80 additions and 39 deletions

View File

@@ -70,7 +70,7 @@ public sealed class Binder
functions.Add(new BoundTraitFuncImpl(func.Tokens, func.Name, signature, body)); 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) private BoundTrait BindTraitDefinition(TraitSyntax node)
@@ -95,10 +95,10 @@ public sealed class Binder
if (field.Value.HasValue) 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); return new BoundStruct(node.Tokens, node.Namespace, node.Name, structFields);
@@ -189,7 +189,7 @@ public sealed class Binder
if (statement.ExplicitType.HasValue) if (statement.ExplicitType.HasValue)
{ {
type = statement.ExplicitType.Value; type = BindType(statement.ExplicitType.Value);
} }
var assignment = Optional<BoundExpression>.Empty(); var assignment = Optional<BoundExpression>.Empty();
@@ -269,7 +269,7 @@ public sealed class Binder
var body = BindFuncBody(expression.Body, funcType.ReturnType, parameters); 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) private BoundArrayIndexAccess BindArrayIndexAccess(ArrayIndexAccessSyntax expression)
@@ -281,7 +281,9 @@ public sealed class Binder
private BoundArrayInitializer BindArrayInitializer(ArrayInitializerSyntax expression) 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) private BoundBinaryExpression BindBinaryExpression(BinaryExpressionSyntax expression)
@@ -334,7 +336,9 @@ public sealed class Binder
var localFunc = localFuncs[0]; 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); return new BoundLocalFuncIdent(expression.Tokens, type, @namespace, expression.Name);
} }
@@ -348,7 +352,9 @@ public sealed class Binder
var externFunc = externFuncs[0]; 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); return new BoundExternFuncIdent(expression.Tokens, type, @namespace, expression.Name);
} }
@@ -382,19 +388,21 @@ public sealed class Binder
{ {
var boundExpression = BindExpression(expression.Target); var boundExpression = BindExpression(expression.Target);
var traitFuncImpls = _definitionTable.LookupTraitFuncImpl(boundExpression.Type, expression.Member).ToArray(); // var traitFuncImpls = _definitionTable.LookupTraitFuncImpl(boundExpression.Type, expression.Member).ToArray();
if (traitFuncImpls.Length > 0) // if (traitFuncImpls.Length > 0)
{ // {
if (traitFuncImpls.Length > 1) // if (traitFuncImpls.Length > 1)
{ // {
throw new BindException(Diagnostic.Error($"Type {boundExpression.Type} implements multiple traits with the function {expression.Member}").Build()); // throw new BindException(Diagnostic.Error($"Type {boundExpression.Type} implements multiple traits with the function {expression.Member}").Build());
} // }
//
var impl = traitFuncImpls[0]; // var impl = traitFuncImpls[0];
//
var type = new NubFuncType(impl.Signature.ReturnType, impl.Signature.Parameters.Select(p => p.Type).ToList()); // var returnType = BindType(impl.Signature.ReturnType);
return new BoundTraitImplFuncAccess(expression.Tokens, type, boundExpression, expression.Member); // 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) if (boundExpression.Type is NubCustomType customType)
{ {
@@ -418,7 +426,9 @@ public sealed class Binder
var traitFunc = traitFuncs[0]; 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); return new BoundTraitFuncAccess(expression.Tokens, type, customType, boundExpression, expression.Member);
} }
} }
@@ -443,7 +453,7 @@ public sealed class Binder
var field = fields[0]; 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) 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()); 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()); 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) private BoundUnaryExpression BindUnaryExpression(UnaryExpressionSyntax expression)
@@ -536,10 +546,10 @@ public sealed class Binder
foreach (var parameter in node.Parameters) 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) private BoundBinaryOperator BindBinaryOperator(BinaryOperator op)
@@ -600,6 +610,37 @@ public sealed class Binder
_funcReturnTypes.Pop(); _funcReturnTypes.Pop();
return body; 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); public record Variable(string Name, NubType Type);

View File

@@ -37,14 +37,14 @@ public class DefinitionTable
return structNode.Fields.Where(x => x.Name == field); return structNode.Fields.Where(x => x.Name == field);
} }
public IEnumerable<TraitFuncImplSyntax> LookupTraitFuncImpl(NubType forType, string name) // public IEnumerable<TraitFuncImplSyntax> LookupTraitFuncImpl(NubType forType, string name)
{ // {
return _definitions // return _definitions
.OfType<TraitImplSyntax>() // .OfType<TraitImplSyntax>()
.Where(x => x.ForType == forType) // .Where(x => x.ForType == forType)
.SelectMany(x => x.Functions) // .SelectMany(x => x.Functions)
.Where(x => x.Name == name); // .Where(x => x.Name == name);
} // }
public IEnumerable<TraitSyntax> LookupTrait(string @namespace, string name) public IEnumerable<TraitSyntax> LookupTrait(string @namespace, string name)
{ {

View File

@@ -95,9 +95,9 @@ public abstract class NubSimpleType : NubType
#region Simple types #region Simple types
public class NubFuncType(NubType returnType, List<NubType> parameters) : NubSimpleType public class NubFuncType(List<NubType> parameters, NubType returnType) : NubSimpleType
{ {
public List<NubType> Parameters { get; } = parameters; public IReadOnlyList<NubType> Parameters { get; } = parameters;
public NubType ReturnType { get; } = returnType; public NubType ReturnType { get; } = returnType;
public override StorageSize StorageSize => StorageSize.U64; public override StorageSize StorageSize => StorageSize.U64;

View File

@@ -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); return new FuncSignatureSyntax(GetTokens(startIndex), parameters, returnType);
} }