X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Flisp%2Fao_lisp_read.c;h=84ef2a616bb09fdbdb9cebba3d4a2e889c14762b;hb=97cf9df882291b9e494b2f64f84eb37357a6ab31;hp=ea98b9767cb59882ca13e34ffeb343b623995c46;hpb=d2408e72d1e0d3459918601712b09860ab17e200;p=fw%2Faltos diff --git a/src/lisp/ao_lisp_read.c b/src/lisp/ao_lisp_read.c index ea98b976..84ef2a61 100644 --- a/src/lisp/ao_lisp_read.c +++ b/src/lisp/ao_lisp_read.c @@ -156,19 +156,7 @@ lex_get() c = lex_unget_c; lex_unget_c = 0; } else { -#if AO_LISP_ALTOS - static uint8_t at_eol; - - if (at_eol) { - ao_cmd_readline(); - at_eol = 0; - } - c = ao_cmd_lex(); - if (c == '\n') - at_eol = 1; -#else - c = getchar(); -#endif + c = ao_lisp_getc(); } return c; } @@ -188,8 +176,6 @@ lex_quoted (void) int count; c = lex_get(); -// if (jumping) -// return nil; if (c == EOF) return EOF; c &= 0x7f; @@ -218,8 +204,6 @@ lex_quoted (void) count = 1; while (count <= 3) { c = lex_get(); -// if (jumping) -// return nil; if (c == EOF) return EOF; c &= 0x7f; @@ -286,13 +270,19 @@ lex(void) for (;;) { c = lexc(); if (lex_class & ENDOFFILE) - return AO_LISP_NIL; + return END; -// if (jumping) -// return nil; if (lex_class & WHITE) continue; + if (lex_class & COMMENT) { + while ((c = lexc()) != '\n') { + if (lex_class & ENDOFFILE) + return END; + } + continue; + } + if (lex_class & (BRA|KET|QUOTEC)) { add_token(c); end_token(); @@ -312,8 +302,6 @@ lex(void) if (lex_class & STRINGC) { for (;;) { c = lexc(); -// if (jumping) -// return nil; if (lex_class & (STRINGC|ENDOFFILE)) { end_token(); return STRING; @@ -349,8 +337,6 @@ lex(void) } add_token (c); c = lexc (); -// if (jumping) -// return nil; if (lex_class & (NOTNAME)) { // if (lex_class & ENDOFFILE) // clearerr (f); @@ -370,40 +356,82 @@ lex(void) } static int parse_token; -static uint8_t been_here; -static struct ao_lisp_cons *read_cons; -static struct ao_lisp_cons *read_cons_tail; -static struct ao_lisp_cons *read_stack; -static ao_poly -read_item(void) +struct ao_lisp_cons *ao_lisp_read_cons; +struct ao_lisp_cons *ao_lisp_read_cons_tail; +struct ao_lisp_cons *ao_lisp_read_stack; + +static int +push_read_stack(int cons, int in_quote) +{ + DBGI("push read stack %p %d\n", ao_lisp_read_cons, in_quote); + DBG_IN(); + if (cons) { + ao_lisp_read_stack = ao_lisp_cons_cons(ao_lisp_cons_poly(ao_lisp_read_cons), + ao_lisp_cons_cons(ao_lisp_int_poly(in_quote), + ao_lisp_read_stack)); + if (!ao_lisp_read_stack) + return 0; + } + ao_lisp_read_cons = NULL; + ao_lisp_read_cons_tail = NULL; + return 1; +} + +static int +pop_read_stack(int cons) +{ + int in_quote = 0; + if (cons) { + ao_lisp_read_cons = ao_lisp_poly_cons(ao_lisp_read_stack->car); + ao_lisp_read_stack = ao_lisp_poly_cons(ao_lisp_read_stack->cdr); + in_quote = ao_lisp_poly_int(ao_lisp_read_stack->car); + ao_lisp_read_stack = ao_lisp_poly_cons(ao_lisp_read_stack->cdr); + for (ao_lisp_read_cons_tail = ao_lisp_read_cons; + ao_lisp_read_cons_tail && ao_lisp_read_cons_tail->cdr; + ao_lisp_read_cons_tail = ao_lisp_poly_cons(ao_lisp_read_cons_tail->cdr)) + ; + } else { + ao_lisp_read_cons = 0; + ao_lisp_read_cons_tail = 0; + ao_lisp_read_stack = 0; + } + DBG_OUT(); + DBGI("pop read stack %p %d\n", ao_lisp_read_cons, in_quote); + return in_quote; +} + +ao_poly +ao_lisp_read(void) { struct ao_lisp_atom *atom; char *string; int cons; + int in_quote; ao_poly v; - if (!been_here) { - ao_lisp_root_add(&ao_lisp_cons_type, &read_cons); - ao_lisp_root_add(&ao_lisp_cons_type, &read_cons_tail); - ao_lisp_root_add(&ao_lisp_cons_type, &read_stack); - } + parse_token = lex(); + DBGI("token %d (%s)\n", parse_token, token_string); cons = 0; - read_cons = read_cons_tail = read_stack = 0; + in_quote = 0; + ao_lisp_read_cons = ao_lisp_read_cons_tail = ao_lisp_read_stack = 0; for (;;) { while (parse_token == OPEN) { - if (cons++) - read_stack = ao_lisp_cons_cons(ao_lisp_cons_poly(read_cons), read_stack); - read_cons = NULL; - read_cons_tail = NULL; + if (!push_read_stack(cons, in_quote)) + return AO_LISP_NIL; + cons++; + in_quote = 0; parse_token = lex(); + DBGI("token %d (%s)\n", parse_token, token_string); } switch (parse_token) { - case ENDOFFILE: + case END: default: - v = AO_LISP_NIL; + if (cons) + ao_lisp_error(AO_LISP_EOF, "unexpected end of file"); + return _ao_lisp_atom_eof; break; case NAME: atom = ao_lisp_atom_intern(token_string); @@ -422,40 +450,49 @@ read_item(void) else v = AO_LISP_NIL; break; + case QUOTE: + if (!push_read_stack(cons, in_quote)) + return AO_LISP_NIL; + cons++; + in_quote = 1; + v = _ao_lisp_atom_quote; + break; case CLOSE: - if (cons) - v = ao_lisp_cons_poly(read_cons); - else + if (!cons) { v = AO_LISP_NIL; - if (--cons) { - read_cons = ao_lisp_poly_cons(read_stack->car); - read_stack = ao_lisp_poly_cons(read_stack->cdr); - for (read_cons_tail = read_cons; - read_cons_tail && read_cons_tail->cdr; - read_cons_tail = ao_lisp_poly_cons(read_cons_tail->cdr)) - ; + break; } + v = ao_lisp_cons_poly(ao_lisp_read_cons); + --cons; + in_quote = pop_read_stack(cons); break; } - if (!cons) - break; + /* loop over QUOTE ends */ + for (;;) { + if (!cons) + return v; + + struct ao_lisp_cons *read = ao_lisp_cons_cons(v, NULL); + if (!read) + return AO_LISP_NIL; + + if (ao_lisp_read_cons_tail) + ao_lisp_read_cons_tail->cdr = ao_lisp_cons_poly(read); + else + ao_lisp_read_cons = read; + ao_lisp_read_cons_tail = read; - struct ao_lisp_cons *read = ao_lisp_cons_cons(v, NULL); - if (read_cons_tail) - read_cons_tail->cdr = ao_lisp_cons_poly(read); - else - read_cons = read; - read_cons_tail = read; + if (!in_quote || !ao_lisp_read_cons->cdr) + break; + + v = ao_lisp_cons_poly(ao_lisp_read_cons); + --cons; + in_quote = pop_read_stack(cons); + } parse_token = lex(); + DBGI("token %d (%s)\n", parse_token, token_string); } return v; } - -ao_poly -ao_lisp_read(void) -{ - parse_token = lex(); - return read_item(); -}