13 using namespace internal;
14 using namespace replxx;
16 Repl::Repl(
const std::vector<std::filesystem::path>& lib_env) :
17 m_line_count(1), m_running(true),
18 m_old_ip(0), m_lib_env(lib_env),
19 m_state(m_lib_env), m_vm(m_state), m_has_init_vm(false),
26 fmt::print(
"ArkScript REPL -- Version {} [LICENSE: Mozilla Public License 2.0]\nType \"quit\" to quit. Try \"help\" for more information\n",
ARK_FULL_VERSION);
35 if (maybe_block.has_value() && !maybe_block.value().empty())
37 std::string new_code =
m_code + maybe_block.value();
65 fmt::println(
"\nCouldn't run code");
74 m_repl.set_completion_callback([
this](
const std::string& ctx,
int& len) {
77 m_repl.set_highlighter_callback([
this](
const std::string& ctx, Replxx::colors_t&
colors) {
80 m_repl.set_hint_callback([
this](
const std::string& ctx,
int& len, Replxx::Color& color) {
84 m_repl.set_word_break_characters(
" \t.,-%!;:=*~^'\"/?<>|[](){}");
85 m_repl.set_completion_count_cutoff(128);
86 m_repl.set_double_tab_completion(
true);
87 m_repl.set_complete_on_empty(
true);
88 m_repl.set_beep_on_ambiguous_completion(
false);
89 m_repl.set_no_color(
false);
91 m_repl.bind_key_internal(Replxx::KEY::HOME,
"move_cursor_to_begining_of_line");
92 m_repl.bind_key_internal(Replxx::KEY::END,
"move_cursor_to_end_of_line");
93 m_repl.bind_key_internal(Replxx::KEY::TAB,
"complete_line");
94 m_repl.bind_key_internal(Replxx::KEY::control(Replxx::KEY::LEFT),
"move_cursor_one_word_left");
95 m_repl.bind_key_internal(Replxx::KEY::control(Replxx::KEY::RIGHT),
"move_cursor_one_word_right");
96 m_repl.bind_key_internal(Replxx::KEY::control(Replxx::KEY::UP),
"hint_previous");
97 m_repl.bind_key_internal(Replxx::KEY::control(Replxx::KEY::DOWN),
"hint_next");
98 m_repl.bind_key_internal(Replxx::KEY::control(Replxx::KEY::ENTER),
"commit_line");
99 m_repl.bind_key_internal(Replxx::KEY::control(
'R'),
"history_incremental_search");
100 m_repl.bind_key_internal(Replxx::KEY::control(
'W'),
"kill_to_begining_of_word");
101 m_repl.bind_key_internal(Replxx::KEY::control(
'U'),
"kill_to_begining_of_line");
102 m_repl.bind_key_internal(Replxx::KEY::control(
'K'),
"kill_to_end_of_line");
103 m_repl.bind_key_internal(Replxx::KEY::control(
'Y'),
"yank");
104 m_repl.bind_key_internal(Replxx::KEY::control(
'L'),
"clear_screen");
105 m_repl.bind_key_internal(Replxx::KEY::control(
'D'),
"send_eof");
106 m_repl.bind_key_internal(Replxx::KEY::control(
'C'),
"abort_line");
107 m_repl.bind_key_internal(Replxx::KEY::control(
'T'),
"transpose_characters");
112 const std::string prompt = fmt::format(
"main:{:0>3}{} ",
m_line_count, continuation ?
":" :
">");
114 const char* buf {
nullptr };
117 buf =
m_repl.input(prompt);
118 }
while ((buf ==
nullptr) && (errno == EAGAIN));
119 std::string line = (buf !=
nullptr) ? std::string(buf) :
"";
126 if (line ==
"quit" || buf ==
nullptr)
128 fmt::println(
"\nExiting REPL");
135 fmt::println(
"Available commands:");
136 fmt::println(
" help -- display this message");
137 fmt::println(
" quit -- quit the REPL");
138 fmt::println(
" save -- save the history to disk");
139 fmt::println(
" history -- print saved code");
140 fmt::println(
" reset -- reset the VM state");
146 std::ofstream history_file(
"arkscript_repl_history.ark");
147 m_repl.history_save(history_file);
149 fmt::println(
"Saved {} lines of history to arkscript_repl_history.ark",
m_line_count);
152 if (line ==
"history")
154 fmt::println(
"\n{}",
m_code);
171 std::string code_block;
172 long open_parentheses = 0;
173 long open_braces = 0;
177 const bool unfinished_block = open_parentheses != 0 || open_braces != 0;
179 auto maybe_line =
getLine(unfinished_block);
180 if (!maybe_line.has_value() && !unfinished_block)
183 if (maybe_line.has_value() && !maybe_line.value().empty())
185 code_block += maybe_line.value() +
"\n";
191 if (open_parentheses == 0 && open_braces == 0)
Host the declaration of all the ArkScript builtins.
constexpr std::string_view ARK_FULL_VERSION
ArkScript REPL - Read Eval Print Loop.
std::vector< std::pair< std::string, replxx::Replxx::Color > > m_words_colors
std::vector< std::string > m_keywords
void cuiSetup()
Configure replxx.
std::optional< std::string > getCodeBlock()
Prompt the user to enter a complete code block and handle the prompt modifications until the code blo...
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, uint16_t features=DefaultFeatures)
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, bool fail_with_exception=false)
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.
std::vector< std::string > getAllKeywords()
Compute a list of all the language keywords and builtins.
long countOpenEnclosures(const std::string &line, char open, char close)
Count the open enclosure and its counterpart: (), {}, [].
void hookColor(const std::vector< std::pair< std::string, replxx::Replxx::Color > > &words_colors, const std::string &context, replxx::Replxx::colors_t &colors)
constexpr std::array colors
replxx::Replxx::completions_t hookCompletion(const std::vector< std::string > &words, const std::string &context, int &length)
std::vector< std::pair< std::string, replxx::Replxx::Color > > getColorPerKeyword()
Compute a list of pairs (word -> color) to be used for coloration by the REPL.
replxx::Replxx::hints_t hookHint(const std::vector< std::string > &words, const std::string &context, int &length, replxx::Replxx::Color &color)
void trimWhitespace(std::string &line)
Remove whitespaces at the start and end of a string.