From 50b640b36499e88be3066fb25486d7c1f908408c Mon Sep 17 00:00:00 2001 From: nub31 Date: Thu, 3 Jul 2025 19:02:25 +0200 Subject: [PATCH] Add back variable assignment at declaration time --- example/src/main.nub | 40 +++++++++---------- src/compiler/Generation/QBE/QBEGenerator.cs | 12 ++++-- src/compiler/Syntax/Parsing/Node/Statement.cs | 2 +- src/compiler/Syntax/Parsing/Parser.cs | 8 +++- src/compiler/Syntax/Typing/Binder.cs | 7 +++- .../Syntax/Typing/BoundNode/Statement.cs | 2 +- 6 files changed, 43 insertions(+), 28 deletions(-) diff --git a/example/src/main.nub b/example/src/main.nub index e05d7e5..eea1134 100644 --- a/example/src/main.nub +++ b/example/src/main.nub @@ -1,31 +1,29 @@ namespace main -// struct Name { -// first: cstring -// last: cstring -// } +struct Name { + first: cstring + last: cstring +} -// struct Human -// { -// name: Name -// age: i64 -// } +struct Human +{ + name: Name + age: i64 +} export func main(args: []cstring): i64 { - // let x: Human + let x: Human = alloc Human + { + name = alloc Name + { + first = "john" + last = "doe" + } + age = 23 + } - // x = alloc Human { - // name = alloc Name { - // first = "john" - // last = "doe" - // } - // age = 23 - // } - - // c::puts(x.name.last) - - c::puts("test") + c::puts(x.name.last) return 0 } diff --git a/src/compiler/Generation/QBE/QBEGenerator.cs b/src/compiler/Generation/QBE/QBEGenerator.cs index 7f11d5e..f4326ed 100644 --- a/src/compiler/Generation/QBE/QBEGenerator.cs +++ b/src/compiler/Generation/QBE/QBEGenerator.cs @@ -707,9 +707,15 @@ public static class QBEGenerator private static void EmitVariableDeclaration(BoundVariableDeclarationNode variableDeclaration) { - var tmp = VarName(); - _builder.AppendLine($" {tmp} =l alloc8 {SizeOf(variableDeclaration.Type)}"); - _variables.Push(new Variable(variableDeclaration.Name, new Val(tmp, variableDeclaration.Type, ValKind.Pointer))); + var variable = VarName(); + _builder.AppendLine($" {variable} =l alloc8 {SizeOf(variableDeclaration.Type)}"); + + if (variableDeclaration.Assignment.HasValue) + { + EmitCopyIntoOrInitialize(variableDeclaration.Assignment.Value, variable); + } + + _variables.Push(new Variable(variableDeclaration.Name, new Val(variable, variableDeclaration.Type, ValKind.Pointer))); } private static void EmitWhile(BoundWhileNode whileStatement) diff --git a/src/compiler/Syntax/Parsing/Node/Statement.cs b/src/compiler/Syntax/Parsing/Node/Statement.cs index 703f114..a65115c 100644 --- a/src/compiler/Syntax/Parsing/Node/Statement.cs +++ b/src/compiler/Syntax/Parsing/Node/Statement.cs @@ -9,7 +9,7 @@ public record StatementExpressionNode(IEnumerable Tokens, ExpressionNode public record ReturnNode(IEnumerable Tokens, Optional 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 VariableDeclarationNode(IEnumerable Tokens, string Name, NubType Type) : StatementNode(Tokens); +public record VariableDeclarationNode(IEnumerable Tokens, string Name, NubType Type, Optional Assignment) : StatementNode(Tokens); public record ContinueNode(IEnumerable Tokens) : StatementNode(Tokens); public record BreakNode(IEnumerable Tokens) : 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 21d8ea7..b8aa056 100644 --- a/src/compiler/Syntax/Parsing/Parser.cs +++ b/src/compiler/Syntax/Parsing/Parser.cs @@ -237,8 +237,14 @@ public static class Parser var name = ExpectIdentifier().Value; ExpectSymbol(Symbol.Colon); var type = ParseType(); + + Optional assignment = Optional.Empty(); + if (TryExpectSymbol(Symbol.Assign)) + { + assignment = ParseExpression(); + } - return new VariableDeclarationNode(GetTokensForNode(startIndex), name, type); + return new VariableDeclarationNode(GetTokensForNode(startIndex), name, type, assignment); } private static StatementNode ParseBreak(int startIndex) diff --git a/src/compiler/Syntax/Typing/Binder.cs b/src/compiler/Syntax/Typing/Binder.cs index 3bb0b5f..4d0a151 100644 --- a/src/compiler/Syntax/Typing/Binder.cs +++ b/src/compiler/Syntax/Typing/Binder.cs @@ -189,7 +189,12 @@ public static class Binder private static BoundVariableDeclarationNode BindVariableDeclaration(VariableDeclarationNode statement) { _variables[statement.Name] = statement.Type; - return new BoundVariableDeclarationNode(statement.Tokens, statement.Name, statement.Type); + var assignment = Optional.Empty(); + if (statement.Assignment.HasValue) + { + assignment = BindExpression(statement.Assignment.Value); + } + return new BoundVariableDeclarationNode(statement.Tokens, statement.Name, statement.Type, assignment); } private static BoundWhileNode BindWhile(WhileNode statement) diff --git a/src/compiler/Syntax/Typing/BoundNode/Statement.cs b/src/compiler/Syntax/Typing/BoundNode/Statement.cs index c149ed0..983cb8b 100644 --- a/src/compiler/Syntax/Typing/BoundNode/Statement.cs +++ b/src/compiler/Syntax/Typing/BoundNode/Statement.cs @@ -8,7 +8,7 @@ public record BoundStatementExpressionNode(IEnumerable Tokens, BoundExpre public record BoundReturnNode(IEnumerable Tokens, Optional 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 BoundVariableDeclarationNode(IEnumerable Tokens, string Name, NubType Type) : BoundStatementNode(Tokens); +public record BoundVariableDeclarationNode(IEnumerable Tokens, string Name, NubType Type, Optional Assignment) : BoundStatementNode(Tokens); public record BoundContinueNode(IEnumerable Tokens) : BoundStatementNode(Tokens); public record BoundBreakNode(IEnumerable Tokens) : BoundStatementNode(Tokens); public record BoundWhileNode(IEnumerable Tokens, BoundExpressionNode Condition, BoundBlockNode Body) : BoundStatementNode(Tokens);