mirror of
https://github.com/usatiuk/psil.git
synced 2025-10-28 10:47:49 +01:00
coffee!
This commit is contained in:
1
clitests/.gitignore
vendored
Normal file
1
clitests/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
*.res
|
||||
@@ -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
16
clitests/coffee.psil.ex
Normal file
@@ -0,0 +1,16 @@
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
0
|
||||
0
|
||||
0
|
||||
1
|
||||
0
|
||||
0
|
||||
1
|
||||
0
|
||||
2
|
||||
3
|
||||
@@ -1,3 +0,0 @@
|
||||
0
|
||||
2
|
||||
3
|
||||
@@ -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
|
||||
|
||||
@@ -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 << "(";
|
||||
|
||||
@@ -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")) {
|
||||
|
||||
@@ -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; }
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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())));
|
||||
|
||||
@@ -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");
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user