Add 'xo-reader/' from commit 'c46c0f1cc4'

git-subtree-dir: xo-reader
git-subtree-mainline: dacdeb2cd7
git-subtree-split: c46c0f1cc4
This commit is contained in:
Roland Conybeare 2025-05-11 01:40:20 -05:00
commit 0ae98c211d
48 changed files with 5184 additions and 0 deletions

View file

@ -0,0 +1,98 @@
/* @file reader.cpp */
#include "reader.hpp"
namespace xo {
namespace scm {
void
reader::begin_translation_unit() {
parser_.begin_translation_unit();
}
reader_result
reader::end_translation_unit() {
return this->read_expr(span_type(nullptr, nullptr), true /*eof*/);
}
reader_result
reader::read_expr(const span_type & input_arg, bool eof)
{
constexpr bool c_debug_flag = true;
scope log(XO_DEBUG(c_debug_flag));
span_type input = input_arg;
/* input text-span consumed by this call.
* Always comprises some number (possibly 0)
* of complete tokens, along with any leading
* whitespace
*/
span_type expr_span = input.prefix(0ul);
while (!input.empty()) {
/* read one token from input */
auto sr = this->tokenizer_.scan2(input, eof);
const auto & tk = sr.first;
const span_type & used_span = sr.second;
log && log(xtag("used_span", used_span));
log && log(xtag("input.pre", input));
input = input.after_prefix(used_span);
log && log(xtag("expr_span.pre", expr_span));
expr_span += used_span;
if (tk.is_valid()) {
/* forward just-read token to parser */
auto expr = this->parser_.include_token(tk);
if (expr) {
log && log(xtag("outcome", "victory!"),
xtag("expr", expr));
/* token completes an expression -> victory */
return reader_result(expr, expr_span);
} else {
/* token did not complete an expression
* (e.g. token for '[')
*
* input span may contain more tokens -> iterate
*/
}
} else {
assert(input.empty());
/* no more tokens in input */
break;
}
}
/* control here: either
* 1. input.empty (perhaps ate some whitespace, ok)
* 2. missing or incomplete token (ok unless eof)
*/
if (eof) {
if (parser_.has_incomplete_expr()) {
throw std::runtime_error
("reader::read_expr"
": eof reached with incomplete expression");
}
if (tokenizer_.has_prefix()) {
throw std::runtime_error
("reader::read_expr"
": unintelligible input recognized at eof");
}
}
log && log(xtag("outcome", "noop"));
return reader_result(nullptr, expr_span);
}
} /*namespace scm*/
} /*namespace xo*/
/* end reader.cpp */