From 86904d513734134beffc29c6f4012d53a99f25c5 Mon Sep 17 00:00:00 2001
From: Ferenc Szontágh <szf@fsociety.hu>
Date: Sun, 13 Apr 2025 15:38:34 +0000
Subject: [PATCH] some clean up, added function declaration
---
src/ScriptInterpreter.hpp | 115 +++++++++++++++++++++++----------------------------------
1 files changed, 46 insertions(+), 69 deletions(-)
diff --git a/src/ScriptInterpreter.hpp b/src/ScriptInterpreter.hpp
index 2791e02..5ecc7c3 100644
--- a/src/ScriptInterpreter.hpp
+++ b/src/ScriptInterpreter.hpp
@@ -1,6 +1,7 @@
#ifndef SSCRIPTINTERPRETER_HPP
#define SSCRIPTINTERPRETER_HPP
#include <functional>
+#include <map>
#include <memory>
#include <string>
#include <unordered_map>
@@ -10,90 +11,66 @@
#include "Token.hpp"
#include "Value.hpp"
-using FunctionValidator = std::function<void(const std::vector<Token> &, size_t &)>;
+using FunctionValidator =
+ std::function<void(const std::vector<Token> &, size_t &, const std::unordered_map<std::string, Value> &)>;
+using VariableContext = std::unordered_map<std::string, Value>;
class ScriptInterpreter {
public:
- void registerFunction(const std::string & name, std::shared_ptr<BaseFunction> fn);
- void executeScript(const std::string & source, const std::string & filenaneame, bool debug = false);
-
- static void throwUnexpectedTokenError(const Token & token, const std::string & expected = "",
- const std::string & file = "", const int & line = 0) {
- const std::string error_content =
- "unexpected token: '" + token.lexeme + "' type: " + tokenTypeNames.at(token.type) +
- (expected.empty() ? "" : ", expected: '" + expected + "'") + " in file: " + token.file + ":" +
- std::to_string(token.lineNumber) + ":" + std::to_string(token.columnNumber);
-#ifdef DEBUG_BUILD
- const std::string error_message = file + ":" + std::to_string(line) + "\n" + error_content;
-#else
- const std::string& error_message = error_content;
-#endif
- throw std::runtime_error(error_message);
- };
-
- static void throwUndefinedVariableError(const std::string & name, const Token & token, const std::string & file,
- const int & line = 0) {
- const std::string error_content = "undefined variable: '$" + name + "' in file: " + token.file + ":" +
- std::to_string(token.lineNumber) + ":" + std::to_string(token.columnNumber);
-#ifdef DEBUG_BUILD
- const std::string error_message = file + ":" + std::to_string(line) + "\n" + error_content;
-#else
- const std::string& error_message = error_content;
-#endif
- throw std::runtime_error(error_message);
- }
-
- static void throwVariableTypeMissmatchError(const std::string & target_variable_name,
- const std::string & target_type,
- const std::string & source_variable_name,
- const std::string & source_type, const Token & token,
- const std::string & file = "", const int & line = 0) {
- std::string error_content =
- "variable type missmatch: '$" + target_variable_name + "' declared type: '" + target_type + "'";
- if (!source_variable_name.empty()) {
- error_content += " source variable: '" + source_variable_name + "'";
- }
- if (!source_type.empty()) {
- error_content += " assigned type: '" + source_type + "'";
- }
-
- error_content += " in file: " + token.file + ":" + std::to_string(token.lineNumber) + ":" +
- std::to_string(token.columnNumber);
-#ifdef DEBUG_BUILD
- const std::string error_message = file + ":" + std::to_string(line) + "\n" + error_content;
-#else
- const std::string error_message = error_content;
-#endif
- throw std::runtime_error(error_message);
- }
-
- static void throwVariableRedefinitionError(const std::string & name, const Token & token,
- const std::string & file = "", const int line = 0) {
- const std::string error_content = "variable alread defined: " + name + " in file: " + token.file + ":" +
- std::to_string(token.lineNumber) + ":" + std::to_string(token.columnNumber);
-#ifdef DEBUG_BUILD
- const std::string error_message = file + ":" + std::to_string(line) + "\n" + error_content;
-#else
- const std::string& error_message = error_content;
-#endif
- throw std::runtime_error(error_message);
- }
+ void registerModule(const std::string & name, std::shared_ptr<BaseFunction> fn);
+ void executeScript(const std::string & source, const std::string & filenaneame, bool ignore_tags = false);
private:
std::unordered_map<std::string, FunctionValidator> functionValidators;
std::unordered_map<std::string, std::shared_ptr<BaseFunction>> functionObjects;
- std::unordered_map<std::string, Value> variables;
+ // store the current script's variables
+ std::unordered_map<std::string, VariableContext> variables;
+ // store the current script's function arguments
+ std::unordered_map<std::string, std::vector<Value>> functionParameters;
+ std::unordered_map<std::string, std::string> functionBodies;
+ std::string filename;
- std::vector<Value> parseArguments(const std::vector<Token> & tokens, std::size_t & current_index) const;
- Value evaluateExpression(const Token & token) const;
+ [[nodiscard]] std::vector<Value> parseFunctionArguments(const std::vector<Token> & tokens,
+ std::size_t & index) const;
+ [[nodiscard]] Value evaluateExpression(const Token & token) const;
+
// type handlers
- void expectSemicolon(const std::vector<Token> & tokens, std::size_t & i, const std::string & message) const;
+ void setVariable(const std::string & name, const Value & value, const std::string & context = "default") {
+ this->variables[context][name] = value;
+ }
+
+ [[nodiscard]] Value getVariable(const std::string & name, const std::string & context = "default") const {
+ for (auto it = variables.begin(); it != variables.end(); ++it) {
+ if (it->first == context) {
+ const auto & innerMap = it->second.find(name);
+ if (innerMap != it->second.end()) {
+ return it->second.at(name);
+ }
+ }
+ }
+ throw std::runtime_error("Variable not found: " + name);
+ };
+
+ [[nodiscard]] Value getVariable(const Token & token, const std::string & context = "default") const {
+ for (auto it = variables.begin(); it != variables.end(); ++it) {
+ if (it->first == context) {
+ const auto & innerMap = it->second.find(token.lexeme);
+ if (innerMap != it->second.end()) {
+ return it->second.at(token.lexeme);
+ }
+ }
+ }
+ THROW_UNDEFINED_VARIABLE_ERROR(token.lexeme, token);
+ };
+
void handleFunctionCall(const std::vector<Token> & tokens, std::size_t & i);
void handleVariableReference(const std::vector<Token> & tokens, std::size_t & i);
void handleComment(std::size_t & i);
void handleSemicolon(std::size_t & i);
void handleStringDeclaration(const std::vector<Token> & tokens, std::size_t & i);
+ void handleBooleanDeclaration(const std::vector<Token> & tokens, std::size_t & i);
void handleNumberDeclaration(const std::vector<Token> & tokens, std::size_t & i, TokenType type);
+ void handleFunctionDeclaration(const std::vector<Token> & tokens, std::size_t & i);
};
#endif // SSCRIPTINTERPRETER_HPP
--
Gitblit v1.9.3