Add 'xo-reader/' from commit 'c46c0f1cc4'
git-subtree-dir: xo-reader git-subtree-mainline:dacdeb2cd7git-subtree-split:c46c0f1cc4
This commit is contained in:
commit
0ae98c211d
48 changed files with 5184 additions and 0 deletions
98
xo-reader/src/reader/reader.cpp
Normal file
98
xo-reader/src/reader/reader.cpp
Normal 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 */
|
||||
Loading…
Add table
Add a link
Reference in a new issue