11 using namespace internal;
13 Repl::Repl(
const std::vector<std::filesystem::path>& lib_env) :
14 m_line_count(1), m_running(true),
15 m_old_ip(0), m_lib_env(lib_env),
16 m_state(m_lib_env), m_vm(m_state), m_has_init_vm(false)
21 fmt::print(
"ArkScript REPL -- Version {} [LICENSE: Mozilla Public License 2.0]\nType \"quit\" to quit. Try \"help\" for more information\n",
ARK_FULL_VERSION);
30 if (maybe_block.has_value() && !maybe_block.value().empty())
32 std::string new_code =
m_code + maybe_block.value();
60 std::cout <<
"\nCouldn't run code\n";
73 m_repl.set_word_break_characters(
" \t.,-%!;:=*~^'\"/?<>|[](){}");
74 m_repl.set_completion_count_cutoff(128);
75 m_repl.set_double_tab_completion(
true);
76 m_repl.set_complete_on_empty(
true);
77 m_repl.set_beep_on_ambiguous_completion(
false);
78 m_repl.set_no_color(
false);
80 m_repl.bind_key_internal(replxx::Replxx::KEY::HOME,
"move_cursor_to_begining_of_line");
81 m_repl.bind_key_internal(replxx::Replxx::KEY::END,
"move_cursor_to_end_of_line");
82 m_repl.bind_key_internal(replxx::Replxx::KEY::TAB,
"complete_line");
83 m_repl.bind_key_internal(replxx::Replxx::KEY::control(replxx::Replxx::KEY::LEFT),
"move_cursor_one_word_left");
84 m_repl.bind_key_internal(replxx::Replxx::KEY::control(replxx::Replxx::KEY::RIGHT),
"move_cursor_one_word_right");
85 m_repl.bind_key_internal(replxx::Replxx::KEY::control(replxx::Replxx::KEY::UP),
"hint_previous");
86 m_repl.bind_key_internal(replxx::Replxx::KEY::control(replxx::Replxx::KEY::DOWN),
"hint_next");
87 m_repl.bind_key_internal(replxx::Replxx::KEY::control(replxx::Replxx::KEY::ENTER),
"commit_line");
88 m_repl.bind_key_internal(replxx::Replxx::KEY::control(
'R'),
"history_incremental_search");
89 m_repl.bind_key_internal(replxx::Replxx::KEY::control(
'W'),
"kill_to_begining_of_word");
90 m_repl.bind_key_internal(replxx::Replxx::KEY::control(
'U'),
"kill_to_begining_of_line");
91 m_repl.bind_key_internal(replxx::Replxx::KEY::control(
'K'),
"kill_to_end_of_line");
92 m_repl.bind_key_internal(replxx::Replxx::KEY::control(
'Y'),
"yank");
93 m_repl.bind_key_internal(replxx::Replxx::KEY::control(
'L'),
"clear_screen");
94 m_repl.bind_key_internal(replxx::Replxx::KEY::control(
'D'),
"send_eof");
95 m_repl.bind_key_internal(replxx::Replxx::KEY::control(
'C'),
"abort_line");
96 m_repl.bind_key_internal(replxx::Replxx::KEY::control(
'T'),
"transpose_characters");
101 const std::string prompt = fmt::format(
"main:{:0>3}{} ",
m_line_count, continuation ?
":" :
">");
103 const char* buf {
nullptr };
106 buf =
m_repl.input(prompt);
107 }
while ((buf ==
nullptr) && (errno == EAGAIN));
108 std::string line = (buf !=
nullptr) ? std::string(buf) :
"";
115 if (line ==
"quit" || buf ==
nullptr)
117 std::cout <<
"\nExiting REPL\n";
124 std::cout <<
"Available commands:\n";
125 std::cout <<
" help -- display this message\n";
126 std::cout <<
" quit -- quit the REPL\n";
127 std::cout <<
" save -- save the history to disk\n";
128 std::cout <<
" history -- print saved code\n";
129 std::cout <<
" reset -- reset the VM state\n";
135 std::ofstream history_file(
"arkscript_repl_history.ark");
136 m_repl.history_save(history_file);
138 fmt::print(
"Saved {} lines of history to arkscript_repl_history.ark\n",
m_line_count);
142 if (line ==
"history")
163 std::string code_block;
164 long open_parentheses = 0;
165 long open_braces = 0;
169 const bool unfinished_block = open_parentheses != 0 || open_braces != 0;
171 auto maybe_line =
getLine(unfinished_block);
172 if (!maybe_line.has_value() && !unfinished_block)
175 if (maybe_line.has_value() && !maybe_line.value().empty())
177 code_block += maybe_line.value() +
"\n";
183 if (open_parentheses == 0 && open_braces == 0)
constexpr std::string_view ARK_FULL_VERSION
ArkScript REPL - Read Eval Print Loop.
void cuiSetup()
Configure replxx.
std::optional< std::string > getCodeBlock()
Repl(const std::vector< std::filesystem::path > &lib_env)
Construct a new Repl object.
std::optional< std::string > getLine(bool continuation)
Get a line via replxx and handle commands.
void reset() noexcept
Reset State (all member variables related to execution)
bool doString(const std::string &code)
Compile a string (representing ArkScript code) and store resulting bytecode in m_bytecode.
std::vector< std::unique_ptr< internal::ExecutionContext > > m_execution_contexts
bool forceReloadPlugins() const
Used by the REPL to force reload all the plugins and their bound methods.
int safeRun(internal::ExecutionContext &context, std::size_t untilFrameCount=0)
Run ArkScript bytecode inside a try catch to retrieve all the exceptions and display a stack trace if...
void init() noexcept
Initialize the VM according to the parameters.
long countOpenEnclosures(const std::string &line, char open, char close)
Count the open enclosure and its counterpart: (), {}, [].
replxx::Replxx::hints_t hookHint(const std::string &context, int &length, replxx::Replxx::Color &color)
void hookColor(const std::string &context, replxx::Replxx::colors_t &colors)
replxx::Replxx::completions_t hookCompletion(const std::string &context, int &length)
void trimWhitespace(std::string &line)
Remove whitespaces at the start and end of a string.