fix function parameter parser
5 files modified
2 files added
| | |
| | | #include "Parser/ParsedExpression.hpp" |
| | | #include "Symbols/ParameterContainer.hpp" |
| | | #include "Symbols/Value.hpp" |
| | | #include "Interpreter/ReturnStatementNode.hpp" |
| | | |
| | | namespace Interpreter { |
| | | |
| | |
| | | ns, |
| | | Operations::Operation{Operations::Type::FunctionCall, functionName, std::move(stmt)}); |
| | | } |
| | | /** |
| | | * @brief Record a return statement operation inside a function. |
| | | * @param pexpr Parsed expression for return value, or nullptr for void return. |
| | | * @param ns Current namespace (function scope). |
| | | * @param fileName Source filename. |
| | | * @param line Line number of return. |
| | | * @param column Column number of return. |
| | | */ |
| | | static void callReturn(const Parser::ParsedExpressionPtr &pexpr, |
| | | const std::string & ns, |
| | | const std::string & fileName, |
| | | int line, |
| | | size_t column) { |
| | | std::unique_ptr<ExpressionNode> expr = pexpr ? buildExpressionFromParsed(pexpr) : nullptr; |
| | | auto stmt = std::make_unique<ReturnStatementNode>(std::move(expr), fileName, line, column); |
| | | Operations::Container::instance()->add(ns, |
| | | Operations::Operation{Operations::Type::Return, std::string(), std::move(stmt)}); |
| | | } |
| | | }; |
| | | |
| | | } // namespace Interpreter |
| New file |
| | |
| | | // ReturnException.hpp |
| | | #ifndef INTERPRETER_RETURN_EXCEPTION_HPP |
| | | #define INTERPRETER_RETURN_EXCEPTION_HPP |
| | | |
| | | #include "Symbols/Value.hpp" |
| | | |
| | | namespace Interpreter { |
| | | /** |
| | | * @brief Exception used to unwind the call stack when a return statement is executed. |
| | | */ |
| | | class ReturnException { |
| | | public: |
| | | explicit ReturnException(const Symbols::Value &value) : value_(value) {} |
| | | const Symbols::Value &value() const { return value_; } |
| | | private: |
| | | Symbols::Value value_; |
| | | }; |
| | | } // namespace Interpreter |
| | | #endif // INTERPRETER_RETURN_EXCEPTION_HPP |
| New file |
| | |
| | | // ReturnStatementNode.hpp |
| | | #ifndef INTERPRETER_RETURN_STATEMENT_NODE_HPP |
| | | #define INTERPRETER_RETURN_STATEMENT_NODE_HPP |
| | | |
| | | #include <memory> |
| | | #include <string> |
| | | #include "StatementNode.hpp" |
| | | #include "ExpressionNode.hpp" |
| | | #include "ReturnException.hpp" |
| | | #include "Symbols/Value.hpp" |
| | | |
| | | namespace Interpreter { |
| | | |
| | | /** |
| | | * @brief Statement node representing a return statement inside a function. |
| | | */ |
| | | class ReturnStatementNode : public StatementNode { |
| | | std::unique_ptr<ExpressionNode> expr_; |
| | | public: |
| | | explicit ReturnStatementNode(std::unique_ptr<ExpressionNode> expr, |
| | | const std::string &file_name, |
| | | int line, |
| | | size_t column) : |
| | | StatementNode(file_name, line, column), expr_(std::move(expr)) {} |
| | | |
| | | void interpret(Interpreter &interpreter) const override { |
| | | Symbols::Value retVal; |
| | | if (expr_) { |
| | | retVal = expr_->evaluate(interpreter); |
| | | } |
| | | throw ReturnException(retVal); |
| | | } |
| | | |
| | | std::string toString() const override { |
| | | return std::string("return") + (expr_ ? (" " + expr_->toString()) : std::string()); |
| | | } |
| | | }; |
| | | |
| | | } // namespace Interpreter |
| | | #endif // INTERPRETER_RETURN_STATEMENT_NODE_HPP |
| | |
| | | id_token.column_number); |
| | | } |
| | | |
| | | // Parse a return statement, e.g., return; or return expression; |
| | | void Parser::parseReturnStatement() { |
| | | // Consume 'return' keyword |
| | | auto returnToken = expect(Lexer::Tokens::Type::KEYWORD_RETURN); |
| | | // Parse optional expression |
| | | ParsedExpressionPtr expr = nullptr; |
| | | if (!(currentToken().type == Lexer::Tokens::Type::PUNCTUATION && currentToken().value == ";")) { |
| | | expr = parseParsedExpression(Symbols::Variables::Type::NULL_TYPE); |
| | | } |
| | | // Record return operation |
| | | Interpreter::OperationsFactory::callReturn( |
| | | expr, |
| | | Symbols::SymbolContainer::instance()->currentScopeName(), |
| | | this->current_filename_, |
| | | returnToken.line_number, |
| | | returnToken.column_number); |
| | | // Consume terminating semicolon |
| | | expect(Lexer::Tokens::Type::PUNCTUATION, ";"); |
| | | } |
| | | |
| | | // Continue with numeric literal parsing |
| | | // |
| | | Symbols::Value Parser::parseNumericLiteral(const std::string & value, bool is_negative, Symbols::Variables::Type type) { |
| | | try { |
| | | switch (type) { |
| | |
| | | throw Exception(message, expected, token); |
| | | } |
| | | |
| | | // parseStatement (unchanged) |
| | | // parseStatement (updated to handle return) |
| | | void parseStatement() { |
| | | const auto & token_type = currentToken().type; |
| | | |
| | | if (token_type == Lexer::Tokens::Type::KEYWORD_FUNCTION_DECLARATION) { |
| | | parseFunctionDefinition(); |
| | | return; |
| | | } |
| | | // Return statement |
| | | if (token_type == Lexer::Tokens::Type::KEYWORD_RETURN) { |
| | | parseReturnStatement(); |
| | | return; |
| | | } |
| | | |
| | |
| | | void parseFunctionDefinition(); |
| | | // Parse a top-level function call statement (e.g., foo(arg1, arg2);) |
| | | void parseCallStatement(); |
| | | // Parse a return statement (e.g., return; or return expr;) |
| | | void parseReturnStatement(); |
| | | |
| | | // --- Parsing helper functions --- |
| | | |
| | |
| | | trimmed.erase(0, trimmed.find_first_not_of(" \t\n\r")); |
| | | trimmed.erase(trimmed.find_last_not_of(" \t\n\r") + 1); |
| | | |
| | | // Check bool |
| | | // Check bool literals |
| | | std::string lower = trimmed; |
| | | std::transform(lower.begin(), lower.end(), lower.begin(), ::tolower); |
| | | if (lower == "true" || lower == "false" || lower == "1" || lower == "0") { |
| | | if (lower == "true" || lower == "false") { |
| | | try { |
| | | return fromStringToBool(trimmed); |
| | | } catch (...) { |
| | |
| | | string $variable2 = $variable; |
| | | |
| | | function test = (int $i) { |
| | | print("Param: ",$i); |
| | | int $result = $i + 1; |
| | | print("The result is: ", $result); |
| | | } |
| | | |
| | | function increment = (int $i) int { |
| | |
| | | } |
| | | |
| | | |
| | | increment(1); |
| | | test(1); |
| | | |
| | | int $t = increment(2); |
| | | print("The result is: ", $t); |