Improve number-reading in preparation for supporting floating-point.
This commit is contained in:
parent
902c489b90
commit
9f0dc52934
55
reader.c
55
reader.c
|
|
@ -21,6 +21,7 @@ typedef struct reader_state
|
||||||
static value_t read_one_value(reader_state_t *state);
|
static value_t read_one_value(reader_state_t *state);
|
||||||
static value_t read_special(reader_state_t *state);
|
static value_t read_special(reader_state_t *state);
|
||||||
static value_t read_list(reader_state_t *state);
|
static value_t read_list(reader_state_t *state);
|
||||||
|
static value_t read_fixnum(reader_state_t *state, int radix);
|
||||||
static value_t read_number(reader_state_t *state);
|
static value_t read_number(reader_state_t *state);
|
||||||
static value_t read_string(reader_state_t *state);
|
static value_t read_string(reader_state_t *state);
|
||||||
|
|
||||||
|
|
@ -79,6 +80,7 @@ static value_t read_one_value(reader_state_t *state)
|
||||||
case '(':
|
case '(':
|
||||||
return read_list(state);
|
return read_list(state);
|
||||||
case '-':
|
case '-':
|
||||||
|
case '+':
|
||||||
case '0' ... '9':
|
case '0' ... '9':
|
||||||
return read_number(state);
|
return read_number(state);
|
||||||
case '\"':
|
case '\"':
|
||||||
|
|
@ -215,12 +217,26 @@ static value_t read_list(reader_state_t *state)
|
||||||
return list_root.value;
|
return list_root.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
static value_t read_number(reader_state_t *state)
|
static short int char_to_digit(int ch)
|
||||||
|
{
|
||||||
|
if (isdigit(ch))
|
||||||
|
{
|
||||||
|
return ch - '0';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
assert(isalpha(ch));
|
||||||
|
return 10 + (toupper(ch) - 'A');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static value_t read_fixnum(reader_state_t *state, int radix)
|
||||||
{
|
{
|
||||||
fixnum_t radix = 10;
|
|
||||||
fixnum_t num = 0;
|
fixnum_t num = 0;
|
||||||
bool negative = false;
|
bool negative = false;
|
||||||
|
|
||||||
|
assert((0 <= radix) && (radix <= 36));
|
||||||
|
|
||||||
if (state->ch == '-')
|
if (state->ch == '-')
|
||||||
{
|
{
|
||||||
negative = true;
|
negative = true;
|
||||||
|
|
@ -233,6 +249,8 @@ static value_t read_number(reader_state_t *state)
|
||||||
|
|
||||||
release_assert(isdigit(state->ch));
|
release_assert(isdigit(state->ch));
|
||||||
|
|
||||||
|
if (radix == 0)
|
||||||
|
{
|
||||||
if (state->ch == '0')
|
if (state->ch == '0')
|
||||||
{
|
{
|
||||||
next_char(state);
|
next_char(state);
|
||||||
|
|
@ -253,15 +271,27 @@ static value_t read_number(reader_state_t *state)
|
||||||
radix = 8;
|
radix = 8;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (radix != 8)
|
||||||
|
{
|
||||||
|
/* Make sure we have at least one digit; if octal then the '0' counts instead */
|
||||||
|
release_assert(isalnum(state->ch));
|
||||||
|
release_assert(char_to_digit(state->ch) < radix);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
radix = 10;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
while (isxdigit(state->ch))
|
while (isalnum(state->ch))
|
||||||
{
|
{
|
||||||
fixnum_t digit = isdigit(state->ch)
|
fixnum_t digit = char_to_digit(state->ch);
|
||||||
? (state->ch - '0')
|
|
||||||
: (10 + (toupper(state->ch) - 'A'));
|
if (digit >= radix)
|
||||||
|
break;
|
||||||
|
|
||||||
release_assert(digit < radix);
|
|
||||||
release_assert(num <= (FIXNUM_MAX/radix));
|
release_assert(num <= (FIXNUM_MAX/radix));
|
||||||
|
|
||||||
num *= radix;
|
num *= radix;
|
||||||
|
|
@ -277,6 +307,13 @@ static value_t read_number(reader_state_t *state)
|
||||||
return fixnum_value(num);
|
return fixnum_value(num);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static value_t read_number(reader_state_t *state)
|
||||||
|
{
|
||||||
|
value_t v = read_fixnum(state, 0);
|
||||||
|
release_assert(!issymbol(state->ch));
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
static value_t read_string(reader_state_t *state)
|
static value_t read_string(reader_state_t *state)
|
||||||
{
|
{
|
||||||
char *buffer = (char*)malloc(128);
|
char *buffer = (char*)malloc(128);
|
||||||
|
|
@ -484,7 +521,7 @@ static value_t read_weak_box(reader_state_t *state)
|
||||||
|
|
||||||
static value_t read_definition(reader_state_t *state)
|
static value_t read_definition(reader_state_t *state)
|
||||||
{
|
{
|
||||||
fixnum_t ref = get_fixnum(read_number(state));
|
fixnum_t ref = get_fixnum(read_fixnum(state, 0));
|
||||||
gc_root_t place_root;
|
gc_root_t place_root;
|
||||||
value_t v;
|
value_t v;
|
||||||
|
|
||||||
|
|
@ -514,7 +551,7 @@ static value_t read_placeholder(reader_state_t *state)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return get_placeholder(state, get_fixnum(read_number(state)));
|
return get_placeholder(state, get_fixnum(read_fixnum(state, 0)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue