From cffb9c915137c1c2baa32ad6796051632c99ffa8 Mon Sep 17 00:00:00 2001 From: Stepan Usatiuk Date: Wed, 3 Jan 2024 23:59:53 +0100 Subject: [PATCH] some prettying --- src/main.cpp | 33 ++++++++++++------------------- src/vm/include/Cell.h | 12 ++++++------ src/vm/include/Handle.h | 36 ++++++++++++++++++++++++++++++---- src/vm/include/MemoryContext.h | 3 +-- src/vm/include/Parser.h | 2 ++ src/vm/include/VM.h | 2 +- src/vm/src/Handle.cpp | 8 ++++---- src/vm/src/Parser.cpp | 6 ++++++ src/vm/src/VM.cpp | 10 +++------- 9 files changed, 67 insertions(+), 45 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index f40e38e..362f9d1 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -21,7 +21,6 @@ void parse_options(int argc, char *argv[]) { continue; } - if (arg.length() < 2 || arg.substr(0, 2) != "--") { throw std::invalid_argument("Can't parse argument " + arg); } std::string rest = arg.substr(2); @@ -35,10 +34,10 @@ void parse_options(int argc, char *argv[]) { if (split.empty()) throw std::invalid_argument("Can't parse argument " + arg); if (split.at(0) == "log") { - if (split.size() != 3) throw std::invalid_argument("Log options must be in format --log:TAG:LEVEL, instead have: " + arg); + if (split.size() != 3) throw std::invalid_argument("Log options must be in format --log:TAG:LEVEL"); try { Logger::set_level(split.at(1), std::stoi(split.at(2))); - } catch (...) { throw std::invalid_argument("Log options must be in format --log:TAG:LEVEL, instead have: " + arg); } + } catch (...) { throw std::invalid_argument("Log options must be in format --log:TAG:LEVEL"); } } else if (split.size() == 1) { std::string str = split.at(0); if (str.back() != '+' && str.back() != '-') { @@ -48,7 +47,7 @@ void parse_options(int argc, char *argv[]) { } else if (split.size() == 2) { try { Options::set(split.at(0), std::stoi(split.at(1))); - } catch (...) { throw std::invalid_argument("Log options must be in format --log:TAG:LEVEL, instead have: " + arg); } + } catch (...) { throw std::invalid_argument("Options must be in format --OPTION:VALUE"); } } else { throw std::invalid_argument("Can't parse argument " + arg); } @@ -64,33 +63,24 @@ int main(int argc, char *argv[]) { parse_options(argc, argv); - Handle repl; - { - Parser parser; - parser.loadStr("(READ EVAL PRINT STOP)"); - repl = parser.parseExpr(); - } - Handle epl; - { - Parser parser; - parser.loadStr("(EVAL PRINT STOP)"); - epl = parser.parseExpr(); - } + Handle repl = Parser::parse_str("(READ EVAL PRINT STOP)"); + Handle epl = Parser::parse_str("(EVAL PRINT STOP)"); VM vm; if (infile) { Handle parsed; + std::stringstream buffer; buffer << "("; { std::ifstream t(*infile); + if (!t.is_open()) throw std::invalid_argument("Requested file could not be opened"); buffer << t.rdbuf(); } buffer << ")"; - Parser parser; - parser.loadStr(buffer.str()); - parsed = parser.parseExpr(); + + parsed = Parser::parse_str(buffer.str()); Handle cur_expr = parsed; while (!cur_expr.null()) { @@ -100,13 +90,14 @@ int main(int argc, char *argv[]) { cur_expr = cur_expr.cdr(); } } + if (Options::get("repl")) while (true) { - std::cout << std::endl << "> "; + std::cout << "> "; vm.loadControl(repl); vm.run(); - std::cout << std::endl; } + } catch (const std::exception &e) { std::cerr << "\nError: " << e.what() << std::endl; return -1; diff --git a/src/vm/include/Cell.h b/src/vm/include/Cell.h index 9505b27..798d15b 100644 --- a/src/vm/include/Cell.h +++ b/src/vm/include/Cell.h @@ -25,7 +25,7 @@ struct Cell { CellType _type; std::atomic _live = false; - virtual void print(std::ostream &out) = 0; + virtual void print(std::ostream &out) const = 0; }; struct NumAtomCell : public Cell { @@ -34,7 +34,7 @@ struct NumAtomCell : public Cell { CellValType _val; - void print(std::ostream &out) override { out << _val; } + void print(std::ostream &out) const override { out << _val; } }; struct StrAtomCell : public Cell { @@ -43,7 +43,7 @@ struct StrAtomCell : public Cell { std::string _val; - void print(std::ostream &out) override { out << _val; } + void print(std::ostream &out) const override { out << _val; } }; struct ConsCell : public Cell { @@ -54,7 +54,7 @@ struct ConsCell : public Cell { std::atomic _car = nullptr; std::atomic _cdr = nullptr; - void print_cons(std::ostream &out, std::set &seen) { + void print_cons(std::ostream &out, std::set &seen) const { std::stringstream res; if (_car) { if (_car.load()->_type == CellType::CONS) { @@ -89,9 +89,9 @@ struct ConsCell : public Cell { out << res.str(); } - void print(std::ostream &out) override { + void print(std::ostream &out) const override { std::stringstream res; - std::set seen{this}; + std::set seen{this}; if (_car) { if (_car.load()->_type == CellType::CONS) { res << "("; diff --git a/src/vm/include/Handle.h b/src/vm/include/Handle.h index a276749..464a0fe 100644 --- a/src/vm/include/Handle.h +++ b/src/vm/include/Handle.h @@ -8,10 +8,15 @@ #include "Cell.h" class MemoryContext; +class Handle; + +template<> +class std::hash; class Handle { public: friend MemoryContext; + friend class std::hash; Handle(Cell *target = nullptr); Handle(int64_t val); @@ -37,16 +42,25 @@ public: static Handle cons(const Handle &car, const Handle &cdr); - Handle car() const { + const Handle car() const { if (!_target) return Handle(nullptr); return dynamic_cast(*_target)._car.load(); } - Handle cdr() const { + const Handle cdr() const { if (!_target) return Handle(nullptr); return dynamic_cast(*_target)._cdr.load(); } - CellValType val() { return dynamic_cast(*_target)._val; } - std::string_view strval() { return dynamic_cast(*_target)._val; } + Handle car() { + if (!_target) return Handle(nullptr); + return dynamic_cast(*_target)._car.load(); + } + Handle cdr() { + if (!_target) return Handle(nullptr); + return dynamic_cast(*_target)._cdr.load(); + } + + CellValType val() const { return dynamic_cast(*_target)._val; } + std::string_view strval() const { return dynamic_cast(*_target)._val; } CellType type() const { if (!_target) return CellType::CONS; @@ -84,4 +98,18 @@ private: Cell *_target = nullptr; }; +namespace std { + template<> + class hash { + public: + size_t operator()(const Handle &c) const { + if (c.type() == CellType::NUMATOM) return std::hash()(c.val()); + else if (c.type() == CellType::STRATOM) + return std::hash()(c.strval()); + else + return std::hash()((uintptr_t) c.get()); + } + }; +}// namespace std + #endif//PSIL_HANDLE_H diff --git a/src/vm/include/MemoryContext.h b/src/vm/include/MemoryContext.h index e2aea58..662f4f6 100644 --- a/src/vm/include/MemoryContext.h +++ b/src/vm/include/MemoryContext.h @@ -37,7 +37,6 @@ public: return alloc_cell(std::forward(args)...); } - void request_gc_and_wait() { std::unique_lock l(_gc_done_m); _gc_done = false; @@ -51,7 +50,7 @@ public: _gc_request_cv.notify_all(); } - size_t cell_count() { return _cells_num; } + size_t cell_count() const { return _cells_num; } template R run_dirty(const std::function)> &f) { diff --git a/src/vm/include/Parser.h b/src/vm/include/Parser.h index 7fb14d4..5dfed4e 100644 --- a/src/vm/include/Parser.h +++ b/src/vm/include/Parser.h @@ -18,6 +18,8 @@ struct Cell; class Parser { public: + static Handle parse_str(std::string_view input); + void loadStr(std::string_view input); Handle parseExpr(); diff --git a/src/vm/include/VM.h b/src/vm/include/VM.h index cbb4edb..b9facc9 100644 --- a/src/vm/include/VM.h +++ b/src/vm/include/VM.h @@ -31,7 +31,7 @@ public: private: Handle _globals_names = Handle::cons(Handle::cons(nullptr, nullptr), nullptr); Handle _globals_vals = Handle::cons(nullptr, nullptr); - std::vector> _globals_names_map; + std::unordered_map _globals_names_map; size_t _cur_global = 0; size_t _cur_call_level = 0; Handle _s = Handle::cons(nullptr, nullptr); diff --git a/src/vm/src/Handle.cpp b/src/vm/src/Handle.cpp index f31d346..acbf280 100644 --- a/src/vm/src/Handle.cpp +++ b/src/vm/src/Handle.cpp @@ -68,15 +68,15 @@ Handle Handle::makeNumCell(int64_t val) { return MemoryContext::get().create_cel Handle Handle::makeStrCell(std::string val) { return MemoryContext::get().create_cell(std::move(val)); } void Handle::setcar(const Handle &car) { - MemoryContext::get().run_dirty([&](std::function dirty) -> void { - dirty(dynamic_cast(*_target)._car); + MemoryContext::get().run_dirty([&](std::function lost) -> void { + lost(dynamic_cast(*_target)._car); dynamic_cast(*_target)._car = car.get(); }); } void Handle::setcdr(const Handle &cdr) { - MemoryContext::get().run_dirty([&](std::function dirty) -> void { - dirty(dynamic_cast(*_target)._cdr); + MemoryContext::get().run_dirty([&](std::function lost) -> void { + lost(dynamic_cast(*_target)._cdr); dynamic_cast(*_target)._cdr = cdr.get(); }); } diff --git a/src/vm/src/Parser.cpp b/src/vm/src/Parser.cpp index 66cf93e..9d15c3e 100644 --- a/src/vm/src/Parser.cpp +++ b/src/vm/src/Parser.cpp @@ -10,6 +10,11 @@ #include "MemoryContext.h" #include "VM.h" +Handle Parser::parse_str(std::string_view input) { + Parser parser; + parser.loadStr(input); + return parser.parseExpr(); +} void Parser::loadStr(std::string_view input) { _tokenizer.load(input); } @@ -52,6 +57,7 @@ Handle Parser::parseExpr() { return Handle::cons(nullptr, nullptr); } + std::string Parser::Tokenizer::getNext() { std::string ret = std::move(_tokens.front()); _tokens.pop(); diff --git a/src/vm/src/VM.cpp b/src/vm/src/VM.cpp index 67839ec..3dd2f3b 100644 --- a/src/vm/src/VM.cpp +++ b/src/vm/src/VM.cpp @@ -90,9 +90,7 @@ void VM::step() { 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; - } + if (_globals_names_map.find(closureH) != _globals_names_map.end()) name = _globals_names_map.at(closureH); _d.push(Handle(*name)); } @@ -226,7 +224,7 @@ void VM::step() { 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()); + _globals_names_map.emplace(newclosure, curName.car().strval()); _cur_global++; _globals_vals.append(newclosure); @@ -242,9 +240,7 @@ void VM::step() { } else if (poppedCmd == READ) { std::string read; std::getline(_instream, read); - Parser parser; - parser.loadStr(read); - _s.push(parser.parseExpr()); + _s.push(Parser::parse_str(read)); } else { assert(false); }