From c8f8dbada301cd66d8c40cd0bd8ea0e8ae669644 Mon Sep 17 00:00:00 2001
From: Ferenc Szontágh <szf@fsociety.hu>
Date: Sat, 19 Apr 2025 18:11:35 +0000
Subject: [PATCH] operator assigments

---
 src/Parser/Parser.cpp               |   25 ++++++++++++++++++++-----
 test_scripts/operator_assigments.vs |   10 ++++++++++
 2 files changed, 30 insertions(+), 5 deletions(-)

diff --git a/src/Parser/Parser.cpp b/src/Parser/Parser.cpp
index 42b3d45..7eabca3 100644
--- a/src/Parser/Parser.cpp
+++ b/src/Parser/Parser.cpp
@@ -289,7 +289,8 @@
             offset += 2;  // skip '->' and following identifier
         }
         const auto & look = peekToken(offset);
-        if (look.type == Lexer::Tokens::Type::OPERATOR_ASSIGNMENT && look.value == "=") {
+        // Handle simple and compound assignment operators (e.g., =, +=, -=, etc.)
+        if (look.type == Lexer::Tokens::Type::OPERATOR_ASSIGNMENT) {
             // Consume base variable
             auto        idTok    = expect(Lexer::Tokens::Type::VARIABLE_IDENTIFIER);
             std::string baseName = idTok.value;
@@ -313,16 +314,29 @@
                 }
                 propertyPath.push_back(propName);
             }
-            // Consume '='
-            auto eqTok   = expect(Lexer::Tokens::Type::OPERATOR_ASSIGNMENT, "=");
+            // Consume assignment operator ("=" or compound like "+=")
+            auto opTok   = expect(Lexer::Tokens::Type::OPERATOR_ASSIGNMENT);
             // Parse RHS expression
             auto rhsExpr = parseParsedExpression(Symbols::Variables::Type::NULL_TYPE);
             expect(Lexer::Tokens::Type::PUNCTUATION, ";");
             // Build RHS node
             auto rhsNode = buildExpressionFromParsed(rhsExpr);
+            // Compound assignment: a OP= b -> a = a OP b
+            if (opTok.value != "=") {
+                // Build LHS expression for current value
+                std::unique_ptr<Interpreter::ExpressionNode> lhsNode =
+                    std::make_unique<Interpreter::IdentifierExpressionNode>(baseName);
+                for (const auto & prop : propertyPath) {
+                    lhsNode = std::make_unique<Interpreter::MemberExpressionNode>(std::move(lhsNode), prop);
+                }
+                // Extract binary operator ("+=" -> "+")
+                std::string binOp = opTok.value.substr(0, opTok.value.size() - 1);
+                // Build binary expression lhs OP rhs
+                rhsNode = std::make_unique<Interpreter::BinaryExpressionNode>(std::move(lhsNode), binOp, std::move(rhsNode));
+            }
             return std::make_unique<Interpreter::AssignmentStatementNode>(baseName, std::move(propertyPath),
                                                                           std::move(rhsNode), this->current_filename_,
-                                                                          eqTok.line_number, eqTok.column_number);
+                                                                          opTok.line_number, opTok.column_number);
         }
     }
     // Function call statement
@@ -1020,7 +1034,8 @@
             offset += 2;
         }
         const auto & look = peekToken(offset);
-        if (look.type == Lexer::Tokens::Type::OPERATOR_ASSIGNMENT && look.value == "=") {
+        // Simple or compound assignment (e.g., =, +=, -=, etc.)
+        if (look.type == Lexer::Tokens::Type::OPERATOR_ASSIGNMENT) {
             parseAssignmentStatement();
             return;
         }
diff --git a/test_scripts/operator_assigments.vs b/test_scripts/operator_assigments.vs
new file mode 100644
index 0000000..7755677
--- /dev/null
+++ b/test_scripts/operator_assigments.vs
@@ -0,0 +1,10 @@
+int $i = 0;
+$i += 10;
+$i -= 1;
+$i /= 1;
+printnl($i);
+
+
+int $x = 5;
+$x %= 2;
+printnl($x);
\ No newline at end of file

--
Gitblit v1.9.3