123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133 |
- int skip_whitespace () {
- int c;
- do {
- c = _getchar();
- } while (c == ' ' || c == '\n');
- lastchar = c;
- return c;
- }
- Atom* parse_list () {
- List *list = NULL, *next = NULL;
- while (1) {
- if (lastchar == -1 || lastchar == ' ' || lastchar == '\n')
- skip_whitespace();
- if (lastchar == ')') {
- lastchar = -1;
- break;
- }
- Atom *at = parse();
- List *tail = cons(at, NULL);
- if (next) {
- next->tail = tail;
- } else {
- list = next = tail;
- }
- next = tail;
- }
- return create_list(list);
- }
- Atom* parse_symbol (int c) {
- int buf[65536], n = 1, stop_at;
- if (lastchar != -1) {
- buf[n] = lastchar;
- lastchar = -1;
- n++;
- }
- switch (c) {
- case '"':
- case '\'':
- stop_at = c;
- do {
- if (c == '\\') {
- c = _getchar();
- switch (c) {
- case 'b': c = '\b'; break;
- case 'n': c = '\n'; break;
- case 't': c = '\t';
- }
- }
- buf[n] = c;
- c = _getchar();
- n ++;
- } while (c != stop_at && n < 65536);
- lastchar = -1;
- default:
- while (n < 65536 && c != ' ' && c != '\n' && c != '(' && c != ')') {
- buf[n] = c;
- c = _getchar();
- n ++;
- }
- lastchar = c;
- }
- if (n == 1)
- return NULL;
- buf[0] = n-1;
- if (symbols_are_equal(buf, nil_symb))
- return NULL;
- return create_symbol(duplicate_symbol(buf));
- }
- Atom* parse_int (int c) {
- char neg = 0;
- int value = 0;
- int input_processed = 0;
- int firstchar = c;
- if (c == '+') {
- } else if (c == '-') {
- neg = 1;
- } else if (c >= '0' && c <= '9') {
- value += (c - '0');
- input_processed = 1;
- lastchar = -1;
- }
- while (1) {
- c = _getchar();
- if (c >= '0' && c <= '9') {
- if (!input_processed)
- input_processed = 1;
- value *= 10;
- value += (c - '0');
- } else {
- lastchar = c;
- break;
- }
- if (value < 0)
- return NULL;
- }
- if (!input_processed) {
- input_processed = firstchar;
- firstchar = lastchar;
- lastchar = input_processed;
- return parse_symbol(firstchar);
- }
- if (neg)
- value = -value;
- return create_int(value);
- }
- Atom* parse () {
- if (lastchar == -1 || lastchar == ' ' || lastchar == '\n')
- skip_whitespace();
- int c = lastchar;
- lastchar = -1;
- if (c == '(') {
- return parse_list();
- } else if (c == '-' || c == '+' || (c >= '0' && c <= '9')) {
- return parse_int(c);
- } else if (c == ';') {
- while (c != '\n')
- c = _getchar();
- return parse();
- } else if (c == ')') {
- return _warning("PARSE" EXTRA_PARENTHESIS);
- } else {
- return parse_symbol(c);
- }
- }
|