mirror of
https://github.com/usatiuk/psil.git
synced 2025-10-28 18:57:48 +01:00
some prettying
This commit is contained in:
33
src/main.cpp
33
src/main.cpp
@@ -21,7 +21,6 @@ void parse_options(int argc, char *argv[]) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (arg.length() < 2 || arg.substr(0, 2) != "--") { throw std::invalid_argument("Can't parse argument " + arg); }
|
if (arg.length() < 2 || arg.substr(0, 2) != "--") { throw std::invalid_argument("Can't parse argument " + arg); }
|
||||||
std::string rest = arg.substr(2);
|
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.empty()) throw std::invalid_argument("Can't parse argument " + arg);
|
||||||
|
|
||||||
if (split.at(0) == "log") {
|
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 {
|
try {
|
||||||
Logger::set_level(split.at(1), std::stoi(split.at(2)));
|
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) {
|
} else if (split.size() == 1) {
|
||||||
std::string str = split.at(0);
|
std::string str = split.at(0);
|
||||||
if (str.back() != '+' && str.back() != '-') {
|
if (str.back() != '+' && str.back() != '-') {
|
||||||
@@ -48,7 +47,7 @@ void parse_options(int argc, char *argv[]) {
|
|||||||
} else if (split.size() == 2) {
|
} else if (split.size() == 2) {
|
||||||
try {
|
try {
|
||||||
Options::set<size_t>(split.at(0), std::stoi(split.at(1)));
|
Options::set<size_t>(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 {
|
} else {
|
||||||
throw std::invalid_argument("Can't parse argument " + arg);
|
throw std::invalid_argument("Can't parse argument " + arg);
|
||||||
}
|
}
|
||||||
@@ -64,33 +63,24 @@ int main(int argc, char *argv[]) {
|
|||||||
|
|
||||||
parse_options(argc, argv);
|
parse_options(argc, argv);
|
||||||
|
|
||||||
Handle repl;
|
Handle repl = Parser::parse_str("(READ EVAL PRINT STOP)");
|
||||||
{
|
Handle epl = Parser::parse_str("(EVAL PRINT STOP)");
|
||||||
Parser parser;
|
|
||||||
parser.loadStr("(READ EVAL PRINT STOP)");
|
|
||||||
repl = parser.parseExpr();
|
|
||||||
}
|
|
||||||
Handle epl;
|
|
||||||
{
|
|
||||||
Parser parser;
|
|
||||||
parser.loadStr("(EVAL PRINT STOP)");
|
|
||||||
epl = parser.parseExpr();
|
|
||||||
}
|
|
||||||
|
|
||||||
VM vm;
|
VM vm;
|
||||||
|
|
||||||
if (infile) {
|
if (infile) {
|
||||||
Handle parsed;
|
Handle parsed;
|
||||||
|
|
||||||
std::stringstream buffer;
|
std::stringstream buffer;
|
||||||
buffer << "(";
|
buffer << "(";
|
||||||
{
|
{
|
||||||
std::ifstream t(*infile);
|
std::ifstream t(*infile);
|
||||||
|
if (!t.is_open()) throw std::invalid_argument("Requested file could not be opened");
|
||||||
buffer << t.rdbuf();
|
buffer << t.rdbuf();
|
||||||
}
|
}
|
||||||
buffer << ")";
|
buffer << ")";
|
||||||
Parser parser;
|
|
||||||
parser.loadStr(buffer.str());
|
parsed = Parser::parse_str(buffer.str());
|
||||||
parsed = parser.parseExpr();
|
|
||||||
|
|
||||||
Handle cur_expr = parsed;
|
Handle cur_expr = parsed;
|
||||||
while (!cur_expr.null()) {
|
while (!cur_expr.null()) {
|
||||||
@@ -100,13 +90,14 @@ int main(int argc, char *argv[]) {
|
|||||||
cur_expr = cur_expr.cdr();
|
cur_expr = cur_expr.cdr();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Options::get<bool>("repl"))
|
if (Options::get<bool>("repl"))
|
||||||
while (true) {
|
while (true) {
|
||||||
std::cout << std::endl << "> ";
|
std::cout << "> ";
|
||||||
vm.loadControl(repl);
|
vm.loadControl(repl);
|
||||||
vm.run();
|
vm.run();
|
||||||
std::cout << std::endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (const std::exception &e) {
|
} catch (const std::exception &e) {
|
||||||
std::cerr << "\nError: " << e.what() << std::endl;
|
std::cerr << "\nError: " << e.what() << std::endl;
|
||||||
return -1;
|
return -1;
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ struct Cell {
|
|||||||
CellType _type;
|
CellType _type;
|
||||||
std::atomic<bool> _live = false;
|
std::atomic<bool> _live = false;
|
||||||
|
|
||||||
virtual void print(std::ostream &out) = 0;
|
virtual void print(std::ostream &out) const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct NumAtomCell : public Cell {
|
struct NumAtomCell : public Cell {
|
||||||
@@ -34,7 +34,7 @@ struct NumAtomCell : public Cell {
|
|||||||
|
|
||||||
CellValType _val;
|
CellValType _val;
|
||||||
|
|
||||||
void print(std::ostream &out) override { out << _val; }
|
void print(std::ostream &out) const override { out << _val; }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct StrAtomCell : public Cell {
|
struct StrAtomCell : public Cell {
|
||||||
@@ -43,7 +43,7 @@ struct StrAtomCell : public Cell {
|
|||||||
|
|
||||||
std::string _val;
|
std::string _val;
|
||||||
|
|
||||||
void print(std::ostream &out) override { out << _val; }
|
void print(std::ostream &out) const override { out << _val; }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ConsCell : public Cell {
|
struct ConsCell : public Cell {
|
||||||
@@ -54,7 +54,7 @@ struct ConsCell : public Cell {
|
|||||||
std::atomic<Cell *> _car = nullptr;
|
std::atomic<Cell *> _car = nullptr;
|
||||||
std::atomic<Cell *> _cdr = nullptr;
|
std::atomic<Cell *> _cdr = nullptr;
|
||||||
|
|
||||||
void print_cons(std::ostream &out, std::set<Cell *> &seen) {
|
void print_cons(std::ostream &out, std::set<const Cell *> &seen) const {
|
||||||
std::stringstream res;
|
std::stringstream res;
|
||||||
if (_car) {
|
if (_car) {
|
||||||
if (_car.load()->_type == CellType::CONS) {
|
if (_car.load()->_type == CellType::CONS) {
|
||||||
@@ -89,9 +89,9 @@ struct ConsCell : public Cell {
|
|||||||
out << res.str();
|
out << res.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
void print(std::ostream &out) override {
|
void print(std::ostream &out) const override {
|
||||||
std::stringstream res;
|
std::stringstream res;
|
||||||
std::set<Cell *> seen{this};
|
std::set<const Cell *> seen{this};
|
||||||
if (_car) {
|
if (_car) {
|
||||||
if (_car.load()->_type == CellType::CONS) {
|
if (_car.load()->_type == CellType::CONS) {
|
||||||
res << "(";
|
res << "(";
|
||||||
|
|||||||
@@ -8,10 +8,15 @@
|
|||||||
#include "Cell.h"
|
#include "Cell.h"
|
||||||
|
|
||||||
class MemoryContext;
|
class MemoryContext;
|
||||||
|
class Handle;
|
||||||
|
|
||||||
|
template<>
|
||||||
|
class std::hash<Handle>;
|
||||||
|
|
||||||
class Handle {
|
class Handle {
|
||||||
public:
|
public:
|
||||||
friend MemoryContext;
|
friend MemoryContext;
|
||||||
|
friend class std::hash<Handle>;
|
||||||
|
|
||||||
Handle(Cell *target = nullptr);
|
Handle(Cell *target = nullptr);
|
||||||
Handle(int64_t val);
|
Handle(int64_t val);
|
||||||
@@ -37,16 +42,25 @@ public:
|
|||||||
|
|
||||||
static Handle cons(const Handle &car, const Handle &cdr);
|
static Handle cons(const Handle &car, const Handle &cdr);
|
||||||
|
|
||||||
Handle car() const {
|
const Handle car() const {
|
||||||
if (!_target) return Handle(nullptr);
|
if (!_target) return Handle(nullptr);
|
||||||
return dynamic_cast<ConsCell &>(*_target)._car.load();
|
return dynamic_cast<ConsCell &>(*_target)._car.load();
|
||||||
}
|
}
|
||||||
Handle cdr() const {
|
const Handle cdr() const {
|
||||||
if (!_target) return Handle(nullptr);
|
if (!_target) return Handle(nullptr);
|
||||||
return dynamic_cast<ConsCell &>(*_target)._cdr.load();
|
return dynamic_cast<ConsCell &>(*_target)._cdr.load();
|
||||||
}
|
}
|
||||||
CellValType val() { return dynamic_cast<NumAtomCell &>(*_target)._val; }
|
Handle car() {
|
||||||
std::string_view strval() { return dynamic_cast<StrAtomCell &>(*_target)._val; }
|
if (!_target) return Handle(nullptr);
|
||||||
|
return dynamic_cast<ConsCell &>(*_target)._car.load();
|
||||||
|
}
|
||||||
|
Handle cdr() {
|
||||||
|
if (!_target) return Handle(nullptr);
|
||||||
|
return dynamic_cast<ConsCell &>(*_target)._cdr.load();
|
||||||
|
}
|
||||||
|
|
||||||
|
CellValType val() const { return dynamic_cast<NumAtomCell &>(*_target)._val; }
|
||||||
|
std::string_view strval() const { return dynamic_cast<StrAtomCell &>(*_target)._val; }
|
||||||
|
|
||||||
CellType type() const {
|
CellType type() const {
|
||||||
if (!_target) return CellType::CONS;
|
if (!_target) return CellType::CONS;
|
||||||
@@ -84,4 +98,18 @@ private:
|
|||||||
Cell *_target = nullptr;
|
Cell *_target = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
namespace std {
|
||||||
|
template<>
|
||||||
|
class hash<Handle> {
|
||||||
|
public:
|
||||||
|
size_t operator()(const Handle &c) const {
|
||||||
|
if (c.type() == CellType::NUMATOM) return std::hash<CellValType>()(c.val());
|
||||||
|
else if (c.type() == CellType::STRATOM)
|
||||||
|
return std::hash<std::string_view>()(c.strval());
|
||||||
|
else
|
||||||
|
return std::hash<uintptr_t>()((uintptr_t) c.get());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}// namespace std
|
||||||
|
|
||||||
#endif//PSIL_HANDLE_H
|
#endif//PSIL_HANDLE_H
|
||||||
|
|||||||
@@ -37,7 +37,6 @@ public:
|
|||||||
return alloc_cell<CT>(std::forward<Args>(args)...);
|
return alloc_cell<CT>(std::forward<Args>(args)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void request_gc_and_wait() {
|
void request_gc_and_wait() {
|
||||||
std::unique_lock l(_gc_done_m);
|
std::unique_lock l(_gc_done_m);
|
||||||
_gc_done = false;
|
_gc_done = false;
|
||||||
@@ -51,7 +50,7 @@ public:
|
|||||||
_gc_request_cv.notify_all();
|
_gc_request_cv.notify_all();
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t cell_count() { return _cells_num; }
|
size_t cell_count() const { return _cells_num; }
|
||||||
|
|
||||||
template<typename R>
|
template<typename R>
|
||||||
R run_dirty(const std::function<R(std::function<void(Cell *)>)> &f) {
|
R run_dirty(const std::function<R(std::function<void(Cell *)>)> &f) {
|
||||||
|
|||||||
@@ -18,6 +18,8 @@ struct Cell;
|
|||||||
|
|
||||||
class Parser {
|
class Parser {
|
||||||
public:
|
public:
|
||||||
|
static Handle parse_str(std::string_view input);
|
||||||
|
|
||||||
void loadStr(std::string_view input);
|
void loadStr(std::string_view input);
|
||||||
Handle parseExpr();
|
Handle parseExpr();
|
||||||
|
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ 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;
|
std::unordered_map<Handle, std::string> _globals_names_map;
|
||||||
size_t _cur_global = 0;
|
size_t _cur_global = 0;
|
||||||
size_t _cur_call_level = 0;
|
size_t _cur_call_level = 0;
|
||||||
Handle _s = Handle::cons(nullptr, nullptr);
|
Handle _s = Handle::cons(nullptr, nullptr);
|
||||||
|
|||||||
@@ -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<StrAtomCell>(std::move(val)); }
|
Handle Handle::makeStrCell(std::string val) { return MemoryContext::get().create_cell<StrAtomCell>(std::move(val)); }
|
||||||
|
|
||||||
void Handle::setcar(const Handle &car) {
|
void Handle::setcar(const Handle &car) {
|
||||||
MemoryContext::get().run_dirty<void>([&](std::function<void(Cell *)> dirty) -> void {
|
MemoryContext::get().run_dirty<void>([&](std::function<void(Cell *)> lost) -> void {
|
||||||
dirty(dynamic_cast<ConsCell &>(*_target)._car);
|
lost(dynamic_cast<ConsCell &>(*_target)._car);
|
||||||
dynamic_cast<ConsCell &>(*_target)._car = car.get();
|
dynamic_cast<ConsCell &>(*_target)._car = car.get();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void Handle::setcdr(const Handle &cdr) {
|
void Handle::setcdr(const Handle &cdr) {
|
||||||
MemoryContext::get().run_dirty<void>([&](std::function<void(Cell *)> dirty) -> void {
|
MemoryContext::get().run_dirty<void>([&](std::function<void(Cell *)> lost) -> void {
|
||||||
dirty(dynamic_cast<ConsCell &>(*_target)._cdr);
|
lost(dynamic_cast<ConsCell &>(*_target)._cdr);
|
||||||
dynamic_cast<ConsCell &>(*_target)._cdr = cdr.get();
|
dynamic_cast<ConsCell &>(*_target)._cdr = cdr.get();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,11 @@
|
|||||||
#include "MemoryContext.h"
|
#include "MemoryContext.h"
|
||||||
#include "VM.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); }
|
void Parser::loadStr(std::string_view input) { _tokenizer.load(input); }
|
||||||
|
|
||||||
@@ -52,6 +57,7 @@ Handle Parser::parseExpr() {
|
|||||||
|
|
||||||
return Handle::cons(nullptr, nullptr);
|
return Handle::cons(nullptr, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Parser::Tokenizer::getNext() {
|
std::string Parser::Tokenizer::getNext() {
|
||||||
std::string ret = std::move(_tokens.front());
|
std::string ret = std::move(_tokens.front());
|
||||||
_tokens.pop();
|
_tokens.pop();
|
||||||
|
|||||||
@@ -90,9 +90,7 @@ void VM::step() {
|
|||||||
std::optional<std::string> name;
|
std::optional<std::string> name;
|
||||||
if (Logger::en_level("VM", Logger::DEBUG)) {
|
if (Logger::en_level("VM", Logger::DEBUG)) {
|
||||||
name = "unknown";
|
name = "unknown";
|
||||||
for (const auto &p: _globals_names_map) {
|
if (_globals_names_map.find(closureH) != _globals_names_map.end()) name = _globals_names_map.at(closureH);
|
||||||
if (p.first == closureH) name = p.second;
|
|
||||||
}
|
|
||||||
_d.push(Handle(*name));
|
_d.push(Handle(*name));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -226,7 +224,7 @@ void VM::step() {
|
|||||||
|
|
||||||
Handle curName = _globals_names.car();
|
Handle curName = _globals_names.car();
|
||||||
for (int i = 0; i < _cur_global; i++) { curName = curName.cdr(); }
|
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++;
|
_cur_global++;
|
||||||
|
|
||||||
_globals_vals.append(newclosure);
|
_globals_vals.append(newclosure);
|
||||||
@@ -242,9 +240,7 @@ void VM::step() {
|
|||||||
} else if (poppedCmd == READ) {
|
} else if (poppedCmd == READ) {
|
||||||
std::string read;
|
std::string read;
|
||||||
std::getline(_instream, read);
|
std::getline(_instream, read);
|
||||||
Parser parser;
|
_s.push(Parser::parse_str(read));
|
||||||
parser.loadStr(read);
|
|
||||||
_s.push(parser.parseExpr());
|
|
||||||
} else {
|
} else {
|
||||||
assert(false);
|
assert(false);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user