From 48d9278f0b75098e83e58c589ea86d006358604d Mon Sep 17 00:00:00 2001
From: Ferenc Szontágh <szf@fsociety.hu>
Date: Sat, 19 Apr 2025 18:02:04 +0000
Subject: [PATCH] add for ( loop, and docs

---
 src/Parser/Parser.cpp |   99 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 99 insertions(+), 0 deletions(-)

diff --git a/src/Parser/Parser.cpp b/src/Parser/Parser.cpp
index 1ec0322..42b3d45 100644
--- a/src/Parser/Parser.cpp
+++ b/src/Parser/Parser.cpp
@@ -13,6 +13,7 @@
 #include "Interpreter/DeclareVariableStatementNode.hpp"
 #include "Interpreter/ExpressionBuilder.hpp"
 #include "Interpreter/ForStatementNode.hpp"
+#include "Interpreter/CStyleForStatementNode.hpp"
 #include "Interpreter/ReturnStatementNode.hpp"
 #include "Symbols/SymbolContainer.hpp"
 
@@ -167,6 +168,54 @@
     std::string firstName = firstTok.value;
     if (!firstName.empty() && firstName[0] == '$') {
         firstName = firstName.substr(1);
+    }
+    // C-style for loop: for (type $i = init; cond; incr) { ... }
+    if (match(Lexer::Tokens::Type::OPERATOR_ASSIGNMENT, "=")) {
+        // Parse initialization expression
+        auto initExpr = parseParsedExpression(elemType);
+        expect(Lexer::Tokens::Type::PUNCTUATION, ";");
+        // Parse condition expression
+        auto condExpr = parseParsedExpression(Symbols::Variables::Type::NULL_TYPE);
+        expect(Lexer::Tokens::Type::PUNCTUATION, ";");
+        // Parse increment statement
+        std::unique_ptr<Interpreter::StatementNode> incrStmt;
+        {
+            auto incrTok = currentToken();
+            if (incrTok.type == Lexer::Tokens::Type::VARIABLE_IDENTIFIER) {
+                auto identTok = consumeToken();
+                std::string incrName = identTok.value;
+                if (!incrName.empty() && incrName[0] == '$') incrName = incrName.substr(1);
+                if (match(Lexer::Tokens::Type::OPERATOR_INCREMENT, "++")) {
+                    auto lhs = std::make_unique<Interpreter::IdentifierExpressionNode>(incrName);
+                    auto rhs = std::make_unique<Interpreter::LiteralExpressionNode>(Symbols::Value(1));
+                    auto bin = std::make_unique<Interpreter::BinaryExpressionNode>(std::move(lhs), "+", std::move(rhs));
+                    incrStmt = std::make_unique<Interpreter::AssignmentStatementNode>(incrName, std::vector<std::string>(), std::move(bin), this->current_filename_, incrTok.line_number, incrTok.column_number);
+                } else if (match(Lexer::Tokens::Type::OPERATOR_INCREMENT, "--")) {
+                    auto lhs = std::make_unique<Interpreter::IdentifierExpressionNode>(incrName);
+                    auto rhs = std::make_unique<Interpreter::LiteralExpressionNode>(Symbols::Value(1));
+                    auto bin = std::make_unique<Interpreter::BinaryExpressionNode>(std::move(lhs), "-", std::move(rhs));
+                    incrStmt = std::make_unique<Interpreter::AssignmentStatementNode>(incrName, std::vector<std::string>(), std::move(bin), this->current_filename_, incrTok.line_number, incrTok.column_number);
+                } else {
+                    reportError("Expected '++' or '--' in for-loop increment");
+                }
+            } else {
+                reportError("Expected variable name in for-loop increment");
+            }
+        }
+        expect(Lexer::Tokens::Type::PUNCTUATION, ")");
+        expect(Lexer::Tokens::Type::PUNCTUATION, "{");
+        // Parse loop body
+        std::vector<std::unique_ptr<Interpreter::StatementNode>> body;
+        while (!(currentToken().type == Lexer::Tokens::Type::PUNCTUATION && currentToken().value == "}")) {
+            body.push_back(parseStatementNode());
+        }
+        expect(Lexer::Tokens::Type::PUNCTUATION, "}");
+        // Build nodes for C-style for
+        auto initExprNode = buildExpressionFromParsed(initExpr);
+        auto initStmt = std::make_unique<Interpreter::DeclareVariableStatementNode>(firstName, Symbols::SymbolContainer::instance()->currentScopeName(), elemType, std::move(initExprNode), this->current_filename_, firstTok.line_number, firstTok.column_number);
+        auto condExprNode = buildExpressionFromParsed(condExpr);
+        auto * cnode = new Interpreter::CStyleForStatementNode(std::move(initStmt), std::move(condExprNode), std::move(incrStmt), std::move(body), this->current_filename_, forToken.line_number, forToken.column_number);
+        return std::unique_ptr<Interpreter::StatementNode>(cnode);
     }
     // Determine loop form: key,value or simple element loop
     std::string keyName, valName;
@@ -431,6 +480,56 @@
     if (!firstName.empty() && firstName[0] == '$') {
         firstName = firstName.substr(1);
     }
+    // C-style for loop: for (type $i = init; cond; incr) { ... }
+    if (match(Lexer::Tokens::Type::OPERATOR_ASSIGNMENT, "=")) {
+        // Parse initialization expression
+        auto initExpr = parseParsedExpression(elemType);
+        expect(Lexer::Tokens::Type::PUNCTUATION, ";");
+        // Parse condition expression
+        auto condExpr = parseParsedExpression(Symbols::Variables::Type::NULL_TYPE);
+        expect(Lexer::Tokens::Type::PUNCTUATION, ";");
+        // Parse increment statement
+        std::unique_ptr<Interpreter::StatementNode> incrStmt;
+        {
+            auto incrTok = currentToken();
+            if (incrTok.type == Lexer::Tokens::Type::VARIABLE_IDENTIFIER) {
+                auto identTok = consumeToken();
+                std::string incrName = identTok.value;
+                if (!incrName.empty() && incrName[0] == '$') incrName = incrName.substr(1);
+                if (match(Lexer::Tokens::Type::OPERATOR_INCREMENT, "++")) {
+                    auto lhs = std::make_unique<Interpreter::IdentifierExpressionNode>(incrName);
+                    auto rhs = std::make_unique<Interpreter::LiteralExpressionNode>(Symbols::Value(1));
+                    auto bin = std::make_unique<Interpreter::BinaryExpressionNode>(std::move(lhs), "+", std::move(rhs));
+                    incrStmt = std::make_unique<Interpreter::AssignmentStatementNode>(incrName, std::vector<std::string>(), std::move(bin), this->current_filename_, incrTok.line_number, incrTok.column_number);
+                } else if (match(Lexer::Tokens::Type::OPERATOR_INCREMENT, "--")) {
+                    auto lhs = std::make_unique<Interpreter::IdentifierExpressionNode>(incrName);
+                    auto rhs = std::make_unique<Interpreter::LiteralExpressionNode>(Symbols::Value(1));
+                    auto bin = std::make_unique<Interpreter::BinaryExpressionNode>(std::move(lhs), "-", std::move(rhs));
+                    incrStmt = std::make_unique<Interpreter::AssignmentStatementNode>(incrName, std::vector<std::string>(), std::move(bin), this->current_filename_, incrTok.line_number, incrTok.column_number);
+                } else {
+                    reportError("Expected '++' or '--' in for-loop increment");
+                }
+            } else {
+                reportError("Expected variable name in for-loop increment");
+            }
+        }
+        expect(Lexer::Tokens::Type::PUNCTUATION, ")");
+        expect(Lexer::Tokens::Type::PUNCTUATION, "{");
+        // Parse loop body
+        std::vector<std::unique_ptr<Interpreter::StatementNode>> body;
+        while (!(currentToken().type == Lexer::Tokens::Type::PUNCTUATION && currentToken().value == "}")) {
+            body.push_back(parseStatementNode());
+        }
+        expect(Lexer::Tokens::Type::PUNCTUATION, "}");
+        // Build nodes for C-style for
+        auto initExprNode = buildExpressionFromParsed(initExpr);
+        auto initStmt = std::make_unique<Interpreter::DeclareVariableStatementNode>(firstName, Symbols::SymbolContainer::instance()->currentScopeName(), elemType, std::move(initExprNode), this->current_filename_, firstTok.line_number, firstTok.column_number);
+        auto condExprNode = buildExpressionFromParsed(condExpr);
+        auto cnode = std::make_unique<Interpreter::CStyleForStatementNode>(std::move(initStmt), std::move(condExprNode), std::move(incrStmt), std::move(body), this->current_filename_, forToken.line_number, forToken.column_number);
+        Operations::Container::instance()->add(Symbols::SymbolContainer::instance()->currentScopeName(),
+                                               Operations::Operation{Operations::Type::Loop, "", std::move(cnode)});
+        return;
+    }
     // Determine loop form: key,value or simple element loop
     std::string keyName, valName;
     Symbols::Variables::Type keyType;

--
Gitblit v1.9.3