valeri/src/reader.cpp

86 lines
2 KiB
C++
Raw Normal View History

2024-07-27 15:25:44 +00:00
#include "reader.hpp"
#include "common.hpp"
static bool is_digit(char32_t c) { return c >= '0' && c <= '9'; }
static bool is_alpha(char32_t c) {
return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
}
static bool is_hex_digit(char32_t c) {
return is_digit(c) || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F');
}
static bool is_symbol_char(char32_t c) {
static char valid_char[] = {'!', '$', '%', '&', '*', '+', '-', '.', '/',
':', '<', '=', '>', '?', '@', '^', '_', '~'};
if (is_digit(c)) return true;
if (is_alpha(c)) return true;
for (size_t i = 0; i < sizeof(valid_char); ++i) {
if (char32_t(valid_char[i]) == c) return true;
}
return false;
}
static bool is_whitespace(char32_t c) {
return c == ' ' || c == '\t' || c == '\v' || c == '\f';
}
static bool is_brace(char32_t c) {
return c == '[' || c == ']' || c == '(' || c == ')' || c == '{' || c == '}';
}
static bool is_newline(char32_t c) { return c == '\r' || c == '\n'; }
static bool is_separator(char32_t c) {
return is_whitespace(c) || is_brace(c) || is_newline(c) || c == ';';
}
#define EOS 0
Result<Value> Reader::read_one() {
forward_whitespace();
auto saved_position = position_;
if (is_numeric_start()) {
auto res = read_number();
if (res.has_value()) return res;
} else if (match("true") || match("false")) {
auto res = read_bool();
if (res.has_value()) return res;
} else if (is_string_start()) {
return read_string();
} else if (match('(')) {
return read_list();
} else if (match('[')) {
return read_array();
} else if (match('{')) {
return read_dict();
}
position_ = saved_position;
if (is_symbol_start()) {
return read_symbol();
}
return ErrorCode::ReadError;
}
Result<Value> Reader::read_multiple() {
Value res = TRY(Nil::create(_arena));
while (1) {
forward_whitespace();
if (is_eof()) {
return reverse(_arena, res);
}
auto val = TRY(read_one());
res = Value(TRY(Pair::create(_arena, val, res)));
}
return ErrorCode::ReadError;
}