Binder almost complete

This commit is contained in:
nub31
2025-06-22 20:22:01 +02:00
parent 23239405e4
commit c90645f751

View File

@@ -1,6 +1,7 @@
using Common; using Common;
using Syntax.Parsing; using Syntax.Parsing;
using Syntax.Parsing.Node; using Syntax.Parsing.Node;
using Syntax.Tokenization;
using Syntax.Typing.BoundNode; using Syntax.Typing.BoundNode;
using UnaryExpressionNode = Syntax.Parsing.Node.UnaryExpressionNode; using UnaryExpressionNode = Syntax.Parsing.Node.UnaryExpressionNode;
@@ -10,6 +11,7 @@ public static class Binder
{ {
private static SyntaxTree _syntaxTree = null!; private static SyntaxTree _syntaxTree = null!;
private static DefinitionTable _definitionTable = null!; private static DefinitionTable _definitionTable = null!;
private static NubType? _funcReturnType = null;
private static Dictionary<string, NubType> _variables = new(); private static Dictionary<string, NubType> _variables = new();
@@ -17,6 +19,9 @@ public static class Binder
{ {
_syntaxTree = syntaxTree; _syntaxTree = syntaxTree;
_definitionTable = definitionTable; _definitionTable = definitionTable;
_variables = [];
var definitions = new List<BoundDefinitionNode>(); var definitions = new List<BoundDefinitionNode>();
foreach (var definition in syntaxTree.Definitions) foreach (var definition in syntaxTree.Definitions)
@@ -40,6 +45,12 @@ public static class Binder
private static BoundStructDefinitionNode BindStruct(StructDefinitionNode node) private static BoundStructDefinitionNode BindStruct(StructDefinitionNode node)
{ {
var defOpt = _definitionTable.LookupStruct(node.Namespace, node.Name);
if (!defOpt.TryGetValue(out var definition))
{
throw new NotImplementedException("Diagnostics not implemented");
}
var structFields = new List<BoundStructField>(); var structFields = new List<BoundStructField>();
foreach (var structField in node.Fields) foreach (var structField in node.Fields)
@@ -48,7 +59,13 @@ public static class Binder
if (structField.Value.HasValue) if (structField.Value.HasValue)
{ {
value = BindExpression(structField.Value.Value); var definitionField = definition.Fields.FirstOrDefault(f => f.Name == structField.Name);
if (definitionField == null)
{
throw new NotImplementedException("Diagnostics not implemented");
}
value = BindExpression(structField.Value.Value, definitionField.Type);
} }
structFields.Add(new BoundStructField(structField.Name, structField.Type, value)); structFields.Add(new BoundStructField(structField.Name, structField.Type, value));
@@ -72,6 +89,7 @@ public static class Binder
private static BoundLocalFuncDefinitionNode BindLocalFuncDefinition(LocalFuncDefinitionNode node) private static BoundLocalFuncDefinitionNode BindLocalFuncDefinition(LocalFuncDefinitionNode node)
{ {
_variables.Clear(); _variables.Clear();
_funcReturnType = node.ReturnType;
var parameters = new List<BoundFuncParameter>(); var parameters = new List<BoundFuncParameter>();
@@ -119,7 +137,9 @@ public static class Binder
private static BoundArrayIndexAssignmentNode BindArrayIndex(ArrayIndexAssignmentNode statement) private static BoundArrayIndexAssignmentNode BindArrayIndex(ArrayIndexAssignmentNode statement)
{ {
return new BoundArrayIndexAssignmentNode(statement.Tokens, BindArrayIndexAccess(statement.ArrayIndexAccess), BindExpression(statement.Value)); var boundArrayIndex = BindArrayIndexAccess(statement.ArrayIndexAccess);
var elementType = ((NubArrayType)boundArrayIndex.Type).ElementType;
return new BoundArrayIndexAssignmentNode(statement.Tokens, boundArrayIndex, BindExpression(statement.Value, elementType));
} }
private static BoundBreakNode BindBreak(BreakNode statement) private static BoundBreakNode BindBreak(BreakNode statement)
@@ -134,7 +154,9 @@ public static class Binder
private static BoundDereferenceAssignmentNode BindDereferenceAssignment(DereferenceAssignmentNode statement) private static BoundDereferenceAssignmentNode BindDereferenceAssignment(DereferenceAssignmentNode statement)
{ {
return new BoundDereferenceAssignmentNode(statement.Tokens, BindDereference(statement.Dereference), BindExpression(statement.Value)); var boundDereference = BindDereference(statement.Dereference);
var dereferenceBaseType = ((NubPointerType)boundDereference.Type).BaseType;
return new BoundDereferenceAssignmentNode(statement.Tokens, boundDereference, BindExpression(statement.Value, dereferenceBaseType));
} }
private static BoundIfNode BindIf(IfNode statement) private static BoundIfNode BindIf(IfNode statement)
@@ -150,12 +172,14 @@ public static class Binder
); );
} }
return new BoundIfNode(statement.Tokens, BindExpression(statement.Condition), BindBlock(statement.Body), elseStatement); return new BoundIfNode(statement.Tokens, BindExpression(statement.Condition, NubPrimitiveType.Bool), BindBlock(statement.Body), elseStatement);
} }
private static BoundMemberAssignmentNode BindMemberAssignment(MemberAssignmentNode statement) private static BoundMemberAssignmentNode BindMemberAssignment(MemberAssignmentNode statement)
{ {
return new BoundMemberAssignmentNode(statement.Tokens, BindMemberAccess(statement.MemberAccess), BindExpression(statement.Value)); var boundMemberAccess = BindMemberAccess(statement.MemberAccess);
var elementType = ((NubArrayType)boundMemberAccess.Type).ElementType;
return new BoundMemberAssignmentNode(statement.Tokens, boundMemberAccess, BindExpression(statement.Value, elementType));
} }
private static BoundReturnNode BindReturn(ReturnNode statement) private static BoundReturnNode BindReturn(ReturnNode statement)
@@ -164,7 +188,7 @@ public static class Binder
if (statement.Value.HasValue) if (statement.Value.HasValue)
{ {
value = BindExpression(statement.Value.Value); value = BindExpression(statement.Value.Value, _funcReturnType);
} }
return new BoundReturnNode(statement.Tokens, value); return new BoundReturnNode(statement.Tokens, value);
@@ -177,7 +201,8 @@ public static class Binder
private static BoundVariableAssignmentNode BindVariableAssignment(VariableAssignmentNode statement) private static BoundVariableAssignmentNode BindVariableAssignment(VariableAssignmentNode statement)
{ {
return new BoundVariableAssignmentNode(statement.Tokens, BindIdentifier(statement.Identifier), BindExpression(statement.Value)); var variableType = _variables[statement.Identifier.Name];
return new BoundVariableAssignmentNode(statement.Tokens, BindIdentifier(statement.Identifier), BindExpression(statement.Value, variableType));
} }
private static BoundVariableDeclarationNode BindVariableDeclaration(VariableDeclarationNode statement) private static BoundVariableDeclarationNode BindVariableDeclaration(VariableDeclarationNode statement)
@@ -188,10 +213,10 @@ public static class Binder
private static BoundWhileNode BindWhile(WhileNode statement) private static BoundWhileNode BindWhile(WhileNode statement)
{ {
return new BoundWhileNode(statement.Tokens, BindExpression(statement.Condition), BindBlock(statement.Body)); return new BoundWhileNode(statement.Tokens, BindExpression(statement.Condition, NubPrimitiveType.Bool), BindBlock(statement.Body));
} }
private static BoundExpressionNode BindExpression(ExpressionNode node) private static BoundExpressionNode BindExpression(ExpressionNode node, NubType? expectedType = null)
{ {
return node switch return node switch
{ {
@@ -204,7 +229,7 @@ public static class Binder
FixedArrayInitializerNode expression => BindFixedArrayInitializer(expression), FixedArrayInitializerNode expression => BindFixedArrayInitializer(expression),
FuncCallNode expression => BindFuncCall(expression), FuncCallNode expression => BindFuncCall(expression),
IdentifierNode expression => BindIdentifier(expression), IdentifierNode expression => BindIdentifier(expression),
LiteralNode expression => BindLiteral(expression), LiteralNode expression => BindLiteral(expression, expectedType),
MemberAccessNode expression => BindMemberAccess(expression), MemberAccessNode expression => BindMemberAccess(expression),
StructInitializerNode expression => BindStructInitializer(expression), StructInitializerNode expression => BindStructInitializer(expression),
UnaryExpressionNode expression => BindUnaryExpression(expression), UnaryExpressionNode expression => BindUnaryExpression(expression),
@@ -239,18 +264,18 @@ public static class Binder
{ {
var boundArray = BindExpression(expression.Array); var boundArray = BindExpression(expression.Array);
var elementType = ((NubArrayType)boundArray.Type).ElementType; var elementType = ((NubArrayType)boundArray.Type).ElementType;
return new BoundArrayIndexAccessNode(expression.Tokens, elementType, boundArray, BindExpression(expression.Index)); return new BoundArrayIndexAccessNode(expression.Tokens, elementType, boundArray, BindExpression(expression.Index, NubPrimitiveType.U64));
} }
private static BoundArrayInitializerNode BindArrayInitializer(ArrayInitializerNode expression) private static BoundArrayInitializerNode BindArrayInitializer(ArrayInitializerNode expression)
{ {
return new BoundArrayInitializerNode(expression.Tokens, new NubArrayType(expression.ElementType), BindExpression(expression.Capacity), expression.ElementType); return new BoundArrayInitializerNode(expression.Tokens, new NubArrayType(expression.ElementType), BindExpression(expression.Capacity, NubPrimitiveType.U64), expression.ElementType);
} }
private static BoundBinaryExpressionNode BindBinaryExpression(BinaryExpressionNode expression) private static BoundBinaryExpressionNode BindBinaryExpression(BinaryExpressionNode expression)
{ {
var boundLeft = BindExpression(expression.Left); var boundLeft = BindExpression(expression.Left);
var boundRight = BindExpression(expression.Right); var boundRight = BindExpression(expression.Right, boundLeft.Type);
return new BoundBinaryExpressionNode(expression.Tokens, boundLeft.Type, boundLeft, expression.Operator, boundRight); return new BoundBinaryExpressionNode(expression.Tokens, boundLeft.Type, boundLeft, expression.Operator, boundRight);
} }
@@ -270,13 +295,21 @@ public static class Binder
{ {
var boundExpression = BindExpression(expression.Expression); var boundExpression = BindExpression(expression.Expression);
var funcType = (NubFuncType)boundExpression.Type;
var returnType = ((NubFuncType)boundExpression.Type).ReturnType; var returnType = ((NubFuncType)boundExpression.Type).ReturnType;
var parameters = new List<BoundExpressionNode>(); var parameters = new List<BoundExpressionNode>();
foreach (var parameter in expression.Parameters) foreach (var (i, parameter) in expression.Parameters.Index())
{ {
parameters.Add(BindExpression(parameter)); if (i >= funcType.Parameters.Count)
{
throw new NotImplementedException("Diagnostics not implemented");
}
var expectedType = funcType.Parameters[i];
parameters.Add(BindExpression(parameter, expectedType));
} }
return new BoundFuncCallNode(expression.Tokens, returnType, boundExpression, parameters); return new BoundFuncCallNode(expression.Tokens, returnType, boundExpression, parameters);
@@ -305,9 +338,18 @@ public static class Binder
return new BoundIdentifierNode(expression.Tokens, type, expression.Namespace, expression.Name); return new BoundIdentifierNode(expression.Tokens, type, expression.Namespace, expression.Name);
} }
private static BoundLiteralNode BindLiteral(LiteralNode expression) private static BoundLiteralNode BindLiteral(LiteralNode expression, NubType? expectedType = null)
{ {
throw new NotImplementedException("Literal requires context"); var type = expectedType ?? expression.Kind switch
{
LiteralKind.Integer => NubPrimitiveType.I64,
LiteralKind.Float => NubPrimitiveType.F64,
LiteralKind.String => new NubCStringType(),
LiteralKind.Bool => NubPrimitiveType.Bool,
_ => throw new ArgumentOutOfRangeException()
};
return new BoundLiteralNode(expression.Tokens, type, expression.Literal, expression.Kind);
} }
private static BoundMemberAccessNode BindMemberAccess(MemberAccessNode expression) private static BoundMemberAccessNode BindMemberAccess(MemberAccessNode expression)
@@ -356,11 +398,23 @@ public static class Binder
private static BoundStructInitializerNode BindStructInitializer(StructInitializerNode expression) private static BoundStructInitializerNode BindStructInitializer(StructInitializerNode expression)
{ {
var defOpt = _definitionTable.LookupStruct(expression.StructType.Namespace, expression.StructType.Name);
if (!defOpt.TryGetValue(out var definition))
{
throw new NotImplementedException("Diagnostics not implemented");
}
var initializers = new Dictionary<string, BoundExpressionNode>(); var initializers = new Dictionary<string, BoundExpressionNode>();
foreach (var (member, initializer) in expression.Initializers) foreach (var (member, initializer) in expression.Initializers)
{ {
initializers[member] = BindExpression(initializer); var definitionField = definition.Fields.FirstOrDefault(x => x.Name == member);
if (definitionField == null)
{
throw new NotImplementedException("Diagnostics not implemented");
}
initializers[member] = BindExpression(initializer, definitionField.Type);
} }
return new BoundStructInitializerNode(expression.Tokens, expression.StructType, expression.StructType, initializers); return new BoundStructInitializerNode(expression.Tokens, expression.StructType, expression.StructType, initializers);
@@ -376,6 +430,8 @@ public static class Binder
{ {
case UnaryExpressionOperator.Negate: case UnaryExpressionOperator.Negate:
{ {
boundOperand = BindExpression(expression.Operand, NubPrimitiveType.I64);
if (boundOperand.Type.IsNumber) if (boundOperand.Type.IsNumber)
{ {
type = boundOperand.Type; type = boundOperand.Type;
@@ -385,6 +441,8 @@ public static class Binder
} }
case UnaryExpressionOperator.Invert: case UnaryExpressionOperator.Invert:
{ {
boundOperand = BindExpression(expression.Operand, NubPrimitiveType.Bool);
type = new NubPrimitiveType(PrimitiveTypeKind.Bool); type = new NubPrimitiveType(PrimitiveTypeKind.Bool);
break; break;
} }