mirror of
https://github.com/usatiuk/psil.git
synced 2025-10-28 18:57:48 +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)
|
(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
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=()
|
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
|
||||||
|
|||||||
@@ -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 << "(";
|
||||||
|
|||||||
@@ -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")) {
|
||||||
|
|||||||
@@ -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; }
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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())));
|
||||||
|
|||||||
@@ -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");
|
||||||
|
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
Reference in New Issue
Block a user