Env: Load lisp code at runtime from files
This commit is contained in:
Vendored
+35
-1
@@ -4,8 +4,11 @@
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#include <memory> // std::static_pointer_cast
|
||||
#include <filesystem>
|
||||
#include <iterator> // std::distance
|
||||
#include <memory> // std::static_pointer_cast
|
||||
|
||||
#include "ruc/file.h"
|
||||
#include "ruc/format/format.h"
|
||||
|
||||
#include "ast.h"
|
||||
@@ -16,6 +19,7 @@
|
||||
namespace blaze {
|
||||
|
||||
std::unordered_map<std::string, FunctionType> Environment::s_functions;
|
||||
std::vector<std::string> Environment::s_lambdas;
|
||||
|
||||
EnvironmentPtr Environment::create()
|
||||
{
|
||||
@@ -86,6 +90,32 @@ void Environment::loadFunctions()
|
||||
loadOther();
|
||||
loadPredicate();
|
||||
loadRepl();
|
||||
|
||||
// Load std files
|
||||
|
||||
std::filesystem::path std = "./lisp";
|
||||
if (!std::filesystem::exists(std) || !std::filesystem::is_directory(std)) {
|
||||
return;
|
||||
}
|
||||
|
||||
s_lambdas.reserve(std::distance(std::filesystem::directory_iterator(std), {}));
|
||||
for (const auto& entry : std::filesystem::directory_iterator(std)) {
|
||||
if (!std::filesystem::is_regular_file(entry.path())
|
||||
|| entry.path().extension().string() != ".bl") {
|
||||
continue;
|
||||
}
|
||||
|
||||
std::filesystem::path filename = entry.path().filename();
|
||||
ruc::File file((std / filename).string());
|
||||
|
||||
// The init will be added to the front and executed first
|
||||
if (filename.string() == "init.bl") {
|
||||
s_lambdas.emplace(s_lambdas.begin(), file.data());
|
||||
}
|
||||
else {
|
||||
s_lambdas.push_back(file.data());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Environment::registerFunction(const std::string& name, FunctionType function)
|
||||
@@ -98,6 +128,10 @@ void Environment::installFunctions(EnvironmentPtr env)
|
||||
for (const auto& [name, function] : s_functions) {
|
||||
env->set(name, makePtr<Function>(name, function));
|
||||
}
|
||||
for (const auto& lambda : s_lambdas) {
|
||||
// Ensure all s-exprs are run with (do)
|
||||
eval(read("(do " + lambda + ")"), env);
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------
|
||||
|
||||
Vendored
+2
@@ -9,6 +9,7 @@
|
||||
#include <list>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
#include "ast.h"
|
||||
#include "forward.h"
|
||||
@@ -53,6 +54,7 @@ private:
|
||||
std::unordered_map<std::string, ValuePtr> m_values;
|
||||
|
||||
static std::unordered_map<std::string, FunctionType> s_functions;
|
||||
static std::vector<std::string> s_lambdas;
|
||||
};
|
||||
|
||||
} // namespace blaze
|
||||
|
||||
@@ -89,27 +89,6 @@ static auto rep(std::string_view input, EnvironmentPtr env) -> std::string
|
||||
return print(eval(read(input), env));
|
||||
}
|
||||
|
||||
static std::string_view lambdaTable[] = {
|
||||
"(def! not (fn* (cond) (if cond false true)))",
|
||||
"(def! load-file (fn* (filename) \
|
||||
(eval (read-string (str \"(do \" (slurp filename) \"\nnil)\")))))",
|
||||
"(defmacro! cond (fn* (& xs) \
|
||||
(if (> (count xs) 0) \
|
||||
(list 'if (first xs) \
|
||||
(if (> (count xs) 1) \
|
||||
(nth xs 1) \
|
||||
(throw \"odd number of forms to cond\")) \
|
||||
(cons 'cond (rest (rest xs)))))))",
|
||||
"(def! *host-language* \"C++\")",
|
||||
};
|
||||
|
||||
static auto installLambdas(EnvironmentPtr env) -> void
|
||||
{
|
||||
for (auto function : lambdaTable) {
|
||||
rep(function, env);
|
||||
}
|
||||
}
|
||||
|
||||
static auto makeArgv(EnvironmentPtr env, std::vector<std::string> arguments) -> void
|
||||
{
|
||||
size_t count = arguments.size();
|
||||
@@ -151,7 +130,6 @@ auto main(int argc, char* argv[]) -> int
|
||||
|
||||
blaze::Environment::loadFunctions();
|
||||
blaze::Environment::installFunctions(blaze::s_outer_env);
|
||||
installLambdas(blaze::s_outer_env);
|
||||
makeArgv(blaze::s_outer_env, arguments);
|
||||
|
||||
if (arguments.size() > 0) {
|
||||
|
||||
Reference in New Issue
Block a user