stop using trie tree-based reader table
This commit is contained in:
parent
1ff8672a11
commit
8c67ad863b
|
@ -510,21 +510,6 @@ gc_mark(pic_state *pic, pic_value v)
|
||||||
gc_mark_object(pic, obj);
|
gc_mark_object(pic, obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
gc_mark_trie(pic_state *pic, struct pic_trie *trie)
|
|
||||||
{
|
|
||||||
size_t i;
|
|
||||||
|
|
||||||
for (i = 0; i < sizeof trie->table / sizeof(struct pic_trie *); ++i) {
|
|
||||||
if (trie->table[i] != NULL) {
|
|
||||||
gc_mark_trie(pic, trie->table[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (trie->proc != NULL) {
|
|
||||||
gc_mark_object(pic, (struct pic_object *)trie->proc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#define M(x) gc_mark_object(pic, (struct pic_object *)pic->x)
|
#define M(x) gc_mark_object(pic, (struct pic_object *)pic->x)
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -606,9 +591,6 @@ gc_mark_phase(pic_state *pic)
|
||||||
/* features */
|
/* features */
|
||||||
gc_mark(pic, pic->features);
|
gc_mark(pic, pic->features);
|
||||||
|
|
||||||
/* readers */
|
|
||||||
gc_mark_trie(pic, pic->reader->trie);
|
|
||||||
|
|
||||||
/* library table */
|
/* library table */
|
||||||
gc_mark(pic, pic->libs);
|
gc_mark(pic, pic->libs);
|
||||||
|
|
||||||
|
|
|
@ -9,29 +9,20 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
typedef pic_value (*pic_reader_t)(pic_state *, struct pic_port *port, int c);
|
||||||
|
|
||||||
|
struct pic_reader {
|
||||||
enum pic_typecase {
|
enum pic_typecase {
|
||||||
PIC_CASE_DEFAULT,
|
PIC_CASE_DEFAULT,
|
||||||
PIC_CASE_FOLD,
|
PIC_CASE_FOLD,
|
||||||
};
|
} typecase;
|
||||||
|
|
||||||
struct pic_trie {
|
|
||||||
struct pic_trie *table[256];
|
|
||||||
struct pic_proc *proc;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct pic_reader {
|
|
||||||
short typecase;
|
|
||||||
xhash labels;
|
xhash labels;
|
||||||
struct pic_trie *trie;
|
pic_reader_t table[256];
|
||||||
|
pic_reader_t dispatch[256];
|
||||||
};
|
};
|
||||||
|
|
||||||
void pic_init_reader(pic_state *);
|
void pic_init_reader(pic_state *);
|
||||||
|
|
||||||
void pic_define_reader(pic_state *, const char *, pic_func_t);
|
|
||||||
|
|
||||||
struct pic_trie *pic_make_trie(pic_state *);
|
|
||||||
void pic_trie_delete(pic_state *, struct pic_trie *);
|
|
||||||
|
|
||||||
#if defined(__cplusplus)
|
#if defined(__cplusplus)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -80,12 +80,9 @@ strcaseeq(const char *s1, const char *s2)
|
||||||
}
|
}
|
||||||
|
|
||||||
static pic_value
|
static pic_value
|
||||||
read_comment(pic_state *pic, struct pic_port *port, const char *str)
|
read_comment(pic_state *pic, struct pic_port *port, int c)
|
||||||
{
|
{
|
||||||
int c;
|
|
||||||
|
|
||||||
PIC_UNUSED(pic);
|
PIC_UNUSED(pic);
|
||||||
PIC_UNUSED(str);
|
|
||||||
|
|
||||||
do {
|
do {
|
||||||
c = next(port);
|
c = next(port);
|
||||||
|
@ -95,13 +92,13 @@ read_comment(pic_state *pic, struct pic_port *port, const char *str)
|
||||||
}
|
}
|
||||||
|
|
||||||
static pic_value
|
static pic_value
|
||||||
read_block_comment(pic_state *pic, struct pic_port *port, const char *str)
|
read_block_comment(pic_state *pic, struct pic_port *port, int c)
|
||||||
{
|
{
|
||||||
int x, y;
|
int x, y;
|
||||||
int i = 1;
|
int i = 1;
|
||||||
|
|
||||||
PIC_UNUSED(pic);
|
PIC_UNUSED(pic);
|
||||||
PIC_UNUSED(str);
|
PIC_UNUSED(c);
|
||||||
|
|
||||||
y = next(port);
|
y = next(port);
|
||||||
|
|
||||||
|
@ -120,9 +117,9 @@ read_block_comment(pic_state *pic, struct pic_port *port, const char *str)
|
||||||
}
|
}
|
||||||
|
|
||||||
static pic_value
|
static pic_value
|
||||||
read_datum_comment(pic_state *pic, struct pic_port *port, const char *str)
|
read_datum_comment(pic_state *pic, struct pic_port *port, int c)
|
||||||
{
|
{
|
||||||
PIC_UNUSED(str);
|
PIC_UNUSED(c);
|
||||||
|
|
||||||
read(pic, port, next(port));
|
read(pic, port, next(port));
|
||||||
|
|
||||||
|
@ -130,7 +127,7 @@ read_datum_comment(pic_state *pic, struct pic_port *port, const char *str)
|
||||||
}
|
}
|
||||||
|
|
||||||
static pic_value
|
static pic_value
|
||||||
read_directive(pic_state *pic, struct pic_port *port, const char *str)
|
read_directive(pic_state *pic, struct pic_port *port, int c)
|
||||||
{
|
{
|
||||||
switch (peek(port)) {
|
switch (peek(port)) {
|
||||||
case 'n':
|
case 'n':
|
||||||
|
@ -147,15 +144,15 @@ read_directive(pic_state *pic, struct pic_port *port, const char *str)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return read_comment(pic, port, str);
|
return read_comment(pic, port, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
static pic_value
|
static pic_value
|
||||||
read_eval(pic_state *pic, struct pic_port *port, const char *str)
|
read_eval(pic_state *pic, struct pic_port *port, int c)
|
||||||
{
|
{
|
||||||
pic_value form;
|
pic_value form;
|
||||||
|
|
||||||
PIC_UNUSED(str);
|
PIC_UNUSED(c);
|
||||||
|
|
||||||
form = read(pic, port, next(port));
|
form = read(pic, port, next(port));
|
||||||
|
|
||||||
|
@ -163,55 +160,46 @@ read_eval(pic_state *pic, struct pic_port *port, const char *str)
|
||||||
}
|
}
|
||||||
|
|
||||||
static pic_value
|
static pic_value
|
||||||
read_quote(pic_state *pic, struct pic_port *port, const char *str)
|
read_quote(pic_state *pic, struct pic_port *port, int c)
|
||||||
{
|
{
|
||||||
PIC_UNUSED(str);
|
PIC_UNUSED(c);
|
||||||
|
|
||||||
return pic_list2(pic, pic_obj_value(pic->sQUOTE), read(pic, port, next(port)));
|
return pic_list2(pic, pic_obj_value(pic->sQUOTE), read(pic, port, next(port)));
|
||||||
}
|
}
|
||||||
|
|
||||||
static pic_value
|
static pic_value
|
||||||
read_quasiquote(pic_state *pic, struct pic_port *port, const char *str)
|
read_quasiquote(pic_state *pic, struct pic_port *port, int c)
|
||||||
{
|
{
|
||||||
PIC_UNUSED(str);
|
PIC_UNUSED(c);
|
||||||
|
|
||||||
return pic_list2(pic, pic_obj_value(pic->sQUASIQUOTE), read(pic, port, next(port)));
|
return pic_list2(pic, pic_obj_value(pic->sQUASIQUOTE), read(pic, port, next(port)));
|
||||||
}
|
}
|
||||||
|
|
||||||
static pic_value
|
static pic_value
|
||||||
read_unquote(pic_state *pic, struct pic_port *port, const char *str)
|
read_unquote(pic_state *pic, struct pic_port *port, int c)
|
||||||
{
|
{
|
||||||
PIC_UNUSED(str);
|
pic_sym *tag = pic->sUNQUOTE;
|
||||||
|
|
||||||
return pic_list2(pic, pic_obj_value(pic->sUNQUOTE), read(pic, port, next(port)));
|
PIC_UNUSED(c);
|
||||||
|
|
||||||
|
if (peek(port) == '@') {
|
||||||
|
tag = pic->sUNQUOTE_SPLICING;
|
||||||
|
next(port);
|
||||||
|
}
|
||||||
|
return pic_list2(pic, pic_obj_value(tag), read(pic, port, next(port)));
|
||||||
}
|
}
|
||||||
|
|
||||||
static pic_value
|
static pic_value
|
||||||
read_unquote_splicing(pic_state *pic, struct pic_port *port, const char *str)
|
read_symbol(pic_state *pic, struct pic_port *port, int c)
|
||||||
{
|
{
|
||||||
PIC_UNUSED(str);
|
size_t len;
|
||||||
|
|
||||||
return pic_list2(pic, pic_obj_value(pic->sUNQUOTE_SPLICING), read(pic, port, next(port)));
|
|
||||||
}
|
|
||||||
|
|
||||||
static pic_value
|
|
||||||
read_symbol(pic_state *pic, struct pic_port *port, const char *str)
|
|
||||||
{
|
|
||||||
size_t len, i;
|
|
||||||
char *buf;
|
char *buf;
|
||||||
pic_sym *sym;
|
pic_sym *sym;
|
||||||
int c;
|
|
||||||
|
|
||||||
len = strlen(str);
|
len = 1;
|
||||||
buf = pic_calloc(pic, 1, len + 1);
|
buf = pic_alloc(pic, len + 1);
|
||||||
|
buf[0] = c;
|
||||||
for (i = 0; i < len; ++i) {
|
buf[1] = 0;
|
||||||
if (pic->reader->typecase == PIC_CASE_FOLD) {
|
|
||||||
buf[i] = (char)tolower(str[i]);
|
|
||||||
} else {
|
|
||||||
buf[i] = str[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
while (! isdelim(peek(port))) {
|
while (! isdelim(peek(port))) {
|
||||||
c = next(port);
|
c = next(port);
|
||||||
|
@ -220,10 +208,10 @@ read_symbol(pic_state *pic, struct pic_port *port, const char *str)
|
||||||
}
|
}
|
||||||
len += 1;
|
len += 1;
|
||||||
buf = pic_realloc(pic, buf, len + 1);
|
buf = pic_realloc(pic, buf, len + 1);
|
||||||
buf[len - 1] = (char)c;
|
buf[len - 1] = c;
|
||||||
|
buf[len] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
buf[len] = 0;
|
|
||||||
sym = pic_intern_cstr(pic, buf);
|
sym = pic_intern_cstr(pic, buf);
|
||||||
pic_free(pic, buf);
|
pic_free(pic, buf);
|
||||||
|
|
||||||
|
@ -295,9 +283,9 @@ read_unsigned(pic_state *pic, struct pic_port *port, int c)
|
||||||
}
|
}
|
||||||
|
|
||||||
static pic_value
|
static pic_value
|
||||||
read_number(pic_state *pic, struct pic_port *port, const char *str)
|
read_number(pic_state *pic, struct pic_port *port, int c)
|
||||||
{
|
{
|
||||||
return read_unsigned(pic, port, str[0]);
|
return read_unsigned(pic, port, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
static pic_value
|
static pic_value
|
||||||
|
@ -311,7 +299,7 @@ negate(pic_value n)
|
||||||
}
|
}
|
||||||
|
|
||||||
static pic_value
|
static pic_value
|
||||||
read_minus(pic_state *pic, struct pic_port *port, const char *str)
|
read_minus(pic_state *pic, struct pic_port *port, int c)
|
||||||
{
|
{
|
||||||
pic_value sym;
|
pic_value sym;
|
||||||
|
|
||||||
|
@ -319,7 +307,7 @@ read_minus(pic_state *pic, struct pic_port *port, const char *str)
|
||||||
return negate(read_unsigned(pic, port, next(port)));
|
return negate(read_unsigned(pic, port, next(port)));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
sym = read_symbol(pic, port, str);
|
sym = read_symbol(pic, port, c);
|
||||||
if (strcaseeq(pic_symbol_name(pic, pic_sym_ptr(sym)), "-inf.0")) {
|
if (strcaseeq(pic_symbol_name(pic, pic_sym_ptr(sym)), "-inf.0")) {
|
||||||
return pic_float_value(-INFINITY);
|
return pic_float_value(-INFINITY);
|
||||||
}
|
}
|
||||||
|
@ -331,7 +319,7 @@ read_minus(pic_state *pic, struct pic_port *port, const char *str)
|
||||||
}
|
}
|
||||||
|
|
||||||
static pic_value
|
static pic_value
|
||||||
read_plus(pic_state *pic, struct pic_port *port, const char *str)
|
read_plus(pic_state *pic, struct pic_port *port, int c)
|
||||||
{
|
{
|
||||||
pic_value sym;
|
pic_value sym;
|
||||||
|
|
||||||
|
@ -339,7 +327,7 @@ read_plus(pic_state *pic, struct pic_port *port, const char *str)
|
||||||
return read_unsigned(pic, port, next(port));
|
return read_unsigned(pic, port, next(port));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
sym = read_symbol(pic, port, str);
|
sym = read_symbol(pic, port, c);
|
||||||
if (strcaseeq(pic_symbol_name(pic, pic_sym_ptr(sym)), "+inf.0")) {
|
if (strcaseeq(pic_symbol_name(pic, pic_sym_ptr(sym)), "+inf.0")) {
|
||||||
return pic_float_value(INFINITY);
|
return pic_float_value(INFINITY);
|
||||||
}
|
}
|
||||||
|
@ -351,32 +339,40 @@ read_plus(pic_state *pic, struct pic_port *port, const char *str)
|
||||||
}
|
}
|
||||||
|
|
||||||
static pic_value
|
static pic_value
|
||||||
read_true(pic_state *pic, struct pic_port *port, const char *str)
|
read_true(pic_state *pic, struct pic_port *port, int c)
|
||||||
{
|
{
|
||||||
PIC_UNUSED(pic);
|
PIC_UNUSED(pic);
|
||||||
PIC_UNUSED(port);
|
|
||||||
PIC_UNUSED(str);
|
if ((c = peek(port)) == 'r') {
|
||||||
|
if (! expect(port, "rue")) {
|
||||||
|
read_error(pic, "unexpected character while reading #true");
|
||||||
|
}
|
||||||
|
} else if (! isdelim(c)) {
|
||||||
|
read_error(pic, "non-delimiter character given after #t");
|
||||||
|
}
|
||||||
|
|
||||||
return pic_true_value();
|
return pic_true_value();
|
||||||
}
|
}
|
||||||
|
|
||||||
static pic_value
|
static pic_value
|
||||||
read_false(pic_state *pic, struct pic_port *port, const char *str)
|
read_false(pic_state *pic, struct pic_port *port, int c)
|
||||||
{
|
{
|
||||||
PIC_UNUSED(pic);
|
PIC_UNUSED(pic);
|
||||||
PIC_UNUSED(port);
|
|
||||||
PIC_UNUSED(str);
|
if ((c = peek(port)) == 'a') {
|
||||||
|
if (! expect(port, "alse")) {
|
||||||
|
read_error(pic, "unexpected character while reading #false");
|
||||||
|
}
|
||||||
|
} else if (! isdelim(c)) {
|
||||||
|
read_error(pic, "non-delimiter character given after #f");
|
||||||
|
}
|
||||||
|
|
||||||
return pic_false_value();
|
return pic_false_value();
|
||||||
}
|
}
|
||||||
|
|
||||||
static pic_value
|
static pic_value
|
||||||
read_char(pic_state *pic, struct pic_port *port, const char *str)
|
read_char(pic_state *pic, struct pic_port *port, int c)
|
||||||
{
|
{
|
||||||
int c;
|
|
||||||
|
|
||||||
PIC_UNUSED(str);
|
|
||||||
|
|
||||||
c = next(port);
|
c = next(port);
|
||||||
|
|
||||||
if (! isdelim(peek(port))) {
|
if (! isdelim(peek(port))) {
|
||||||
|
@ -410,15 +406,12 @@ read_char(pic_state *pic, struct pic_port *port, const char *str)
|
||||||
}
|
}
|
||||||
|
|
||||||
static pic_value
|
static pic_value
|
||||||
read_string(pic_state *pic, struct pic_port *port, const char *name)
|
read_string(pic_state *pic, struct pic_port *port, int c)
|
||||||
{
|
{
|
||||||
int c;
|
|
||||||
char *buf;
|
char *buf;
|
||||||
size_t size, cnt;
|
size_t size, cnt;
|
||||||
pic_str *str;
|
pic_str *str;
|
||||||
|
|
||||||
PIC_UNUSED(name);
|
|
||||||
|
|
||||||
size = 256;
|
size = 256;
|
||||||
buf = pic_alloc(pic, size);
|
buf = pic_alloc(pic, size);
|
||||||
cnt = 0;
|
cnt = 0;
|
||||||
|
@ -448,7 +441,7 @@ read_string(pic_state *pic, struct pic_port *port, const char *name)
|
||||||
}
|
}
|
||||||
|
|
||||||
static pic_value
|
static pic_value
|
||||||
read_pipe(pic_state *pic, struct pic_port *port, const char *str)
|
read_pipe(pic_state *pic, struct pic_port *port, int c)
|
||||||
{
|
{
|
||||||
char *buf;
|
char *buf;
|
||||||
size_t size, cnt;
|
size_t size, cnt;
|
||||||
|
@ -456,9 +449,6 @@ read_pipe(pic_state *pic, struct pic_port *port, const char *str)
|
||||||
/* Currently supports only ascii chars */
|
/* Currently supports only ascii chars */
|
||||||
char HEX_BUF[3];
|
char HEX_BUF[3];
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
int c;
|
|
||||||
|
|
||||||
PIC_UNUSED(str);
|
|
||||||
|
|
||||||
size = 256;
|
size = 256;
|
||||||
buf = pic_alloc(pic, size);
|
buf = pic_alloc(pic, size);
|
||||||
|
@ -495,16 +485,14 @@ read_pipe(pic_state *pic, struct pic_port *port, const char *str)
|
||||||
}
|
}
|
||||||
|
|
||||||
static pic_value
|
static pic_value
|
||||||
read_blob(pic_state *pic, struct pic_port *port, const char *str)
|
read_blob(pic_state *pic, struct pic_port *port, int c)
|
||||||
{
|
{
|
||||||
int nbits, n, c;
|
int nbits, n;
|
||||||
size_t len, i;
|
size_t len, i;
|
||||||
char buf[256];
|
char buf[256];
|
||||||
unsigned char *dat;
|
unsigned char *dat;
|
||||||
pic_blob *blob;
|
pic_blob *blob;
|
||||||
|
|
||||||
PIC_UNUSED(str);
|
|
||||||
|
|
||||||
nbits = 0;
|
nbits = 0;
|
||||||
|
|
||||||
while (isdigit(c = next(port))) {
|
while (isdigit(c = next(port))) {
|
||||||
|
@ -544,11 +532,11 @@ read_blob(pic_state *pic, struct pic_port *port, const char *str)
|
||||||
}
|
}
|
||||||
|
|
||||||
static pic_value
|
static pic_value
|
||||||
read_pair(pic_state *pic, struct pic_port *port, const char *str)
|
read_pair(pic_state *pic, struct pic_port *port, int c)
|
||||||
{
|
{
|
||||||
const int tCLOSE = (str[0] == '(') ? ')' : ']';
|
const int tOPEN = c;
|
||||||
|
const int tCLOSE = (c == '(') ? ')' : ']';
|
||||||
pic_value car, cdr;
|
pic_value car, cdr;
|
||||||
int c;
|
|
||||||
|
|
||||||
retry:
|
retry:
|
||||||
|
|
||||||
|
@ -576,17 +564,17 @@ read_pair(pic_state *pic, struct pic_port *port, const char *str)
|
||||||
goto retry;
|
goto retry;
|
||||||
}
|
}
|
||||||
|
|
||||||
cdr = read_pair(pic, port, str);
|
cdr = read_pair(pic, port, tOPEN);
|
||||||
return pic_cons(pic, car, cdr);
|
return pic_cons(pic, car, cdr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static pic_value
|
static pic_value
|
||||||
read_vector(pic_state *pic, struct pic_port *port, const char *str)
|
read_vector(pic_state *pic, struct pic_port *port, int c)
|
||||||
{
|
{
|
||||||
pic_value list;
|
pic_value list;
|
||||||
|
|
||||||
list = read(pic, port, str[1]);
|
list = read(pic, port, c);
|
||||||
|
|
||||||
return pic_obj_value(pic_make_vec_from_list(pic, list));
|
return pic_obj_value(pic_make_vec_from_list(pic, list));
|
||||||
}
|
}
|
||||||
|
@ -664,14 +652,13 @@ read_label_ref(pic_state *pic, struct pic_port *port, int i)
|
||||||
}
|
}
|
||||||
|
|
||||||
static pic_value
|
static pic_value
|
||||||
read_label(pic_state *pic, struct pic_port *port, const char *str)
|
read_label(pic_state *pic, struct pic_port *port, int c)
|
||||||
{
|
{
|
||||||
int i, c;
|
int i;
|
||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
c = str[1]; /* initial index letter */
|
|
||||||
do {
|
do {
|
||||||
i = i * 10 + c;
|
i = i * 10 + c - '0';
|
||||||
} while (isdigit(c = next(port)));
|
} while (isdigit(c = next(port)));
|
||||||
|
|
||||||
if (c == '=') {
|
if (c == '=') {
|
||||||
|
@ -684,54 +671,44 @@ read_label(pic_state *pic, struct pic_port *port, const char *str)
|
||||||
}
|
}
|
||||||
|
|
||||||
static pic_value
|
static pic_value
|
||||||
read_unmatch(pic_state *pic, struct pic_port *port, const char *str)
|
read_unmatch(pic_state *pic, struct pic_port *port, int c)
|
||||||
{
|
{
|
||||||
PIC_UNUSED(port);
|
PIC_UNUSED(port);
|
||||||
PIC_UNUSED(str);
|
PIC_UNUSED(c);
|
||||||
|
|
||||||
read_error(pic, "unmatched parenthesis");
|
read_error(pic, "unmatched parenthesis");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static pic_value
|
||||||
|
read_dispatch(pic_state *pic, struct pic_port *port, int c)
|
||||||
|
{
|
||||||
|
c = next(port);
|
||||||
|
|
||||||
|
if (c == EOF) {
|
||||||
|
read_error(pic, "unexpected EOF");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pic->reader->dispatch[c] == NULL) {
|
||||||
|
read_error(pic, "invalid character at the seeker head");
|
||||||
|
}
|
||||||
|
|
||||||
|
return pic->reader->dispatch[c](pic, port, c);
|
||||||
|
}
|
||||||
|
|
||||||
static pic_value
|
static pic_value
|
||||||
read_nullable(pic_state *pic, struct pic_port *port, int c)
|
read_nullable(pic_state *pic, struct pic_port *port, int c)
|
||||||
{
|
{
|
||||||
struct pic_trie *trie = pic->reader->trie;
|
|
||||||
char buf[128];
|
|
||||||
size_t i = 0;
|
|
||||||
pic_str *str;
|
|
||||||
|
|
||||||
c = skip(port, c);
|
c = skip(port, c);
|
||||||
|
|
||||||
if (c == EOF) {
|
if (c == EOF) {
|
||||||
read_error(pic, "unexpected EOF");
|
read_error(pic, "unexpected EOF");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (trie->table[c] == NULL) {
|
if (pic->reader->table[c] == NULL) {
|
||||||
read_error(pic, "invalid character at the seeker head");
|
read_error(pic, "invalid character at the seeker head");
|
||||||
}
|
}
|
||||||
|
|
||||||
buf[i++] = (char)c;
|
return pic->reader->table[c](pic, port, c);
|
||||||
|
|
||||||
while (i < sizeof buf) {
|
|
||||||
trie = trie->table[c];
|
|
||||||
|
|
||||||
if ((c = peek(port)) == EOF) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (trie->table[c] == NULL) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
buf[i++] = (char)next(port);
|
|
||||||
}
|
|
||||||
if (i == sizeof buf) {
|
|
||||||
read_error(pic, "too long dispatch string");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (trie->proc == NULL) {
|
|
||||||
read_error(pic, "no reader registered for current string");
|
|
||||||
}
|
|
||||||
str = pic_make_str(pic, buf, i);
|
|
||||||
return pic_apply2(pic, trie->proc, pic_obj_value(port), pic_obj_value(str));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static pic_value
|
static pic_value
|
||||||
|
@ -750,136 +727,54 @@ read(pic_state *pic, struct pic_port *port, int c)
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct pic_trie *
|
|
||||||
pic_make_trie(pic_state *pic)
|
|
||||||
{
|
|
||||||
struct pic_trie *trie;
|
|
||||||
|
|
||||||
trie = pic_alloc(pic, sizeof(struct pic_trie));
|
|
||||||
trie->proc = NULL;
|
|
||||||
memset(trie->table, 0, sizeof trie->table);
|
|
||||||
|
|
||||||
return trie;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
pic_trie_delete(pic_state *pic, struct pic_trie *trie)
|
|
||||||
{
|
|
||||||
size_t i;
|
|
||||||
|
|
||||||
for (i = 0; i < sizeof trie->table / sizeof(struct pic_trie *); ++i) {
|
|
||||||
if (trie->table[i] != NULL) {
|
|
||||||
pic_trie_delete(pic, trie->table[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pic_free(pic, trie);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
pic_define_reader(pic_state *pic, const char *str, pic_func_t reader)
|
|
||||||
{
|
|
||||||
struct pic_trie *trie = pic->reader->trie;
|
|
||||||
int c;
|
|
||||||
|
|
||||||
while ((c = *str++)) {
|
|
||||||
if (trie->table[c] == NULL) {
|
|
||||||
trie->table[c] = pic_make_trie(pic);
|
|
||||||
}
|
|
||||||
trie = trie->table[c];
|
|
||||||
}
|
|
||||||
trie->proc = pic_make_proc(pic, reader, "reader");
|
|
||||||
}
|
|
||||||
|
|
||||||
#define DEFINE_READER(name) \
|
|
||||||
static pic_value \
|
|
||||||
pic_##name(pic_state *pic) \
|
|
||||||
{ \
|
|
||||||
struct pic_port *port; \
|
|
||||||
const char *str; \
|
|
||||||
\
|
|
||||||
pic_get_args(pic, "pz", &port, &str); \
|
|
||||||
\
|
|
||||||
return name(pic, port, str); \
|
|
||||||
}
|
|
||||||
|
|
||||||
DEFINE_READER(read_unmatch)
|
|
||||||
DEFINE_READER(read_comment)
|
|
||||||
DEFINE_READER(read_quote)
|
|
||||||
DEFINE_READER(read_quasiquote)
|
|
||||||
DEFINE_READER(read_unquote)
|
|
||||||
DEFINE_READER(read_unquote_splicing)
|
|
||||||
DEFINE_READER(read_string)
|
|
||||||
DEFINE_READER(read_pipe)
|
|
||||||
DEFINE_READER(read_plus)
|
|
||||||
DEFINE_READER(read_minus)
|
|
||||||
DEFINE_READER(read_pair)
|
|
||||||
DEFINE_READER(read_directive)
|
|
||||||
DEFINE_READER(read_block_comment)
|
|
||||||
DEFINE_READER(read_datum_comment)
|
|
||||||
DEFINE_READER(read_true)
|
|
||||||
DEFINE_READER(read_false)
|
|
||||||
DEFINE_READER(read_char)
|
|
||||||
DEFINE_READER(read_vector)
|
|
||||||
DEFINE_READER(read_blob)
|
|
||||||
DEFINE_READER(read_eval)
|
|
||||||
DEFINE_READER(read_symbol)
|
|
||||||
DEFINE_READER(read_number)
|
|
||||||
DEFINE_READER(read_label)
|
|
||||||
|
|
||||||
void
|
void
|
||||||
pic_init_reader(pic_state *pic)
|
pic_init_reader(pic_state *pic)
|
||||||
{
|
{
|
||||||
static const char INIT[] = "!$%&*./:<=>?@^_~";
|
int c;
|
||||||
char buf[3] = { 0 };
|
|
||||||
size_t i;
|
|
||||||
|
|
||||||
pic_define_reader(pic, ")", pic_read_unmatch);
|
pic->reader->table[0] = NULL;
|
||||||
pic_define_reader(pic, ";", pic_read_comment);
|
|
||||||
pic_define_reader(pic, "'", pic_read_quote);
|
|
||||||
pic_define_reader(pic, "`", pic_read_quasiquote);
|
|
||||||
pic_define_reader(pic, ",", pic_read_unquote);
|
|
||||||
pic_define_reader(pic, ",@", pic_read_unquote_splicing);
|
|
||||||
pic_define_reader(pic, "\"", pic_read_string);
|
|
||||||
pic_define_reader(pic, "|", pic_read_pipe);
|
|
||||||
pic_define_reader(pic, "+", pic_read_plus);
|
|
||||||
pic_define_reader(pic, "-", pic_read_minus);
|
|
||||||
pic_define_reader(pic, "(", pic_read_pair);
|
|
||||||
pic_define_reader(pic, "[", pic_read_pair);
|
|
||||||
|
|
||||||
pic_define_reader(pic, "#!", pic_read_directive);
|
/* default reader */
|
||||||
pic_define_reader(pic, "#|", pic_read_block_comment);
|
for (c = 1; c < 256; ++c) {
|
||||||
pic_define_reader(pic, "#;", pic_read_datum_comment);
|
pic->reader->table[c] = read_symbol;
|
||||||
pic_define_reader(pic, "#t", pic_read_true);
|
}
|
||||||
pic_define_reader(pic, "#true", pic_read_true);
|
|
||||||
pic_define_reader(pic, "#f", pic_read_false);
|
pic->reader->table[')'] = read_unmatch;
|
||||||
pic_define_reader(pic, "#false", pic_read_false);
|
pic->reader->table[';'] = read_comment;
|
||||||
pic_define_reader(pic, "#\\", pic_read_char);
|
pic->reader->table['\''] = read_quote;
|
||||||
pic_define_reader(pic, "#(", pic_read_vector);
|
pic->reader->table['`'] = read_quasiquote;
|
||||||
pic_define_reader(pic, "#u", pic_read_blob);
|
pic->reader->table[','] = read_unquote;
|
||||||
pic_define_reader(pic, "#.", pic_read_eval);
|
pic->reader->table['"'] = read_string;
|
||||||
|
pic->reader->table['|'] = read_pipe;
|
||||||
|
pic->reader->table['+'] = read_plus;
|
||||||
|
pic->reader->table['-'] = read_minus;
|
||||||
|
pic->reader->table['('] = read_pair;
|
||||||
|
pic->reader->table['['] = read_pair;
|
||||||
|
pic->reader->table['#'] = read_dispatch;
|
||||||
|
|
||||||
/* read number */
|
/* read number */
|
||||||
for (buf[0] = '0'; buf[0] <= '9'; ++buf[0]) {
|
for (c = '0'; c <= '9'; ++c) {
|
||||||
pic_define_reader(pic, buf, pic_read_number);
|
pic->reader->table[c] = read_number;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* read symbol */
|
/* default dispatch reader */
|
||||||
for (buf[0] = 'a'; buf[0] <= 'z'; ++buf[0]) {
|
for (c = 0; c < 256; ++c) {
|
||||||
pic_define_reader(pic, buf, pic_read_symbol);
|
pic->reader->dispatch[c] = NULL;
|
||||||
}
|
|
||||||
for (buf[0] = 'A'; buf[0] <= 'Z'; ++buf[0]) {
|
|
||||||
pic_define_reader(pic, buf, pic_read_symbol);
|
|
||||||
}
|
|
||||||
for (i = 0; i < sizeof INIT; ++i) {
|
|
||||||
buf[0] = INIT[i];
|
|
||||||
pic_define_reader(pic, buf, pic_read_symbol);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* read label */
|
pic->reader->dispatch['!'] = read_directive;
|
||||||
buf[0] = '#';
|
pic->reader->dispatch['|'] = read_block_comment;
|
||||||
for (buf[1] = '0'; buf[1] <= '9'; ++buf[1]) {
|
pic->reader->dispatch[';'] = read_datum_comment;
|
||||||
pic_define_reader(pic, buf, pic_read_label);
|
pic->reader->dispatch['t'] = read_true;
|
||||||
|
pic->reader->dispatch['f'] = read_false;
|
||||||
|
pic->reader->dispatch['\\'] = read_char;
|
||||||
|
pic->reader->dispatch['('] = read_vector;
|
||||||
|
pic->reader->dispatch['u'] = read_blob;
|
||||||
|
pic->reader->dispatch['.'] = read_eval;
|
||||||
|
|
||||||
|
/* read labels */
|
||||||
|
for (c = '0'; c <= '9'; ++c) {
|
||||||
|
pic->reader->dispatch[c] = read_label;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -172,7 +172,6 @@ pic_open(int argc, char *argv[], char **envp)
|
||||||
/* reader */
|
/* reader */
|
||||||
pic->reader = malloc(sizeof(struct pic_reader));
|
pic->reader = malloc(sizeof(struct pic_reader));
|
||||||
pic->reader->typecase = PIC_CASE_DEFAULT;
|
pic->reader->typecase = PIC_CASE_DEFAULT;
|
||||||
pic->reader->trie = pic_make_trie(pic);
|
|
||||||
xh_init_int(&pic->reader->labels, sizeof(pic_value));
|
xh_init_int(&pic->reader->labels, sizeof(pic_value));
|
||||||
|
|
||||||
/* init readers */
|
/* init readers */
|
||||||
|
@ -242,7 +241,6 @@ pic_close(pic_state *pic)
|
||||||
|
|
||||||
/* free reader struct */
|
/* free reader struct */
|
||||||
xh_destroy(&pic->reader->labels);
|
xh_destroy(&pic->reader->labels);
|
||||||
pic_trie_delete(pic, pic->reader->trie);
|
|
||||||
free(pic->reader);
|
free(pic->reader);
|
||||||
|
|
||||||
/* free global stacks */
|
/* free global stacks */
|
||||||
|
|
Loading…
Reference in New Issue