✨ add command history in repl
This commit is contained in:
parent
d0d9ce3b80
commit
85bc699905
|
@ -51,7 +51,7 @@ public:
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
int flag = fcntl(0, F_GETFL);
|
int flag = fcntl(0, F_GETFL);
|
||||||
fcntl(0, F_SETFL,flag|O_NONBLOCK);
|
fcntl(0, F_SETFL, flag|O_NONBLOCK);
|
||||||
nread = read(0, &ch, 1);
|
nread = read(0, &ch, 1);
|
||||||
fcntl(0, F_SETFL, flag);
|
fcntl(0, F_SETFL, flag);
|
||||||
if (nread==1) {
|
if (nread==1) {
|
||||||
|
@ -83,25 +83,25 @@ public:
|
||||||
noecho_input this_window;
|
noecho_input this_window;
|
||||||
|
|
||||||
var nas_getch(var* args, usize size, gc* ngc) {
|
var nas_getch(var* args, usize size, gc* ngc) {
|
||||||
return var::num((double)this_window.noecho_getch());
|
return var::num(static_cast<double>(this_window.noecho_getch()));
|
||||||
}
|
}
|
||||||
|
|
||||||
var nas_kbhit(var* args, usize size, gc* ngc) {
|
var nas_kbhit(var* args, usize size, gc* ngc) {
|
||||||
return var::num((double)this_window.noecho_kbhit());
|
return var::num(static_cast<double>(this_window.noecho_kbhit()));
|
||||||
}
|
}
|
||||||
|
|
||||||
var nas_noblock(var* args, usize size, gc* ngc) {
|
var nas_noblock(var* args, usize size, gc* ngc) {
|
||||||
if (this_window.noecho_kbhit()) {
|
if (this_window.noecho_kbhit()) {
|
||||||
return var::num((double)this_window.noecho_getch());
|
return var::num(static_cast<double>(this_window.noecho_getch()));
|
||||||
}
|
}
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
module_func_info func_tbl[] = {
|
module_func_info func_tbl[] = {
|
||||||
{"nas_getch",nas_getch},
|
{"nas_getch", nas_getch},
|
||||||
{"nas_kbhit",nas_kbhit},
|
{"nas_kbhit", nas_kbhit},
|
||||||
{"nas_noblock",nas_noblock},
|
{"nas_noblock", nas_noblock},
|
||||||
{nullptr,nullptr}
|
{nullptr, nullptr}
|
||||||
};
|
};
|
||||||
|
|
||||||
extern "C" module_func_info* get() {
|
extern "C" module_func_info* get() {
|
||||||
|
|
|
@ -34,16 +34,16 @@ var nas_socket(var* args, usize size, gc* ngc) {
|
||||||
if (args[0].type!=vm_num || args[1].type!=vm_num || args[2].type!=vm_num)
|
if (args[0].type!=vm_num || args[1].type!=vm_num || args[2].type!=vm_num)
|
||||||
return nas_err("socket", "\"af\", \"type\", \"protocol\" should be number");
|
return nas_err("socket", "\"af\", \"type\", \"protocol\" should be number");
|
||||||
int sd = socket(args[0].num(), args[1].num(), args[2].num());
|
int sd = socket(args[0].num(), args[1].num(), args[2].num());
|
||||||
return var::num((double)sd);
|
return var::num(static_cast<double>(sd));
|
||||||
}
|
}
|
||||||
|
|
||||||
var nas_closesocket(var* args, usize size, gc* ngc) {
|
var nas_closesocket(var* args, usize size, gc* ngc) {
|
||||||
if (args[0].type!=vm_num)
|
if (args[0].type!=vm_num)
|
||||||
return nas_err("closesocket", "\"sd\" should be number");
|
return nas_err("closesocket", "\"sd\" should be number");
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
return var::num((double)closesocket(args[0].num()));
|
return var::num(static_cast<double>(closesocket(args[0].num())));
|
||||||
#else
|
#else
|
||||||
return var::num((double)close(args[0].num()));
|
return var::num(static_cast<double>(close(args[0].num())));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,7 +52,7 @@ var nas_shutdown(var* args, usize size, gc* ngc) {
|
||||||
return nas_err("shutdown", "\"sd\" must be a number");
|
return nas_err("shutdown", "\"sd\" must be a number");
|
||||||
if (args[1].type!=vm_num)
|
if (args[1].type!=vm_num)
|
||||||
return nas_err("shutdown", "\"how\" must be a number");
|
return nas_err("shutdown", "\"how\" must be a number");
|
||||||
return var::num((double)shutdown(args[0].num(), args[1].num()));
|
return var::num(static_cast<double>(shutdown(args[0].num(), args[1].num())));
|
||||||
}
|
}
|
||||||
|
|
||||||
var nas_bind(var* args, usize size, gc* ngc) {
|
var nas_bind(var* args, usize size, gc* ngc) {
|
||||||
|
@ -67,7 +67,11 @@ var nas_bind(var* args, usize size, gc* ngc) {
|
||||||
server.sin_family = AF_INET;
|
server.sin_family = AF_INET;
|
||||||
server.sin_addr.s_addr = inet_addr(args[1].str().c_str());
|
server.sin_addr.s_addr = inet_addr(args[1].str().c_str());
|
||||||
server.sin_port = htons(args[2].num());
|
server.sin_port = htons(args[2].num());
|
||||||
return var::num((double)bind(args[0].num(), (sockaddr*)&server, sizeof(server)));
|
return var::num(static_cast<double>(bind(
|
||||||
|
args[0].num(),
|
||||||
|
(sockaddr*)&server,
|
||||||
|
sizeof(server)
|
||||||
|
)));
|
||||||
}
|
}
|
||||||
|
|
||||||
var nas_listen(var* args, usize size, gc* ngc) {
|
var nas_listen(var* args, usize size, gc* ngc) {
|
||||||
|
@ -75,7 +79,7 @@ var nas_listen(var* args, usize size, gc* ngc) {
|
||||||
return nas_err("listen", "\"sd\" must be a number");
|
return nas_err("listen", "\"sd\" must be a number");
|
||||||
if (args[1].type!=vm_num)
|
if (args[1].type!=vm_num)
|
||||||
return nas_err("listen", "\"backlog\" must be a number");
|
return nas_err("listen", "\"backlog\" must be a number");
|
||||||
return var::num((double)listen(args[0].num(), args[1].num()));
|
return var::num(static_cast<double>(listen(args[0].num(), args[1].num())));
|
||||||
}
|
}
|
||||||
|
|
||||||
var nas_connect(var* args, usize size, gc* ngc) {
|
var nas_connect(var* args, usize size, gc* ngc) {
|
||||||
|
@ -91,11 +95,11 @@ var nas_connect(var* args, usize size, gc* ngc) {
|
||||||
addr.sin_port = htons(args[2].num());
|
addr.sin_port = htons(args[2].num());
|
||||||
hostent* entry = gethostbyname(args[1].str().c_str());
|
hostent* entry = gethostbyname(args[1].str().c_str());
|
||||||
memcpy(&addr.sin_addr, entry->h_addr, entry->h_length);
|
memcpy(&addr.sin_addr, entry->h_addr, entry->h_length);
|
||||||
return var::num((double)connect(
|
return var::num(static_cast<double>(connect(
|
||||||
args[0].num(),
|
args[0].num(),
|
||||||
(sockaddr*)&addr,
|
(sockaddr*)&addr,
|
||||||
sizeof(sockaddr_in)
|
sizeof(sockaddr_in)
|
||||||
));
|
)));
|
||||||
}
|
}
|
||||||
|
|
||||||
var nas_accept(var* args, usize size, gc* ngc) {
|
var nas_accept(var* args, usize size, gc* ngc) {
|
||||||
|
@ -110,7 +114,7 @@ var nas_accept(var* args, usize size, gc* ngc) {
|
||||||
#endif
|
#endif
|
||||||
var res=ngc->temp = ngc->alloc(vm_hash);
|
var res=ngc->temp = ngc->alloc(vm_hash);
|
||||||
auto& hash = res.hash().elems;
|
auto& hash = res.hash().elems;
|
||||||
hash["sd"] = var::num((double)client_sd);
|
hash["sd"] = var::num(static_cast<double>(client_sd));
|
||||||
hash["ip"] = ngc->newstr(inet_ntoa(client.sin_addr));
|
hash["ip"] = ngc->newstr(inet_ntoa(client.sin_addr));
|
||||||
ngc->temp = nil;
|
ngc->temp = nil;
|
||||||
return res;
|
return res;
|
||||||
|
@ -123,12 +127,12 @@ var nas_send(var* args, usize size, gc* ngc) {
|
||||||
return nas_err("send", "\"buff\" must be a string");
|
return nas_err("send", "\"buff\" must be a string");
|
||||||
if (args[2].type!=vm_num)
|
if (args[2].type!=vm_num)
|
||||||
return nas_err("send", "\"flags\" muse be a number");
|
return nas_err("send", "\"flags\" muse be a number");
|
||||||
return var::num((double)send(
|
return var::num(static_cast<double>(send(
|
||||||
args[0].num(),
|
args[0].num(),
|
||||||
args[1].str().c_str(),
|
args[1].str().c_str(),
|
||||||
args[1].str().length(),
|
args[1].str().length(),
|
||||||
args[2].num()
|
args[2].num()
|
||||||
));
|
)));
|
||||||
}
|
}
|
||||||
|
|
||||||
var nas_sendto(var* args, usize size, gc* ngc) {
|
var nas_sendto(var* args, usize size, gc* ngc) {
|
||||||
|
@ -148,14 +152,14 @@ var nas_sendto(var* args, usize size, gc* ngc) {
|
||||||
addr.sin_port = htons(args[2].num());
|
addr.sin_port = htons(args[2].num());
|
||||||
hostent* entry = gethostbyname(args[1].str().c_str());
|
hostent* entry = gethostbyname(args[1].str().c_str());
|
||||||
memcpy(&addr.sin_addr, entry->h_addr, entry->h_length);
|
memcpy(&addr.sin_addr, entry->h_addr, entry->h_length);
|
||||||
return var::num((double)sendto(
|
return var::num(static_cast<double>(sendto(
|
||||||
args[0].num(),
|
args[0].num(),
|
||||||
args[3].str().c_str(),
|
args[3].str().c_str(),
|
||||||
args[3].str().length(),
|
args[3].str().length(),
|
||||||
args[4].num(),
|
args[4].num(),
|
||||||
(sockaddr*)&addr,
|
(sockaddr*)&addr,
|
||||||
sizeof(sockaddr_in)
|
sizeof(sockaddr_in)
|
||||||
));
|
)));
|
||||||
}
|
}
|
||||||
|
|
||||||
var nas_recv(var* args, usize size, gc* ngc) {
|
var nas_recv(var* args, usize size, gc* ngc) {
|
||||||
|
@ -169,9 +173,9 @@ var nas_recv(var* args, usize size, gc* ngc) {
|
||||||
return nas_err("recv", "\"flags\" muse be a number");
|
return nas_err("recv", "\"flags\" muse be a number");
|
||||||
var res = ngc->temp = ngc->alloc(vm_hash);
|
var res = ngc->temp = ngc->alloc(vm_hash);
|
||||||
auto& hash = res.hash().elems;
|
auto& hash = res.hash().elems;
|
||||||
char* buf = new char[(int)args[1].num()];
|
char* buf = new char[static_cast<int>(args[1].num())];
|
||||||
auto recvsize = recv(args[0].num(), buf,args[1].num(), args[2].num());
|
auto recvsize = recv(args[0].num(), buf,args[1].num(), args[2].num());
|
||||||
hash["size"] = var::num((double)recvsize);
|
hash["size"] = var::num(static_cast<double>(recvsize));
|
||||||
buf[recvsize>=0? recvsize:0] = 0;
|
buf[recvsize>=0? recvsize:0] = 0;
|
||||||
hash["str"] = ngc->newstr(buf);
|
hash["str"] = ngc->newstr(buf);
|
||||||
delete[] buf;
|
delete[] buf;
|
||||||
|
@ -192,7 +196,7 @@ var nas_recvfrom(var* args, usize size, gc* ngc) {
|
||||||
int socklen = sizeof(sockaddr_in);
|
int socklen = sizeof(sockaddr_in);
|
||||||
var res = ngc->temp = ngc->alloc(vm_hash);
|
var res = ngc->temp = ngc->alloc(vm_hash);
|
||||||
auto& hash = res.hash().elems;
|
auto& hash = res.hash().elems;
|
||||||
char* buf = new char[(int)args[1].num()+1];
|
char* buf = new char[static_cast<int>(args[1].num()+1)];
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
auto recvsize = recvfrom(
|
auto recvsize = recvfrom(
|
||||||
args[0].num(),
|
args[0].num(),
|
||||||
|
@ -212,7 +216,7 @@ var nas_recvfrom(var* args, usize size, gc* ngc) {
|
||||||
(socklen_t*)&socklen
|
(socklen_t*)&socklen
|
||||||
);
|
);
|
||||||
#endif
|
#endif
|
||||||
hash["size"] = var::num((double)recvsize);
|
hash["size"] = var::num(static_cast<double>(recvsize));
|
||||||
buf[recvsize>=0? recvsize:0] = 0;
|
buf[recvsize>=0? recvsize:0] = 0;
|
||||||
hash["str"] = ngc->newstr(buf);
|
hash["str"] = ngc->newstr(buf);
|
||||||
delete[] buf;
|
delete[] buf;
|
||||||
|
|
|
@ -9,6 +9,13 @@
|
||||||
namespace nasal {
|
namespace nasal {
|
||||||
namespace repl {
|
namespace repl {
|
||||||
|
|
||||||
|
void repl::add_command_history(const std::string& history) {
|
||||||
|
command_history.push_back(history);
|
||||||
|
if (command_history.size()>1000) {
|
||||||
|
command_history.pop_front();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::string repl::readline(std::string prompt = ">>> ") {
|
std::string repl::readline(std::string prompt = ">>> ") {
|
||||||
auto line = std::string("");
|
auto line = std::string("");
|
||||||
std::cout << prompt;
|
std::cout << prompt;
|
||||||
|
@ -51,6 +58,7 @@ bool repl::check_need_more_input() {
|
||||||
}
|
}
|
||||||
|
|
||||||
auto line = readline("... ");
|
auto line = readline("... ");
|
||||||
|
add_command_history(line);
|
||||||
source.back() += "\n" + line;
|
source.back() += "\n" + line;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -117,6 +125,7 @@ void repl::execute() {
|
||||||
if (!line.length()) {
|
if (!line.length()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
add_command_history(line);
|
||||||
|
|
||||||
if (line == ".e" || line == ".exit") {
|
if (line == ".e" || line == ".exit") {
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <deque>
|
||||||
|
|
||||||
namespace nasal {
|
namespace nasal {
|
||||||
namespace repl {
|
namespace repl {
|
||||||
|
@ -27,9 +28,11 @@ struct info {
|
||||||
class repl {
|
class repl {
|
||||||
private:
|
private:
|
||||||
std::vector<std::string> source;
|
std::vector<std::string> source;
|
||||||
|
std::deque<std::string> command_history;
|
||||||
vm runtime;
|
vm runtime;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void add_command_history(const std::string&);
|
||||||
std::string readline(std::string);
|
std::string readline(std::string);
|
||||||
bool check_need_more_input();
|
bool check_need_more_input();
|
||||||
void update_temp_file();
|
void update_temp_file();
|
||||||
|
@ -42,6 +45,8 @@ public:
|
||||||
runtime.set_repl_mode_flag(true);
|
runtime.set_repl_mode_flag(true);
|
||||||
// no detail report info
|
// no detail report info
|
||||||
runtime.set_detail_report_info(false);
|
runtime.set_detail_report_info(false);
|
||||||
|
// set empty history
|
||||||
|
command_history = {""};
|
||||||
}
|
}
|
||||||
void execute();
|
void execute();
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue