refactor number parser

This commit is contained in:
Yuichi Nishiwaki 2014-06-28 22:32:26 +09:00
parent 5c3e5b116e
commit 690e2cdba6
1 changed files with 22 additions and 24 deletions

View File

@ -155,46 +155,43 @@ read_symbol(pic_state *pic, struct pic_port *port, char c)
return pic_sym_value(sym); return pic_sym_value(sym);
} }
static int64_t static size_t
read_uinteger(pic_state *pic, struct pic_port *port, char c) read_uinteger(pic_state *pic, struct pic_port *port, char c, char buf[])
{ {
int64_t n; size_t i = 0;
c = skip(port, c);
if (! isdigit(c)) { if (! isdigit(c)) {
read_error(pic, "expected one or more digits"); read_error(pic, "expected one or more digits");
} }
n = c - '0'; buf[i++] = c;
while (isdigit(c = peek(port))) { while (isdigit(c = peek(port))) {
next(port); buf[i++] = next(port);
n = n * 10 + c - '0';
} }
return n; buf[i] = '\0';
return i;
} }
static pic_value static pic_value
read_number(pic_state *pic, struct pic_port *port, char c) read_number(pic_state *pic, struct pic_port *port, char c)
{ {
char buf[256], *cur; char buf[256];
int64_t i; size_t i;
i = read_uinteger(pic, port, c); i = read_uinteger(pic, port, c, buf);
if (peek(port) == '.') { if (peek(port) == '.') {
cur = buf + snprintf(buf, sizeof buf, "%lld", i);
do { do {
*cur++ = next(port); buf[i++] = next(port);
} while (isdigit(peek(port))); } while (isdigit(peek(port)));
*cur = '\0'; buf[i] = '\0';
return pic_float_value(atof(buf)); return pic_float_value(atof(buf));
} }
else { else {
return pic_int_value(i); return pic_int_value(atoi(buf));
} }
} }
static pic_value static pic_value
@ -313,7 +310,7 @@ read_unsigned_blob(pic_state *pic, struct pic_port *port, char c)
{ {
int nbits, n; int nbits, n;
size_t len; size_t len;
char *buf; char *dat, buf[256];
pic_blob *blob; pic_blob *blob;
nbits = 0; nbits = 0;
@ -331,21 +328,22 @@ read_unsigned_blob(pic_state *pic, struct pic_port *port, char c)
} }
len = 0; len = 0;
buf = NULL; dat = NULL;
c = next(port); c = next(port);
while ((c = skip(port, c)) != ')') { while ((c = skip(port, c)) != ')') {
n = read_uinteger(pic, port, c); read_uinteger(pic, port, c, buf);
n = atoi(buf);
if (n < 0 || (1 << nbits) <= n) { if (n < 0 || (1 << nbits) <= n) {
read_error(pic, "invalid element in bytevector literal"); read_error(pic, "invalid element in bytevector literal");
} }
len += 1; len += 1;
buf = pic_realloc(pic, buf, len); dat = pic_realloc(pic, dat, len);
buf[len - 1] = n; dat[len - 1] = n;
c = next(port); c = next(port);
} }
blob = pic_blob_new(pic, buf, len); blob = pic_blob_new(pic, dat, len);
pic_free(pic, buf); pic_free(pic, dat);
return pic_obj_value(blob); return pic_obj_value(blob);
} }