repl quit

This commit is contained in:
2024-01-04 12:50:26 +01:00
parent 8f5294fea7
commit efc60b4c23
6 changed files with 27 additions and 20 deletions

View File

@@ -31,7 +31,7 @@ PSIL="../build/src/psil" clitests/testall.sh
# How to use # How to use
You can just run the executable and you'll be in REPL mode (ctrl-c to exit should work), You can just run the executable and you'll be in REPL mode (ctrl-c to exit should work, or `(quit)`),
or specify an input file like `-f <file>`, the effect is the same as if you or specify an input file like `-f <file>`, the effect is the same as if you
had put it there yourself. had put it there yourself.
@@ -91,10 +91,10 @@ build/src/psil -f clitests/decorate.psil --repl- --command_strs+ --default_log_l
# Some notes on the implementation # Some notes on the implementation
The implementation is rather straightforward, based mostly on the compiler from "THE ARCHITECTURE OF SYMBOLIC The implementation is rather straightforward, based mostly on the compiler from "The Architecture of Symbolic
COMPUTERS", with little modification and some additions. Notably, the let/letrec is more lisp-like, using racket-like Computers", with little modification and some additions. Notably, the let/letrec is more lisp-like, using racket-like
name-value pairs instead of them being in separate lists like in the book. Also, there's support for top-level functions name-value pairs instead of them being in separate lists like in the book. Also, there's support for top-level functions
using `define`, and a simple concurrent garbage collector. using `define`, quoting using `(quote value)`, and a simple concurrent garbage collector.
There are three basic value types which is a string atom, number atom, and a cons cell. There are three basic value types which is a string atom, number atom, and a cons cell.

View File

@@ -94,7 +94,7 @@ int main(int argc, char *argv[]) {
} }
if (Options::get<bool>("repl")) if (Options::get<bool>("repl"))
while (true) { while (true && !vm.is_quit()) {
std::cout << "> "; std::cout << "> ";
vm.loadControl(repl); vm.loadControl(repl);
vm.run(); vm.run();

View File

@@ -47,21 +47,22 @@ namespace Command {
GT = 27, GT = 27,
NILC = 28, NILC = 28,
MULT = 29, MULT = 29,
DIV = 30 DIV = 30,
QUIT = 31
}; };
static inline std::unordered_map<std::string_view, CellValType> str_to_cmd{ static inline std::unordered_map<std::string_view, CellValType> str_to_cmd{
{"NIL", 1}, {"LDC", 2}, {"LD", 3}, {"SEL", 4}, {"JOIN", 5}, {"LDF", 6}, {"NIL", 1}, {"LDC", 2}, {"LD", 3}, {"SEL", 4}, {"JOIN", 5}, {"LDF", 6}, {"AP", 7},
{"AP", 7}, {"RET", 8}, {"DUM", 9}, {"RAP", 10}, {"STOP", 11}, {"ATOM", 12}, {"RET", 8}, {"DUM", 9}, {"RAP", 10}, {"STOP", 11}, {"ATOM", 12}, {"ADD", 13}, {"SUB", 14},
{"ADD", 13}, {"SUB", 14}, {"READCHAR", 15}, {"PUTCHAR", 16}, {"PUTNUM", 17}, {"EVAL", 18}, {"READCHAR", 15}, {"PUTCHAR", 16}, {"PUTNUM", 17}, {"EVAL", 18}, {"PRINT", 19}, {"READ", 20}, {"CONS", 21},
{"PRINT", 19}, {"READ", 20}, {"CONS", 21}, {"LDG", 22}, {"CAR", 23}, {"CDR", 24}, {"LDG", 22}, {"CAR", 23}, {"CDR", 24}, {"EQ", 25}, {"LT", 26}, {"GT", 27}, {"NILC", 28},
{"EQ", 25}, {"LT", 26}, {"GT", 27}, {"NILC", 28}, {"MULT", 29}, {"DIV", 30}}; {"MULT", 29}, {"DIV", 30}, {"QUIT", 31}};
static inline std::unordered_map<CellValType, std::string> cmd_to_str{ static inline std::unordered_map<CellValType, std::string> cmd_to_str{
{1, "NIL"}, {2, "LDC"}, {3, "LD"}, {4, "SEL"}, {5, "JOIN"}, {6, "LDF"}, {1, "NIL"}, {2, "LDC"}, {3, "LD"}, {4, "SEL"}, {5, "JOIN"}, {6, "LDF"}, {7, "AP"},
{7, "AP"}, {8, "RET"}, {9, "DUM"}, {10, "RAP"}, {11, "STOP"}, {12, "ATOM"}, {8, "RET"}, {9, "DUM"}, {10, "RAP"}, {11, "STOP"}, {12, "ATOM"}, {13, "ADD"}, {14, "SUB"},
{13, "ADD"}, {14, "SUB"}, {15, "READCHAR"}, {16, "PUTCHAR"}, {17, "PUTNUM"}, {18, "EVAL"}, {15, "READCHAR"}, {16, "PUTCHAR"}, {17, "PUTNUM"}, {18, "EVAL"}, {19, "PRINT"}, {20, "READ"}, {21, "CONS"},
{19, "PRINT"}, {20, "READ"}, {21, "CONS"}, {22, "LDG"}, {23, "CAR"}, {24, "CDR"}, {22, "LDG"}, {23, "CAR"}, {24, "CDR"}, {25, "EQ"}, {26, "LT"}, {27, "GT"}, {28, "NILC"},
{25, "EQ"}, {26, "LT"}, {27, "GT"}, {28, "NILC"}, {29, "MULT"}, {30, "DIV"}}; {29, "MULT"}, {30, "DIV"}, {31, "QUIT"}};
static inline Handle make_cmd(CellValType cmd) { static inline Handle make_cmd(CellValType cmd) {
if (Options::get<bool>("command_strs")) { if (Options::get<bool>("command_strs")) {

View File

@@ -26,6 +26,7 @@ public:
void loadStack(const Handle &h) { _s = h; } void loadStack(const Handle &h) { _s = h; }
bool is_quit() const { return _quit; }
void step(); void step();
private: private:
@@ -39,6 +40,7 @@ private:
Handle _c = Handle::cons(nullptr, nullptr); Handle _c = Handle::cons(nullptr, nullptr);
Handle _d = Handle::cons(nullptr, nullptr); Handle _d = Handle::cons(nullptr, nullptr);
bool _stop = false; bool _stop = false;
bool _quit = false;
std::istream &_instream; std::istream &_instream;
std::ostream &_outstream; std::ostream &_outstream;

View File

@@ -18,8 +18,9 @@ using namespace Command;
static std::unordered_map<std::string_view, CommandE> builtins{ static std::unordered_map<std::string_view, CommandE> builtins{
{"+", ADD}, {"-", SUB}, {"cons", CONS}, {"car", CAR}, {"cdr", CDR}, {"=", EQ}, {">", GT}, {"+", ADD}, {"-", SUB}, {"cons", CONS}, {"car", CAR}, {"cdr", CDR}, {"=", EQ},
{"<", LT}, {"nil", NIL}, {"nil?", NILC}, {"atom", ATOM}, {"*", MULT}, {"/", DIV}}; {">", GT}, {"<", LT}, {"nil", NIL}, {"nil?", NILC}, {"atom", ATOM}, {"*", MULT},
{"/", DIV}, {"read", READ}, {"eval", EVAL}, {"print", PRINT}, {"quit", QUIT}};
Handle Compiler::compile(const Handle &src, Handle fake_env, const Handle &suffix) { Handle Compiler::compile(const Handle &src, Handle fake_env, const Handle &suffix) {
Handle out; Handle out;
@@ -82,8 +83,6 @@ Handle Compiler::compile(const Handle &src, Handle fake_env, const Handle &suffi
} else if (builtins.find(car.strval()) != builtins.end()) { } else if (builtins.find(car.strval()) != builtins.end()) {
out.splice(compileArgsRaw(cdr)); out.splice(compileArgsRaw(cdr));
out.append(make_cmd(builtins.at(car.strval()))); out.append(make_cmd(builtins.at(car.strval())));
} else if (car.strval() == "read") {
out.append(make_cmd(READ));
} else if (car.strval() == "lambda") { } else if (car.strval() == "lambda") {
out.append(make_cmd(LDF)); out.append(make_cmd(LDF));
out.append(compile(cdr.cdr().car(), Handle::cons(cdr.car(), fake_env), make_cmd(RET))); out.append(compile(cdr.cdr().car(), Handle::cons(cdr.car(), fake_env), make_cmd(RET)));

View File

@@ -194,6 +194,11 @@ void VM::step() {
_stop = true; _stop = true;
break; break;
} }
case QUIT: {
_stop = true;
_quit = true;
break;
}
case ADD: { case ADD: {
_s.push(_s.pop().val() + _s.pop().val()); _s.push(_s.pop().val() + _s.pop().val());
break; break;