A simple scripting language in C++
Ferenc Szontágh
2025-04-19 d729312dde311aa6c5e9a2008461c04e98ab4ea1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
#ifndef OPERATIONSFACTORY_HPP
#define OPERATIONSFACTORY_HPP
 
#include <memory>
#include <string>
 
#include "Interpreter/DeclareFunctionStatementNode.hpp"
#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"
#include "Symbols/ParameterContainer.hpp"
#include "Symbols/Value.hpp"
#include "Interpreter/ReturnStatementNode.hpp"
 
namespace Interpreter {
 
class OperationsFactory {
  public:
    OperationsFactory() {}
 
    static void defineFunction(const std::string & functionName, const Symbols::FunctionParameterInfo & params,
                               const Symbols::Variables::Type & returnType, const std::string & ns,
                               const std::string & fileName, int line, size_t column) {
        std::unique_ptr<DeclareFunctionStatementNode> stmt = std::make_unique<DeclareFunctionStatementNode>(
            functionName, ns, params, returnType, nullptr, fileName, line, column);
        Operations::Container::instance()->add(
            ns, Operations::Operation{ Operations::Type::FuncDeclaration, functionName, std::move(stmt) });
    }
 
    static void defineSimpleVariable(const std::string & varName, const Symbols::Value & value, const std::string & ns,
                                     const std::string & filename, int line, size_t column) {
        auto literalExpr = std::make_unique<LiteralExpressionNode>(value);
 
        std::unique_ptr<DeclareVariableStatementNode> stmt = std::make_unique<DeclareVariableStatementNode>(
            varName, ns, value.getType(), std::move(literalExpr), filename, line, column);
 
        Operations::Container::instance()->add(
            ns, Operations::Operation{ Operations::Type::Declaration, varName, std::move(stmt) });
    }
 
    static void defineVariableWithExpression(const std::string & varName, Symbols::Variables::Type type,
                                             const Parser::ParsedExpressionPtr pexpr, const std::string & ns,
                                             const std::string & filename, int line, size_t column) {
                                              // ParsedExpression → ExpressionNode
                                              std::unique_ptr<ExpressionNode> expr = buildExpressionFromParsed(pexpr);
 
                                              std::unique_ptr<DeclareVariableStatementNode> stmt = std::make_unique<DeclareVariableStatementNode>(
                                                  varName, ns, type, std::move(expr), filename, line, column);
 
                                              Operations::Container::instance()->add(
                                                  ns, Operations::Operation{Operations::Type::Declaration, varName, std::move(stmt)});
                                          }
    /**
     * @brief Record a constant declaration operation with an initializer expression.
     */
    static void defineConstantWithExpression(const std::string & varName, Symbols::Variables::Type type,
                                             const Parser::ParsedExpressionPtr pexpr, const std::string & ns,
                                             const std::string & filename, int line, size_t column) {
        // Build initializer expression
        std::unique_ptr<ExpressionNode> expr = buildExpressionFromParsed(pexpr);
        // Create declaration node with const flag
        std::unique_ptr<DeclareVariableStatementNode> stmt = std::make_unique<DeclareVariableStatementNode>(
            varName, ns, type, std::move(expr), filename, line, column, /* isConst */ true);
        Operations::Container::instance()->add(
            ns, Operations::Operation{Operations::Type::Declaration, varName, std::move(stmt)});
    }
    
    /**
     * @brief Record a function call operation with argument expressions.
     * @param functionName Name of the function being called.
     * @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) {
        // 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, 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
 
#endif  // OPERATIONSFACTORY_HPP