diff --git a/core-image.rla b/core-image.rla index f9cf792..da70159 100644 --- a/core-image.rla +++ b/core-image.rla @@ -8,11 +8,11 @@ #(1 #f) #() 1 - "\x02\x80\x01\x00"; (set! 128 (cons 1 0)) - 254 - 128 - 2 - 255 + "\x02\x80\x01\x00"; (set! f0 (cons g1 nil)) + 0xfe + 0x80 + 0x02 + 0xff ) #S(#="template" #( @@ -21,57 +21,57 @@ #(#f) "\x40\xff\xfe" ; i0 ctx k 1 - "\x00\x80\x03\xfd\; (set! 128 (car 253)) - \x0a\x80\x40\x80\; (set! 128 (fix* 64 128)) - \x02\x80\x80\x00"; (set! 128 (cons 128 0)) - 66 - 128 - 1 - 65 + "\x00\x80\x03\xfd\; (set! f0 (car argv)) + \x0a\x80\x40\x80\; (set! f0 (fix* i0 f0)) + \x02\x80\x80\x00"; (set! f0 (cons f0 nil)) + 0x42 ; i2 + 0x80 ; f0 + 0x01 ; g1 + 0x41 ; i1 ) 1 ) "\x80" ; f0 2 - "\x09\x80\x40\x03\; (set! 128 (fix- 64 3)) - \x02\x80\x80\x00\; (set! 128 (cons 128 0)) - \x00\x81\x1b\x02"; (set! 129 (lambda 2)) - 1 - 128 - 129 - 255 + "\x09\x80\x40\x03\; (set! f0 (fix- i0 g3)) + \x02\x80\x80\x00\; (set! f0 (cons f0 nil)) + \x00\x81\x1b\x02"; (set! f1 (lambda g2)) + 0x01 + 0x80 + 0x81 + 0xff ) 1 ) #() 2 - "\x00\x80\x03\xfd\; (set! 128 (car 253)) - \x0d\x81\x80\x03\; (set! 129 (fix< 128 3)) - \x81\x81\x01\x02\; (set! 129 (if 129 1 2)) - \x00\x81\x1b\x81"; (set! 129 (lambda 129)) - 129 - 0 - 254 - 255 + "\x00\x80\x03\xfd\; (set! f0 (car argv)) + \x0d\x81\x80\x03\; (set! f1 (fix< f0 g3)) + \x81\x81\x01\x02\; (set! f1 (if f1 g1 g2)) + \x00\x81\x1b\x81"; (set! f1 (lambda f1)) + 0x81 + 0x00 + 0xfe + 0xff ) #f ) "\xfe\xff" ; k ctx 0 "" - 1 - 253 - 64 - 65 + 0x01 + 0xfd + 0x40 + 0x41 ) #="string->number" ) #() 1 - "\x00\x80\x1b\x01"; (set! 128 (lambda 1)) - 2 - 253 - 128 - 255 + "\x00\x80\x1b\x01"; (set! f0 (lambda g1)) + 0x02 + 0xfd + 0x80 + 0xff ) -; vim:set sw=2 expandtab syntax=: +; vim:set syntax= sw=2 expandtab: diff --git a/reader.c b/reader.c index 9abaf77..fe9d476 100644 --- a/reader.c +++ b/reader.c @@ -215,6 +215,7 @@ static value_t read_list(reader_state_t *state) static value_t read_number(reader_state_t *state) { + fixnum_t radix = 10; fixnum_t num = 0; bool negative = false; @@ -230,11 +231,40 @@ static value_t read_number(reader_state_t *state) release_assert(isdigit(state->ch)); - while (isdigit(state->ch)) + if (state->ch == '0') { - release_assert(num <= (FIXNUM_MAX/10)); - num *= 10; - num += (state->ch - '0'); + next_char(state); + + 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); } @@ -346,11 +376,26 @@ static value_t read_string(reader_state_t *state) if (skip_ws) { - /* Slightly different from the normal skip_whitespace(); - * Assumes first char is space, and bounded by '\n' afterward. */ + bool hit_eol = false; + + /* Slightly different from the normal skip_whitespace(); skips + * whitespace through the _second_ EOL following the backslash. */ do { + if (state->ch == '\n') + { + if (!hit_eol) + { + hit_eol = true; + } + else + { + next_char(state); + break; + } + } + next_char(state); - } while (isspace(state->ch) && (state->ch != '\n')); + } while (isspace(state->ch)); } else { @@ -585,21 +630,29 @@ static void next_char(reader_state_t *state) static void skip_whitespace(reader_state_t *state) { - while (isspace(state->ch)) - next_char(state); - - /* Comments count as whitespace */ - if (state->ch == ';') + for (;;) { - do { + if (isspace(state->ch)) + { next_char(state); - - if (state->ch == '\n') - { + } + else if (state->ch == ';') + { + /* Comments count as whitespace */ + do { next_char(state); - break; - } - } while (state->ch != EOF); + + if (state->ch == '\n') + { + next_char(state); + break; + } + } while (state->ch != EOF); + } + else + { + break; + } } }