Skip to content

Commit 12c4d06

Browse files
committed
feat(repl): add repl:load to load code from a file in the repl
1 parent 83058f2 commit 12c4d06

2 files changed

Lines changed: 24 additions & 3 deletions

File tree

include/CLI/REPL/Repl.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ namespace Ark
4141
replxx::Replxx m_repl;
4242
unsigned m_line_count;
4343
std::string m_code;
44+
std::string m_temp_additional_code;
4445
bool m_running;
4546

4647
std::size_t m_old_ip;

src/arkscript/REPL/Repl.cpp

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,8 @@ namespace Ark
5858
if (m_vm.safeRun(*m_vm.m_execution_contexts[0]) == 0)
5959
{
6060
// save good code
61-
m_code = new_code;
61+
m_code = new_code + m_temp_additional_code;
62+
m_temp_additional_code.clear();
6263
// place ip to end of bytecode instruction (HALT)
6364
m_vm.m_execution_contexts[0]->ip -= 4;
6465

@@ -75,8 +76,6 @@ namespace Ark
7576
m_state.reset();
7677
registerBuiltins();
7778
}
78-
else
79-
fmt::println("\nCouldn't run code");
8079
}
8180
}
8281

@@ -126,6 +125,7 @@ namespace Ark
126125
m_state.loadFunction("repl:history", [this]([[maybe_unused]] std::vector<Value>&, [[maybe_unused]] VM*) {
127126
return Value(m_code);
128127
});
128+
129129
m_state.loadFunction("repl:save", [this](std::vector<Value>& n, [[maybe_unused]] VM*) {
130130
if (!types::check(n, ValueType::String))
131131
throw types::TypeCheckingError(
@@ -137,6 +137,22 @@ namespace Ark
137137
history_file << m_code;
138138
return Nil;
139139
});
140+
141+
m_state.loadFunction("repl:load", [this](std::vector<Value>& n, [[maybe_unused]] VM*) {
142+
if (!types::check(n, ValueType::String))
143+
throw types::TypeCheckingError(
144+
"repl:load",
145+
{ { types::Contract { { types::Typedef("filename", ValueType::String) } } } },
146+
n);
147+
148+
const std::string path = n[0].string();
149+
if (!Utils::fileExists(path))
150+
throw Error(fmt::format("`repl:load` expected a valid path to a file. {} doesn't exist, or can't be reached (try with an absolute path?)", path));
151+
152+
// we use += so that it can be called multiple times without overwriting previous code
153+
m_temp_additional_code += fmt::format("## (repl:load \"{}\") ##\n{}\n## END ##\n", path, Utils::readFile(path));
154+
return Nil;
155+
});
140156
}
141157

142158
std::optional<std::string> Repl::getLine(const bool continuation)
@@ -170,6 +186,10 @@ namespace Ark
170186
fmt::println(" save -- save the history to disk");
171187
fmt::println(" history -- print saved code");
172188
fmt::println(" reset -- reset the VM state");
189+
fmt::println("Available builtins:");
190+
fmt::println("(repl:history): returns the REPL history as a string");
191+
fmt::println("(repl:save filename): saves the REPL history to a file");
192+
fmt::println("(repl:load filename): loads code from a file in the REPL");
173193

174194
return std::nullopt;
175195
}

0 commit comments

Comments
 (0)