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