From 5e414ce09b5c4be234ac85737e6b9c7b007e72ab Mon Sep 17 00:00:00 2001 From: nub31 Date: Sun, 26 Jan 2025 22:23:48 +0100 Subject: [PATCH] Variable reassignment --- Nub.Lang/Nub.Lang/Generation/Generator.cs | 22 ++++++++++++++----- Nub.Lang/Nub.Lang/Input/program.nub | 9 +++++--- Nub.Lang/Nub.Lang/Parsing/Parser.cs | 12 ++++++++-- .../Parsing/VariableReassignmentNode.cs | 7 ++++++ Nub.Lang/Nub.Lang/Typing/ExpressionTyper.cs | 8 +++++++ 5 files changed, 47 insertions(+), 11 deletions(-) create mode 100644 Nub.Lang/Nub.Lang/Parsing/VariableReassignmentNode.cs diff --git a/Nub.Lang/Nub.Lang/Generation/Generator.cs b/Nub.Lang/Nub.Lang/Generation/Generator.cs index 44341b5..67deb12 100644 --- a/Nub.Lang/Nub.Lang/Generation/Generator.cs +++ b/Nub.Lang/Nub.Lang/Generation/Generator.cs @@ -10,7 +10,7 @@ public class Generator private readonly IReadOnlyCollection _definitions; private readonly SymbolTable _symbolTable; private readonly StringBuilder _builder; - private Dictionary _strings; + private readonly Dictionary _strings; private int _stringIndex; public Generator(IReadOnlyCollection definitions) @@ -73,13 +73,13 @@ public class Generator strlen: push rcx ; save and clear out counter xor rcx, rcx - .strlen_next: + strlen_next: cmp [rdi], byte 0 ; null byte yet? - jz .strlen_null ; yes, get out + jz strlen_null ; yes, get out inc rcx ; char is ok, count it inc rdi ; move to next char - jmp .strlen_next ; process again - .strlen_null: + jmp strlen_next ; process again + strlen_null: mov rax, rcx ; rcx = the length (put in rax) pop rcx ; restore rcx ret ; get out @@ -154,6 +154,9 @@ public class Generator case VariableAssignmentNode variableAssignment: GenerateVariableAssignment(func, variableAssignment); break; + case VariableReassignmentNode variableReassignment: + GenerateVariableReassignment(variableReassignment, func); + break; default: throw new ArgumentOutOfRangeException(nameof(statement)); } @@ -171,8 +174,15 @@ public class Generator private void GenerateVariableAssignment(Func func, VariableAssignmentNode variableAssignment) { - GenerateExpression(variableAssignment.Value, func); var variable = func.ResolveLocalVariable(variableAssignment.Name); + GenerateExpression(variableAssignment.Value, func); + _builder.AppendLine($" mov [rbp - {variable.Offset}], rax"); + } + + private void GenerateVariableReassignment(VariableReassignmentNode variableReassignment, Func func) + { + var variable = func.ResolveLocalVariable(variableReassignment.Name); + GenerateExpression(variableReassignment.Value, func); _builder.AppendLine($" mov [rbp - {variable.Offset}], rax"); } diff --git a/Nub.Lang/Nub.Lang/Input/program.nub b/Nub.Lang/Nub.Lang/Input/program.nub index fa028af..9e7616a 100644 --- a/Nub.Lang/Nub.Lang/Input/program.nub +++ b/Nub.Lang/Nub.Lang/Input/program.nub @@ -4,9 +4,12 @@ let STD_OUT = 1; let STD_ERR = 2; func main() { - write("test\n"); + let x = "test\n"; + write(x); + x = "uwu\n"; + write(x); } -func write(msg: String): int64 { - return syscall(SYS_WRITE, STD_OUT, msg, strlen(msg)); +func write(msg: String) { + syscall(SYS_WRITE, STD_OUT, msg, strlen(msg)); } \ No newline at end of file diff --git a/Nub.Lang/Nub.Lang/Parsing/Parser.cs b/Nub.Lang/Nub.Lang/Parsing/Parser.cs index 7a9451f..332be87 100644 --- a/Nub.Lang/Nub.Lang/Parsing/Parser.cs +++ b/Nub.Lang/Nub.Lang/Parsing/Parser.cs @@ -106,12 +106,18 @@ public class Parser return new SyscallStatementNode(new Syscall(parameters)); } - return new FuncCallStatementNode(new FuncCall(identifier.Value, parameters)); + return new FuncCallStatementNode(new FuncCall(identifier.Value, parameters)); } case Symbol.Assign: - throw new NotImplementedException(); + { + var value = ParseExpression(); + ExpectSymbol(Symbol.Semicolon); + return new VariableReassignmentNode(identifier.Value, value); + } default: + { throw new Exception($"Unexpected symbol {symbol.Symbol}"); + } } } case SymbolToken symbol: @@ -144,7 +150,9 @@ public class Parser } } default: + { throw new Exception($"Unexpected token type {token.GetType().Name}"); + } } } diff --git a/Nub.Lang/Nub.Lang/Parsing/VariableReassignmentNode.cs b/Nub.Lang/Nub.Lang/Parsing/VariableReassignmentNode.cs new file mode 100644 index 0000000..147807b --- /dev/null +++ b/Nub.Lang/Nub.Lang/Parsing/VariableReassignmentNode.cs @@ -0,0 +1,7 @@ +namespace Nub.Lang.Parsing; + +public class VariableReassignmentNode(string name, ExpressionNode value) : StatementNode +{ + public string Name { get; } = name; + public ExpressionNode Value { get; } = value; +} \ No newline at end of file diff --git a/Nub.Lang/Nub.Lang/Typing/ExpressionTyper.cs b/Nub.Lang/Nub.Lang/Typing/ExpressionTyper.cs index 1f43595..1e2644c 100644 --- a/Nub.Lang/Nub.Lang/Typing/ExpressionTyper.cs +++ b/Nub.Lang/Nub.Lang/Typing/ExpressionTyper.cs @@ -68,6 +68,9 @@ public class ExpressionTyper case VariableAssignmentNode variableAssignment: PopulateVariableAssignment(variableAssignment); break; + case VariableReassignmentNode variableReassignment: + PopulateVariableReassignment(variableReassignment); + break; default: throw new ArgumentOutOfRangeException(nameof(statement)); } @@ -103,6 +106,11 @@ public class ExpressionTyper _variables.Push(new Variable(variableAssignment.Name, variableAssignment.Value.Type)); } + private void PopulateVariableReassignment(VariableReassignmentNode variableReassignment) + { + PopulateExpression(variableReassignment.Value); + } + private void PopulateExpression(ExpressionNode expression) { switch (expression)