bound types

This commit is contained in:
nub31
2025-07-09 20:44:20 +02:00
parent 652c644e36
commit 44665654c8
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));
}
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<BoundExpression>.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);

View File

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

View File

@@ -95,9 +95,9 @@ public abstract class NubSimpleType : NubType
#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 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);
}