Add back variable assignment at declaration time

This commit is contained in:
nub31
2025-07-03 19:02:25 +02:00
parent 66d47b9100
commit 50b640b364
6 changed files with 43 additions and 28 deletions

View File

@@ -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
}

View File

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

View File

@@ -9,7 +9,7 @@ public record StatementExpressionNode(IEnumerable<Token> Tokens, ExpressionNode
public record ReturnNode(IEnumerable<Token> Tokens, Optional<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 VariableDeclarationNode(IEnumerable<Token> Tokens, string Name, NubType Type) : StatementNode(Tokens);
public record VariableDeclarationNode(IEnumerable<Token> Tokens, string Name, NubType Type, Optional<ExpressionNode> Assignment) : StatementNode(Tokens);
public record ContinueNode(IEnumerable<Token> Tokens) : StatementNode(Tokens);
public record BreakNode(IEnumerable<Token> Tokens) : StatementNode(Tokens);
public record WhileNode(IEnumerable<Token> Tokens, ExpressionNode Condition, BlockNode Body) : StatementNode(Tokens);

View File

@@ -238,7 +238,13 @@ public static class Parser
ExpectSymbol(Symbol.Colon);
var type = ParseType();
return new VariableDeclarationNode(GetTokensForNode(startIndex), name, type);
Optional<ExpressionNode> assignment = Optional<ExpressionNode>.Empty();
if (TryExpectSymbol(Symbol.Assign))
{
assignment = ParseExpression();
}
return new VariableDeclarationNode(GetTokensForNode(startIndex), name, type, assignment);
}
private static StatementNode ParseBreak(int startIndex)

View File

@@ -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<BoundExpressionNode>.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)

View File

@@ -8,7 +8,7 @@ public record BoundStatementExpressionNode(IEnumerable<Token> Tokens, BoundExpre
public record BoundReturnNode(IEnumerable<Token> Tokens, Optional<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 BoundVariableDeclarationNode(IEnumerable<Token> Tokens, string Name, NubType Type) : BoundStatementNode(Tokens);
public record BoundVariableDeclarationNode(IEnumerable<Token> Tokens, string Name, NubType Type, Optional<BoundExpressionNode> Assignment) : BoundStatementNode(Tokens);
public record BoundContinueNode(IEnumerable<Token> Tokens) : BoundStatementNode(Tokens);
public record BoundBreakNode(IEnumerable<Token> Tokens) : BoundStatementNode(Tokens);
public record BoundWhileNode(IEnumerable<Token> Tokens, BoundExpressionNode Condition, BoundBlockNode Body) : BoundStatementNode(Tokens);