forked from PuqiAR/Fig-TreeWalker
114 lines
4.0 KiB
C++
114 lines
4.0 KiB
C++
#include <Core/executablePath.hpp>
|
|
|
|
#include <Evaluator/evaluator.hpp>
|
|
#include <Evaluator/evaluator_error.hpp>
|
|
|
|
namespace Fig
|
|
{
|
|
|
|
std::filesystem::path Evaluator::resolveModulePath(const std::vector<FString> &pathVec)
|
|
{
|
|
namespace fs = std::filesystem;
|
|
|
|
static const std::vector<fs::path> defaultLibraryPath{"Library", "Library/fpm"};
|
|
|
|
std::vector<fs::path> pathToFind(defaultLibraryPath);
|
|
|
|
fs::path interpreterPath = getExecutablePath().parent_path();
|
|
|
|
for (fs::path &p : pathToFind)
|
|
{
|
|
p = interpreterPath / p; // 相对路径 -> 绝对路径
|
|
}
|
|
|
|
pathToFind.insert(
|
|
pathToFind.begin(),
|
|
fs::path(this->sourcePath.toBasicString()).parent_path()); // first search module at the source file path
|
|
|
|
fs::path path;
|
|
|
|
/*
|
|
Example:
|
|
import comp.config;
|
|
*/
|
|
|
|
const FString &modPathStrTop = pathVec.at(0);
|
|
fs::path modPath;
|
|
|
|
bool found = false;
|
|
for (auto &parentFolder : pathToFind)
|
|
{
|
|
modPath = parentFolder / FString(modPathStrTop + u8".fig").toBasicString();
|
|
if (fs::exists(modPath))
|
|
{
|
|
path = modPath;
|
|
found = true;
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
modPath = parentFolder / modPathStrTop.toBasicString();
|
|
if (fs::is_directory(modPath)) // comp is a directory
|
|
{
|
|
modPath = modPath / FString(modPathStrTop + u8".fig").toBasicString();
|
|
/*
|
|
if module name is a directory, we require [module
|
|
name].fig at the directory
|
|
*/
|
|
if (!fs::exists(modPath))
|
|
{
|
|
throw RuntimeError(FString(std::format("requires module file, {}\\{}",
|
|
modPathStrTop.toBasicString(),
|
|
FString(modPathStrTop + u8".fig").toBasicString())));
|
|
}
|
|
found = true;
|
|
path = modPath;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!found)
|
|
throw RuntimeError(FString(std::format("Could not find module `{}`", modPathStrTop.toBasicString())));
|
|
|
|
bool found2 = false;
|
|
|
|
for (size_t i = 1; i < pathVec.size(); ++i) // has next module
|
|
{
|
|
const FString &next = pathVec.at(i);
|
|
modPath = modPath.parent_path(); // get the folder
|
|
modPath = modPath / FString(next + u8".fig").toBasicString();
|
|
if (fs::exists(modPath))
|
|
{
|
|
if (i != pathVec.size() - 1)
|
|
throw RuntimeError(FString(std::format(
|
|
"expects {} as parent directory and find next module, but got a file", next.toBasicString())));
|
|
// it's the last module
|
|
found2 = true;
|
|
path = modPath;
|
|
break;
|
|
}
|
|
// `next` is a folder
|
|
modPath = modPath.parent_path() / next.toBasicString();
|
|
if (!fs::exists(modPath))
|
|
throw RuntimeError(FString(std::format("Could not find module `{}`", next.toBasicString())));
|
|
if (i == pathVec.size() - 1)
|
|
{
|
|
// `next` is the last module
|
|
modPath = modPath / FString(next + u8".fig").toBasicString();
|
|
if (!fs::exists(modPath))
|
|
{
|
|
throw RuntimeError(FString(std::format(
|
|
"expects {} as parent directory and find next module, but got a file", next.toBasicString())));
|
|
}
|
|
found2 = true;
|
|
path = modPath;
|
|
}
|
|
}
|
|
|
|
if (!found2 && !fs::exists(modPath))
|
|
throw RuntimeError(FString(std::format("Could not find module `{}`", pathVec.end()->toBasicString())));
|
|
|
|
return path;
|
|
}
|
|
}; |