repl cleanup

master
Daniel Kolesa 2016-09-11 23:33:02 +02:00
parent 083f905913
commit 931f7294de
4 changed files with 44 additions and 39 deletions

View File

@ -4,10 +4,10 @@
#include <ostd/string.hh> #include <ostd/string.hh>
#include <ostd/maybe.hh> #include <ostd/maybe.hh>
static void init_lineedit(ostd::ConstCharRange) { static void init_lineedit(CsState &, ostd::ConstCharRange) {
} }
static ostd::Maybe<ostd::String> read_line(CsSvar *pr) { static ostd::Maybe<ostd::String> read_line(CsState &, CsSvar *pr) {
ostd::write(pr->get_value()); ostd::write(pr->get_value());
ostd::String ret; ostd::String ret;
/* i really need to implement some sort of get_line for ostd streams */ /* i really need to implement some sort of get_line for ostd streams */
@ -17,7 +17,7 @@ static ostd::Maybe<ostd::String> read_line(CsSvar *pr) {
return ostd::move(ret); return ostd::move(ret);
} }
static void add_history(ostd::ConstCharRange) { static void add_history(CsState &, ostd::ConstCharRange) {
} }
#endif #endif

View File

@ -13,10 +13,12 @@
#include "linenoise.hh" #include "linenoise.hh"
static CsState *ln_cs = nullptr;
#ifdef CS_REPL_HAS_COMPLETE #ifdef CS_REPL_HAS_COMPLETE
static void ln_complete(char const *buf, linenoiseCompletions *lc) { static void ln_complete(char const *buf, linenoiseCompletions *lc) {
ostd::ConstCharRange cmd = get_complete_cmd(buf); ostd::ConstCharRange cmd = get_complete_cmd(buf);
for (auto id: gcs->identmap.iter()) { for (auto id: ln_cs->identmap.iter()) {
if (!id->is_command()) { if (!id->is_command()) {
continue; continue;
} }
@ -33,7 +35,7 @@ static void ln_complete(char const *buf, linenoiseCompletions *lc) {
#ifdef CS_REPL_HAS_HINTS #ifdef CS_REPL_HAS_HINTS
static char *ln_hint(char const *buf, int *color, int *bold) { static char *ln_hint(char const *buf, int *color, int *bold) {
CsCommand *cmd = get_hint_cmd(buf); CsCommand *cmd = get_hint_cmd(*ln_cs, buf);
if (!cmd) { if (!cmd) {
return nullptr; return nullptr;
} }
@ -52,9 +54,10 @@ static void ln_hint_free(void *hint) {
} }
#endif /* CS_REPL_HAS_HINTS */ #endif /* CS_REPL_HAS_HINTS */
static void init_lineedit(ostd::ConstCharRange) { static void init_lineedit(CsState &cs, ostd::ConstCharRange) {
/* sensible default history size */ /* sensible default history size */
linenoiseHistorySetMaxLen(1000); linenoiseHistorySetMaxLen(1000);
ln_cs = &cs;
#ifdef CS_REPL_HAS_COMPLETE #ifdef CS_REPL_HAS_COMPLETE
linenoiseSetCompletionCallback(ln_complete); linenoiseSetCompletionCallback(ln_complete);
#endif #endif
@ -64,7 +67,7 @@ static void init_lineedit(ostd::ConstCharRange) {
#endif #endif
} }
static ostd::Maybe<ostd::String> read_line(CsSvar *pr) { static ostd::Maybe<ostd::String> read_line(CsState &, CsSvar *pr) {
auto line = linenoise(pr->get_value().data()); auto line = linenoise(pr->get_value().data());
if (!line) { if (!line) {
/* linenoise traps ctrl-c, detect it and let the user exit */ /* linenoise traps ctrl-c, detect it and let the user exit */
@ -79,7 +82,7 @@ static ostd::Maybe<ostd::String> read_line(CsSvar *pr) {
return ostd::move(ret); return ostd::move(ret);
} }
static void add_history(ostd::ConstCharRange line) { static void add_history(CsState &, ostd::ConstCharRange line) {
/* backed by ostd::String so it's terminated */ /* backed by ostd::String so it's terminated */
linenoiseHistoryAdd(line.data()); linenoiseHistoryAdd(line.data());
} }

View File

@ -11,6 +11,8 @@
#include <readline/readline.h> #include <readline/readline.h>
#include <readline/history.h> #include <readline/history.h>
static CsState *rd_cs = nullptr;
#ifdef CS_REPL_HAS_COMPLETE #ifdef CS_REPL_HAS_COMPLETE
static char *ln_complete_list(char const *buf, int state) { static char *ln_complete_list(char const *buf, int state) {
static ostd::ConstCharRange cmd; static ostd::ConstCharRange cmd;
@ -18,7 +20,7 @@ static char *ln_complete_list(char const *buf, int state) {
if (!state) { if (!state) {
cmd = get_complete_cmd(buf); cmd = get_complete_cmd(buf);
itr = gcs->identmap.iter(); itr = rd_cs->identmap.iter();
} }
for (; !itr.empty(); itr.pop_front()) { for (; !itr.empty(); itr.pop_front()) {
@ -47,7 +49,7 @@ static char **ln_complete(char const *buf, int, int) {
#ifdef CS_REPL_HAS_HINTS #ifdef CS_REPL_HAS_HINTS
void ln_hint() { void ln_hint() {
CsCommand *cmd = get_hint_cmd(rl_line_buffer); CsCommand *cmd = get_hint_cmd(*rd_cs, rl_line_buffer);
if (!cmd) { if (!cmd) {
rl_redisplay(); rl_redisplay();
return; return;
@ -64,7 +66,8 @@ void ln_hint() {
} }
#endif #endif
static void init_lineedit(ostd::ConstCharRange) { static void init_lineedit(CsState &cs, ostd::ConstCharRange) {
rd_cs = &cs;
#ifdef CS_REPL_HAS_COMPLETE #ifdef CS_REPL_HAS_COMPLETE
rl_attempted_completion_function = ln_complete; rl_attempted_completion_function = ln_complete;
#endif #endif
@ -73,7 +76,7 @@ static void init_lineedit(ostd::ConstCharRange) {
#endif #endif
} }
static ostd::Maybe<ostd::String> read_line(CsSvar *pr) { static ostd::Maybe<ostd::String> read_line(CsState &, CsSvar *pr) {
auto line = readline(pr->get_value().data()); auto line = readline(pr->get_value().data());
if (!line) { if (!line) {
return ostd::String(); return ostd::String();
@ -83,7 +86,7 @@ static ostd::Maybe<ostd::String> read_line(CsSvar *pr) {
return ostd::move(ret); return ostd::move(ret);
} }
static void add_history(ostd::ConstCharRange line) { static void add_history(CsState &, ostd::ConstCharRange line) {
/* backed by ostd::String so it's terminated */ /* backed by ostd::String so it's terminated */
add_history(line.data()); add_history(line.data());
} }

View File

@ -27,8 +27,6 @@ static bool stdin_is_tty() {
/* line editing support */ /* line editing support */
CsState *gcs = nullptr;
#ifdef CS_REPL_HAS_COMPLETE #ifdef CS_REPL_HAS_COMPLETE
static ostd::ConstCharRange get_complete_cmd(ostd::ConstCharRange buf) { static ostd::ConstCharRange get_complete_cmd(ostd::ConstCharRange buf) {
ostd::ConstCharRange not_allowed = "\"/;()[] \t\r\n\0"; ostd::ConstCharRange not_allowed = "\"/;()[] \t\r\n\0";
@ -132,11 +130,11 @@ static void fill_cmd_args(ostd::String &writer, ostd::ConstCharRange args) {
} }
} }
static CsCommand *get_hint_cmd(ostd::ConstCharRange buf) { static CsCommand *get_hint_cmd(CsState &cs, ostd::ConstCharRange buf) {
ostd::ConstCharRange nextchars = "([;"; ostd::ConstCharRange nextchars = "([;";
auto lp = ostd::find_one_of(buf, nextchars); auto lp = ostd::find_one_of(buf, nextchars);
if (!lp.empty()) { if (!lp.empty()) {
CsCommand *cmd = get_hint_cmd(buf + 1); CsCommand *cmd = get_hint_cmd(cs, buf + 1);
if (cmd) { if (cmd) {
return cmd; return cmd;
} }
@ -150,7 +148,7 @@ static CsCommand *get_hint_cmd(ostd::ConstCharRange buf) {
buf = ostd::slice_until(buf, s); buf = ostd::slice_until(buf, s);
} }
if (!buf.empty()) { if (!buf.empty()) {
auto cmd = gcs->get_ident(buf); auto cmd = cs.get_ident(buf);
return cmd ? cmd->get_command() : nullptr; return cmd ? cmd->get_command() : nullptr;
} }
return nullptr; return nullptr;
@ -182,19 +180,19 @@ void print_version() {
ostd::writeln(version); ostd::writeln(version);
} }
static CsState *scs = nullptr;
static void do_sigint(int n) { static void do_sigint(int n) {
/* in case another SIGINT happens, terminate normally */ /* in case another SIGINT happens, terminate normally */
signal(n, SIG_DFL); signal(n, SIG_DFL);
if (gcs) { scs->set_call_hook([](CsState &cs) {
gcs->set_call_hook([](CsState &cs) { cs.set_call_hook(nullptr);
cs.set_call_hook(nullptr); cs.error("<execution interrupted>");
cs.error("<execution interrupted>"); });
});
}
} }
static bool do_call(CsState &cs, ostd::ConstCharRange line, bool file = false) { static bool do_call(CsState &cs, ostd::ConstCharRange line, bool file = false) {
CsValue ret; CsValue ret;
scs = &cs;
signal(SIGINT, do_sigint); signal(SIGINT, do_sigint);
ostd::String err; ostd::String err;
cscript::CsStackState st; cscript::CsStackState st;
@ -209,6 +207,7 @@ static bool do_call(CsState &cs, ostd::ConstCharRange line, bool file = false) {
}; };
if (!cs.pcall(ostd::move(tocall), &err, &st)) { if (!cs.pcall(ostd::move(tocall), &err, &st)) {
signal(SIGINT, SIG_DFL); signal(SIGINT, SIG_DFL);
scs = nullptr;
ostd::ConstCharRange terr = err; ostd::ConstCharRange terr = err;
auto col = ostd::find(terr, ':'); auto col = ostd::find(terr, ':');
if (!col.empty()) { if (!col.empty()) {
@ -225,6 +224,7 @@ static bool do_call(CsState &cs, ostd::ConstCharRange line, bool file = false) {
return false; return false;
} }
signal(SIGINT, SIG_DFL); signal(SIGINT, SIG_DFL);
scs = nullptr;
if (ret.get_type() != CsValueType::Null) { if (ret.get_type() != CsValueType::Null) {
ostd::writeln(ret.get_str()); ostd::writeln(ret.get_str());
} }
@ -242,7 +242,7 @@ static void do_tty(CsState &cs) {
ostd::writeln(version, " (REPL mode)"); ostd::writeln(version, " (REPL mode)");
for (;;) { for (;;) {
auto line = read_line(prompt); auto line = read_line(cs, prompt);
if (!line) { if (!line) {
return; return;
} }
@ -255,7 +255,7 @@ static void do_tty(CsState &cs) {
if (bsl) { if (bsl) {
lv.resize(lv.size() - 1); lv.resize(lv.size() - 1);
} }
auto line2 = read_line(prompt2); auto line2 = read_line(cs, prompt2);
if (!line2) { if (!line2) {
return; return;
} }
@ -264,7 +264,7 @@ static void do_tty(CsState &cs) {
} }
lv += line2.value(); lv += line2.value();
} }
add_history(lv); add_history(cs, lv);
if (do_exit) { if (do_exit) {
return; return;
} }
@ -272,11 +272,10 @@ static void do_tty(CsState &cs) {
} }
int main(int argc, char **argv) { int main(int argc, char **argv) {
CsState csg; CsState gcs;
gcs = &csg; gcs.init_libs();
csg.init_libs();
csg.new_command("exec", "sb", [](CsState &cs, auto args, auto &res) { gcs.new_command("exec", "sb", [](CsState &cs, auto args, auto &res) {
auto file = args[0].get_strr(); auto file = args[0].get_strr();
bool ret = cs.run_file(file); bool ret = cs.run_file(file);
if (!ret) { if (!ret) {
@ -289,7 +288,7 @@ int main(int argc, char **argv) {
} }
}); });
csg.new_command("echo", "C", [](CsState &cs, auto args, auto &) { gcs.new_command("echo", "C", [](CsState &cs, auto args, auto &) {
cs.get_out().writeln(args[0].get_strr()); cs.get_out().writeln(args[0].get_strr());
}); });
@ -366,31 +365,31 @@ endargs:
if (*str == '\0') { if (*str == '\0') {
str = argv[++i]; str = argv[++i];
} }
do_call(csg, str); do_call(gcs, str);
break; break;
} }
} }
} }
if (firstarg) { if (firstarg) {
do_call(csg, argv[firstarg], true); do_call(gcs, argv[firstarg], true);
} }
if (!firstarg && !has_str && !has_ver) { if (!firstarg && !has_str && !has_ver) {
if (stdin_is_tty()) { if (stdin_is_tty()) {
init_lineedit(argv[0]); init_lineedit(gcs, argv[0]);
do_tty(csg); do_tty(gcs);
return 0; return 0;
} else { } else {
ostd::String str; ostd::String str;
for (char c = '\0'; (c = ostd::in.getchar()) != EOF;) { for (char c = '\0'; (c = ostd::in.getchar()) != EOF;) {
str += c; str += c;
} }
do_call(csg, str); do_call(gcs, str);
} }
} }
if (has_inter) { if (has_inter) {
if (stdin_is_tty()) { if (stdin_is_tty()) {
init_lineedit(argv[0]); init_lineedit(gcs, argv[0]);
do_tty(csg); do_tty(gcs);
} }
return 0; return 0;
} }