dispatch by string

This commit is contained in:
Yuichi Nishiwaki 2014-08-12 19:43:43 +09:00
parent 0dd7e85e72
commit e1fededa1e
1 changed files with 86 additions and 54 deletions

View File

@ -82,9 +82,12 @@ strcaseeq(const char *s1, const char *s2)
} }
static pic_value static pic_value
read_comment(pic_state *pic, struct pic_port *port, int c) read_comment(pic_state *pic, struct pic_port *port, const char *str)
{ {
int c;
UNUSED(pic); UNUSED(pic);
UNUSED(str);
do { do {
c = next(port); c = next(port);
@ -94,13 +97,13 @@ read_comment(pic_state *pic, struct pic_port *port, int c)
} }
static pic_value static pic_value
read_block_comment(pic_state *pic, struct pic_port *port, int c) read_block_comment(pic_state *pic, struct pic_port *port, const char *str)
{ {
int x, y; int x, y;
int i = 1; int i = 1;
UNUSED(pic); UNUSED(pic);
UNUSED(c); UNUSED(str);
y = next(port); y = next(port);
@ -119,9 +122,9 @@ read_block_comment(pic_state *pic, struct pic_port *port, int c)
} }
static pic_value static pic_value
read_datum_comment(pic_state *pic, struct pic_port *port, int c) read_datum_comment(pic_state *pic, struct pic_port *port, const char *str)
{ {
UNUSED(c); UNUSED(str);
read(pic, port, next(port)); read(pic, port, next(port));
@ -129,7 +132,7 @@ read_datum_comment(pic_state *pic, struct pic_port *port, int c)
} }
static pic_value static pic_value
read_directive(pic_state *pic, struct pic_port *port, int c) read_directive(pic_state *pic, struct pic_port *port, const char *str)
{ {
switch (peek(port)) { switch (peek(port)) {
case 'n': case 'n':
@ -146,15 +149,15 @@ read_directive(pic_state *pic, struct pic_port *port, int c)
break; break;
} }
return read_comment(pic, port, c); return read_comment(pic, port, str);
} }
static pic_value static pic_value
read_eval(pic_state *pic, struct pic_port *port, int c) read_eval(pic_state *pic, struct pic_port *port, const char *str)
{ {
pic_value form; pic_value form;
UNUSED(c); UNUSED(str);
form = read(pic, port, next(port)); form = read(pic, port, next(port));
@ -162,58 +165,65 @@ read_eval(pic_state *pic, struct pic_port *port, int c)
} }
static pic_value static pic_value
read_quote(pic_state *pic, struct pic_port *port, int c) read_quote(pic_state *pic, struct pic_port *port, const char *str)
{ {
UNUSED(c); UNUSED(str);
return pic_list2(pic, pic_sym_value(pic->sQUOTE), read(pic, port, next(port))); return pic_list2(pic, pic_sym_value(pic->sQUOTE), read(pic, port, next(port)));
} }
static pic_value static pic_value
read_quasiquote(pic_state *pic, struct pic_port *port, int c) read_quasiquote(pic_state *pic, struct pic_port *port, const char *str)
{ {
UNUSED(c); UNUSED(str);
return pic_list2(pic, pic_sym_value(pic->sQUASIQUOTE), read(pic, port, next(port))); return pic_list2(pic, pic_sym_value(pic->sQUASIQUOTE), read(pic, port, next(port)));
} }
static pic_value static pic_value
read_unquote(pic_state *pic, struct pic_port *port, int c) read_unquote(pic_state *pic, struct pic_port *port, const char *str)
{ {
UNUSED(c); UNUSED(str);
return pic_list2(pic, pic_sym_value(pic->sUNQUOTE), read(pic, port, next(port))); return pic_list2(pic, pic_sym_value(pic->sUNQUOTE), read(pic, port, next(port)));
} }
static pic_value static pic_value
read_unquote_splicing(pic_state *pic, struct pic_port *port, int c) read_unquote_splicing(pic_state *pic, struct pic_port *port, const char *str)
{ {
UNUSED(c); UNUSED(str);
return pic_list2(pic, pic_sym_value(pic->sUNQUOTE_SPLICING), read(pic, port, next(port))); return pic_list2(pic, pic_sym_value(pic->sUNQUOTE_SPLICING), read(pic, port, next(port)));
} }
static pic_value static pic_value
read_symbol(pic_state *pic, struct pic_port *port, int c) read_symbol(pic_state *pic, struct pic_port *port, const char *str)
{ {
size_t len; size_t len, i;
char *buf; char *buf;
pic_sym sym; pic_sym sym;
int c;
len = 0; len = strlen(str);
buf = NULL; buf = pic_calloc(pic, 1, len + 1);
do { for (i = 0; i < len; ++i) {
if (len != 0) { if (pic->reader->typecase == PIC_CASE_FOLD) {
c = next(port); buf[i] = tolower(str[i]);
} else {
buf[i] = str[i];
} }
}
while (! isdelim(peek(port))) {
c = next(port);
if (pic->reader->typecase == PIC_CASE_FOLD) { if (pic->reader->typecase == PIC_CASE_FOLD) {
c = tolower(c); c = tolower(c);
} }
len += 1; len += 1;
buf = pic_realloc(pic, buf, len + 1); buf = pic_realloc(pic, buf, len + 1);
buf[len - 1] = c; buf[len - 1] = c;
} while (! isdelim(peek(port))); }
sym = pic_intern(pic, buf, len); sym = pic_intern(pic, buf, len);
pic_free(pic, buf); pic_free(pic, buf);
@ -265,7 +275,7 @@ read_suffix(pic_state *pic, struct pic_port *port, char buf[])
} }
static pic_value static pic_value
read_number(pic_state *pic, struct pic_port *port, int c) read_unsigned(pic_state *pic, struct pic_port *port, int c)
{ {
char buf[256]; char buf[256];
size_t i; size_t i;
@ -285,6 +295,12 @@ read_number(pic_state *pic, struct pic_port *port, int c)
} }
} }
static pic_value
read_number(pic_state *pic, struct pic_port *port, const char *str)
{
return read_unsigned(pic, port, str[0]);
}
static pic_value static pic_value
negate(pic_value n) negate(pic_value n)
{ {
@ -296,15 +312,15 @@ negate(pic_value n)
} }
static pic_value static pic_value
read_minus(pic_state *pic, struct pic_port *port, int c) read_minus(pic_state *pic, struct pic_port *port, const char *str)
{ {
pic_value sym; pic_value sym;
if (isdigit(peek(port))) { if (isdigit(peek(port))) {
return negate(read_number(pic, port, next(port))); return negate(read_unsigned(pic, port, next(port)));
} }
else { else {
sym = read_symbol(pic, port, c); sym = read_symbol(pic, port, str);
if (strcaseeq(pic_symbol_name(pic, pic_sym(sym)), "-inf.0")) { if (strcaseeq(pic_symbol_name(pic, pic_sym(sym)), "-inf.0")) {
return pic_float_value(-INFINITY); return pic_float_value(-INFINITY);
} }
@ -316,15 +332,15 @@ read_minus(pic_state *pic, struct pic_port *port, int c)
} }
static pic_value static pic_value
read_plus(pic_state *pic, struct pic_port *port, int c) read_plus(pic_state *pic, struct pic_port *port, const char *str)
{ {
pic_value sym; pic_value sym;
if (isdigit(peek(port))) { if (isdigit(peek(port))) {
return read_number(pic, port, next(port)); return read_unsigned(pic, port, next(port));
} }
else { else {
sym = read_symbol(pic, port, c); sym = read_symbol(pic, port, str);
if (strcaseeq(pic_symbol_name(pic, pic_sym(sym)), "+inf.0")) { if (strcaseeq(pic_symbol_name(pic, pic_sym(sym)), "+inf.0")) {
return pic_float_value(INFINITY); return pic_float_value(INFINITY);
} }
@ -336,28 +352,32 @@ read_plus(pic_state *pic, struct pic_port *port, int c)
} }
static pic_value static pic_value
read_true(pic_state *pic, struct pic_port *port, int c) read_true(pic_state *pic, struct pic_port *port, const char *str)
{ {
UNUSED(pic); UNUSED(pic);
UNUSED(port); UNUSED(port);
UNUSED(c); UNUSED(str);
return pic_true_value(); return pic_true_value();
} }
static pic_value static pic_value
read_false(pic_state *pic, struct pic_port *port, int c) read_false(pic_state *pic, struct pic_port *port, const char *str)
{ {
UNUSED(pic); UNUSED(pic);
UNUSED(port); UNUSED(port);
UNUSED(c); UNUSED(str);
return pic_false_value(); return pic_false_value();
} }
static pic_value static pic_value
read_char(pic_state *pic, struct pic_port *port, int c) read_char(pic_state *pic, struct pic_port *port, const char *str)
{ {
int c;
UNUSED(str);
c = next(port); c = next(port);
if (! isdelim(peek(port))) { if (! isdelim(peek(port))) {
@ -391,12 +411,15 @@ read_char(pic_state *pic, struct pic_port *port, int c)
} }
static pic_value static pic_value
read_string(pic_state *pic, struct pic_port *port, int c) read_string(pic_state *pic, struct pic_port *port, const char *name)
{ {
int c;
char *buf; char *buf;
size_t size, cnt; size_t size, cnt;
pic_str *str; pic_str *str;
UNUSED(name);
size = 256; size = 256;
buf = pic_alloc(pic, size); buf = pic_alloc(pic, size);
cnt = 0; cnt = 0;
@ -426,7 +449,7 @@ read_string(pic_state *pic, struct pic_port *port, int c)
} }
static pic_value static pic_value
read_pipe(pic_state *pic, struct pic_port *port, int c) read_pipe(pic_state *pic, struct pic_port *port, const char *str)
{ {
char *buf; char *buf;
size_t size, cnt; size_t size, cnt;
@ -434,6 +457,9 @@ read_pipe(pic_state *pic, struct pic_port *port, int c)
/* 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;
UNUSED(str);
size = 256; size = 256;
buf = pic_alloc(pic, size); buf = pic_alloc(pic, size);
@ -470,13 +496,15 @@ read_pipe(pic_state *pic, struct pic_port *port, int c)
} }
static pic_value static pic_value
read_blob(pic_state *pic, struct pic_port *port, int c) read_blob(pic_state *pic, struct pic_port *port, const char *str)
{ {
int nbits, n; int nbits, n, c;
size_t len, i; size_t len, i;
char *dat, buf[256]; char *dat, buf[256];
pic_blob *blob; pic_blob *blob;
UNUSED(str);
nbits = 0; nbits = 0;
while (isdigit(c = next(port))) { while (isdigit(c = next(port))) {
@ -516,10 +544,11 @@ read_blob(pic_state *pic, struct pic_port *port, int c)
} }
static pic_value static pic_value
read_pair(pic_state *pic, struct pic_port *port, int c) read_pair(pic_state *pic, struct pic_port *port, const char *str)
{ {
int tOPEN = c, tCLOSE = (tOPEN == '(') ? ')' : ']'; const int tCLOSE = (str[0] == '(') ? ')' : ']';
pic_value car, cdr; pic_value car, cdr;
int c;
retry: retry:
@ -547,17 +576,17 @@ read_pair(pic_state *pic, struct pic_port *port, int c)
goto retry; goto retry;
} }
cdr = read_pair(pic, port, tOPEN); /* FIXME: don't use recursion */ cdr = read_pair(pic, port, str);
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, int c) read_vector(pic_state *pic, struct pic_port *port, const char *str)
{ {
pic_value list; pic_value list;
list = read(pic, port, c); list = read(pic, port, str[1]);
return pic_obj_value(pic_vec_new_from_list(pic, list)); return pic_obj_value(pic_vec_new_from_list(pic, list));
} }
@ -635,11 +664,12 @@ 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, int c) read_label(pic_state *pic, struct pic_port *port, const char *str)
{ {
int i; int i, c;
i = 0; i = 0;
c = str[1]; /* initial index letter */
do { do {
i = i * 10 + c; i = i * 10 + c;
} while (isdigit(c = next(port))); } while (isdigit(c = next(port)));
@ -654,10 +684,10 @@ read_label(pic_state *pic, struct pic_port *port, int c)
} }
static pic_value static pic_value
read_unmatch(pic_state *pic, struct pic_port *port, int c) read_unmatch(pic_state *pic, struct pic_port *port, const char *str)
{ {
UNUSED(port); UNUSED(port);
UNUSED(c); UNUSED(str);
read_error(pic, "unmatched parenthesis"); read_error(pic, "unmatched parenthesis");
} }
@ -668,6 +698,7 @@ read_nullable(pic_state *pic, struct pic_port *port, int c)
struct pic_trie *trie = pic->reader->trie; struct pic_trie *trie = pic->reader->trie;
char buf[128]; char buf[128];
size_t i = 0; size_t i = 0;
pic_str *str;
c = skip(port, c); c = skip(port, c);
@ -699,7 +730,8 @@ read_nullable(pic_state *pic, struct pic_port *port, int c)
if (trie->proc == NULL) { if (trie->proc == NULL) {
read_error(pic, "no reader registered for current string"); read_error(pic, "no reader registered for current string");
} }
return pic_apply2(pic, trie->proc, pic_obj_value(port), pic_char_value(buf[i-1])); str = pic_str_new(pic, buf, i);
return pic_apply2(pic, trie->proc, pic_obj_value(port), pic_obj_value(str));
} }
static pic_value static pic_value
@ -764,11 +796,11 @@ pic_define_reader(pic_state *pic, const char *str, pic_func_t reader)
pic_##name(pic_state *pic) \ pic_##name(pic_state *pic) \
{ \ { \
struct pic_port *port; \ struct pic_port *port; \
char c; \ const char *str; \
\ \
pic_get_args(pic, "pc", &port, &c); \ pic_get_args(pic, "pz", &port, &str); \
\ \
return name(pic, port, c); \ return name(pic, port, str); \
} }
DEFINE_READER(read_unmatch) DEFINE_READER(read_unmatch)