diff --git a/example/src/main.nub b/example/src/main.nub index fd8ef94..fb9c2e3 100644 --- a/example/src/main.nub +++ b/example/src/main.nub @@ -1,6 +1,25 @@ namespace main -export func main(args: []cstring): i64 { - c::puts("test") +struct Human +{ + name: cstring + age: i64 +} + +func test() { + +} + +export func main(args: []cstring): i64 +{ + let x: []cstring + + x = [2]cstring + + x[0] = "test1" + x[1] = "test2" + + c::puts(x[1]) + return 0 } diff --git a/src/compiler/CLI/Program.cs b/src/compiler/CLI/Program.cs index 56b20b8..552eb12 100644 --- a/src/compiler/CLI/Program.cs +++ b/src/compiler/CLI/Program.cs @@ -12,6 +12,7 @@ const string BIN_DIR = "bin"; const string INT_DIR = "bin-int"; var INT_BUILTIN_DIR = Path.Join(INT_DIR, "builtin"); var INT_OBJECT_DIR = Path.Join(INT_DIR, "obj"); +var INT_DEBUG_DIR = Path.Join(INT_DIR, "debug"); if (Directory.Exists(INT_DIR)) { @@ -21,6 +22,7 @@ if (Directory.Exists(INT_DIR)) Directory.CreateDirectory(BIN_DIR); Directory.CreateDirectory(INT_BUILTIN_DIR); Directory.CreateDirectory(INT_OBJECT_DIR); +Directory.CreateDirectory(INT_DEBUG_DIR); var options = new Options(); @@ -116,14 +118,20 @@ var objectFiles = new List(); foreach (var file in options.Files) { + var outFileName = $"{HexString.CreateUnique(8)}_{Path.GetFileNameWithoutExtension(file)}"; + var ssa = QBEGenerator.Emit(boundSyntaxTrees[file], boundDefinitionTable); + File.WriteAllText(Path.Join(INT_DEBUG_DIR, $"{outFileName}.ssa"), ssa); + var asm = await QBE.Invoke(ssa); if (asm == null) { return 1; } - var fileName = Path.Join(INT_OBJECT_DIR, $"{HexString.CreateUnique(8)}_{Path.GetFileNameWithoutExtension(file)}.o"); + File.WriteAllText(Path.Join(INT_DEBUG_DIR, $"{outFileName}.s"), asm); + + var fileName = Path.Join(INT_OBJECT_DIR, $"{outFileName}.o"); var asmSuccess = await GCC.Assemble(asm, fileName); if (!asmSuccess) { diff --git a/src/compiler/Generation/QBE/QBEGenerator.cs b/src/compiler/Generation/QBE/QBEGenerator.cs index 503f729..049d3ad 100644 --- a/src/compiler/Generation/QBE/QBEGenerator.cs +++ b/src/compiler/Generation/QBE/QBEGenerator.cs @@ -477,8 +477,8 @@ public static class QBEGenerator { switch (statement) { - case BoundArrayIndexAssignmentNode arrayIndexAssignment: - EmitArrayIndexAssignment(arrayIndexAssignment); + case BoundAssignmentNode assignment: + EmitAssignment(assignment); break; case BoundBreakNode: EmitBreak(); @@ -486,15 +486,9 @@ public static class QBEGenerator case BoundContinueNode: EmitContinue(); break; - case BoundDereferenceAssignmentNode dereferenceAssignment: - EmitDereferenceAssignment(dereferenceAssignment); - break; case BoundIfNode ifStatement: EmitIf(ifStatement); break; - case BoundMemberAssignmentNode memberAssignment: - EmitMemberAssignment(memberAssignment); - break; case BoundReturnNode @return: EmitReturn(@return); break; @@ -504,9 +498,6 @@ public static class QBEGenerator case BoundVariableDeclarationNode variableDeclaration: EmitVariableDeclaration(variableDeclaration); break; - case BoundVariableAssignmentNode variableAssignment: - EmitVariableAssignment(variableAssignment); - break; case BoundWhileNode whileStatement: EmitWhile(whileStatement); break; @@ -515,30 +506,16 @@ public static class QBEGenerator } } - private static void EmitArrayIndexAssignment(BoundArrayIndexAssignmentNode arrayIndexAssignment) + private static void EmitAssignment(BoundAssignmentNode assignment) { - var array = EmitUnwrap(EmitExpression(arrayIndexAssignment.ArrayIndexAccess.Array)); - var index = EmitUnwrap(EmitExpression(arrayIndexAssignment.ArrayIndexAccess.Index)); - EmitArrayBoundsCheck(array, index); - var value = EmitUnwrap(EmitExpression(arrayIndexAssignment.Value)); - - switch (arrayIndexAssignment.ArrayIndexAccess.Array.Type) + var expression = EmitExpression(assignment.Expression); + if (expression.Kind != ValKind.Pointer) { - case NubArrayType arrayType: - { - var pointer = VarName(); - _builder.AppendLine($" {pointer} =l mul {index}, {SizeOf(arrayType.ElementType)}"); - _builder.AppendLine($" {pointer} =l add {pointer}, 8"); - _builder.AppendLine($" {pointer} =l add {array}, {pointer}"); - - EmitCopy(arrayType.ElementType, value, pointer); - break; - } - default: - { - throw new ArgumentOutOfRangeException(); - } + throw new UnreachableException(); } + + var value = EmitUnwrap(EmitExpression(assignment.Value)); + EmitCopy(assignment.Value.Type, value, expression.Name); } private static void EmitBlock(BoundBlockNode block, List? variables = null) @@ -578,13 +555,6 @@ public static class QBEGenerator _codeIsReachable = false; } - private static void EmitDereferenceAssignment(BoundDereferenceAssignmentNode dereferenceAssignment) - { - var pointer = EmitUnwrap(EmitExpression(dereferenceAssignment.Dereference.Expression)); - var value = EmitUnwrap(EmitExpression(dereferenceAssignment.Value)); - EmitCopy(dereferenceAssignment.Value.Type, value, pointer); - } - private static void EmitIf(BoundIfNode ifStatement) { var trueLabel = LabelName(); @@ -609,24 +579,6 @@ public static class QBEGenerator _builder.AppendLine(endLabel); } - private static void EmitMemberAssignment(BoundMemberAssignmentNode memberAssignment) - { - var structType = memberAssignment.MemberAccess.Expression.Type as NubStructType; - Debug.Assert(structType != null); - - var structDefinition = _definitionTable.LookupStruct(structType.Namespace, structType.Name).GetValue(); - var offset = OffsetOf(structDefinition, memberAssignment.MemberAccess.Member); - - var item = EmitUnwrap(EmitExpression(memberAssignment.MemberAccess.Expression)); - var pointer = VarName(); - - _builder.AppendLine($" {pointer} =l add {item}, {offset}"); - - var value = EmitUnwrap(EmitExpression(memberAssignment.Value)); - - EmitCopy(memberAssignment.Value.Type, value, pointer); - } - private static void EmitReturn(BoundReturnNode @return) { if (@return.Value.HasValue) @@ -647,13 +599,6 @@ public static class QBEGenerator _variables.Push(new Variable(variableDeclaration.Name, new Val(tmp, variableDeclaration.Type, ValKind.Pointer))); } - private static void EmitVariableAssignment(BoundVariableAssignmentNode variableAssignment) - { - var value = EmitUnwrap(EmitExpression(variableAssignment.Value)); - var variable = _variables.Single(x => x.Name == variableAssignment.Identifier.Name); - EmitCopy(variableAssignment.Value.Type, value, variable.Val.Name); - } - private static void EmitWhile(BoundWhileNode whileStatement) { var conditionLabel = LabelName(); @@ -685,7 +630,6 @@ public static class QBEGenerator BoundArrayInitializerNode arrayInitializer => EmitArrayInitializer(arrayInitializer), BoundBinaryExpressionNode binaryExpression => EmitBinaryExpression(binaryExpression), BoundDereferenceNode dereference => EmitDereference(dereference), - BoundFixedArrayInitializerNode fixedArrayInitializer => EmitFixedArrayInitializer(fixedArrayInitializer), BoundFuncCallNode funcCallExpression => EmitFuncCall(funcCallExpression), BoundIdentifierNode identifier => EmitIdentifier(identifier), BoundLiteralNode literal => EmitLiteral(literal), @@ -703,31 +647,18 @@ public static class QBEGenerator return new Val(name, anonymousFunc.Type, ValKind.Func); } - private static string EmitArrayIndexPointer(BoundArrayIndexAccessNode arrayIndexAccess) + private static Val EmitArrayIndexAccess(BoundArrayIndexAccessNode arrayIndexAccess) { var array = EmitUnwrap(EmitExpression(arrayIndexAccess.Array)); var index = EmitUnwrap(EmitExpression(arrayIndexAccess.Index)); - EmitArrayBoundsCheck(array, index); - var elementType = arrayIndexAccess.Array.Type switch - { - NubArrayType arrayType => arrayType.ElementType, - _ => throw new ArgumentOutOfRangeException() - }; + var elementType = ((NubArrayType)arrayIndexAccess.Array.Type).ElementType; var pointer = VarName(); _builder.AppendLine($" {pointer} =l mul {index}, {SizeOf(elementType)}"); _builder.AppendLine($" {pointer} =l add {pointer}, 8"); _builder.AppendLine($" {pointer} =l add {array}, {pointer}"); - return pointer; - } - - private static Val EmitArrayIndexAccess(BoundArrayIndexAccessNode arrayIndexAccess) - { - var pointer = EmitArrayIndexPointer(arrayIndexAccess); - var outputName = VarName(); - _builder.AppendLine($" {outputName} {QBEAssign(arrayIndexAccess.Type)} {QBELoad(arrayIndexAccess.Type)} {pointer}"); - return new Val(outputName, arrayIndexAccess.Type, ValKind.Immediate); + return new Val(pointer, arrayIndexAccess.Type, ValKind.Pointer); } private static void EmitArrayBoundsCheck(string array, string index) @@ -785,31 +716,13 @@ public static class QBEGenerator private static Val EmitAddressOf(BoundAddressOfNode addressOf) { - switch (addressOf.Expression) + var value = EmitExpression(addressOf.Expression); + if (value.Kind != ValKind.Pointer) { - case BoundArrayIndexAccessNode arrayIndexAccess: - { - var pointer = EmitArrayIndexPointer(arrayIndexAccess); - return new Val(pointer, addressOf.Type, ValKind.Immediate); - } - case BoundDereferenceNode dereference: - { - return EmitExpression(dereference.Expression); - } - case BoundIdentifierNode identifier: - { - if (identifier.Namespace.HasValue) - { - throw new NotSupportedException("There is nothing to address in another namespace"); - } - - return _variables.Single(x => x.Name == identifier.Name).Val; - } - default: - { - throw new ArgumentOutOfRangeException(); - } + throw new UnreachableException(); } + + return value; } private static Val EmitBinaryExpression(BoundBinaryExpressionNode binaryExpression) @@ -1217,19 +1130,27 @@ public static class QBEGenerator if (memberAccess.Member == "count") { _builder.AppendLine($" {output} =l loadl {item}"); - break; + return new Val(output, memberAccess.Type, ValKind.Immediate); } - throw new UnreachableException(); + break; } case NubStringType: { - _builder.AppendLine($" {output} =l call $nub_string_length(l {item})"); + if (memberAccess.Member == "count") + { + _builder.AppendLine($" {output} =l call $nub_string_length(l {item})"); + return new Val(output, memberAccess.Type, ValKind.Immediate); + } break; } case NubCStringType: { - _builder.AppendLine($" {output} =l call $nub_cstring_length(l {item})"); + if (memberAccess.Member == "count") + { + _builder.AppendLine($" {output} =l call $nub_cstring_length(l {item})"); + return new Val(output, memberAccess.Type, ValKind.Immediate); + } break; } case NubStructType structType: @@ -1237,35 +1158,12 @@ public static class QBEGenerator var structDefinition = _definitionTable.LookupStruct(structType.Namespace, structType.Name).GetValue(); var offset = OffsetOf(structDefinition, memberAccess.Member); - var offsetName = VarName(); - _builder.AppendLine($" {offsetName} =l add {item}, {offset}"); - _builder.AppendLine($" {output} {QBEAssign(memberAccess.Type)} {QBELoad(memberAccess.Type)} {item}"); - break; - } - default: - { - throw new ArgumentOutOfRangeException(); + _builder.AppendLine($" {output} =l add {item}, {offset}"); + return new Val(output, memberAccess.Type, ValKind.Pointer); } } - return new Val(output, memberAccess.Type, ValKind.Immediate); - } - - private static Val EmitFixedArrayInitializer(BoundFixedArrayInitializerNode fixedArrayInitializer) - { - var totalSize = SizeOf(fixedArrayInitializer.Type); - var outputName = VarName(); - _builder.AppendLine($" {outputName} =l alloc8 {totalSize}"); - - _builder.AppendLine($" storel {fixedArrayInitializer.Capacity}, {outputName}"); - - var dataPtr = VarName(); - _builder.AppendLine($" {dataPtr} =l add {outputName}, 8"); - - var dataSize = totalSize - 8; - _builder.AppendLine($" call $nub_memset(l {dataPtr}, w 0, l {dataSize})"); - - return new Val(outputName, fixedArrayInitializer.Type, ValKind.Immediate); + throw new UnreachableException(); } private static Val EmitFuncCall(BoundFuncCallNode funcCall) diff --git a/src/compiler/Syntax/Parsing/Node/Expression.cs b/src/compiler/Syntax/Parsing/Node/Expression.cs index a71316b..0f61aea 100644 --- a/src/compiler/Syntax/Parsing/Node/Expression.cs +++ b/src/compiler/Syntax/Parsing/Node/Expression.cs @@ -5,7 +5,6 @@ using Syntax.Typing; namespace Syntax.Parsing.Node; public abstract record ExpressionNode(IEnumerable Tokens) : Node(Tokens); -public abstract record LValueNode(IEnumerable Tokens) : ExpressionNode(Tokens); public record BinaryExpressionNode(IEnumerable Tokens, ExpressionNode Left, BinaryExpressionOperator Operator, ExpressionNode Right) : ExpressionNode(Tokens); @@ -32,13 +31,12 @@ public enum UnaryExpressionOperator } public record FuncCallNode(IEnumerable Tokens, ExpressionNode Expression, List Parameters) : ExpressionNode(Tokens); -public record IdentifierNode(IEnumerable Tokens, Optional Namespace, string Name) : LValueNode(Tokens); +public record IdentifierNode(IEnumerable Tokens, Optional Namespace, string Name) : ExpressionNode(Tokens); public record ArrayInitializerNode(IEnumerable Tokens, ExpressionNode Capacity, NubType ElementType) : ExpressionNode(Tokens); -public record ArrayIndexAccessNode(IEnumerable Tokens, ExpressionNode Array, ExpressionNode Index) : LValueNode(Tokens); +public record ArrayIndexAccessNode(IEnumerable Tokens, ExpressionNode Array, ExpressionNode Index) : ExpressionNode(Tokens); public record AnonymousFuncNode(IEnumerable Tokens, List Parameters, BlockNode Body, NubType ReturnType) : ExpressionNode(Tokens); -public record AddressOfNode(IEnumerable Tokens, LValueNode Expression) : ExpressionNode(Tokens); -public record FixedArrayInitializerNode(IEnumerable Tokens, NubType ElementType, int Capacity) : ExpressionNode(Tokens); +public record AddressOfNode(IEnumerable Tokens, ExpressionNode Expression) : ExpressionNode(Tokens); public record LiteralNode(IEnumerable Tokens, string Literal, LiteralKind Kind) : ExpressionNode(Tokens); public record MemberAccessNode(IEnumerable Tokens, ExpressionNode Expression, string Member) : ExpressionNode(Tokens); public record StructInitializerNode(IEnumerable Tokens, NubStructType StructType, Dictionary Initializers) : ExpressionNode(Tokens); -public record DereferenceNode(IEnumerable Tokens, ExpressionNode Expression) : LValueNode(Tokens); +public record DereferenceNode(IEnumerable Tokens, ExpressionNode Expression) : ExpressionNode(Tokens); diff --git a/src/compiler/Syntax/Parsing/Node/Statement.cs b/src/compiler/Syntax/Parsing/Node/Statement.cs index db506de..703f114 100644 --- a/src/compiler/Syntax/Parsing/Node/Statement.cs +++ b/src/compiler/Syntax/Parsing/Node/Statement.cs @@ -7,12 +7,9 @@ namespace Syntax.Parsing.Node; public record StatementNode(IEnumerable Tokens) : Node(Tokens); public record StatementExpressionNode(IEnumerable Tokens, ExpressionNode Expression) : StatementNode(Tokens); public record ReturnNode(IEnumerable Tokens, Optional Value) : StatementNode(Tokens); -public record MemberAssignmentNode(IEnumerable Tokens, MemberAccessNode MemberAccess, ExpressionNode Value) : StatementNode(Tokens); +public record AssignmentNode(IEnumerable Tokens, ExpressionNode Expression, ExpressionNode Value) : StatementNode(Tokens); public record IfNode(IEnumerable Tokens, ExpressionNode Condition, BlockNode Body, Optional> Else) : StatementNode(Tokens); -public record DereferenceAssignmentNode(IEnumerable Tokens, DereferenceNode Dereference, ExpressionNode Value) : StatementNode(Tokens); -public record VariableAssignmentNode(IEnumerable Tokens, IdentifierNode Identifier, ExpressionNode Value) : StatementNode(Tokens); public record VariableDeclarationNode(IEnumerable Tokens, string Name, NubType Type) : StatementNode(Tokens); public record ContinueNode(IEnumerable Tokens) : StatementNode(Tokens); public record BreakNode(IEnumerable Tokens) : StatementNode(Tokens); -public record ArrayIndexAssignmentNode(IEnumerable Tokens, ArrayIndexAccessNode ArrayIndexAccess, ExpressionNode Value) : StatementNode(Tokens); public record WhileNode(IEnumerable Tokens, ExpressionNode Condition, BlockNode Body) : StatementNode(Tokens); diff --git a/src/compiler/Syntax/Parsing/Parser.cs b/src/compiler/Syntax/Parsing/Parser.cs index 69d8dce..21d8ea7 100644 --- a/src/compiler/Syntax/Parsing/Parser.cs +++ b/src/compiler/Syntax/Parsing/Parser.cs @@ -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); diff --git a/src/compiler/Syntax/Typing/Binder.cs b/src/compiler/Syntax/Typing/Binder.cs index 526356c..3bb0b5f 100644 --- a/src/compiler/Syntax/Typing/Binder.cs +++ b/src/compiler/Syntax/Typing/Binder.cs @@ -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>(); @@ -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(); @@ -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); diff --git a/src/compiler/Syntax/Typing/BoundNode/Expression.cs b/src/compiler/Syntax/Typing/BoundNode/Expression.cs index f6f204f..61891fa 100644 --- a/src/compiler/Syntax/Typing/BoundNode/Expression.cs +++ b/src/compiler/Syntax/Typing/BoundNode/Expression.cs @@ -5,17 +5,15 @@ using Syntax.Tokenization; namespace Syntax.Typing.BoundNode; public abstract record BoundExpressionNode(IEnumerable Tokens, NubType Type) : BoundNode(Tokens); -public abstract record BoundLValueNode(IEnumerable Tokens, NubType Type) : BoundExpressionNode(Tokens, Type); public record BoundBinaryExpressionNode(IEnumerable Tokens, NubType Type, BoundExpressionNode Left, BinaryExpressionOperator Operator, BoundExpressionNode Right) : BoundExpressionNode(Tokens, Type); public record BoundUnaryExpressionNode(IEnumerable Tokens, NubType Type, UnaryExpressionOperator Operator, BoundExpressionNode Operand) : BoundExpressionNode(Tokens, Type); public record BoundFuncCallNode(IEnumerable Tokens, NubType Type, BoundExpressionNode Expression, List Parameters) : BoundExpressionNode(Tokens, Type); -public record BoundIdentifierNode(IEnumerable Tokens, NubType Type, Optional Namespace, string Name) : BoundLValueNode(Tokens, Type); +public record BoundIdentifierNode(IEnumerable Tokens, NubType Type, Optional Namespace, string Name) : BoundExpressionNode(Tokens, Type); public record BoundArrayInitializerNode(IEnumerable Tokens, NubType Type, BoundExpressionNode Capacity, NubType ElementType) : BoundExpressionNode(Tokens, Type); -public record BoundArrayIndexAccessNode(IEnumerable Tokens, NubType Type, BoundExpressionNode Array, BoundExpressionNode Index) : BoundLValueNode(Tokens, Type); +public record BoundArrayIndexAccessNode(IEnumerable Tokens, NubType Type, BoundExpressionNode Array, BoundExpressionNode Index) : BoundExpressionNode(Tokens, Type); public record BoundAnonymousFuncNode(IEnumerable Tokens, NubType Type, List Parameters, BoundBlockNode Body, NubType ReturnType) : BoundExpressionNode(Tokens, Type); -public record BoundAddressOfNode(IEnumerable Tokens, NubType Type, BoundLValueNode Expression) : BoundExpressionNode(Tokens, Type); -public record BoundFixedArrayInitializerNode(IEnumerable Tokens, NubType Type, NubType ElementType, int Capacity) : BoundExpressionNode(Tokens, Type); +public record BoundAddressOfNode(IEnumerable Tokens, NubType Type, BoundExpressionNode Expression) : BoundExpressionNode(Tokens, Type); public record BoundLiteralNode(IEnumerable Tokens, NubType Type, string Literal, LiteralKind Kind) : BoundExpressionNode(Tokens, Type); public record BoundMemberAccessNode(IEnumerable Tokens, NubType Type, BoundExpressionNode Expression, string Member) : BoundExpressionNode(Tokens, Type); public record BoundStructInitializerNode(IEnumerable Tokens, NubType Type, NubStructType StructType, Dictionary Initializers) : BoundExpressionNode(Tokens, Type); -public record BoundDereferenceNode(IEnumerable Tokens, NubType Type, BoundExpressionNode Expression) : BoundLValueNode(Tokens, Type); +public record BoundDereferenceNode(IEnumerable Tokens, NubType Type, BoundExpressionNode Expression) : BoundExpressionNode(Tokens, Type); diff --git a/src/compiler/Syntax/Typing/BoundNode/Statement.cs b/src/compiler/Syntax/Typing/BoundNode/Statement.cs index 151626a..c149ed0 100644 --- a/src/compiler/Syntax/Typing/BoundNode/Statement.cs +++ b/src/compiler/Syntax/Typing/BoundNode/Statement.cs @@ -6,12 +6,9 @@ namespace Syntax.Typing.BoundNode; public record BoundStatementNode(IEnumerable Tokens) : BoundNode(Tokens); public record BoundStatementExpressionNode(IEnumerable Tokens, BoundExpressionNode Expression) : BoundStatementNode(Tokens); public record BoundReturnNode(IEnumerable Tokens, Optional Value) : BoundStatementNode(Tokens); -public record BoundMemberAssignmentNode(IEnumerable Tokens, BoundMemberAccessNode MemberAccess, BoundExpressionNode Value) : BoundStatementNode(Tokens); +public record BoundAssignmentNode(IEnumerable Tokens, BoundExpressionNode Expression, BoundExpressionNode Value) : BoundStatementNode(Tokens); public record BoundIfNode(IEnumerable Tokens, BoundExpressionNode Condition, BoundBlockNode Body, Optional> Else) : BoundStatementNode(Tokens); -public record BoundDereferenceAssignmentNode(IEnumerable Tokens, BoundDereferenceNode Dereference, BoundExpressionNode Value) : BoundStatementNode(Tokens); -public record BoundVariableAssignmentNode(IEnumerable Tokens, BoundIdentifierNode Identifier, BoundExpressionNode Value) : BoundStatementNode(Tokens); public record BoundVariableDeclarationNode(IEnumerable Tokens, string Name, NubType Type) : BoundStatementNode(Tokens); public record BoundContinueNode(IEnumerable Tokens) : BoundStatementNode(Tokens); public record BoundBreakNode(IEnumerable Tokens) : BoundStatementNode(Tokens); -public record BoundArrayIndexAssignmentNode(IEnumerable Tokens, BoundArrayIndexAccessNode ArrayIndexAccess, BoundExpressionNode Value) : BoundStatementNode(Tokens); public record BoundWhileNode(IEnumerable Tokens, BoundExpressionNode Condition, BoundBlockNode Body) : BoundStatementNode(Tokens);