...
This commit is contained in:
@@ -5,7 +5,6 @@ using Syntax.Typing;
|
||||
namespace Syntax.Parsing.Node;
|
||||
|
||||
public abstract record ExpressionNode(IEnumerable<Token> Tokens) : Node(Tokens);
|
||||
public abstract record LValueNode(IEnumerable<Token> Tokens) : ExpressionNode(Tokens);
|
||||
|
||||
public record BinaryExpressionNode(IEnumerable<Token> Tokens, ExpressionNode Left, BinaryExpressionOperator Operator, ExpressionNode Right) : ExpressionNode(Tokens);
|
||||
|
||||
@@ -32,13 +31,12 @@ public enum UnaryExpressionOperator
|
||||
}
|
||||
|
||||
public record FuncCallNode(IEnumerable<Token> Tokens, ExpressionNode Expression, List<ExpressionNode> Parameters) : ExpressionNode(Tokens);
|
||||
public record IdentifierNode(IEnumerable<Token> Tokens, Optional<string> Namespace, string Name) : LValueNode(Tokens);
|
||||
public record IdentifierNode(IEnumerable<Token> Tokens, Optional<string> Namespace, string Name) : ExpressionNode(Tokens);
|
||||
public record ArrayInitializerNode(IEnumerable<Token> Tokens, ExpressionNode Capacity, NubType ElementType) : ExpressionNode(Tokens);
|
||||
public record ArrayIndexAccessNode(IEnumerable<Token> Tokens, ExpressionNode Array, ExpressionNode Index) : LValueNode(Tokens);
|
||||
public record ArrayIndexAccessNode(IEnumerable<Token> Tokens, ExpressionNode Array, ExpressionNode Index) : ExpressionNode(Tokens);
|
||||
public record AnonymousFuncNode(IEnumerable<Token> Tokens, List<FuncParameter> Parameters, BlockNode Body, NubType ReturnType) : ExpressionNode(Tokens);
|
||||
public record AddressOfNode(IEnumerable<Token> Tokens, LValueNode Expression) : ExpressionNode(Tokens);
|
||||
public record FixedArrayInitializerNode(IEnumerable<Token> Tokens, NubType ElementType, int Capacity) : ExpressionNode(Tokens);
|
||||
public record AddressOfNode(IEnumerable<Token> Tokens, ExpressionNode Expression) : ExpressionNode(Tokens);
|
||||
public record LiteralNode(IEnumerable<Token> Tokens, string Literal, LiteralKind Kind) : ExpressionNode(Tokens);
|
||||
public record MemberAccessNode(IEnumerable<Token> Tokens, ExpressionNode Expression, string Member) : ExpressionNode(Tokens);
|
||||
public record StructInitializerNode(IEnumerable<Token> Tokens, NubStructType StructType, Dictionary<string, ExpressionNode> Initializers) : ExpressionNode(Tokens);
|
||||
public record DereferenceNode(IEnumerable<Token> Tokens, ExpressionNode Expression) : LValueNode(Tokens);
|
||||
public record DereferenceNode(IEnumerable<Token> Tokens, ExpressionNode Expression) : ExpressionNode(Tokens);
|
||||
|
||||
@@ -7,12 +7,9 @@ namespace Syntax.Parsing.Node;
|
||||
public record StatementNode(IEnumerable<Token> Tokens) : Node(Tokens);
|
||||
public record StatementExpressionNode(IEnumerable<Token> Tokens, ExpressionNode Expression) : StatementNode(Tokens);
|
||||
public record ReturnNode(IEnumerable<Token> Tokens, Optional<ExpressionNode> Value) : StatementNode(Tokens);
|
||||
public record MemberAssignmentNode(IEnumerable<Token> Tokens, MemberAccessNode MemberAccess, ExpressionNode Value) : StatementNode(Tokens);
|
||||
public record AssignmentNode(IEnumerable<Token> Tokens, ExpressionNode Expression, ExpressionNode Value) : StatementNode(Tokens);
|
||||
public record IfNode(IEnumerable<Token> Tokens, ExpressionNode Condition, BlockNode Body, Optional<Variant<IfNode, BlockNode>> Else) : StatementNode(Tokens);
|
||||
public record DereferenceAssignmentNode(IEnumerable<Token> Tokens, DereferenceNode Dereference, ExpressionNode Value) : StatementNode(Tokens);
|
||||
public record VariableAssignmentNode(IEnumerable<Token> Tokens, IdentifierNode Identifier, ExpressionNode Value) : StatementNode(Tokens);
|
||||
public record VariableDeclarationNode(IEnumerable<Token> Tokens, string Name, NubType Type) : StatementNode(Tokens);
|
||||
public record ContinueNode(IEnumerable<Token> Tokens) : StatementNode(Tokens);
|
||||
public record BreakNode(IEnumerable<Token> Tokens) : StatementNode(Tokens);
|
||||
public record ArrayIndexAssignmentNode(IEnumerable<Token> Tokens, ArrayIndexAccessNode ArrayIndexAccess, ExpressionNode Value) : StatementNode(Tokens);
|
||||
public record WhileNode(IEnumerable<Token> Tokens, ExpressionNode Condition, BlockNode Body) : StatementNode(Tokens);
|
||||
|
||||
@@ -222,46 +222,10 @@ public static class Parser
|
||||
{
|
||||
var expr = ParseExpression();
|
||||
|
||||
if (Peek().TryGetValue(out var token))
|
||||
if (TryExpectSymbol(Symbol.Assign))
|
||||
{
|
||||
if (token is SymbolToken symbol)
|
||||
{
|
||||
switch (symbol.Symbol)
|
||||
{
|
||||
case Symbol.Assign:
|
||||
{
|
||||
switch (expr)
|
||||
{
|
||||
case MemberAccessNode memberAccess:
|
||||
{
|
||||
Next();
|
||||
var value = ParseExpression();
|
||||
return new MemberAssignmentNode(GetTokensForNode(startIndex), memberAccess, value);
|
||||
}
|
||||
case ArrayIndexAccessNode arrayIndexAccess:
|
||||
{
|
||||
Next();
|
||||
var value = ParseExpression();
|
||||
return new ArrayIndexAssignmentNode(GetTokensForNode(startIndex), arrayIndexAccess, value);
|
||||
}
|
||||
case IdentifierNode identifier:
|
||||
{
|
||||
Next();
|
||||
var value = ParseExpression();
|
||||
return new VariableAssignmentNode(GetTokensForNode(startIndex), identifier, value);
|
||||
}
|
||||
case DereferenceNode dereference:
|
||||
{
|
||||
Next();
|
||||
var value = ParseExpression();
|
||||
return new DereferenceAssignmentNode(GetTokensForNode(startIndex), dereference, value);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
var value = ParseExpression();
|
||||
return new AssignmentNode(GetTokensForNode(startIndex), expr, value);
|
||||
}
|
||||
|
||||
return new StatementExpressionNode(GetTokensForNode(startIndex), expr);
|
||||
@@ -471,20 +435,6 @@ public static class Parser
|
||||
expr = expression;
|
||||
break;
|
||||
}
|
||||
case Symbol.Ampersand:
|
||||
{
|
||||
var expression = ParsePrimaryExpression();
|
||||
if (expression is not LValueNode lValue)
|
||||
{
|
||||
throw new ParseException(Diagnostic
|
||||
.Error("& symbol can only be used on lvalues")
|
||||
.At(expression)
|
||||
.Build());
|
||||
}
|
||||
|
||||
expr = new AddressOfNode(GetTokensForNode(startIndex), lValue);
|
||||
break;
|
||||
}
|
||||
case Symbol.Minus:
|
||||
{
|
||||
var expression = ParsePrimaryExpression();
|
||||
@@ -499,35 +449,10 @@ public static class Parser
|
||||
}
|
||||
case Symbol.OpenBracket:
|
||||
{
|
||||
if (Peek().TryGetValue(out var capacityToken) && capacityToken is LiteralToken { Kind: LiteralKind.Integer } literalToken)
|
||||
{
|
||||
var capacity = int.Parse(literalToken.Value);
|
||||
Next();
|
||||
ExpectSymbol(Symbol.CloseBracket);
|
||||
var elementType = ParseType();
|
||||
|
||||
if (capacity > 0)
|
||||
{
|
||||
expr = new FixedArrayInitializerNode(GetTokensForNode(startIndex), elementType, capacity);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new ParseException(Diagnostic
|
||||
.Error("Fixed array size must be a positive integer")
|
||||
.WithHelp("Use a positive integer literal for the array size")
|
||||
.At(literalToken)
|
||||
.Build());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var capacity = ParseExpression();
|
||||
ExpectSymbol(Symbol.CloseBracket);
|
||||
var type = ParseType();
|
||||
|
||||
expr = new ArrayInitializerNode(GetTokensForNode(startIndex), capacity, type);
|
||||
}
|
||||
|
||||
var capacity = ParseExpression();
|
||||
ExpectSymbol(Symbol.CloseBracket);
|
||||
var type = ParseType();
|
||||
expr = new ArrayInitializerNode(GetTokensForNode(startIndex), capacity, type);
|
||||
break;
|
||||
}
|
||||
case Symbol.Alloc:
|
||||
@@ -583,6 +508,12 @@ public static class Parser
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
if (TryExpectSymbol(Symbol.Ampersand))
|
||||
{
|
||||
expr = new AddressOfNode(GetTokensForNode(startIndex), expr);
|
||||
break;
|
||||
}
|
||||
|
||||
if (TryExpectSymbol(Symbol.Caret))
|
||||
{
|
||||
expr = new DereferenceNode(GetTokensForNode(startIndex), expr);
|
||||
|
||||
@@ -124,26 +124,23 @@ public static class Binder
|
||||
{
|
||||
return node switch
|
||||
{
|
||||
ArrayIndexAssignmentNode statement => BindArrayIndex(statement),
|
||||
AssignmentNode statement => BindAssignment(statement),
|
||||
BreakNode statement => BindBreak(statement),
|
||||
ContinueNode statement => BindContinue(statement),
|
||||
DereferenceAssignmentNode statement => BindDereferenceAssignment(statement),
|
||||
IfNode statement => BindIf(statement),
|
||||
MemberAssignmentNode statement => BindMemberAssignment(statement),
|
||||
ReturnNode statement => BindReturn(statement),
|
||||
StatementExpressionNode statement => BindStatementExpression(statement),
|
||||
VariableAssignmentNode statement => BindVariableAssignment(statement),
|
||||
VariableDeclarationNode statement => BindVariableDeclaration(statement),
|
||||
WhileNode statement => BindWhile(statement),
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(node))
|
||||
};
|
||||
}
|
||||
|
||||
private static BoundArrayIndexAssignmentNode BindArrayIndex(ArrayIndexAssignmentNode statement)
|
||||
private static BoundStatementNode BindAssignment(AssignmentNode statement)
|
||||
{
|
||||
var boundArrayIndex = BindArrayIndexAccess(statement.ArrayIndexAccess);
|
||||
var elementType = ((NubArrayType)boundArrayIndex.Type).ElementType;
|
||||
return new BoundArrayIndexAssignmentNode(statement.Tokens, boundArrayIndex, BindExpression(statement.Value, elementType));
|
||||
var expression = BindExpression(statement.Expression);
|
||||
var value = BindExpression(statement.Value, expression.Type);
|
||||
return new BoundAssignmentNode(statement.Tokens, expression, value);
|
||||
}
|
||||
|
||||
private static BoundBreakNode BindBreak(BreakNode statement)
|
||||
@@ -156,13 +153,6 @@ public static class Binder
|
||||
return new BoundContinueNode(statement.Tokens);
|
||||
}
|
||||
|
||||
private static BoundDereferenceAssignmentNode BindDereferenceAssignment(DereferenceAssignmentNode statement)
|
||||
{
|
||||
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)
|
||||
{
|
||||
var elseStatement = Optional.Empty<Variant<BoundIfNode, BoundBlockNode>>();
|
||||
@@ -179,13 +169,6 @@ public static class Binder
|
||||
return new BoundIfNode(statement.Tokens, BindExpression(statement.Condition, NubPrimitiveType.Bool), BindBlock(statement.Body), elseStatement);
|
||||
}
|
||||
|
||||
private static BoundMemberAssignmentNode BindMemberAssignment(MemberAssignmentNode statement)
|
||||
{
|
||||
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)
|
||||
{
|
||||
var value = Optional.Empty<BoundExpressionNode>();
|
||||
@@ -203,12 +186,6 @@ public static class Binder
|
||||
return new BoundStatementExpressionNode(statement.Tokens, BindExpression(statement.Expression));
|
||||
}
|
||||
|
||||
private static BoundVariableAssignmentNode BindVariableAssignment(VariableAssignmentNode statement)
|
||||
{
|
||||
var variableType = _variables[statement.Identifier.Name];
|
||||
return new BoundVariableAssignmentNode(statement.Tokens, BindIdentifier(statement.Identifier), BindExpression(statement.Value, variableType));
|
||||
}
|
||||
|
||||
private static BoundVariableDeclarationNode BindVariableDeclaration(VariableDeclarationNode statement)
|
||||
{
|
||||
_variables[statement.Name] = statement.Type;
|
||||
@@ -230,7 +207,6 @@ public static class Binder
|
||||
ArrayInitializerNode expression => BindArrayInitializer(expression),
|
||||
BinaryExpressionNode expression => BindBinaryExpression(expression),
|
||||
DereferenceNode expression => BindDereference(expression),
|
||||
FixedArrayInitializerNode expression => BindFixedArrayInitializer(expression),
|
||||
FuncCallNode expression => BindFuncCall(expression),
|
||||
IdentifierNode expression => BindIdentifier(expression),
|
||||
LiteralNode expression => BindLiteral(expression, expectedType),
|
||||
@@ -243,7 +219,7 @@ public static class Binder
|
||||
|
||||
private static BoundAddressOfNode BindAddressOf(AddressOfNode expression)
|
||||
{
|
||||
var inner = (BoundLValueNode)BindExpression(expression.Expression);
|
||||
var inner = BindExpression(expression.Expression);
|
||||
return new BoundAddressOfNode(expression.Tokens, new NubPointerType(inner.Type), inner);
|
||||
}
|
||||
|
||||
@@ -291,11 +267,6 @@ public static class Binder
|
||||
return new BoundDereferenceNode(expression.Tokens, dereferencedType, boundExpression);
|
||||
}
|
||||
|
||||
private static BoundFixedArrayInitializerNode BindFixedArrayInitializer(FixedArrayInitializerNode expression)
|
||||
{
|
||||
return new BoundFixedArrayInitializerNode(expression.Tokens, new NubArrayType(expression.ElementType), expression.ElementType, expression.Capacity);
|
||||
}
|
||||
|
||||
private static BoundFuncCallNode BindFuncCall(FuncCallNode expression)
|
||||
{
|
||||
var boundExpression = BindExpression(expression.Expression);
|
||||
|
||||
@@ -5,17 +5,15 @@ using Syntax.Tokenization;
|
||||
namespace Syntax.Typing.BoundNode;
|
||||
|
||||
public abstract record BoundExpressionNode(IEnumerable<Token> Tokens, NubType Type) : BoundNode(Tokens);
|
||||
public abstract record BoundLValueNode(IEnumerable<Token> Tokens, NubType Type) : BoundExpressionNode(Tokens, Type);
|
||||
public record BoundBinaryExpressionNode(IEnumerable<Token> Tokens, NubType Type, BoundExpressionNode Left, BinaryExpressionOperator Operator, BoundExpressionNode Right) : BoundExpressionNode(Tokens, Type);
|
||||
public record BoundUnaryExpressionNode(IEnumerable<Token> Tokens, NubType Type, UnaryExpressionOperator Operator, BoundExpressionNode Operand) : BoundExpressionNode(Tokens, Type);
|
||||
public record BoundFuncCallNode(IEnumerable<Token> Tokens, NubType Type, BoundExpressionNode Expression, List<BoundExpressionNode> Parameters) : BoundExpressionNode(Tokens, Type);
|
||||
public record BoundIdentifierNode(IEnumerable<Token> Tokens, NubType Type, Optional<string> Namespace, string Name) : BoundLValueNode(Tokens, Type);
|
||||
public record BoundIdentifierNode(IEnumerable<Token> Tokens, NubType Type, Optional<string> Namespace, string Name) : BoundExpressionNode(Tokens, Type);
|
||||
public record BoundArrayInitializerNode(IEnumerable<Token> Tokens, NubType Type, BoundExpressionNode Capacity, NubType ElementType) : BoundExpressionNode(Tokens, Type);
|
||||
public record BoundArrayIndexAccessNode(IEnumerable<Token> Tokens, NubType Type, BoundExpressionNode Array, BoundExpressionNode Index) : BoundLValueNode(Tokens, Type);
|
||||
public record BoundArrayIndexAccessNode(IEnumerable<Token> Tokens, NubType Type, BoundExpressionNode Array, BoundExpressionNode Index) : BoundExpressionNode(Tokens, Type);
|
||||
public record BoundAnonymousFuncNode(IEnumerable<Token> Tokens, NubType Type, List<BoundFuncParameter> Parameters, BoundBlockNode Body, NubType ReturnType) : BoundExpressionNode(Tokens, Type);
|
||||
public record BoundAddressOfNode(IEnumerable<Token> Tokens, NubType Type, BoundLValueNode Expression) : BoundExpressionNode(Tokens, Type);
|
||||
public record BoundFixedArrayInitializerNode(IEnumerable<Token> Tokens, NubType Type, NubType ElementType, int Capacity) : BoundExpressionNode(Tokens, Type);
|
||||
public record BoundAddressOfNode(IEnumerable<Token> Tokens, NubType Type, BoundExpressionNode Expression) : BoundExpressionNode(Tokens, Type);
|
||||
public record BoundLiteralNode(IEnumerable<Token> Tokens, NubType Type, string Literal, LiteralKind Kind) : BoundExpressionNode(Tokens, Type);
|
||||
public record BoundMemberAccessNode(IEnumerable<Token> Tokens, NubType Type, BoundExpressionNode Expression, string Member) : BoundExpressionNode(Tokens, Type);
|
||||
public record BoundStructInitializerNode(IEnumerable<Token> Tokens, NubType Type, NubStructType StructType, Dictionary<string, BoundExpressionNode> Initializers) : BoundExpressionNode(Tokens, Type);
|
||||
public record BoundDereferenceNode(IEnumerable<Token> Tokens, NubType Type, BoundExpressionNode Expression) : BoundLValueNode(Tokens, Type);
|
||||
public record BoundDereferenceNode(IEnumerable<Token> Tokens, NubType Type, BoundExpressionNode Expression) : BoundExpressionNode(Tokens, Type);
|
||||
|
||||
@@ -6,12 +6,9 @@ namespace Syntax.Typing.BoundNode;
|
||||
public record BoundStatementNode(IEnumerable<Token> Tokens) : BoundNode(Tokens);
|
||||
public record BoundStatementExpressionNode(IEnumerable<Token> Tokens, BoundExpressionNode Expression) : BoundStatementNode(Tokens);
|
||||
public record BoundReturnNode(IEnumerable<Token> Tokens, Optional<BoundExpressionNode> Value) : BoundStatementNode(Tokens);
|
||||
public record BoundMemberAssignmentNode(IEnumerable<Token> Tokens, BoundMemberAccessNode MemberAccess, BoundExpressionNode Value) : BoundStatementNode(Tokens);
|
||||
public record BoundAssignmentNode(IEnumerable<Token> Tokens, BoundExpressionNode Expression, BoundExpressionNode Value) : BoundStatementNode(Tokens);
|
||||
public record BoundIfNode(IEnumerable<Token> Tokens, BoundExpressionNode Condition, BoundBlockNode Body, Optional<Variant<BoundIfNode, BoundBlockNode>> Else) : BoundStatementNode(Tokens);
|
||||
public record BoundDereferenceAssignmentNode(IEnumerable<Token> Tokens, BoundDereferenceNode Dereference, BoundExpressionNode Value) : BoundStatementNode(Tokens);
|
||||
public record BoundVariableAssignmentNode(IEnumerable<Token> Tokens, BoundIdentifierNode Identifier, BoundExpressionNode Value) : BoundStatementNode(Tokens);
|
||||
public record BoundVariableDeclarationNode(IEnumerable<Token> Tokens, string Name, NubType Type) : BoundStatementNode(Tokens);
|
||||
public record BoundContinueNode(IEnumerable<Token> Tokens) : BoundStatementNode(Tokens);
|
||||
public record BoundBreakNode(IEnumerable<Token> Tokens) : BoundStatementNode(Tokens);
|
||||
public record BoundArrayIndexAssignmentNode(IEnumerable<Token> Tokens, BoundArrayIndexAccessNode ArrayIndexAccess, BoundExpressionNode Value) : BoundStatementNode(Tokens);
|
||||
public record BoundWhileNode(IEnumerable<Token> Tokens, BoundExpressionNode Condition, BoundBlockNode Body) : BoundStatementNode(Tokens);
|
||||
|
||||
Reference in New Issue
Block a user