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/BaseFunction.hpp | 68 ++++++++++++++++++++++++++++++----
1 files changed, 60 insertions(+), 8 deletions(-)
diff --git a/src/BaseFunction.hpp b/src/BaseFunction.hpp
index a870da6..9038dbc 100644
--- a/src/BaseFunction.hpp
+++ b/src/BaseFunction.hpp
@@ -1,26 +1,78 @@
-// ScriptFunction.hpp
#ifndef SCRIPT_FUNCTION_HPP
#define SCRIPT_FUNCTION_HPP
+#include <functional>
+#include <stdexcept>
+#include <unordered_map>
+#include <utility>
#include <vector>
+#include "ScriptExceptionMacros.h"
+#include "ScriptInterpreterHelpers.hpp"
#include "Token.hpp"
#include "Value.hpp"
-
class ScriptInterpreter;
+
+using CallbackFunction = std::function<Value(const std::vector<Value> &)>;
+using CallBackStorage = std::unordered_map<std::string, CallbackFunction>;
class BaseFunction {
protected:
- std::string name;
+ std::string name;
+ CallBackStorage functionMap;
+
+
public:
- virtual ~BaseFunction() = default;
- virtual void validate(const std::vector<Token> & tokens, size_t & i) const = 0;
+ BaseFunction(const std::string & functionName) : name(functionName) {}
+
+ virtual void addFunction(const std::string & name, std::function<Value(const std::vector<Value> &)> callback) {
+ functionMap[name] = std::move(callback);
+ }
+
+ virtual void validate(const std::vector<Token> & tokens, size_t & i,
+ const std::unordered_map<std::string, Value> & variables) {
+ size_t index = i;
+
+ if (tokens[index].type != TokenType::Identifier) {
+ THROW_UNEXPECTED_TOKEN_ERROR(tokens[index], "identifier");
+ }
+ index++; // skip function name
+
+ if (tokens[index].type != TokenType::LeftParenthesis) {
+ THROW_UNEXPECTED_TOKEN_ERROR(tokens[index], "(");
+ }
+ index++; // skip '('
+
+ std::vector<Token> args;
+ while (tokens[index].type != TokenType::RightParenthesis) {
+ if (tokens[index].type == TokenType::Comma) {
+ index++;
+ continue;
+ }
+ if (tokens[index].type == TokenType::Variable && !variables.contains(tokens[index].lexeme)) {
+ THROW_UNDEFINED_VARIABLE_ERROR(tokens[index].lexeme, tokens[index]);
+ }
+ args.push_back(tokens[index]);
+ index++;
+ }
+
+ index++; // skip ')'
+
+ if (tokens[index].type != TokenType::Semicolon) {
+ THROW_UNEXPECTED_TOKEN_ERROR(tokens[index], ";");
+ }
+
+ this->validateArgs(args, variables);
+ ScriptInterpreterHelpers::expectSemicolon(tokens, index, "function call");
+ }
+
+ virtual void validateArgs(const std::vector<Token> & args,
+ const std::unordered_map<std::string, Value> & variables) = 0;
+
virtual Value call(const std::vector<Value> & args, bool debug = false) const = 0;
- template <typename FuncClass> void registerFunctionTo(ScriptInterpreter & interp) {
- FuncClass::registerTo(interp);
- }
+ template <typename FuncClass> void registerFunctionTo(ScriptInterpreter & interp) { FuncClass::registerTo(interp); }
};
#endif // SCRIPT_FUNCTION_HPP
--
Gitblit v1.9.3