| src/!NameSpaceManager.hpp | ●●●●● patch | view | raw | blame | history | |
| src/Interpreter/CallStatementNode.hpp | ●●●●● patch | view | raw | blame | history | |
| src/Interpreter/Interpreter.hpp | ●●●●● patch | view | raw | blame | history | |
| src/Interpreter/OperationsFactory.hpp | ●●●●● patch | view | raw | blame | history | |
| src/Lexer/Operators.hpp | ●●●●● patch | view | raw | blame | history | |
| src/Parser/Parser.cpp | ●●●●● patch | view | raw | blame | history | |
| src/Symbols/SymbolFactory.hpp | ●●●●● patch | view | raw | blame | history | |
| test_scripts/test2.vs | ●●●●● patch | view | raw | blame | history |
src/!NameSpaceManager.hpp
File was deleted src/Interpreter/CallStatementNode.hpp
New file @@ -0,0 +1,90 @@ #ifndef INTERPRETER_CALL_STATEMENT_NODE_HPP #define INTERPRETER_CALL_STATEMENT_NODE_HPP #include <memory> #include <string> #include <vector> #include "ExpressionNode.hpp" #include "Interpreter/Interpreter.hpp" #include "Interpreter/OperationContainer.hpp" #include "StatementNode.hpp" #include "Symbols/FunctionSymbol.hpp" #include "Symbols/SymbolContainer.hpp" #include "Symbols/SymbolFactory.hpp" #include "Symbols/Value.hpp" namespace Interpreter { /** * @brief Statement node representing a function call with argument expressions. */ class CallStatementNode : public StatementNode { std::string functionName_; std::vector<std::unique_ptr<ExpressionNode>> args_; public: CallStatementNode(const std::string & functionName, std::vector<std::unique_ptr<ExpressionNode>> args, const std::string & file_name, int file_line, size_t column) : StatementNode(file_name, file_line, column), functionName_(functionName), args_(std::move(args)) {} void interpret(Interpreter & interpreter) const override { using namespace Symbols; // Evaluate argument expressions std::vector<Value> argValues; argValues.reserve(args_.size()); for (const auto & expr : args_) { argValues.push_back(expr->evaluate(interpreter)); } // Lookup function symbol in functions namespace SymbolContainer * sc = SymbolContainer::instance(); const std::string currentNs = sc->currentScopeName(); const std::string fnSymNs = currentNs + ".functions"; auto sym = sc->get(fnSymNs, functionName_); if (!sym || sym->getKind() != Kind::Function) { throw std::runtime_error("Function not found: " + functionName_); } auto funcSym = std::static_pointer_cast<FunctionSymbol>(sym); // Check parameter count const auto & params = funcSym->parameters(); if (params.size() != argValues.size()) { throw std::runtime_error("Function '" + functionName_ + "' expects " + std::to_string(params.size()) + " args, got " + std::to_string(argValues.size())); } // Enter function scope to bind parameters and execute body const std::string fnOpNs = currentNs + "." + functionName_; sc->enter(fnOpNs); // Bind parameters as local variables for (size_t i = 0; i < params.size(); ++i) { const auto & p = params[i]; const Value & v = argValues[i]; auto varSym = SymbolFactory::createVariable(p.name, v, fnOpNs); sc->add(varSym); } // Execute function body operations auto ops = Operations::Container::instance()->getAll(fnOpNs); auto it = ops.begin(); for (; it != ops.end(); ++it) { interpreter.runOperation(*(*it)); } // Exit function scope sc->enterPreviousScope(); } std::string toString() const override { return "CallStatementNode{ functionName='" + functionName_ + "', " + "args=" + std::to_string(args_.size()) + " " + "filename='" + filename_ + "', " + "line=" + std::to_string(line_) + ", " + "column=" + std::to_string(column_) + "}"; }; }; } // namespace Interpreter // namespace Interpreter #endif // INTERPRETER_CALL_STATEMENT_NODE_HPP src/Interpreter/Interpreter.hpp
@@ -12,6 +12,22 @@ class Interpreter { private: public: Interpreter() {} /** * @brief Execute all operations in the current namespace (e.g., file-level or function-level). */ void run() { // Determine namespace to execute const std::string ns = Symbols::SymbolContainer::instance()->currentScopeName(); for (const auto & operation : Operations::Container::instance()->getAll(ns)) { runOperation(*operation); } } void runOperation(const Operations::Operation & op) { std::cout << "Operation: " << op.toString() << "\n"; @@ -39,13 +55,11 @@ break; } case Operations::Type::FunctionCall: { // Check that the called function is defined in the symbol table if (!Symbols::SymbolContainer::instance()->exists(op.targetName)) { throw std::runtime_error("Function not declared: " + op.targetName); case Operations::Type::FunctionCall: if (op.statement) { op.statement->interpret(*this); } break; } case Operations::Type::Return: case Operations::Type::Loop: case Operations::Type::Break: @@ -58,15 +72,6 @@ break; default: throw std::runtime_error("Not implemented operation type"); } } public: Interpreter() {} void run() { for (const auto & operation : Operations::Container::instance()->getAll()) { runOperation(*operation); } } src/Interpreter/OperationsFactory.hpp
@@ -8,6 +8,7 @@ #include "Interpreter/DeclareVariableStatementNode.hpp" #include "Interpreter/ExpressionBuilder.hpp" #include "Interpreter/LiteralExpressionNode.hpp" #include "Interpreter/CallStatementNode.hpp" #include "Interpreter/Operation.hpp" #include "Interpreter/OperationContainer.hpp" #include "Parser/ParsedExpression.hpp" @@ -54,22 +55,31 @@ } /** * @brief Record a function call operation for later detection. * @brief Record a function call operation with argument expressions. * @param functionName Name of the function being called. * @param ns Current namespace scope. * @param parsedArgs Vector of parsed argument expressions. * @param ns Current namespace scope for operations. * @param fileName Source filename. * @param line Line number of call. * @param column Column number of call. */ static void callFunction(const std::string & functionName, std::vector<Parser::ParsedExpressionPtr> &&parsedArgs, const std::string & ns, const std::string & fileName, int line, size_t column) { // No associated StatementNode; this is for detection only // Build argument ExpressionNode list std::vector<std::unique_ptr<ExpressionNode>> exprs; exprs.reserve(parsedArgs.size()); for (auto &pexpr : parsedArgs) { exprs.push_back(buildExpressionFromParsed(pexpr)); } // Create call statement node auto stmt = std::make_unique<CallStatementNode>(functionName, std::move(exprs), fileName, line, column); Operations::Container::instance()->add( ns, Operations::Operation{Operations::Type::FunctionCall, functionName, nullptr}); Operations::Operation{Operations::Type::FunctionCall, functionName, std::move(stmt)}); } }; src/Lexer/Operators.hpp
@@ -59,8 +59,16 @@ std::vector<Parser::ParsedExpressionPtr> & output_queue) { if (token.type == Tokens::Type::NUMBER || token.type == Tokens::Type::STRING_LITERAL || token.type == Tokens::Type::KEYWORD) { output_queue.push_back( Parser::ParsedExpression::makeLiteral(Symbols::Value::fromString(token.value, expected_var_type))); // Parse literal: use expected type if provided, otherwise auto-detect if (expected_var_type == Symbols::Variables::Type::NULL_TYPE) { output_queue.push_back( Parser::ParsedExpression::makeLiteral( Symbols::Value::fromString(token.value, /*autoDetectType*/ true))); } else { output_queue.push_back( Parser::ParsedExpression::makeLiteral( Symbols::Value::fromString(token.value, expected_var_type))); } return true; } if (token.type == Tokens::Type::VARIABLE_IDENTIFIER) { src/Parser/Parser.cpp
@@ -133,8 +133,13 @@ expect(Lexer::Tokens::Type::PUNCTUATION, ")"); expect(Lexer::Tokens::Type::PUNCTUATION, ";"); // Record the function call operation Interpreter::OperationsFactory::callFunction(func_name, Symbols::SymbolContainer::instance()->currentScopeName(), this->current_filename_, id_token.line_number, id_token.column_number); Interpreter::OperationsFactory::callFunction( func_name, std::move(args), Symbols::SymbolContainer::instance()->currentScopeName(), this->current_filename_, id_token.line_number, id_token.column_number); } Symbols::Value Parser::parseNumericLiteral(const std::string & value, bool is_negative, Symbols::Variables::Type type) { src/Symbols/SymbolFactory.hpp
@@ -14,6 +14,11 @@ class SymbolFactory { public: static std::shared_ptr<Symbol> createVariable(const std::string & name, const Symbols::Value & value, const std::string & context) { return std::make_shared<VariableSymbol>(name, value, context, value.getType()); } static std::shared_ptr<Symbol> createVariable(const std::string & name, const Symbols::Value & value, const std::string & context, Variables::Type type) { return std::make_shared<VariableSymbol>(name, value, context, type); } test_scripts/test2.vs
@@ -4,7 +4,9 @@ string $variable2 = $variable; print("$double: ", $double, "\n"); print("$variable2: ", $variable2, "\n"); print("$variable: ", $variable, "\n"); function test = (int $i) { int $result = $i + 1; } test(5);