This commit is contained in:
2024-01-03 21:18:01 +01:00
parent 2db8b5984f
commit 02fe73f42f
12 changed files with 88 additions and 18 deletions

1
clitests/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
*.res

View File

@@ -2,10 +2,19 @@
(if (> a b) a b) (if (> a b) a b)
) )
(define (equal a b)
(if (nil? a) (if (nil? b) 1 0)
(if (atom a)
(if (atom b) (= a b) 0)
(if (atom b) 0 (if (equal (car a) (car b)) (equal (cdr a) (cdr b)) 0))
)
)
)
(define (coffee-shop-impl times last cur max) (define (coffee-shop-impl times last cur max)
(if (= times (nil)) (if (= times (nil))
(getmax cur max) (getmax cur max)
(if (= last (car times)) (if (equal last (car times))
(coffee-shop-impl (cdr times) last (+ cur 1) max) (coffee-shop-impl (cdr times) last (+ cur 1) max)
(coffee-shop-impl (cdr times) (car times) 1 (getmax cur max)) (coffee-shop-impl (cdr times) (car times) 1 (getmax cur max))
) )
@@ -16,6 +25,23 @@
(coffee-shop-impl times (nil) 0 0) (coffee-shop-impl times (nil) 0 0)
) )
(equal (nil) (nil))
(equal (nil) ())
(equal () (nil))
(equal (nil) (quote()))
(equal () (nil))
(equal () (quote()))
(equal (quote(a))(quote()))
(equal (quote(a)) ())
(equal (quote(a)) (nil))
(equal (quote(a)) (quote(a.)))
(equal (quote(a.)) (quote(a b)))
(equal (quote(a b)) (quote(a.b)))
(equal (quote(a b)) (quote(a b)))
(coffee-shop (nil)) (coffee-shop (nil))
(coffee-shop (quote( (8 0) (8 10) (8 10) (8 45) ))) (coffee-shop (quote( (8 0) (8 10) (8 10) (8 45) )))
(coffee-shop (quote( (8 12) (10 11) (10 11) (15 15) (15 15) (15 15) (22 22) (22 22) (22 59) ))) (coffee-shop (quote( (8 12) (10 11) (10 11) (15 15) (15 15) (15 15) (22 22) (22 22) (22 59) )))

16
clitests/coffee.psil.ex Normal file
View File

@@ -0,0 +1,16 @@
1
1
1
1
1
1
0
0
0
1
0
0
1
0
2
3

View File

@@ -1,3 +0,0 @@
0
2
3

View File

@@ -3,8 +3,6 @@ cd "$(dirname "$0")"
FAILED=() FAILED=()
PSIL="../cmake-build-debug/src/psil"
for FILE in *.psil; do for FILE in *.psil; do
echo "TESTING $FILE" echo "TESTING $FILE"
$PSIL -f $FILE --repl- > $FILE.res $PSIL -f $FILE --repl- > $FILE.res

View File

@@ -89,7 +89,7 @@ struct ConsCell : public Cell {
void print(std::ostream &out) override { void print(std::ostream &out) override {
std::stringstream res; std::stringstream res;
std::set<Cell *> seen; std::set<Cell *> seen{this};
if (_car) { if (_car) {
if (_car.load()->_type == CellType::CONS) { if (_car.load()->_type == CellType::CONS) {
res << "("; res << "(";

View File

@@ -43,19 +43,20 @@ namespace Command {
CDR = 24, CDR = 24,
EQ = 25, EQ = 25,
LT = 26, LT = 26,
GT = 27 GT = 27,
NILC = 28
}; };
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}, {"AP", 7}, {"NIL", 1}, {"LDC", 2}, {"LD", 3}, {"SEL", 4}, {"JOIN", 5}, {"LDF", 6}, {"AP", 7},
{"RET", 8}, {"DUM", 9}, {"RAP", 10}, {"STOP", 11}, {"ATOM", 12}, {"ADD", 13}, {"SUB", 14}, {"RET", 8}, {"DUM", 9}, {"RAP", 10}, {"STOP", 11}, {"ATOM", 12}, {"ADD", 13}, {"SUB", 14},
{"READCHAR", 15}, {"PUTCHAR", 16}, {"PUTNUM", 17}, {"EVAL", 18}, {"PRINT", 19}, {"READ", 20}, {"CONS", 21}, {"READCHAR", 15}, {"PUTCHAR", 16}, {"PUTNUM", 17}, {"EVAL", 18}, {"PRINT", 19}, {"READ", 20}, {"CONS", 21},
{"LDG", 22}, {"CAR", 23}, {"CDR", 24}, {"EQ", 25}, {"LT", 26}, {"GT", 27}}; {"LDG", 22}, {"CAR", 23}, {"CDR", 24}, {"EQ", 25}, {"LT", 26}, {"GT", 27}, {"NILC", 28}};
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"}, {7, "AP"}, {1, "NIL"}, {2, "LDC"}, {3, "LD"}, {4, "SEL"}, {5, "JOIN"}, {6, "LDF"}, {7, "AP"},
{8, "RET"}, {9, "DUM"}, {10, "RAP"}, {11, "STOP"}, {12, "ATOM"}, {13, "ADD"}, {14, "SUB"}, {8, "RET"}, {9, "DUM"}, {10, "RAP"}, {11, "STOP"}, {12, "ATOM"}, {13, "ADD"}, {14, "SUB"},
{15, "READCHAR"}, {16, "PUTCHAR"}, {17, "PUTNUM"}, {18, "EVAL"}, {19, "PRINT"}, {20, "READ"}, {21, "CONS"}, {15, "READCHAR"}, {16, "PUTCHAR"}, {17, "PUTNUM"}, {18, "EVAL"}, {19, "PRINT"}, {20, "READ"}, {21, "CONS"},
{22, "LDG"}, {23, "CAR"}, {24, "CDR"}, {25, "EQ"}, {26, "LT"}, {27, "GT"}}; {22, "LDG"}, {23, "CAR"}, {24, "CDR"}, {25, "EQ"}, {26, "LT"}, {27, "GT"}, {28, "NILC"}};
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

@@ -37,8 +37,14 @@ public:
static Handle cons(const Handle &car, const Handle &cdr); static Handle cons(const Handle &car, const Handle &cdr);
Handle car() const { return dynamic_cast<ConsCell &>(*_target)._car.load(); } Handle car() const {
Handle cdr() const { return dynamic_cast<ConsCell &>(*_target)._cdr.load(); } if (!_target) return Handle(nullptr);
return dynamic_cast<ConsCell &>(*_target)._car.load();
}
Handle cdr() const {
if (!_target) return Handle(nullptr);
return dynamic_cast<ConsCell &>(*_target)._cdr.load();
}
CellValType val() { return dynamic_cast<NumAtomCell &>(*_target)._val; } CellValType val() { return dynamic_cast<NumAtomCell &>(*_target)._val; }
std::string_view strval() { return dynamic_cast<StrAtomCell &>(*_target)._val; } std::string_view strval() { return dynamic_cast<StrAtomCell &>(*_target)._val; }

View File

@@ -31,6 +31,8 @@ public:
private: private:
Handle _globals_names = Handle::cons(Handle::cons(nullptr, nullptr), nullptr); Handle _globals_names = Handle::cons(Handle::cons(nullptr, nullptr), nullptr);
Handle _globals_vals = Handle::cons(nullptr, nullptr); Handle _globals_vals = Handle::cons(nullptr, nullptr);
std::vector<std::pair<Handle, std::string>> _globals_names_map;
size_t _cur_global = 0;
Handle _s = Handle::cons(nullptr, nullptr); Handle _s = Handle::cons(nullptr, nullptr);
Handle _e = Handle::cons(_globals_vals, nullptr); Handle _e = Handle::cons(_globals_vals, nullptr);
Handle _c = Handle::cons(nullptr, nullptr); Handle _c = Handle::cons(nullptr, nullptr);

View File

@@ -16,8 +16,9 @@
using namespace Command; using namespace Command;
static std::unordered_map<std::string_view, CommandE> builtins{{"+", ADD}, {"-", SUB}, {"cons", CONS}, {"car", CAR}, {"cdr", CDR}, static std::unordered_map<std::string_view, CommandE> builtins{{"+", ADD}, {"-", SUB}, {"cons", CONS}, {"car", CAR},
{"=", EQ}, {">", GT}, {"<", LT}, {"nil", NIL}}; {"cdr", CDR}, {"=", EQ}, {">", GT}, {"<", LT},
{"nil", NIL}, {"nil?", NILC}, {"atom", ATOM}};
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;
@@ -80,7 +81,7 @@ Handle Compiler::compile(const Handle &src, Handle fake_env, const Handle &suffi
if (car.atom()) { if (car.atom()) {
if (car.strval() == "quote") { if (car.strval() == "quote") {
out.append(make_cmd(LDC)); out.append(make_cmd(LDC));
out.splice(cdr); out.splice(Handle::cons(cdr.car(), cdr.cdr()));
} 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())));

View File

@@ -23,7 +23,7 @@ Handle Parser::parseExpr() {
if (token == ".") { if (token == ".") {
_tokenizer.getNext(); _tokenizer.getNext();
out.setcdr(parseExpr()); if (_tokenizer.peek() != ")") out.setcdr(parseExpr());
if (_tokenizer.getNext() != ")") throw std::invalid_argument("Missing ) after pair"); if (_tokenizer.getNext() != ")") throw std::invalid_argument("Missing ) after pair");

View File

@@ -41,7 +41,9 @@ void VM::step() {
} else if (poppedCmd == LDC) { } else if (poppedCmd == LDC) {
_s.push(_c.pop()); _s.push(_c.pop());
} else if (poppedCmd == ATOM) { } else if (poppedCmd == ATOM) {
_s.push(_c.pop().atom() ? 1 : 0); _s.push(_s.pop().atom() ? 1 : 0);
} else if (poppedCmd == NILC) {
_s.push(_s.pop().null() ? 1 : 0);
} else if (poppedCmd == LD) { } else if (poppedCmd == LD) {
Handle poppedH2 = _c.pop(); Handle poppedH2 = _c.pop();
@@ -87,6 +89,19 @@ void VM::step() {
_s = Handle::cons(nullptr, nullptr); _s = Handle::cons(nullptr, nullptr);
_c = closureH.car(); _c = closureH.car();
_e = closureH.cdr(); _e = closureH.cdr();
Logger::log(
"VM",
[&](std::ostream &out) {
out << "Applying ";
for (const auto &p: _globals_names_map) {
if (p.first == closureH) out << p.second;
}
out << " with args " << argsH;
},
Logger::DEBUG);
_e.push(argsH); _e.push(argsH);
} else if (poppedCmd == RET) { } else if (poppedCmd == RET) {
Handle c = _d.pop(); Handle c = _d.pop();
@@ -170,7 +185,14 @@ void VM::step() {
newc.splice(_c); newc.splice(_c);
_c = newc; _c = newc;
} else if (poppedCmd == LDG) { } else if (poppedCmd == LDG) {
_globals_vals.append(Handle::cons(_c.pop(), _e)); Handle newclosure = Handle::cons(_c.pop(), _e);
Handle curName = _globals_names.car();
for (int i = 0; i < _cur_global; i++) { curName = curName.cdr(); }
_globals_names_map.emplace_back(newclosure, curName.car().strval());
_cur_global++;
_globals_vals.append(newclosure);
} else if (poppedCmd == PRINT) { } else if (poppedCmd == PRINT) {
if (!_s.null()) { if (!_s.null()) {
Handle val = _s.pop(); Handle val = _s.pop();