From 3d9e8a26930930a4b63143f800bfa28e5d3caaf6 Mon Sep 17 00:00:00 2001
From: Ferenc Szontágh <szf@fsociety.hu>
Date: Fri, 18 Apr 2025 19:35:21 +0000
Subject: [PATCH] fix object variable assigment
---
src/Parser/Parser.cpp | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 51 insertions(+), 0 deletions(-)
diff --git a/src/Parser/Parser.cpp b/src/Parser/Parser.cpp
index 6aa0348..a2fd154 100644
--- a/src/Parser/Parser.cpp
+++ b/src/Parser/Parser.cpp
@@ -8,6 +8,7 @@
#include "Interpreter/ConditionalStatementNode.hpp"
// #include "Interpreter/ForStatementNode.hpp" // removed until for-in loops are implemented
#include "Interpreter/CallStatementNode.hpp"
+#include "Interpreter/AssignmentStatementNode.hpp"
#include "Interpreter/DeclareVariableStatementNode.hpp"
#include "Interpreter/ReturnStatementNode.hpp"
#include "Symbols/SymbolContainer.hpp"
@@ -68,6 +69,15 @@
expect(Lexer::Tokens::Type::PUNCTUATION, ";");
}
+// Parse a top-level assignment statement and record it
+void Parser::parseAssignmentStatement() {
+ auto stmt = parseStatementNode();
+ Operations::Container::instance()->add(
+ Symbols::SymbolContainer::instance()->currentScopeName(),
+ Operations::Operation{Operations::Type::Assignment, "", std::move(stmt)}
+ );
+}
+
// Parse an if-else conditional statement
void Parser::parseIfStatement() {
// 'if'
@@ -116,6 +126,47 @@
return std::make_unique<Interpreter::ReturnStatementNode>(
std::move(exprNode), this->current_filename_, tok.line_number, tok.column_number);
}
+ // Assignment statement: variable or object member assignment
+ if (currentToken().type == Lexer::Tokens::Type::VARIABLE_IDENTIFIER) {
+ // Lookahead to detect '=' after optional '->' chains
+ size_t offset = 1;
+ // Skip member access sequence
+ while (peekToken(offset).type == Lexer::Tokens::Type::PUNCTUATION && peekToken(offset).value == "->") {
+ offset += 2; // skip '->' and following identifier
+ }
+ const auto & look = peekToken(offset);
+ if (look.type == Lexer::Tokens::Type::OPERATOR_ASSIGNMENT && look.value == "=") {
+ // Consume base variable
+ auto idTok = expect(Lexer::Tokens::Type::VARIABLE_IDENTIFIER);
+ std::string baseName = idTok.value;
+ if (!baseName.empty() && baseName[0] == '$') baseName = baseName.substr(1);
+ // Collect member path keys
+ std::vector<std::string> propertyPath;
+ while (match(Lexer::Tokens::Type::PUNCTUATION, "->")) {
+ // Next token must be identifier or variable identifier
+ Lexer::Tokens::Token propTok;
+ if (currentToken().type == Lexer::Tokens::Type::VARIABLE_IDENTIFIER ||
+ currentToken().type == Lexer::Tokens::Type::IDENTIFIER) {
+ propTok = consumeToken();
+ } else {
+ reportError("Expected property name after '->'");
+ }
+ std::string propName = propTok.value;
+ if (!propName.empty() && propName[0] == '$') propName = propName.substr(1);
+ propertyPath.push_back(propName);
+ }
+ // Consume '='
+ auto eqTok = 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);
+ return std::make_unique<Interpreter::AssignmentStatementNode>(
+ baseName, std::move(propertyPath), std::move(rhsNode),
+ this->current_filename_, eqTok.line_number, eqTok.column_number);
+ }
+ }
// Function call statement
if (currentToken().type == Lexer::Tokens::Type::IDENTIFIER &&
peekToken().type == Lexer::Tokens::Type::PUNCTUATION && peekToken().value == "(") {
--
Gitblit v1.9.3