diff --git a/src/vm/include/Handle.h b/src/vm/include/Handle.h index 464a0fe..7dd2d57 100644 --- a/src/vm/include/Handle.h +++ b/src/vm/include/Handle.h @@ -44,23 +44,33 @@ public: const Handle car() const { if (!_target) return Handle(nullptr); + if (_target->_type != CellType::CONS) throw std::invalid_argument("Expected cons cell, got something else"); return dynamic_cast(*_target)._car.load(); } const Handle cdr() const { if (!_target) return Handle(nullptr); + if (_target->_type != CellType::CONS) throw std::invalid_argument("Expected cons cell, got something else"); return dynamic_cast(*_target)._cdr.load(); } Handle car() { if (!_target) return Handle(nullptr); + if (_target->_type != CellType::CONS) throw std::invalid_argument("Expected cons cell, got something else"); return dynamic_cast(*_target)._car.load(); } Handle cdr() { if (!_target) return Handle(nullptr); + if (_target->_type != CellType::CONS) throw std::invalid_argument("Expected cons cell, got something else"); return dynamic_cast(*_target)._cdr.load(); } - CellValType val() const { return dynamic_cast(*_target)._val; } - std::string_view strval() const { return dynamic_cast(*_target)._val; } + CellValType val() const { + if (_target->_type != CellType::NUMATOM) throw std::invalid_argument("Expected number cell, got something else"); + return dynamic_cast(*_target)._val; + } + std::string_view strval() const { + if (_target->_type != CellType::STRATOM) throw std::invalid_argument("Expected string cell, got something else"); + return dynamic_cast(*_target)._val; + } CellType type() const { if (!_target) return CellType::CONS; diff --git a/src/vm/src/Handle.cpp b/src/vm/src/Handle.cpp index acbf280..7abe617 100644 --- a/src/vm/src/Handle.cpp +++ b/src/vm/src/Handle.cpp @@ -68,6 +68,7 @@ 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) { + if (_target->_type != CellType::CONS) throw std::invalid_argument("Expected cons cell, got something else"); MemoryContext::get().run_dirty([&](std::function lost) -> void { lost(dynamic_cast(*_target)._car); dynamic_cast(*_target)._car = car.get(); @@ -75,6 +76,7 @@ void Handle::setcar(const Handle &car) { } void Handle::setcdr(const Handle &cdr) { + if (_target->_type != CellType::CONS) throw std::invalid_argument("Expected cons cell, got something else"); 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 9d15c3e..9b57987 100644 --- a/src/vm/src/Parser.cpp +++ b/src/vm/src/Parser.cpp @@ -64,7 +64,10 @@ std::string Parser::Tokenizer::getNext() { return ret; } -std::string_view Parser::Tokenizer::peek() const { return _tokens.front(); } +std::string_view Parser::Tokenizer::peek() const { + if (_tokens.empty()) throw std::invalid_argument("Unexpected end of input (or maybe missing \")\"?"); + return _tokens.front(); +} void Parser::Tokenizer::load(std::string_view input) { std::string_view::size_type curpos = input.find_first_not_of(std::string{' ', '\n', '\r'}); diff --git a/src/vm/src/VM.cpp b/src/vm/src/VM.cpp index 3dd2f3b..2846821 100644 --- a/src/vm/src/VM.cpp +++ b/src/vm/src/VM.cpp @@ -242,7 +242,7 @@ void VM::step() { std::getline(_instream, read); _s.push(Parser::parse_str(read)); } else { - assert(false); + throw std::invalid_argument("Unexpected end of program"); }