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)
)
(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)
(if (= times (nil))
(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) (car times) 1 (getmax cur max))
)
@@ -16,6 +25,23 @@
(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 (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) )))

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=()
PSIL="../cmake-build-debug/src/psil"
for FILE in *.psil; do
echo "TESTING $FILE"
$PSIL -f $FILE --repl- > $FILE.res

View File

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

View File

@@ -43,19 +43,20 @@ namespace Command {
CDR = 24,
EQ = 25,
LT = 26,
GT = 27
GT = 27,
NILC = 28
};
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},
{"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},
{"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{
{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"},
{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) {
if (Options::get_bool("command_strs")) {

View File

@@ -37,8 +37,14 @@ public:
static Handle cons(const Handle &car, const Handle &cdr);
Handle car() const { return dynamic_cast<ConsCell &>(*_target)._car.load(); }
Handle cdr() const { return dynamic_cast<ConsCell &>(*_target)._cdr.load(); }
Handle car() const {
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; }
std::string_view strval() { return dynamic_cast<StrAtomCell &>(*_target)._val; }

View File

@@ -31,6 +31,8 @@ public:
private:
Handle _globals_names = Handle::cons(Handle::cons(nullptr, 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 _e = Handle::cons(_globals_vals, nullptr);
Handle _c = Handle::cons(nullptr, nullptr);

View File

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

View File

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

View File

@@ -41,7 +41,9 @@ void VM::step() {
} else if (poppedCmd == LDC) {
_s.push(_c.pop());
} 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) {
Handle poppedH2 = _c.pop();
@@ -87,6 +89,19 @@ void VM::step() {
_s = Handle::cons(nullptr, nullptr);
_c = closureH.car();
_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);
} else if (poppedCmd == RET) {
Handle c = _d.pop();
@@ -170,7 +185,14 @@ void VM::step() {
newc.splice(_c);
_c = newc;
} 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) {
if (!_s.null()) {
Handle val = _s.pop();