diff --git a/src/functions.cpp b/src/functions.cpp index 73ba45f..aa92cc2 100644 --- a/src/functions.cpp +++ b/src/functions.cpp @@ -7,6 +7,7 @@ #include // std::static_pointer_cast #include +#include "ruc/file.h" #include "ruc/format/format.h" #include "ast.h" @@ -371,6 +372,58 @@ ADD_FUNCTION( return makePtr((result) ? Value::True : Value::False); }); +ADD_FUNCTION( + "read-string", + { + if (nodes.size() != 1) { + Error::the().add(format("wrong number of arguments: read-string, {}", nodes.size())); + return nullptr; + } + + if (!is(nodes.front().get())) { + Error::the().add(format("wrong argument type: string, '{}'", nodes.front())); + return nullptr; + } + + std::string input = std::static_pointer_cast(nodes.front())->data(); + + return read(input); + }); + +ADD_FUNCTION( + "slurp", + { + if (nodes.size() != 1) { + Error::the().add(format("wrong number of arguments: slurp, {}", nodes.size())); + return nullptr; + } + + if (!is(nodes.front().get())) { + Error::the().add(format("wrong argument type: string, '{}'", nodes.front())); + return nullptr; + } + + std::string path = std::static_pointer_cast(nodes.front())->data(); + + auto file = ruc::File(path); + + return makePtr(file.data()); + }); + + +ADD_FUNCTION( + "eval", + { + if (nodes.size() != 1) { + Error::the().add(format("wrong number of arguments: eval, {}", nodes.size())); + return nullptr; + } + + return eval(nodes.front(), nullptr); + }); + +// ----------------------------------------- + void installFunctions(EnvironmentPtr env) { for (const auto& [name, lambda] : s_functions) { diff --git a/src/step6_file.cpp b/src/step6_file.cpp index 08d80db..b60ff02 100644 --- a/src/step6_file.cpp +++ b/src/step6_file.cpp @@ -53,6 +53,10 @@ auto read(std::string_view input) -> ASTNodePtr auto eval(ASTNodePtr ast, EnvironmentPtr env) -> ASTNodePtr { + if (env == nullptr) { + env = s_outer_env; + } + Eval eval(ast, env); eval.eval(); @@ -76,6 +80,8 @@ static auto rep(std::string_view input, EnvironmentPtr env) -> std::string 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)\")))))", }; static auto installLambdas(EnvironmentPtr env) -> void