Fix interaction between comments and whitespace in the reader.
Add support for fixnums in binary (0b), octal (0), and hexadecimal (0x). Minor changes to the example input program to improve readability.
This commit is contained in:
parent
861f1f7617
commit
0404777049
|
|
@ -8,11 +8,11 @@
|
||||||
#(1 #f)
|
#(1 #f)
|
||||||
#()
|
#()
|
||||||
1
|
1
|
||||||
"\x02\x80\x01\x00"; (set! 128 (cons 1 0))
|
"\x02\x80\x01\x00"; (set! f0 (cons g1 nil))
|
||||||
254
|
0xfe
|
||||||
128
|
0x80
|
||||||
2
|
0x02
|
||||||
255
|
0xff
|
||||||
)
|
)
|
||||||
#S(#="template"
|
#S(#="template"
|
||||||
#(
|
#(
|
||||||
|
|
@ -21,57 +21,57 @@
|
||||||
#(#f)
|
#(#f)
|
||||||
"\x40\xff\xfe" ; i0 ctx k
|
"\x40\xff\xfe" ; i0 ctx k
|
||||||
1
|
1
|
||||||
"\x00\x80\x03\xfd\; (set! 128 (car 253))
|
"\x00\x80\x03\xfd\; (set! f0 (car argv))
|
||||||
\x0a\x80\x40\x80\; (set! 128 (fix* 64 128))
|
\x0a\x80\x40\x80\; (set! f0 (fix* i0 f0))
|
||||||
\x02\x80\x80\x00"; (set! 128 (cons 128 0))
|
\x02\x80\x80\x00"; (set! f0 (cons f0 nil))
|
||||||
66
|
0x42 ; i2
|
||||||
128
|
0x80 ; f0
|
||||||
1
|
0x01 ; g1
|
||||||
65
|
0x41 ; i1
|
||||||
)
|
)
|
||||||
1
|
1
|
||||||
)
|
)
|
||||||
"\x80" ; f0
|
"\x80" ; f0
|
||||||
2
|
2
|
||||||
"\x09\x80\x40\x03\; (set! 128 (fix- 64 3))
|
"\x09\x80\x40\x03\; (set! f0 (fix- i0 g3))
|
||||||
\x02\x80\x80\x00\; (set! 128 (cons 128 0))
|
\x02\x80\x80\x00\; (set! f0 (cons f0 nil))
|
||||||
\x00\x81\x1b\x02"; (set! 129 (lambda 2))
|
\x00\x81\x1b\x02"; (set! f1 (lambda g2))
|
||||||
1
|
0x01
|
||||||
128
|
0x80
|
||||||
129
|
0x81
|
||||||
255
|
0xff
|
||||||
)
|
)
|
||||||
1
|
1
|
||||||
)
|
)
|
||||||
#()
|
#()
|
||||||
2
|
2
|
||||||
"\x00\x80\x03\xfd\; (set! 128 (car 253))
|
"\x00\x80\x03\xfd\; (set! f0 (car argv))
|
||||||
\x0d\x81\x80\x03\; (set! 129 (fix< 128 3))
|
\x0d\x81\x80\x03\; (set! f1 (fix< f0 g3))
|
||||||
\x81\x81\x01\x02\; (set! 129 (if 129 1 2))
|
\x81\x81\x01\x02\; (set! f1 (if f1 g1 g2))
|
||||||
\x00\x81\x1b\x81"; (set! 129 (lambda 129))
|
\x00\x81\x1b\x81"; (set! f1 (lambda f1))
|
||||||
129
|
0x81
|
||||||
0
|
0x00
|
||||||
254
|
0xfe
|
||||||
255
|
0xff
|
||||||
)
|
)
|
||||||
#f
|
#f
|
||||||
)
|
)
|
||||||
"\xfe\xff" ; k ctx
|
"\xfe\xff" ; k ctx
|
||||||
0
|
0
|
||||||
""
|
""
|
||||||
1
|
0x01
|
||||||
253
|
0xfd
|
||||||
64
|
0x40
|
||||||
65
|
0x41
|
||||||
)
|
)
|
||||||
#="string->number"
|
#="string->number"
|
||||||
)
|
)
|
||||||
#()
|
#()
|
||||||
1
|
1
|
||||||
"\x00\x80\x1b\x01"; (set! 128 (lambda 1))
|
"\x00\x80\x1b\x01"; (set! f0 (lambda g1))
|
||||||
2
|
0x02
|
||||||
253
|
0xfd
|
||||||
128
|
0x80
|
||||||
255
|
0xff
|
||||||
)
|
)
|
||||||
; vim:set sw=2 expandtab syntax=:
|
; vim:set syntax= sw=2 expandtab:
|
||||||
|
|
|
||||||
91
reader.c
91
reader.c
|
|
@ -215,6 +215,7 @@ static value_t read_list(reader_state_t *state)
|
||||||
|
|
||||||
static value_t read_number(reader_state_t *state)
|
static value_t read_number(reader_state_t *state)
|
||||||
{
|
{
|
||||||
|
fixnum_t radix = 10;
|
||||||
fixnum_t num = 0;
|
fixnum_t num = 0;
|
||||||
bool negative = false;
|
bool negative = false;
|
||||||
|
|
||||||
|
|
@ -230,11 +231,40 @@ static value_t read_number(reader_state_t *state)
|
||||||
|
|
||||||
release_assert(isdigit(state->ch));
|
release_assert(isdigit(state->ch));
|
||||||
|
|
||||||
while (isdigit(state->ch))
|
if (state->ch == '0')
|
||||||
{
|
{
|
||||||
release_assert(num <= (FIXNUM_MAX/10));
|
next_char(state);
|
||||||
num *= 10;
|
|
||||||
num += (state->ch - '0');
|
switch (state->ch)
|
||||||
|
{
|
||||||
|
case 'X':
|
||||||
|
case 'x':
|
||||||
|
next_char(state);
|
||||||
|
radix = 16;
|
||||||
|
break;
|
||||||
|
case 'B':
|
||||||
|
case 'b':
|
||||||
|
next_char(state);
|
||||||
|
radix = 2;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
radix = 8;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
while (isxdigit(state->ch))
|
||||||
|
{
|
||||||
|
fixnum_t digit = isdigit(state->ch)
|
||||||
|
? (state->ch - '0')
|
||||||
|
: (10 + (toupper(state->ch) - 'A'));
|
||||||
|
|
||||||
|
release_assert(digit < radix);
|
||||||
|
release_assert(num <= (FIXNUM_MAX/radix));
|
||||||
|
|
||||||
|
num *= radix;
|
||||||
|
num += digit;
|
||||||
|
|
||||||
next_char(state);
|
next_char(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -346,11 +376,26 @@ static value_t read_string(reader_state_t *state)
|
||||||
|
|
||||||
if (skip_ws)
|
if (skip_ws)
|
||||||
{
|
{
|
||||||
/* Slightly different from the normal skip_whitespace();
|
bool hit_eol = false;
|
||||||
* Assumes first char is space, and bounded by '\n' afterward. */
|
|
||||||
|
/* Slightly different from the normal skip_whitespace(); skips
|
||||||
|
* whitespace through the _second_ EOL following the backslash. */
|
||||||
do {
|
do {
|
||||||
|
if (state->ch == '\n')
|
||||||
|
{
|
||||||
|
if (!hit_eol)
|
||||||
|
{
|
||||||
|
hit_eol = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
next_char(state);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
next_char(state);
|
next_char(state);
|
||||||
} while (isspace(state->ch) && (state->ch != '\n'));
|
} while (isspace(state->ch));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -585,21 +630,29 @@ static void next_char(reader_state_t *state)
|
||||||
|
|
||||||
static void skip_whitespace(reader_state_t *state)
|
static void skip_whitespace(reader_state_t *state)
|
||||||
{
|
{
|
||||||
while (isspace(state->ch))
|
for (;;)
|
||||||
next_char(state);
|
|
||||||
|
|
||||||
/* Comments count as whitespace */
|
|
||||||
if (state->ch == ';')
|
|
||||||
{
|
{
|
||||||
do {
|
if (isspace(state->ch))
|
||||||
|
{
|
||||||
next_char(state);
|
next_char(state);
|
||||||
|
}
|
||||||
if (state->ch == '\n')
|
else if (state->ch == ';')
|
||||||
{
|
{
|
||||||
|
/* Comments count as whitespace */
|
||||||
|
do {
|
||||||
next_char(state);
|
next_char(state);
|
||||||
break;
|
|
||||||
}
|
if (state->ch == '\n')
|
||||||
} while (state->ch != EOF);
|
{
|
||||||
|
next_char(state);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} while (state->ch != EOF);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue