diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/.name b/.idea/.name new file mode 100644 index 0000000..b2edcbc --- /dev/null +++ b/.idea/.name @@ -0,0 +1 @@ +LuaCpp \ No newline at end of file diff --git a/.idea/LUA-Cpp.iml b/.idea/LUA-Cpp.iml new file mode 100644 index 0000000..f08604b --- /dev/null +++ b/.idea/LUA-Cpp.iml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/.idea/betterCommentsSettings.xml b/.idea/betterCommentsSettings.xml new file mode 100644 index 0000000..4f152ed --- /dev/null +++ b/.idea/betterCommentsSettings.xml @@ -0,0 +1,31 @@ + + + + + + \ No newline at end of file diff --git a/.idea/editor.xml b/.idea/editor.xml new file mode 100644 index 0000000..970f097 --- /dev/null +++ b/.idea/editor.xml @@ -0,0 +1,341 @@ + + + + + \ No newline at end of file diff --git a/.idea/material_theme_project_new.xml b/.idea/material_theme_project_new.xml new file mode 100644 index 0000000..2bed42b --- /dev/null +++ b/.idea/material_theme_project_new.xml @@ -0,0 +1,10 @@ + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..0b76fe5 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..e65c27f --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..bb770b9 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,17 @@ +cmake_minimum_required(VERSION 3.10) +project(LuaCpp) + +set(CMAKE_CXX_STANDARD 20) + + +include_directories(src) + + + +add_executable(LuaCpp + + src/LuaCpp.cpp + src/LuaCpp.h + main.cpp + +) diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..9aed70d --- /dev/null +++ b/main.cpp @@ -0,0 +1,17 @@ +// +// Created by spenc on 5/19/2025. +// +#include "LuaCpp.h" + +int main() +{ + LC::LuaCpp luaState; + + luaState.loadFile("./test.lua"); + + luaState.Call("test"); + + + + +} \ No newline at end of file diff --git a/src/LuaCpp.cpp b/src/LuaCpp.cpp new file mode 100644 index 0000000..8081b50 --- /dev/null +++ b/src/LuaCpp.cpp @@ -0,0 +1,134 @@ +// +// Created by spenc on 5/19/2025. +// + +#include "LuaCpp.h" +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#ifndef NDEBUG +#define LC_LOG(fmt, ...) std::printf("[Lua] " fmt "\n", ##__VA_ARGS__) +#else + #define LC_LOG(fmt, ...) ((void)0) +#endif + +std::ostream& operator<<(std::ostream& os, const std::unordered_map& map) { + os << "{\n"; + for (const auto& [key, value] : map) { + os << " \"" << key << "\": " << static_cast(value) << ",\n"; + } + os << "}"; + return os; +} + + +namespace LC +{ + // Public API + LuaStatus LuaCpp::Call(const std::string &functionName) + { + + if (!luaFunctions.contains(functionName)) { + LC_LOG("Not Found '%s'", functionName.c_str()); + return LC_FUNCTIONNOTFOUND; + } + + + + + LC_LOG("Called %s", functionName.c_str()); + return LC_OK; + } + + LuaStatus LuaCpp::loadFile(const std::string &scriptPath) + { + luaFunctions.clear(); + + path = scriptPath; + LuaStatus status = LoadInternal(); + + if (!status.Ok()) { + printf("[LuaCpp] %s", status.ToString().c_str()); + return status; + } + + initialized = true; + return LC_OK; + } + + + // Private API + LuaCpp::LuaCpp() + { + luaFunctions.clear(); + } + + void LuaCpp::ExtractLuaFunctions(const std::string &luaCode) + { + std::regex funcRegex(R"(\bfunction\s+([a-zA-Z_][\w.:]*)\b)"); + std::smatch match; + auto begin = luaCode.cbegin(); + auto end = luaCode.cend(); + + while (std::regex_search(begin, end, match, funcRegex)) { + std::string functionName = match[1]; + luaFunctions[functionName] = 0; // placeholder value + begin = match.suffix().first; + } + } + + void LuaCpp::ExtractLuaVariables(const std::string& luaCode) + { + std::regex varRegex(R"(\b([a-zA-Z_][\w]*)\s*=\s*[^=])"); // avoids '==' + std::smatch match; + auto begin = luaCode.cbegin(); + auto end = luaCode.cend(); + + while (std::regex_search(begin, end, match, varRegex)) { + std::string varName = match[1]; + luaVariables[varName] = 0; // Placeholder bytecode pointer + begin = match.suffix().first; + } + + + } + + + + std::string LuaCpp::ReadFile(const std::string &path) + { + const std::ifstream file(path, std::ios::in | std::ios::binary); + if (!file) { + return ""; + } + std::ostringstream contents; + contents << file.rdbuf(); + return contents.str(); + } + + LuaStatus LuaCpp::LoadInternal() + { + std::string fileContents = ReadFile(path); + + + if (fileContents.empty()) { + return LC_FILEREADERROR; + } + ExtractLuaVariables(fileContents); + ExtractLuaFunctions(fileContents); + + std::cout << luaFunctions << std::endl; + std::cout << luaVariables << std::endl; + + return LC_OK; + } +} // LC diff --git a/src/LuaCpp.h b/src/LuaCpp.h new file mode 100644 index 0000000..4dba6d5 --- /dev/null +++ b/src/LuaCpp.h @@ -0,0 +1,91 @@ +// +// Created by spenc on 5/19/2025. +// + +#ifndef LUACPP_H +#define LUACPP_H +#include +#include +#include + +namespace LC +{ + enum LuaStatusCode { + LC_OK = 0, + LC_ERROR, + LC_UNINITIALIZED, + LC_UNAVAILABLE, + LC_UNAUTHORIZED, + LC_UNSUPPORTED, + LC_NOFILE, + LC_FILEREADERROR, + LC_FUNCTIONNOTFOUND, + }; + + class LuaStatus { + public: + LuaStatus(LuaStatusCode code = LC_OK) : code_(code) {} + + [[nodiscard]] bool Ok() const { return code_ == LC_OK; } + + [[nodiscard]] LuaStatusCode Code() const { return code_; } + + [[nodiscard]] std::string ToString() const { + switch (code_) { + case LC_OK: return "OK"; + case LC_ERROR: return "Error"; + case LC_UNINITIALIZED: return "Uninitialized"; + case LC_UNAVAILABLE: return "Unavailable"; + case LC_UNAUTHORIZED: return "Unauthorized"; + case LC_UNSUPPORTED: return "Unsupported"; + case LC_NOFILE: return "No File"; + case LC_FILEREADERROR: return "File Read Error"; + case LC_FUNCTIONNOTFOUND: return "Function Not Found"; + + default: return "Unknown"; + } + } + + bool operator==(LuaStatusCode other) const { return code_ == other; } + bool operator!=(LuaStatusCode other) const { return code_ != other; } + + private: + LuaStatusCode code_; + }; + + + + class LuaCpp + { + public: + + LuaCpp(); + ~LuaCpp() = default; + LuaCpp(const LuaCpp&) = delete; + + + LuaStatus loadFile(const std::string& scriptPath); + LuaStatus Call(const std::string& functionName); + + + private: + // Private Functions + void ExtractLuaFunctions(const std::string& luaCode); + void ExtractLuaVariables(const std::string& luaCode); + LuaStatus LoadInternal(); + static std::string ReadFile(const std::string& path); + + + + // Private Vars (alphabetical by and by type) + bool initialized = false; + + std::unordered_map luaFunctions; + std::unordered_map luaVariables; + + + std::string path; + }; +} // LC + +#endif //LUACPP_H diff --git a/test.lua b/test.lua new file mode 100644 index 0000000..3a18da8 --- /dev/null +++ b/test.lua @@ -0,0 +1,12 @@ + + +local numberVariable = 0 + +local function test() + + print(numberVariable .. ";") + +end + + +test() \ No newline at end of file