diff --git a/clitests/cities.psil b/clitests/cities.psil new file mode 100644 index 0000000..946a9ea --- /dev/null +++ b/clitests/cities.psil @@ -0,0 +1,90 @@ +(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 (empty? l) + (equal? l (nil)) +) + +(define (not a) + (if a 0 1) +) + +(not 2) +(not 1) +(not 0) + + +(define (lhas list what) + (if (empty? list) 0 + (if (equal? (car list) what) 1 (lhas (cdr list) what)) +) +) + +(define (onehas list l) + (if (empty? list) 0 + (if (l (car list)) 1 (onehas (cdr list) l)) +) +) + +(define (appfront list what) +(cons what list) + ) + +(define (pathslist acc paths from) + (if (empty? paths) + acc + (if (equal? (car (car paths)) from) + (pathslist (appfront acc (car(cdr (car paths)))) (cdr paths) from) + (pathslist acc (cdr paths) from) + ) + ) +) + +(equal? (pathslist () (quote((1 2))) 1) (quote(2))) + + +(define (filter p l) +(if (empty? l) (nil) + (if (p (car l)) + (cons (car l) (filter p (cdr l)) ) + (filter p (cdr l)) + ) +)) + +(filter (lambda (x) (if (> x 0) 1 0 )) (quote(-1 2 0 3 -3 1))) +(equal? (filter (lambda (x) (if (> (car x) 0) (if (> (car(cdr x)) 0) 1 0) 0 )) (quote((-1 2) (0 3) (-3 1) (1 1)))) (quote((1 1)))) + +(define (cities-path-impl seen paths from to) + (if (equal? from to) + 1 + (onehas + (filter (lambda (w) (not (lhas (appfront seen from) w))) (pathslist (nil) paths from)) + (lambda (f) (cities-path-impl (appfront seen from) paths f to)) + ) + ) + ) + +(define (cities-path? paths from to) + (cities-path-impl (nil) paths from to) +) + +(cities-path? (nil) 1 2) +(cities-path? (nil) 2 2) +(cities-path? (quote((1 2))) 1 2) +(cities-path? (quote((1 2))) 1 3) +(cities-path? (quote((1 2))) 2 1) +(cities-path? (quote((2 1))) 1 2) +(cities-path? (quote((1 2) (2 1))) 1 2) +(cities-path? (quote((1 2) (2 1))) 2 1) +(cities-path? (quote((1 2) (2 3) (3 4) (4 2))) 1 2) +(cities-path? (quote((1 2) (2 3) (3 4) (4 2))) 1 3) +(cities-path? (quote((1 2) (2 3) (3 4) (4 2))) 1 4) +(cities-path? (quote((1 2) (2 3) (3 4) (4 2))) 2 3) +(cities-path? (quote((1 2) (2 3) (3 4) (4 2))) 2 4) +(cities-path? (quote((4 2) (3 4) (2 3) (1 2))) 3 2) diff --git a/clitests/cities.psil.ex b/clitests/cities.psil.ex new file mode 100644 index 0000000..8662b46 --- /dev/null +++ b/clitests/cities.psil.ex @@ -0,0 +1,20 @@ +0 +0 +1 +1 +(2 3 1) +1 +0 +1 +1 +0 +0 +0 +1 +1 +1 +1 +1 +1 +1 +1 \ No newline at end of file diff --git a/src/support/include/Logger.h b/src/support/include/Logger.h index 793898f..f136674 100644 --- a/src/support/include/Logger.h +++ b/src/support/include/Logger.h @@ -26,6 +26,8 @@ public: // 3 - debug // 4 - trace static void set_level(const std::string &tag, int level); + static int get_level(const std::string &tag); + static bool en_level(const std::string &tag, int level); static void set_out(std::ostream &out); static void set_out_err(std::ostream &out_err); diff --git a/src/support/src/Logger.cpp b/src/support/src/Logger.cpp index 3001aa6..be36815 100644 --- a/src/support/src/Logger.cpp +++ b/src/support/src/Logger.cpp @@ -14,29 +14,23 @@ Logger &Logger::get() { } void Logger::log(const std::string &tag, const std::string &what, int level) { - std::shared_lock l(get()._mutex); - int en_level = Options::get_int("default_log_level"); - if (get()._levels.find(tag) != get()._levels.end()) en_level = get()._levels.at(tag); + if (!en_level(tag, level)) return; + { + std::shared_lock l(get()._mutex); + auto now = std::chrono::high_resolution_clock::now(); + std::stringstream out; + out << std::setprecision(4) << std::fixed << "[" + << static_cast(std::chrono::duration_cast(now - get()._start_time).count()) / 1000.0 << "s]" + << "[" << tag << "][" << get()._level_names.at(level) << "] " << what << '\n'; - if (en_level < level) return; - - auto now = std::chrono::high_resolution_clock::now(); - std::stringstream out; - out << std::setprecision(4) << std::fixed << "[" - << static_cast(std::chrono::duration_cast(now - get()._start_time).count()) / 1000.0 << "s]" - << "[" << tag << "][" << get()._level_names.at(level) << "] " << what << '\n'; - - if (level == 1) get()._out_err.get() << out.str(); - else - get()._out.get() << out.str(); + if (level == 1) get()._out_err.get() << out.str(); + else + get()._out.get() << out.str(); + } } void Logger::log(const std::string &tag, const std::function &fn, int level) { - std::shared_lock l(get()._mutex); - int en_level = Options::get_int("default_log_level"); - if (get()._levels.find(tag) != get()._levels.end()) en_level = get()._levels.at(tag); - - if (en_level < level) return; + if (!en_level(tag, level)) return; std::stringstream out; fn(out); @@ -59,3 +53,14 @@ void Logger::reset() { std::lock_guard l(get()._mutex); get()._levels = {}; } +int Logger::get_level(const std::string &tag) { + std::shared_lock l(get()._mutex); + int en_level = Options::get_int("default_log_level"); + if (get()._levels.find(tag) != get()._levels.end()) en_level = get()._levels.at(tag); + return en_level; +} +bool Logger::en_level(const std::string &tag, int level) { + int en_level = get_level(tag); + if (en_level < level) return false; + return true; +} diff --git a/src/vm/include/VM.h b/src/vm/include/VM.h index 4e6aa04..cbb4edb 100644 --- a/src/vm/include/VM.h +++ b/src/vm/include/VM.h @@ -33,6 +33,7 @@ private: Handle _globals_vals = Handle::cons(nullptr, nullptr); std::vector> _globals_names_map; size_t _cur_global = 0; + size_t _cur_call_level = 0; Handle _s = Handle::cons(nullptr, nullptr); Handle _e = Handle::cons(_globals_vals, nullptr); Handle _c = Handle::cons(nullptr, nullptr); diff --git a/src/vm/src/VM.cpp b/src/vm/src/VM.cpp index 933066c..199317c 100644 --- a/src/vm/src/VM.cpp +++ b/src/vm/src/VM.cpp @@ -3,6 +3,7 @@ // #include +#include #include #include @@ -86,6 +87,15 @@ void VM::step() { _d.push(_e); _d.push(_c); + std::optional name; + if (Logger::en_level("VM", Logger::DEBUG)) { + name = "unknown"; + for (const auto &p: _globals_names_map) { + if (p.first == closureH) name = p.second; + } + _d.push(Handle(*name)); + } + _s = Handle::cons(nullptr, nullptr); _c = closureH.car(); _e = closureH.cdr(); @@ -93,17 +103,21 @@ void VM::step() { Logger::log( "VM", [&](std::ostream &out) { - out << "Applying "; - for (const auto &p: _globals_names_map) { - if (p.first == closureH) out << p.second; - } + out << _cur_call_level; + for (int i = 0; i < _cur_call_level; i++) out << " "; + out << " Applying " << *name; out << " with args " << argsH; }, Logger::DEBUG); - + _cur_call_level++; _e.push(argsH); } else if (poppedCmd == RET) { + _cur_call_level--; + + Handle n; + if (Logger::en_level("VM", Logger::DEBUG)) n = _d.pop(); + Handle c = _d.pop(); Handle e = _d.pop(); Handle s = _d.pop(); @@ -114,6 +128,19 @@ void VM::step() { _e = e; _s = s; + Logger::log( + "VM", + [&](std::ostream &out) { + out << _cur_call_level; + for (int i = 0; i < _cur_call_level; i++) out << " "; + out << " Returning from " << n << " "; + bool cons = !ret.atom(); + if (cons) out << "("; + out << ret; + if (cons) out << ")"; + }, + Logger::DEBUG); + _s.push(ret); } else if (poppedCmd == DUM) { _e.push(nullptr); @@ -127,6 +154,8 @@ void VM::step() { _d.push(origE); _d.push(_c); + if (Logger::en_level("VM", Logger::DEBUG)) _d.push(Handle("rap")); + _s = Handle::cons(nullptr, nullptr); _c = closureH.car(); _e = closureH.cdr(); @@ -134,6 +163,8 @@ void VM::step() { Handle fnEnv = closureH.cdr(); assert(_e == fnEnv); + _cur_call_level++; + _e.push(argsH); fnEnv.setcar(argsH); } else if (poppedCmd == STOP) {