|
|
|
@@ -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);
|
|
|
|
|