diff --git a/Parser/include/RigCParser/Grammar/Tokens.hpp b/Parser/include/RigCParser/Grammar/Tokens.hpp index 74c8bbc..63b7231 100644 --- a/Parser/include/RigCParser/Grammar/Tokens.hpp +++ b/Parser/include/RigCParser/Grammar/Tokens.hpp @@ -11,22 +11,8 @@ namespace rigc struct Name; -struct PackageImportNames - : p::seq< - Name, - p::opt< - p::seq< p::one<'.'>, PackageImportNames> - > - > -{ -}; - struct PackageImportFullName - : - p::sor< - StringLiteral, - PackageImportNames - > + : StringLiteral { }; diff --git a/VM/include/RigCVM/Environment.hpp b/VM/include/RigCVM/Environment.hpp new file mode 100644 index 0000000..576038a --- /dev/null +++ b/VM/include/RigCVM/Environment.hpp @@ -0,0 +1,6 @@ +#include RIGCVM_PCH + +namespace rigc::vm +{ +fs::path getVmAppPath(); +} \ No newline at end of file diff --git a/VM/include/RigCVM/ErrorHandling/Exceptions.hpp b/VM/include/RigCVM/ErrorHandling/Exceptions.hpp index ddcec1c..3eaeba6 100644 --- a/VM/include/RigCVM/ErrorHandling/Exceptions.hpp +++ b/VM/include/RigCVM/ErrorHandling/Exceptions.hpp @@ -8,6 +8,7 @@ struct RigCError : std::exception { +private: std::string basicMessage; std::string helpMessage; diff --git a/VM/include/RigCVM/ErrorHandling/Formatting.hpp b/VM/include/RigCVM/ErrorHandling/Formatting.hpp index 6186669..b7284b0 100644 --- a/VM/include/RigCVM/ErrorHandling/Formatting.hpp +++ b/VM/include/RigCVM/ErrorHandling/Formatting.hpp @@ -68,7 +68,7 @@ inline auto errorWithLineArgPair(std::size_t line) -> ArgPair auto const value = fmt::format( "{}{}{}{}{}", - format(boldRedFmt, "[Error"), + fmt::format(boldRedFmt, "[Error"), reset, " on line ", format(s().LightBlue, "{}", line), diff --git a/VM/include/RigCVM/TypeSystem/FuncType.hpp b/VM/include/RigCVM/TypeSystem/FuncType.hpp index 23aa8a3..eed5c5d 100644 --- a/VM/include/RigCVM/TypeSystem/FuncType.hpp +++ b/VM/include/RigCVM/TypeSystem/FuncType.hpp @@ -7,12 +7,13 @@ namespace rigc::vm { -//todo: refactor maybe use template? struct FuncType : IType { +private: InnerType result; std::vector parameters; +public: bool isVariadic = false; auto name() const -> std::string override; @@ -35,11 +36,12 @@ struct FuncType : IType struct MethodType : IType { +private: InnerType result; InnerType classType; std::vector parameters; - +public: auto name() const -> std::string override; auto symbolName() const -> std::string override { return "Method"; diff --git a/VM/include/RigCVM/VM.hpp b/VM/include/RigCVM/VM.hpp index 307b65d..2036d30 100644 --- a/VM/include/RigCVM/VM.hpp +++ b/VM/include/RigCVM/VM.hpp @@ -99,6 +99,7 @@ struct Instance auto parseModule(std::string_view name_) -> Module*; + auto getPathFromAlias(std::string_view alias_) const; auto evaluateModule(Module& module_) -> void; auto findModulePath(std::string_view name_) const -> fs::path; diff --git a/VM/src/Environment.cpp b/VM/src/Environment.cpp new file mode 100644 index 0000000..630cc9d --- /dev/null +++ b/VM/src/Environment.cpp @@ -0,0 +1,24 @@ +#include "RigCVM/Environment.hpp" + +namespace rigc::vm +{ +fs::path getVmAppPath() +{ + std::array buf; + + #ifdef PACC_SYSTEM_WINDOWS + size_t bytes; + #elif defined(PACC_SYSTEM_LINUX) + ssize_t bytes; + #endif + + // Obtain the path in `buf` and length in `bytes` + #ifdef PACC_SYSTEM_WINDOWS + bytes = static_cast( GetModuleFileNameA(nullptr, buf.data(), static_cast(buf.size()) ) ); + #elif defined(PACC_SYSTEM_LINUX) + bytes = std::min(readlink("/proc/self/exe", buf.data(), buf.size()), ssize_t(buf.size() - 1)); + #endif + + return fs::path(std::string(buf.data(), bytes)); +} +} \ No newline at end of file diff --git a/VM/src/Executors/All.cpp b/VM/src/Executors/All.cpp index 9d50659..d4cde12 100644 --- a/VM/src/Executors/All.cpp +++ b/VM/src/Executors/All.cpp @@ -99,7 +99,6 @@ auto evaluateExpression(Instance &vm_, rigc::ParserNode const& expr_) -> OptValu return ExpressionExecutor{vm_, expr_}.evaluate(); } -//todo refactor evaluateSymbol and evaluateName //////////////////////////////////////// auto evaluateSymbol(Instance &vm_, rigc::ParserNode const& expr_) -> OptValue { diff --git a/VM/src/VM.cpp b/VM/src/VM.cpp index e8df083..f8b8948 100644 --- a/VM/src/VM.cpp +++ b/VM/src/VM.cpp @@ -2,6 +2,7 @@ #include +#include "RigCVM/Environment.hpp" #include #include #include @@ -9,7 +10,6 @@ #include #include #include - #include namespace rigc::vm @@ -32,31 +32,87 @@ DEFINE_BUILTIN_CONVERT_OP (double, Float64); #undef DEFINE_BUILTIN_CONVERT_OP -////////////////////////////////////////// -auto Instance::findModulePath(std::string_view name_) const -> fs::path +auto getSeparatorPos(std::string_view name_) { - auto relativeTo = fs::current_path(); - auto path = fs::path(std::string(name_)); + return name_.find(fs::path::preferred_separator); +} - if (currentModule && name_.starts_with("./") || name_.starts_with(".\\")) +auto getAlias(std::string_view name_) +{ + auto separatorPos = getSeparatorPos(name_); + return std::string(name_.substr(0,separatorPos)); +} + +auto Instance::getPathFromAlias(std::string_view alias_) const +{ + auto const relativeStdPath = fs::path("lib/std").make_preferred(); + auto const stdPath = getVmAppPath().parent_path().parent_path() / relativeStdPath; + + auto aliasesPaths = std::unordered_map{ + {"root",fs::current_path()}, + {"std",stdPath} + }; + auto const separatorPos = getSeparatorPos(alias_); + + if(separatorPos == std::string_view::npos) { - relativeTo = currentModule->absolutePath.parent_path(); + throw RigCError("Could not find module {} - only provided a directory alias", alias_) + .withHelp("Provide a module name, example: {}/Module",alias_) + .withLine(lastEvaluatedLine); } + else + { + auto const alias = std::string(alias_.substr(0,separatorPos)); + auto const mappedPath = aliasesPaths.find(alias); + if(mappedPath == aliasesPaths.end()) + { + throw RigCError("Could not find alias {}",alias_) + .withHelp("Ensure the {} alias is defined within the configuration file", alias_) + .withLine(lastEvaluatedLine); + } + else + { + alias_.remove_prefix(alias.size() + 1); + return mappedPath->second; + } + } +} - path = relativeTo / path; - - if (!path.has_extension()) +auto modulePathExtenstionExists(fs::path modulePath) +{ + if (!modulePath.has_extension()) { - path.replace_extension(".rigc"); - if (!fs::exists(path)) + modulePath.replace_extension(".rigc"); + if (!fs::exists(modulePath)) { - path.replace_extension(".rigcz"); - if (!fs::exists(path)) + modulePath.replace_extension(".rigcz"); + if (!fs::exists(modulePath)) return fs::path{}; } } + return modulePath; +} + +auto Instance::findModulePath(std::string_view name_) const -> fs::path +{ + auto relativeTo = fs::current_path(); + auto modulePath = fs::path(std::string(name_)); + auto alias = getAlias(name_); + + if (currentModule && name_.starts_with("./") || name_.starts_with(".\\")) + { + relativeTo = currentModule->absolutePath.parent_path(); + } + if(name_.starts_with('@')) + { + relativeTo = getPathFromAlias(alias); + } + + modulePath = relativeTo / modulePath; - return path; + modulePathExtenstionExists(modulePath); + + return modulePath; } ////////////////////////////////////////// @@ -560,4 +616,4 @@ auto Instance::popStackFrame() -> void stack.popFrame(); currentScope = stack.frames.back().scope; } -} +} \ No newline at end of file