~ubuntu-branches/ubuntu/quantal/gclcvs/quantal

« back to all changes in this revision

Viewing changes to o/read.d

  • Committer: Bazaar Package Importer
  • Author(s): Camm Maguire
  • Date: 2004-06-24 15:13:46 UTC
  • Revision ID: james.westby@ubuntu.com-20040624151346-xh0xaaktyyp7aorc
Tags: 2.7.0-26
C_GC_OFFSET is 2 on m68k-linux

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 Copyright (C) 1994 M. Hagiya, W. Schelter, T. Yuasa
 
3
 
 
4
This file is part of GNU Common Lisp, herein referred to as GCL
 
5
 
 
6
GCL is free software; you can redistribute it and/or modify it under
 
7
the terms of the GNU LIBRARY GENERAL PUBLIC LICENSE as published by
 
8
the Free Software Foundation; either version 2, or (at your option)
 
9
any later version.
 
10
 
 
11
GCL is distributed in the hope that it will be useful, but WITHOUT
 
12
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 
13
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public 
 
14
License for more details.
 
15
 
 
16
You should have received a copy of the GNU Library General Public License 
 
17
along with GCL; see the file COPYING.  If not, write to the Free Software
 
18
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
 
19
*/
 
20
 
 
21
/*
 
22
        read.d
 
23
*/
 
24
 
 
25
#define NEED_ISFINITE
 
26
#include "include.h"
 
27
#include <string.h>
 
28
 
 
29
static object
 
30
current_readtable(void);
 
31
 
 
32
static object
 
33
patch_sharp(object);
 
34
 
 
35
static object
 
36
parse_number(char *,int,int *,int);
 
37
 
 
38
#define token_buffer    token->st.st_self
 
39
/* the active length of the token */
 
40
int tok_leng;
 
41
 
 
42
 
 
43
 
 
44
object dispatch_reader;
 
45
 
 
46
 
 
47
#define cat(c)  (READtable->rt.rt_self[char_code((c))] \
 
48
                 .rte_chattrib)
 
49
 
 
50
#ifndef SHARP_EQ_CONTEXT_SIZE
 
51
#define SHARP_EQ_CONTEXT_SIZE   500
 
52
#endif
 
53
 
 
54
static void
 
55
setup_READtable()
 
56
{
 
57
        READtable = current_readtable();
 
58
}
 
59
 
 
60
struct sharp_eq_context_struct {
 
61
        object  sharp_index;
 
62
        object  sharp_eq;
 
63
        object  sharp_sharp;
 
64
} sharp_eq_context[SHARP_EQ_CONTEXT_SIZE];
 
65
 
 
66
/*
 
67
        NOTE:
 
68
 
 
69
                I believe that there is no need to enter
 
70
                sharp_eq_context to mark_origin.
 
71
*/
 
72
 
 
73
 
 
74
static void
 
75
setup_READ()
 
76
{
 
77
        object x;
 
78
 
 
79
        READtable = current_readtable();
 
80
        x = symbol_value(sLAread_default_float_formatA);
 
81
        if (x == sLshort_float)
 
82
                READdefault_float_format = 'S';
 
83
        else if (x == sLsingle_float || x == sLdouble_float || x == sLlong_float)
 
84
                READdefault_float_format = 'F';
 
85
        else {
 
86
                vs_push(x);
 
87
                sLAread_default_float_formatA->s.s_dbind = sLsingle_float;
 
88
        FEerror("The value of *READ-DEFAULT-FLOAT-FORMAT*, ~S, was illegal.",
 
89
                        1, x);
 
90
        }
 
91
        x = symbol_value(sLAread_baseA);
 
92
        if (type_of(x) != t_fixnum || fix(x) < 2 || fix(x) > 36) {
 
93
                vs_push(x);
 
94
                sLAread_baseA->s.s_dbind = make_fixnum(10);
 
95
                FEerror("The value of *READ-BASE*, ~S, was illegal.", 1, x);
 
96
        }
 
97
        READbase = fix(x);
 
98
        READsuppress = symbol_value(sLAread_suppressA) != Cnil;
 
99
        sharp_eq_context_max = 0;
 
100
 
 
101
        backq_level = 0;
 
102
}
 
103
 
 
104
static void
 
105
setup_standard_READ()
 
106
{
 
107
        READtable = standard_readtable;
 
108
        READdefault_float_format = 'F';
 
109
        READbase = 10;
 
110
        READsuppress = FALSE;
 
111
        sharp_eq_context_max = 0;
 
112
        backq_level = 0;
 
113
}
 
114
 
 
115
object
 
116
read_char(in)
 
117
object in;
 
118
{
 
119
        return(code_char(readc_stream(in)));
 
120
}
 
121
 
 
122
#define read_char(in)   code_char(readc_stream(in))
 
123
 
 
124
static void
 
125
unread_char(c, in)
 
126
object c, in;
 
127
{
 
128
        if (type_of(c) != t_character)
 
129
                FEwrong_type_argument(sLcharacter, c);
 
130
        unreadc_stream(char_code(c), in);
 
131
}
 
132
 
 
133
/*
 
134
        Peek_char corresponds to COMMON Lisp function PEEK-CHAR.
 
135
        When pt is TRUE, preceeding whitespaces are ignored.
 
136
*/
 
137
object
 
138
peek_char(pt, in)
 
139
bool pt;
 
140
object in;
 
141
{
 
142
        object c;
 
143
 
 
144
        if (pt) {
 
145
                do
 
146
                        c = read_char(in);
 
147
                while (cat(c) == cat_whitespace);
 
148
                unread_char(c, in);
 
149
                return(c);
 
150
        } else {
 
151
                c = read_char(in);
 
152
                unread_char(c, in);
 
153
                return(c);
 
154
        }
 
155
}
 
156
                
 
157
 
 
158
static object
 
159
read_object_recursive(in)
 
160
object in;
 
161
{
 
162
        VOL object x;
 
163
        bool e;
 
164
 
 
165
        object old_READtable = READtable;
 
166
        int old_READdefault_float_format = READdefault_float_format;
 
167
        int old_READbase = READbase;
 
168
        bool old_READsuppress = READsuppress;
 
169
 
 
170
        /* BUG FIX by Toshiba */
 
171
        vs_push(old_READtable);
 
172
 
 
173
        frs_push(FRS_PROTECT, Cnil);
 
174
        if (nlj_active) {
 
175
                e = TRUE;
 
176
                goto L;
 
177
        }
 
178
 
 
179
        READtable = current_readtable();
 
180
        x = symbol_value(sLAread_default_float_formatA);
 
181
        if (x == sLshort_float)
 
182
                READdefault_float_format = 'S';
 
183
        else if (x == sLsingle_float || x == sLdouble_float || x == sLlong_float)
 
184
                READdefault_float_format = 'F';
 
185
        else {
 
186
                vs_push(x);
 
187
                sLAread_default_float_formatA->s.s_dbind = sLsingle_float;
 
188
        FEerror("The value of *READ-DEFAULT-FLOAT-FORMAT*, ~S, was illegal.",
 
189
                        1, x);
 
190
        }
 
191
        x = symbol_value(sLAread_baseA);
 
192
        if (type_of(x) != t_fixnum || fix(x) < 2 || fix(x) > 36) {
 
193
                vs_push(x);
 
194
                sLAread_baseA->s.s_dbind = make_fixnum(10);
 
195
                FEerror("The value of *READ-BASE*, ~S, was illegal.", 1, x);
 
196
        }
 
197
        READbase = fix(x);
 
198
        READsuppress = symbol_value(sLAread_suppressA) != Cnil;
 
199
 
 
200
        x = read_object(in);
 
201
        e = FALSE;
 
202
 
 
203
L:
 
204
        frs_pop();
 
205
 
 
206
        READtable = old_READtable;
 
207
        READdefault_float_format = old_READdefault_float_format;
 
208
        READbase = old_READbase;
 
209
        READsuppress = old_READsuppress;
 
210
 
 
211
        /* BUG FIX by Toshiba */
 
212
        vs_popp;
 
213
 
 
214
        if (e) {
 
215
                nlj_active = FALSE;
 
216
                unwind(nlj_fr, nlj_tag);
 
217
        }
 
218
 
 
219
        return(x);
 
220
}
 
221
 
 
222
 
 
223
object
 
224
read_object_non_recursive(in)
 
225
object in;
 
226
{
 
227
        VOL object x;
 
228
        int i;
 
229
        bool e;
 
230
        object old_READtable;
 
231
        int old_READdefault_float_format;
 
232
        int old_READbase;
 
233
        int old_READsuppress;
 
234
        int old_sharp_eq_context_max;
 
235
        struct sharp_eq_context_struct
 
236
                old_sharp_eq_context[SHARP_EQ_CONTEXT_SIZE];
 
237
        int old_backq_level;
 
238
 
 
239
        old_READtable = READtable;
 
240
        old_READdefault_float_format = READdefault_float_format;
 
241
        old_READbase = READbase;
 
242
        old_READsuppress = READsuppress;
 
243
        old_sharp_eq_context_max = sharp_eq_context_max;
 
244
        /* BUG FIX by Toshiba */
 
245
        vs_push(old_READtable);
 
246
        for (i = 0;  i < sharp_eq_context_max;  i++)
 
247
                old_sharp_eq_context[i] = sharp_eq_context[i];
 
248
        old_backq_level = backq_level;
 
249
        setup_READ();
 
250
 
 
251
        frs_push(FRS_PROTECT, Cnil);
 
252
        if (nlj_active) {
 
253
                e = TRUE;
 
254
                goto L;
 
255
        }
 
256
 
 
257
        x = read_object(in);
 
258
        vs_push(x);
 
259
 
 
260
        if (sharp_eq_context_max > 0)
 
261
                x = vs_head = patch_sharp(x);
 
262
 
 
263
        e = FALSE;
 
264
 
 
265
L:
 
266
        frs_pop();
 
267
 
 
268
        READtable = old_READtable;
 
269
        READdefault_float_format = old_READdefault_float_format;
 
270
        READbase = old_READbase;
 
271
        READsuppress = old_READsuppress;
 
272
        sharp_eq_context_max = old_sharp_eq_context_max;
 
273
        for (i = 0;  i < sharp_eq_context_max;  i++)
 
274
                sharp_eq_context[i] = old_sharp_eq_context[i];
 
275
        backq_level = old_backq_level;
 
276
        if (e) {
 
277
                nlj_active = FALSE;
 
278
                unwind(nlj_fr, nlj_tag);
 
279
        }
 
280
        vs_popp;
 
281
        /* BUG FIX by Toshiba */
 
282
        vs_popp;
 
283
        return(x);
 
284
}
 
285
 
 
286
/* static object
 
287
standard_read_object_non_recursive(in)
 
288
object in;
 
289
{
 
290
        VOL object x;
 
291
        int i;
 
292
        bool e;
 
293
        object old_READtable;
 
294
        int old_READdefault_float_format;
 
295
        int old_READbase;
 
296
        int old_READsuppress;
 
297
        int old_sharp_eq_context_max;
 
298
        struct sharp_eq_context_struct
 
299
                old_sharp_eq_context[SHARP_EQ_CONTEXT_SIZE];
 
300
        int old_backq_level;
 
301
 
 
302
        old_READtable = READtable;
 
303
        old_READdefault_float_format = READdefault_float_format;
 
304
        old_READbase = READbase;
 
305
        old_READsuppress = READsuppress;
 
306
        old_sharp_eq_context_max = sharp_eq_context_max;
 
307
        BUG FIX by Toshiba
 
308
        vs_push(old_READtable);
 
309
        for (i = 0;  i < sharp_eq_context_max;  i++)
 
310
                old_sharp_eq_context[i] = sharp_eq_context[i];
 
311
        old_backq_level = backq_level;
 
312
 
 
313
        setup_standard_READ();
 
314
 
 
315
        frs_push(FRS_PROTECT, Cnil);
 
316
        if (nlj_active) {
 
317
                e = TRUE;
 
318
                goto L;
 
319
        }
 
320
 
 
321
        x = read_object(in);
 
322
        vs_push(x);
 
323
 
 
324
        if (sharp_eq_context_max > 0)
 
325
                x = vs_head = patch_sharp(x);
 
326
 
 
327
        e = FALSE;
 
328
 
 
329
L:
 
330
        frs_pop();
 
331
 
 
332
        READtable = old_READtable;
 
333
        READdefault_float_format = old_READdefault_float_format;
 
334
        READbase = old_READbase;
 
335
        READsuppress = old_READsuppress;
 
336
        sharp_eq_context_max = old_sharp_eq_context_max;
 
337
        for (i = 0;  i < sharp_eq_context_max;  i++)
 
338
                sharp_eq_context[i] = old_sharp_eq_context[i];
 
339
        backq_level = old_backq_level;
 
340
        if (e) {
 
341
                nlj_active = FALSE;
 
342
                unwind(nlj_fr, nlj_tag);
 
343
        }
 
344
        vs_popp;
 
345
        BUG FIX by Toshiba
 
346
        vs_popp;
 
347
        return(x);
 
348
}*/
 
349
#ifdef UNIX  /* faster code for inner loop from file stream */
 
350
#define xxxread_char_to(res,in,eof_code) \
 
351
  do{FILE *fp; \
 
352
      if(fp=in->sm.sm_fp) \
 
353
        {int ch = getc(fp); \
 
354
      if (ch==EOF) { \
 
355
        if (feof(fp)) { eof_code;} \
 
356
          else if (in->sm.sm_mode==smm_socket) \
 
357
             {  ch = getOneChar(fp); \
 
358
               if (ch==EOF) { eof_code;}}} \
 
359
       else res=code_char(ch);} \
 
360
      else \
 
361
        { if (stream_at_end(in)) \
 
362
            {eof_code;} \
 
363
        else res=read_char(in);}} while(0)
 
364
 
 
365
#define read_char_to(res,in,eof_code) \
 
366
  do{FILE *fp; \
 
367
      if((fp=in->sm.sm_fp)) \
 
368
        {int ch = getc(fp); \
 
369
      if (ch==EOF && feof(fp))  \
 
370
         { eof_code;} \
 
371
       else res=code_char(ch);} \
 
372
      else \
 
373
        {int ch ; \
 
374
        if(stream_at_end(in)) {eof_code ;} \
 
375
        ch = readc_stream(in); \
 
376
         if (ch == EOF) { eof_code;} \
 
377
         res = code_char(ch); \
 
378
          }} while(0)
 
379
#else
 
380
#define read_char_to(res,in,eof_code) \
 
381
 do {if(stream_at_end(in)) {eof_code ;} \
 
382
  else { int ch = readc_stream(in); \
 
383
         if (ch == EOF) { eof_code;} \
 
384
         res = code_char(ch); \
 
385
          } \
 
386
   } while(0)
 
387
#endif
 
388
 
 
389
static void
 
390
too_long_token(void);
 
391
/*
 
392
        Read_object(in) reads an object from stream in.
 
393
        This routine corresponds to COMMON Lisp function READ.
 
394
*/
 
395
 
 
396
/* FIXME What should this be? Apparently no reliable way to use value stack */ 
 
397
#define MAX_PACKAGE_STACK 1024
 
398
static object P0[MAX_PACKAGE_STACK],*PP0=P0,LP;
 
399
 
 
400
object
 
401
read_object(in)
 
402
object in;
 
403
{
 
404
        object x;
 
405
        object c=Cnil;
 
406
        enum chattrib a;
 
407
        object *old_vs_base;
 
408
        object result;
 
409
        object p;
 
410
        int  colon=0, colon_type;
 
411
        int i;
 
412
        bool df, ilf;
 
413
        VOL int length;
 
414
        vs_mark;
 
415
 
 
416
        cs_check(in);
 
417
 
 
418
        vs_check_push(delimiting_char);
 
419
        delimiting_char = OBJNULL;
 
420
        df = detect_eos_flag;
 
421
        detect_eos_flag = FALSE;
 
422
        ilf = in_list_flag;
 
423
        in_list_flag = FALSE;
 
424
        dot_flag = FALSE;
 
425
 
 
426
BEGIN:
 
427
        do { read_char_to(c,in, {
 
428
          if (df) {
 
429
            vs_reset;
 
430
            return(OBJNULL);
 
431
          } else
 
432
            end_of_stream(in);
 
433
        });
 
434
                a = cat(c);
 
435
        } while (a == cat_whitespace);
 
436
        if (c->ch.ch_code == '(') { /* Loose package extension */
 
437
          LP=LP || PP0==P0 ? LP : PP0[-1]; /* push loose packages into nested lists */
 
438
          if (LP) {
 
439
            if (PP0-P0>=MAX_PACKAGE_STACK)
 
440
              FEerror("Too many nested package specifiers",0);
 
441
            *PP0++=LP;
 
442
            LP=NULL;
 
443
          }
 
444
        } else if (LP)
 
445
            FEerror("Loose package prefix must be followed by a list",0);
 
446
        if (c->ch.ch_code==')' && PP0>P0) PP0--; /* regardless of error behavior, 
 
447
                                                    will pop stack to beginning as parens
 
448
                                                    must match before the reader starts */
 
449
        delimiting_char = vs_head;
 
450
        if (delimiting_char != OBJNULL && c == delimiting_char) {
 
451
                delimiting_char = OBJNULL;
 
452
                vs_reset;
 
453
                return(OBJNULL);
 
454
        }
 
455
        delimiting_char = OBJNULL;
 
456
        if (a == cat_terminating || a == cat_non_terminating)
 
457
        {
 
458
                object *fun_box = vs_top;
 
459
 
 
460
                old_vs_base = vs_base;
 
461
                vs_push(Cnil);
 
462
                vs_base = vs_top;
 
463
                vs_push(in);
 
464
                vs_push(c);
 
465
 
 
466
                x =
 
467
                READtable->rt.rt_self[char_code(c)].rte_macro;
 
468
                fun_box[0] = x;
 
469
                super_funcall(x);
 
470
 
 
471
                i = vs_top - vs_base;
 
472
                if (i == 0) {
 
473
                        vs_base = old_vs_base;
 
474
                        vs_top = old_vs_top + 1;
 
475
                        goto BEGIN;
 
476
                }
 
477
                if (i > 1) {
 
478
                        vs_push(make_fixnum(i));
 
479
                        FEerror("The readmacro ~S returned ~D values.",
 
480
                                 2, fun_box[0], vs_top[-1]);
 
481
                }
 
482
                result = vs_base[0];
 
483
                vs_base = old_vs_base;
 
484
                vs_reset;
 
485
                return(result);
 
486
        }
 
487
        escape_flag = FALSE;
 
488
        length = 0; tok_leng=0;
 
489
        colon_type = 0;
 
490
        goto L;
 
491
        for (;;) {
 
492
                if (length >= token->st.st_dim)
 
493
                        too_long_token();
 
494
                token_buffer[(tok_leng++,length++)] = char_code(c);
 
495
        K:
 
496
                read_char_to(c,in,goto M);
 
497
                a = cat(c);
 
498
        L:
 
499
                if (a == cat_single_escape) {
 
500
                        c = read_char(in);
 
501
                        a = cat_constituent;
 
502
                        escape_flag = TRUE;
 
503
                } else if (a == cat_multiple_escape) {
 
504
                        escape_flag = TRUE;
 
505
                        for (;;) {
 
506
                                if (stream_at_end(in))
 
507
                                        end_of_stream(in);
 
508
                                c = read_char(in);
 
509
                                a = cat(c);
 
510
                                if (a == cat_single_escape) {
 
511
                                        c = read_char(in);
 
512
                                        a = cat_constituent;
 
513
                                } else if (a == cat_multiple_escape)
 
514
                                        break;
 
515
                                if (length >= token->st.st_dim)
 
516
                                        too_long_token();
 
517
                                token_buffer[(tok_leng++,length++)] = char_code(c);
 
518
                        }
 
519
                        goto K;
 
520
                } else if (a == cat_terminating) {
 
521
                        break;
 
522
                } else if (a == cat_whitespace) {
 
523
                  /* skip all whitespace after trailing colon if no escape seen */
 
524
                  if (colon+colon_type==length && !escape_flag)
 
525
                    goto K;
 
526
                  else
 
527
                    break;
 
528
                }
 
529
                else if ('a' <= char_code(c) && char_code(c) <= 'z')
 
530
                        c = code_char(char_code(c) - ('a' - 'A'));
 
531
                else if (char_code(c) == ':') {
 
532
                        if (colon_type == 0) {
 
533
                                colon_type = 1;
 
534
                                colon = length;
 
535
                        } else if (colon_type == 1 && colon == length-1)
 
536
                                colon_type = 2;
 
537
                        else
 
538
                                colon_type = -1;
 
539
                                /*  Colon has appeared twice.  */
 
540
                }
 
541
        }
 
542
        if (preserving_whitespace_flag || cat(c) != cat_whitespace)
 
543
                unread_char(c, in);
 
544
 
 
545
M:
 
546
        if (READsuppress) {
 
547
                token->st.st_fillp = length;
 
548
                vs_reset;
 
549
                return(Cnil);
 
550
        }
 
551
        if (ilf && !escape_flag &&
 
552
            length == 1 && token->st.st_self[0] == '.') {
 
553
                dot_flag = TRUE;
 
554
                vs_reset;
 
555
                return(Cnil);
 
556
        } else if (!escape_flag && length > 0) {
 
557
                for (i = 0;  i < length;  i++)
 
558
                        if (token->st.st_self[i] != '.')
 
559
                                goto N;
 
560
                FEerror("Dots appeared illegally.", 0);
 
561
        }
 
562
 
 
563
N:
 
564
        token->st.st_fillp = length;
 
565
        if (escape_flag || (READbase<=10 && token_buffer[0]>'9'))
 
566
                goto SYMBOL;
 
567
        x = parse_number(token_buffer, length, &i, READbase);
 
568
        if (x != OBJNULL && length == i) {
 
569
                vs_reset;
 
570
                return(x);
 
571
        }
 
572
 
 
573
SYMBOL:
 
574
        if (colon_type == 1 /* && length > colon + 1 */) {
 
575
                if (colon == 0)
 
576
                        p = keyword_package;
 
577
                else {
 
578
                        token->st.st_fillp = colon;
 
579
                        p = find_package(token);
 
580
                        if (p == Cnil) {
 
581
                            vs_push(copy_simple_string(token));
 
582
                            FEerror("There is no package with the name ~A.",
 
583
                                    1, vs_head);
 
584
                        }
 
585
                }
 
586
                for (i = colon + 1;  i < length;  i++)
 
587
                        token_buffer[i - (colon + 1)]
 
588
                        = token_buffer[i];
 
589
                token->st.st_fillp = length - (colon + 1);
 
590
                if (colon > 0) {
 
591
                        x = find_symbol(token, p);
 
592
                        if (intern_flag != EXTERNAL) {
 
593
                                vs_push(copy_simple_string(token));
 
594
                        FEerror("Cannot find the external symbol ~A in ~S.",
 
595
                                                2, vs_head, p);
 
596
                                /*  no need to push a package  */
 
597
                        }
 
598
                        vs_reset;
 
599
                        return(x);
 
600
                }
 
601
        } else if (colon_type == 2 /* && colon > 0 && length > colon + 2 */) {
 
602
                token->st.st_fillp = colon;
 
603
                p = find_package(token);
 
604
                if (p == Cnil) {
 
605
                        vs_push(copy_simple_string(token));
 
606
                        FEerror("There is no package with the name ~A.",
 
607
                                1, vs_head);
 
608
                }
 
609
                for (i = colon + 2;  i < length;  i++)
 
610
                        token_buffer[i - (colon + 2)]
 
611
                        = token_buffer[i];
 
612
                token->st.st_fillp = length - (colon + 2);
 
613
        } else
 
614
                p = current_package();
 
615
        /* loose package is an empty token following a non-beginning 
 
616
           colon with no escape, to allow for ||*/
 
617
        if (!token->st.st_fillp && colon && !escape_flag) {
 
618
          LP=p;
 
619
          goto BEGIN;
 
620
        }
 
621
        /* unless package specified for this symbol, use loose package if present */
 
622
        if (PP0>P0 && !colon_type)
 
623
          p=PP0[-1];
 
624
        vs_push(p);
 
625
        x = intern(token, p);
 
626
        vs_push(x);
 
627
        if (x->s.s_self == token_buffer) {
 
628
                {BEGIN_NO_INTERRUPT;
 
629
                x->s.s_self = alloc_relblock(token->st.st_fillp);
 
630
                for (i = 0;  i < token->st.st_fillp;  i++)
 
631
                        x->s.s_self[i] = token_buffer[i];
 
632
                END_NO_INTERRUPT;}
 
633
        }
 
634
        vs_reset;
 
635
        return(x);
 
636
}
 
637
 
 
638
static void
 
639
Lleft_parenthesis_reader()
 
640
{
 
641
        object in, c, x;
 
642
        object *p;
 
643
 
 
644
        check_arg(2);
 
645
        in = vs_base[0];
 
646
        vs_head = Cnil;
 
647
        p = &vs_head;
 
648
        for (;;) {
 
649
                delimiting_char = code_char(')');
 
650
                in_list_flag = TRUE;
 
651
                x = read_object(in);
 
652
                if (x == OBJNULL)
 
653
                        goto ENDUP;
 
654
                if (dot_flag) {
 
655
                        if (p == &vs_head)
 
656
        FEerror("A dot appeared after a left parenthesis.", 0);
 
657
                        in_list_flag = TRUE;
 
658
                        *p = read_object(in);
 
659
                        if (dot_flag)
 
660
        FEerror("Two dots appeared consecutively.", 0);
 
661
                        c = read_char(in);
 
662
                        while (cat(c) == cat_whitespace)
 
663
                                c = read_char(in);
 
664
                        if (char_code(c) != ')')
 
665
        FEerror("A dot appeared before a right parenthesis.", 0);
 
666
                        else if (PP0>P0) PP0--; /* should be the only other place
 
667
                                                   outside of read_object where
 
668
                                                   closing parens are read */
 
669
                        goto ENDUP;
 
670
                }
 
671
                vs_push(x);
 
672
                *p = make_cons(x, Cnil);
 
673
                vs_popp;
 
674
                p = &((*p)->c.c_cdr);
 
675
        }
 
676
 
 
677
ENDUP:
 
678
        vs_base[0] = vs_pop;
 
679
        return;
 
680
}
 
681
 
 
682
#define is_exponent_marker(i)   \
 
683
        ((i) == 'e' || (i) == 'E' ||    \
 
684
         (i) == 's' || (i) == 'S' || (i) == 'f' || (i) == 'F' || \
 
685
         (i) == 'd' || (i) == 'D' || (i) == 'l' || (i) == 'L' || \
 
686
         (i) == 'b' || (i) == 'B')
 
687
 
 
688
double pow();
 
689
/*
 
690
        Parse_number(s, end, ep, radix) parses C string s
 
691
        up to (but not including) s[end]
 
692
        using radix as the radix for the rational number.
 
693
        (For floating numbers, radix should be 10.)
 
694
        When parsing has been succeeded,
 
695
        the index of the next character is assigned to *ep,
 
696
        and the number is returned as a lisp data object.
 
697
        If not, OBJNULL is returned.
 
698
*/
 
699
static object
 
700
parse_number(s, end, ep, radix)
 
701
char *s;
 
702
int end, *ep, radix;
 
703
{
 
704
        object x=Cnil;
 
705
        fixnum sign;
 
706
        object integer_part;
 
707
        double fraction, fraction_unit, f;
 
708
        char exponent_marker;
 
709
        int exponent;
 
710
        int i, j, k;
 
711
        int d;
 
712
        vs_mark;
 
713
 
 
714
        if (s[end-1] == '.')
 
715
                radix = 10;
 
716
                /*
 
717
                        DIRTY CODE!!
 
718
                */
 
719
BEGIN:
 
720
        exponent_marker = 'E';
 
721
        i = 0;
 
722
        sign = 1;
 
723
        if (s[i] == '+')
 
724
                i++;
 
725
        else if (s[i] == '-') {
 
726
                sign = -1;
 
727
                i++;
 
728
        }
 
729
        integer_part = (object)  big_register_0;
 
730
        zero_big(big_register_0);
 
731
        vs_push((object)integer_part);
 
732
        if (i >= end)
 
733
                goto NO_NUMBER;
 
734
        if (s[i] == '.') {
 
735
                if (radix != 10) {
 
736
                        radix = 10;
 
737
                        goto BEGIN;
 
738
                }
 
739
                i++;
 
740
                goto FRACTION;
 
741
        }
 
742
        if ((d = digitp(s[i], radix)) < 0)
 
743
                goto NO_NUMBER;
 
744
#define MOST_POSITIVE_FIX (((unsigned int) (~0) ) /2)
 
745
#define TEN_EXPT_9 1000000000
 
746
 
 
747
      if (radix == 10 && TEN_EXPT_9 <MOST_POSITIVE_FIX ) {
 
748
        int chunk = 0;
 
749
        int sum = 0;
 
750
        do {    sum = 10*sum+d;
 
751
                chunk++;
 
752
                if (chunk == 9) {
 
753
                mul_int_big(1000000000, integer_part);
 
754
                add_int_big(sum, integer_part);
 
755
                chunk=0; sum=0;
 
756
            } 
 
757
             i++;
 
758
        } while (i < end && (d = digitp(s[i], radix)) >= 0);
 
759
        if (chunk) {
 
760
          int fac=10;
 
761
          while(--chunk> 0) {fac *=10;}
 
762
          mul_int_big(fac,integer_part);
 
763
          add_int_big(sum,integer_part);
 
764
        }
 
765
 
 
766
    } else {
 
767
                
 
768
        
 
769
        do {
 
770
                mul_int_big(radix, integer_part);
 
771
                add_int_big(d, integer_part);
 
772
                i++;
 
773
        } while (i < end && (d = digitp(s[i], radix)) >= 0);
 
774
     }
 
775
 
 
776
 
 
777
        if (i >= end)
 
778
                goto MAKE_INTEGER;
 
779
        if (s[i] == '.') {
 
780
                if (radix != 10) {
 
781
                        radix = 10;
 
782
                        goto BEGIN;
 
783
                }
 
784
                if (++i >= end)
 
785
                        goto MAKE_INTEGER;
 
786
                else if (digitp(s[i], radix) >= 0)
 
787
                        goto FRACTION;
 
788
                else if (is_exponent_marker(s[i])) {
 
789
                        fraction
 
790
                        = (double)sign * big_to_double(integer_part);
 
791
                        goto EXPONENT;
 
792
                } else
 
793
                        goto MAKE_INTEGER;
 
794
        }
 
795
        if (s[i] == '/') {
 
796
                i++;
 
797
                goto DENOMINATOR;
 
798
        }
 
799
        if (is_exponent_marker(s[i])) {
 
800
                fraction = (double)sign * big_to_double(integer_part);
 
801
                goto EXPONENT;
 
802
        }
 
803
/*
 
804
        goto NO_NUMBER;
 
805
*/
 
806
 
 
807
MAKE_INTEGER:
 
808
        if (sign < 0 && signe(MP(integer_part)))
 
809
                set_big_sign(integer_part,-1);
 
810
        x = normalize_big_to_object(integer_part);
 
811
/**/
 
812
        if (x == big_register_0)
 
813
                big_register_0 = alloc_object(t_bignum);
 
814
        zero_big(big_register_0);
 
815
 
 
816
/**/
 
817
        goto END;
 
818
 
 
819
FRACTION:
 
820
/*
 
821
        if (radix != 10)
 
822
                goto NO_NUMBER;
 
823
*/
 
824
        radix = 10;
 
825
        if ((d = digitp(s[i], radix)) < 0)
 
826
                goto NO_NUMBER;
 
827
        fraction = 0.0;
 
828
        fraction_unit = 1000000000.0;
 
829
        for (;;) {
 
830
                k = j = 0;
 
831
                do {
 
832
                        j = 10*j + d;
 
833
                        i++;
 
834
                        k++;
 
835
                        if (i < end)
 
836
                                d = digitp(s[i], radix);
 
837
                        else
 
838
                                break;
 
839
                } while (k < 9 && d >= 0);
 
840
                while (k++ < 9)
 
841
                        j *= 10;
 
842
                fraction += ((double)j /fraction_unit);
 
843
                if (i >= end || d < 0)
 
844
                        break;
 
845
                fraction_unit *= 1000000000.0;
 
846
        }
 
847
        fraction += big_to_double(integer_part);
 
848
        fraction *= (double)sign;
 
849
        if (i >= end)
 
850
                goto MAKE_FLOAT;
 
851
        if (is_exponent_marker(s[i]))
 
852
                goto EXPONENT;
 
853
        goto MAKE_FLOAT;
 
854
 
 
855
EXPONENT:
 
856
/*
 
857
        if (radix != 10)
 
858
                goto NO_NUMBER;
 
859
*/
 
860
        radix = 10;
 
861
        exponent_marker = s[i];
 
862
        i++;
 
863
        if (i >= end)
 
864
                goto NO_NUMBER;
 
865
        sign = 1;
 
866
        if (s[i] == '+')
 
867
                i++;
 
868
        else if (s[i] == '-') {
 
869
                sign = -1;
 
870
                i++;
 
871
        }
 
872
        if (i >= end)
 
873
                goto NO_NUMBER;
 
874
        if ((d = digitp(s[i], radix)) < 0)
 
875
                goto NO_NUMBER;
 
876
        exponent = 0;
 
877
        do {
 
878
                exponent = 10 * exponent + d;
 
879
                i++;
 
880
        } while (i < end && (d = digitp(s[i], radix)) >= 0);
 
881
        d = exponent;
 
882
        f = 10.0;
 
883
        /* Use pow because it is more accurate */
 
884
        { double po = pow(10.0,(double)(sign * d));
 
885
          if (po == 0.0)
 
886
            { fraction = fraction *pow(10.0,(double)(sign * (d-1)));
 
887
               fraction /= 10.0;}  
 
888
          else     
 
889
        fraction = fraction * po;}
 
890
 
 
891
MAKE_FLOAT:
 
892
#ifdef IEEEFLOAT
 
893
/*      if ((*((int *)&fraction +HIND) & 0x7ff00000) == 0x7ff00000)*/
 
894
        if (!ISFINITE(fraction))
 
895
                FEerror("Floating-point overflow.", 0);
 
896
#endif
 
897
        switch (exponent_marker) {
 
898
 
 
899
        case 'e':  case 'E':
 
900
                exponent_marker = READdefault_float_format;
 
901
                goto MAKE_FLOAT;
 
902
 
 
903
        case 's':  case 'S':
 
904
                x = make_shortfloat((shortfloat)fraction);
 
905
                break;
 
906
 
 
907
        case 'f':  case 'F':  case 'd':  case 'D':  case 'l':  case 'L':
 
908
                x = make_longfloat((longfloat)fraction);
 
909
                break;
 
910
 
 
911
        case 'b':  case 'B':
 
912
                goto NO_NUMBER;
 
913
        }
 
914
/**/
 
915
        zero_big(big_register_0);
 
916
 
 
917
 
 
918
/**/
 
919
        goto END;
 
920
 
 
921
DENOMINATOR:
 
922
        if (sign < 0)
 
923
                set_big_sign(integer_part,-1);
 
924
        vs_push(normalize_big_to_object(integer_part));
 
925
/**/
 
926
        if (vs_head == big_register_0)
 
927
                big_register_0 = new_bignum();
 
928
        zero_big(big_register_0);
 
929
 
 
930
/**/
 
931
        if ((d = digitp(s[i], radix)) < 0)
 
932
                goto NO_NUMBER;
 
933
        integer_part = big_register_0;
 
934
        /*      zero_big(integer_part); */
 
935
        do {
 
936
                mul_int_big(radix, integer_part);
 
937
                add_int_big(d, integer_part);
 
938
                i++;
 
939
        } while (i < end && (d = digitp(s[i], radix)) >= 0);
 
940
        vs_push(normalize_big_to_object(integer_part));
 
941
        x = make_ratio(vs_top[-2], vs_top[-1]);
 
942
        goto END;
 
943
 
 
944
END:
 
945
        *ep = i;
 
946
        vs_reset;
 
947
        return(x);
 
948
 
 
949
NO_NUMBER:
 
950
        *ep = i;
 
951
        vs_reset;
 
952
/**/
 
953
        zero_big(big_register_0);
 
954
 
 
955
 
 
956
 /**/
 
957
        return(OBJNULL);
 
958
}
 
959
 
 
960
static object
 
961
parse_integer(s, end, ep, radix)
 
962
char *s;
 
963
int end, *ep, radix;
 
964
{
 
965
        object x;
 
966
        fixnum sign;
 
967
        object integer_part;
 
968
        int i, d;
 
969
        vs_mark;
 
970
 
 
971
        i = 0;
 
972
        sign = 1;
 
973
        if (s[i] == '+')
 
974
                i++;
 
975
        else if (s[i] == '-') {
 
976
                sign = -1;
 
977
                i++;
 
978
        }
 
979
        integer_part = big_register_0;
 
980
        vs_push((object)integer_part);
 
981
        if (i >= end)
 
982
                goto NO_NUMBER;
 
983
        if ((d = digitp(s[i], radix)) < 0)
 
984
                goto NO_NUMBER;
 
985
        
 
986
        do {
 
987
                mul_int_big(radix, integer_part);
 
988
                add_int_big(d, integer_part);
 
989
                i++;
 
990
        } while (i < end && (d = digitp(s[i], radix)) >= 0);
 
991
 
 
992
 
 
993
        if (sign < 0)
 
994
                set_big_sign(integer_part,-1);
 
995
        x = normalize_big_to_object(integer_part);
 
996
/**/
 
997
        if (x == big_register_0)
 
998
                big_register_0 = alloc_object(t_bignum);
 
999
        zero_big(big_register_0);
 
1000
        
 
1001
/**/
 
1002
        *ep = i;
 
1003
        vs_reset;
 
1004
        return(x);
 
1005
 
 
1006
NO_NUMBER:
 
1007
        *ep = i;
 
1008
        vs_reset;
 
1009
/**/
 
1010
        zero_big(big_register_0);
 
1011
/**/
 
1012
        return(OBJNULL);
 
1013
}
 
1014
 
 
1015
 
 
1016
static void
 
1017
too_long_string(void);
 
1018
 
 
1019
/*
 
1020
        Read_string(delim, in) reads
 
1021
        a simple string terminated by character code delim
 
1022
        and places it in token.
 
1023
        Delim is not included in the string but discarded.
 
1024
*/
 
1025
static void
 
1026
read_string(delim, in)
 
1027
int delim;
 
1028
object in;
 
1029
{
 
1030
        int i;
 
1031
        object c;
 
1032
 
 
1033
        i = 0;
 
1034
        for (;;) {
 
1035
                c = read_char(in);
 
1036
                if (char_code(c) == delim)
 
1037
                        break;
 
1038
                else if (cat(c) == cat_single_escape)
 
1039
                        c = read_char(in);
 
1040
                if (i >= token->st.st_dim)
 
1041
                        too_long_string();
 
1042
                token_buffer[i++] = char_code(c);
 
1043
        }
 
1044
        token->st.st_fillp = i;
 
1045
}
 
1046
 
 
1047
/*
 
1048
        Read_constituent(in) reads
 
1049
        a sequence of constituent characters from stream in
 
1050
        and places it in token_buffer.
 
1051
*/
 
1052
static void
 
1053
read_constituent(in)
 
1054
object in;
 
1055
{
 
1056
        int i, j;
 
1057
        object c;
 
1058
 
 
1059
        i = 0;
 
1060
        for (;;) {
 
1061
                read_char_to(c,in,goto FIN);
 
1062
                if (cat(c) != cat_constituent) {
 
1063
                        unread_char(c, in);
 
1064
                        break;
 
1065
                }
 
1066
                j = char_code(c);
 
1067
                token_buffer[i++] = j;
 
1068
        }
 
1069
      FIN:
 
1070
        token->st.st_fillp = i;
 
1071
        
 
1072
}
 
1073
 
 
1074
static void
 
1075
Ldouble_quote_reader()
 
1076
{
 
1077
        check_arg(2);
 
1078
        vs_popp;
 
1079
        read_string('"', vs_base[0]);
 
1080
        vs_base[0] = copy_simple_string(token);
 
1081
}
 
1082
 
 
1083
static void
 
1084
Ldispatch_reader()
 
1085
{
 
1086
        object c, x;
 
1087
        int i, d;
 
1088
        object in;
 
1089
 
 
1090
        check_arg(2);
 
1091
        
 
1092
        in = vs_base[0];
 
1093
        c = vs_base[1];
 
1094
 
 
1095
        if (READtable->rt.rt_self[char_code(c)].rte_dtab == NULL)
 
1096
                FEerror("~C is not a dispatching macro character", 1, c);
 
1097
 
 
1098
        c = read_char(in);
 
1099
        d = digitp(char_code(c), 10);
 
1100
        if (d >= 0) {
 
1101
                i = 0;
 
1102
                do {
 
1103
                        i = 10*i + d;
 
1104
                        c = read_char(in);
 
1105
                        d = digitp(char_code(c), 10);
 
1106
                } while (d >= 0);
 
1107
                vs_push(make_fixnum(i));
 
1108
        } else
 
1109
                vs_push(Cnil);
 
1110
 
 
1111
        x =
 
1112
        READtable->rt.rt_self[char_code(vs_base[1])].rte_dtab[char_code(c)];
 
1113
        vs_base[1] = c;
 
1114
        super_funcall(x);
 
1115
}
 
1116
 
 
1117
static void
 
1118
Lsingle_quote_reader()
 
1119
{
 
1120
        check_arg(2);
 
1121
        vs_popp;
 
1122
        vs_push(sLquote);
 
1123
        vs_push(read_object(vs_base[0]));
 
1124
        vs_push(Cnil);
 
1125
        stack_cons();
 
1126
        stack_cons();
 
1127
        vs_base[0] = vs_pop;
 
1128
}
 
1129
 
 
1130
static void
 
1131
Lright_parenthesis_reader()
 
1132
{
 
1133
        check_arg(2);
 
1134
        vs_popp;
 
1135
        vs_popp;
 
1136
                /*  no result  */
 
1137
}
 
1138
 
 
1139
/*
 
1140
Lcomma_reader(){}
 
1141
*/
 
1142
 
 
1143
static void
 
1144
Lsemicolon_reader()
 
1145
{
 
1146
        object c;
 
1147
        object str= vs_base[0];
 
1148
        check_arg(2);
 
1149
        vs_popp;
 
1150
        do
 
1151
        { read_char_to(c,str, goto L); }
 
1152
                while (char_code(c) != '\n');
 
1153
L:      
 
1154
        vs_popp;
 
1155
        vs_base[0] = Cnil;
 
1156
        /*  no result  */
 
1157
}
 
1158
 
 
1159
/*
 
1160
Lbackquote_reader(){}
 
1161
*/
 
1162
 
 
1163
/*
 
1164
        sharpmacro routines
 
1165
*/
 
1166
static void
 
1167
extra_argument(int);
 
1168
 
 
1169
static void
 
1170
Lsharp_C_reader()
 
1171
{
 
1172
        object x, c;
 
1173
 
 
1174
        check_arg(3);
 
1175
        if (vs_base[2] != Cnil && !READsuppress)
 
1176
                extra_argument('C');
 
1177
        vs_popp;
 
1178
        vs_popp;
 
1179
        c = read_char(vs_base[0]);
 
1180
        if (char_code(c) != '(')
 
1181
                FEerror("A left parenthesis is expected.", 0);
 
1182
        delimiting_char = code_char(')');
 
1183
        x = read_object(vs_base[0]);
 
1184
        if (x == OBJNULL)
 
1185
                FEerror("No real part.", 0);
 
1186
        vs_push(x);
 
1187
        delimiting_char = code_char(')');
 
1188
        x = read_object(vs_base[0]);
 
1189
        if (x == OBJNULL)
 
1190
                FEerror("No imaginary part.", 0);
 
1191
        vs_push(x);
 
1192
        delimiting_char = code_char(')');
 
1193
        x = read_object(vs_base[0]);
 
1194
        if (x != OBJNULL)
 
1195
                FEerror("A right parenthesis is expected.", 0);
 
1196
        if (READsuppress) vs_base[0]= Cnil ;
 
1197
         else
 
1198
        if (contains_sharp_comma(vs_base[1]) ||
 
1199
            contains_sharp_comma(vs_base[2])) {
 
1200
                vs_base[0] = alloc_object(t_complex);
 
1201
                vs_base[0]->cmp.cmp_real = vs_base[1];
 
1202
                vs_base[0]->cmp.cmp_imag = vs_base[2];
 
1203
        } else {
 
1204
                check_type_number(&vs_base[1]);
 
1205
                check_type_number(&vs_base[2]);
 
1206
                vs_base[0] = make_complex(vs_base[1], vs_base[2]);
 
1207
        }
 
1208
        vs_top = vs_base + 1;
 
1209
}
 
1210
 
 
1211
static void
 
1212
Lsharp_backslash_reader()
 
1213
{
 
1214
        object c;
 
1215
 
 
1216
        check_arg(3);
 
1217
        if (vs_base[2] != Cnil && !READsuppress)
 
1218
                if (type_of(vs_base[2]) != t_fixnum ||
 
1219
                    fix(vs_base[2]) != 0)
 
1220
                        FEerror("~S is an illegal CHAR-FONT.", 1, vs_base[2]);
 
1221
                        /*  assuming that CHAR-FONT-LIMIT is 1  */
 
1222
        vs_popp;
 
1223
        vs_popp;
 
1224
        unread_char(code_char('\\'), vs_base[0]);
 
1225
        if (READsuppress) {
 
1226
                (void)read_object(vs_base[0]);
 
1227
                vs_base[0] = Cnil;
 
1228
                return;
 
1229
        }
 
1230
        READsuppress = TRUE;
 
1231
        (void)read_object(vs_base[0]);
 
1232
        READsuppress = FALSE;
 
1233
        c = token;
 
1234
        if (c->s.s_fillp == 1) {
 
1235
                vs_base[0] = code_char(c->ust.ust_self[0]);
 
1236
                return;
 
1237
        }
 
1238
        if (string_equal(c, STreturn))
 
1239
                vs_base[0] = code_char('\r');
 
1240
        else if (string_equal(c, STspace))
 
1241
                vs_base[0] = code_char(' ');
 
1242
        else if (string_equal(c, STrubout))
 
1243
                vs_base[0] = code_char('\177');
 
1244
        else if (string_equal(c, STpage))
 
1245
                vs_base[0] = code_char('\f');
 
1246
        else if (string_equal(c, STtab))
 
1247
                vs_base[0] = code_char('\t');
 
1248
        else if (string_equal(c, STbackspace))
 
1249
                vs_base[0] = code_char('\b');
 
1250
        else if (string_equal(c, STlinefeed) || string_equal(c, STnewline))
 
1251
                vs_base[0] = code_char('\n');
 
1252
        else if (c->s.s_fillp == 2 && c->s.s_self[0] == '^')
 
1253
                vs_base[0] = code_char(c->s.s_self[1] & 037);
 
1254
        else if (c->s.s_self[0] =='\\' && c->s.s_fillp > 1) {
 
1255
                int i, n;
 
1256
                for (n = 0, i = 1;  i < c->s.s_fillp;  i++)
 
1257
                        if (c->s.s_self[i] < '0' || '7' < c->s.s_self[i])
 
1258
                                FEerror("Octal digit expected.", 0);
 
1259
                        else
 
1260
                                n = 8*n + c->s.s_self[i] - '0';
 
1261
                vs_base[0] = code_char(n & 0377);
 
1262
        } else
 
1263
                FEerror("~S is an illegal character name.", 1, c);
 
1264
}
 
1265
 
 
1266
static void
 
1267
Lsharp_single_quote_reader()
 
1268
{
 
1269
 
 
1270
        check_arg(3);
 
1271
        if(vs_base[2] != Cnil && !READsuppress)
 
1272
                extra_argument('#');
 
1273
        vs_popp;
 
1274
        vs_popp;
 
1275
        vs_push(sLfunction);
 
1276
        vs_push(read_object(vs_base[0]));
 
1277
        vs_push(Cnil);
 
1278
        stack_cons();
 
1279
        stack_cons();
 
1280
        vs_base[0] = vs_pop;
 
1281
}
 
1282
 
 
1283
#define QUOTE   1
 
1284
#define EVAL    2
 
1285
#define LIST    3
 
1286
#define LISTA   4
 
1287
#define APPEND  5
 
1288
#define NCONC   6
 
1289
 
 
1290
object siScomma;
 
1291
 
 
1292
static void
 
1293
Lsharp_left_parenthesis_reader()
 
1294
{
 
1295
 
 
1296
        int dim=0;
 
1297
        int dimcount;
 
1298
        object in, x;
 
1299
        int a;
 
1300
        object *vsp;            
 
1301
 
 
1302
        check_arg(3);
 
1303
        if (vs_base[2] == Cnil || READsuppress)
 
1304
                dim = -1;
 
1305
        else if (type_of(vs_base[2]) == t_fixnum)
 
1306
                dim = fix(vs_base[2]);
 
1307
        vs_popp;
 
1308
        vs_popp;
 
1309
        in = vs_base[0];
 
1310
        if (backq_level > 0) {
 
1311
                unreadc_stream('(', in);
 
1312
                vs_push(read_object(in));
 
1313
                a = backq_car(vs_base[1]);
 
1314
                if (a == APPEND || a == NCONC)
 
1315
                FEerror(",at or ,. has appeared in an illegal position.", 0);
 
1316
                if (a == QUOTE) {
 
1317
                        vsp = vs_top;
 
1318
                        dimcount = 0;
 
1319
                        for (x = vs_base[2];  !endp(x);  x = x->c.c_cdr) {
 
1320
                                vs_check_push(x->c.c_car);
 
1321
                                dimcount++;
 
1322
                        }       
 
1323
                        goto L;
 
1324
                }
 
1325
                vs_push(siScomma);
 
1326
                vs_push(sLapply);
 
1327
                vs_push(sLquote);
 
1328
                vs_push(sLvector);
 
1329
                vs_push(Cnil);
 
1330
                stack_cons();
 
1331
                stack_cons();
 
1332
                vs_push(vs_base[2]);
 
1333
                vs_push(Cnil);
 
1334
                stack_cons();
 
1335
                stack_cons();
 
1336
                stack_cons();
 
1337
                stack_cons();
 
1338
                vs_base = vs_top - 1;
 
1339
                return;
 
1340
        }
 
1341
        vsp = vs_top;
 
1342
        dimcount = 0;
 
1343
        for (;;) {
 
1344
                delimiting_char = code_char(')');
 
1345
                x = read_object(in);
 
1346
                if (x == OBJNULL)
 
1347
                        break;
 
1348
                vs_check_push(x);
 
1349
                dimcount++;
 
1350
        }       
 
1351
L:
 
1352
        if (dim >= 0) {
 
1353
                if (dimcount > dim)
 
1354
                        FEerror("Too many elements in #(...).", 0);
 
1355
                else {
 
1356
                        if (dimcount == 0)
 
1357
                                FEerror("Cannot fill the vector #().", 0);
 
1358
                        x = vs_head;
 
1359
                        for (;  dimcount < dim;  dimcount++)
 
1360
                                vs_push(x);
 
1361
                }
 
1362
        }
 
1363
        {BEGIN_NO_INTERRUPT;
 
1364
        x = alloc_simple_vector(dimcount, aet_object);
 
1365
        vs_push(x);
 
1366
        x->v.v_self
 
1367
        = (object *)alloc_relblock(dimcount * sizeof(object));
 
1368
        vs_popp;
 
1369
        for (dim = 0; dim < dimcount; dim++)
 
1370
                x->v.v_self[dim] = vsp[dim];
 
1371
        vs_top = vs_base;
 
1372
        END_NO_INTERRUPT;}
 
1373
        vs_push(x);
 
1374
}
 
1375
 
 
1376
static void
 
1377
Lsharp_asterisk_reader()
 
1378
{
 
1379
        int dim=0;
 
1380
        int dimcount;
 
1381
        object in, x;
 
1382
        object *vsp;            
 
1383
 
 
1384
        check_arg(3);
 
1385
        if (READsuppress) {
 
1386
                read_constituent(vs_base[0]);
 
1387
                vs_popp;
 
1388
                vs_popp;
 
1389
                vs_base[0] = Cnil;
 
1390
                return;
 
1391
        }
 
1392
        if (vs_head == Cnil)
 
1393
                dim = -1;
 
1394
        else if (type_of(vs_head) == t_fixnum)
 
1395
                dim = fix(vs_head);
 
1396
        vs_popp;
 
1397
        vs_popp;
 
1398
        in = vs_head;
 
1399
        vsp = vs_top;
 
1400
        dimcount = 0;
 
1401
        for (;;) {
 
1402
                if (stream_at_end(in))
 
1403
                        break;
 
1404
                x = read_char(in);
 
1405
                if (char_code(x) != '0' && char_code(x) != '1') {
 
1406
                        unread_char(x, in);
 
1407
                        break;
 
1408
                }
 
1409
                vs_check_push(x);
 
1410
                dimcount++;
 
1411
        }       
 
1412
        if (dim >= 0) {
 
1413
                if (dimcount > dim)
 
1414
                        FEerror("Too many elements in #*....", 0);
 
1415
                else {
 
1416
                        if (dimcount == 0)
 
1417
                                error("Cannot fill the bit-vector #*.");
 
1418
                        x = vs_head;
 
1419
                        for (;  dimcount < dim;  dimcount++)
 
1420
                                vs_push(x);
 
1421
                }
 
1422
        }
 
1423
        {BEGIN_NO_INTERRUPT;
 
1424
        x = alloc_simple_bitvector(dimcount);
 
1425
        vs_push(x);
 
1426
        x->bv.bv_self = alloc_relblock((dimcount + 7)/8);
 
1427
        vs_popp;
 
1428
        for (dim = 0; dim < dimcount; dim++)
 
1429
                if (char_code(vsp[dim]) == '0')
 
1430
                        x->bv.bv_self[dim/8] &= ~(0200 >> dim%8);
 
1431
                else
 
1432
                        x->bv.bv_self[dim/8] |= 0200 >> dim%8;
 
1433
        END_NO_INTERRUPT;}
 
1434
        vs_top = vs_base;
 
1435
        vs_push(x);
 
1436
}
 
1437
 
 
1438
static void
 
1439
Lsharp_colon_reader()
 
1440
{
 
1441
        object in;
 
1442
        int length;
 
1443
        object c;
 
1444
        enum chattrib a;
 
1445
 
 
1446
        if (vs_base[2] != Cnil && !READsuppress)
 
1447
                extra_argument(':');
 
1448
        vs_popp;
 
1449
        vs_popp;
 
1450
        in = vs_base[0];
 
1451
        c = read_char(in);
 
1452
        a = cat(c);
 
1453
        escape_flag = FALSE;
 
1454
        length = 0; tok_leng=0;
 
1455
        goto L;
 
1456
        for (;;) {
 
1457
                if (length >= token->st.st_dim)
 
1458
                        too_long_token();
 
1459
                token_buffer[(tok_leng++,length++)] = char_code(c);
 
1460
        K:
 
1461
                if (stream_at_end(in))
 
1462
                        goto M;
 
1463
                c = read_char(in);
 
1464
                a = cat(c);
 
1465
        L:
 
1466
                if (a == cat_single_escape) {
 
1467
                        c = read_char(in);
 
1468
                        a = cat_constituent;
 
1469
                        escape_flag = TRUE;
 
1470
                } else if (a == cat_multiple_escape) {
 
1471
                        escape_flag = TRUE;
 
1472
                        for (;;) {
 
1473
                                if (stream_at_end(in))
 
1474
                                        end_of_stream(in);
 
1475
                                c = read_char(in);
 
1476
                                a = cat(c);
 
1477
                                if (a == cat_single_escape) {
 
1478
                                        c = read_char(in);
 
1479
                                        a = cat_constituent;
 
1480
                                } else if (a == cat_multiple_escape)
 
1481
                                        break;
 
1482
                                if (length >= token->st.st_dim)
 
1483
                                        too_long_token();
 
1484
                                token_buffer[(tok_leng++,length++)] = char_code(c);
 
1485
                        }
 
1486
                        goto K;
 
1487
                } else if ('a' <= char_code(c) && char_code(c) <= 'z')
 
1488
                        c = code_char(char_code(c) - ('a' - 'A'));
 
1489
                if (a == cat_whitespace || a == cat_terminating)
 
1490
                        break;
 
1491
        }
 
1492
        if (preserving_whitespace_flag || cat(c) != cat_whitespace)
 
1493
                unread_char(c, in);
 
1494
 
 
1495
M:
 
1496
        if (READsuppress) {
 
1497
                vs_base[0] = Cnil;
 
1498
                return;
 
1499
        }
 
1500
        token->st.st_fillp = length;
 
1501
        vs_base[0] = copy_simple_string(token);
 
1502
        vs_base[0] = make_symbol(vs_base[0]);
 
1503
}
 
1504
 
 
1505
static void
 
1506
Lsharp_dot_reader()
 
1507
{
 
1508
        check_arg(3);
 
1509
        if(vs_base[2] != Cnil && !READsuppress)
 
1510
                extra_argument('.');
 
1511
        vs_popp;
 
1512
        vs_popp;
 
1513
        if (READsuppress) {
 
1514
                read_object(vs_base[0]);        
 
1515
                vs_base[0] = Cnil;
 
1516
                return;
 
1517
        }
 
1518
        vs_base[0] = read_object(vs_base[0]);
 
1519
        vs_base[0] = ieval(vs_base[0]);
 
1520
}
 
1521
 
 
1522
static void
 
1523
Lsharp_comma_reader()
 
1524
{
 
1525
        check_arg(3);
 
1526
        if(vs_base[2] != Cnil && !READsuppress)
 
1527
                extra_argument(',');
 
1528
        vs_popp;
 
1529
        vs_popp;
 
1530
        if (READsuppress) {
 
1531
                read_object(vs_base[0]);
 
1532
                vs_base[0] = Cnil;
 
1533
                return;
 
1534
        }
 
1535
        vs_base[0] = read_object(vs_base[0]);
 
1536
        vs_base[0] = ieval(vs_base[0]);
 
1537
}
 
1538
 
 
1539
static void
 
1540
FFN(siLsharp_comma_reader_for_compiler)()
 
1541
{
 
1542
        check_arg(3);
 
1543
        if(vs_base[2] != Cnil && !READsuppress)
 
1544
                extra_argument(',');
 
1545
        vs_popp;
 
1546
        vs_popp;
 
1547
        if (READsuppress) {
 
1548
                vs_base[0] = Cnil;
 
1549
                return;
 
1550
        }
 
1551
        vs_base[0] = read_object(vs_base[0]);
 
1552
        vs_base[0] = make_cons(siSsharp_comma, vs_base[0]);
 
1553
}
 
1554
 
 
1555
/*
 
1556
        For fasload.
 
1557
*/
 
1558
static void
 
1559
Lsharp_exclamation_reader()
 
1560
{
 
1561
        check_arg(3);
 
1562
        if(vs_base[2] != Cnil && !READsuppress)
 
1563
                extra_argument('!');
 
1564
        vs_popp;
 
1565
        vs_popp;
 
1566
        if (READsuppress) {
 
1567
                vs_base[0] = Cnil;
 
1568
                return;
 
1569
        }
 
1570
        vs_base[0] = read_object(vs_base[0]);
 
1571
        if (sharp_eq_context_max > 0)
 
1572
                vs_base[0]=patch_sharp(vs_base[0]);
 
1573
        ieval(vs_base[0]);
 
1574
        vs_popp;
 
1575
}
 
1576
 
 
1577
static void
 
1578
Lsharp_B_reader()
 
1579
{
 
1580
        int i;
 
1581
 
 
1582
        if(vs_base[2] != Cnil && !READsuppress)
 
1583
                extra_argument('B');
 
1584
        vs_popp;
 
1585
        vs_popp;
 
1586
        read_constituent(vs_base[0]);
 
1587
        if (READsuppress) {
 
1588
                vs_base[0] = Cnil;
 
1589
                return;
 
1590
        }
 
1591
        vs_base[0]
 
1592
        = parse_number(token_buffer, token->st.st_fillp, &i, 2);
 
1593
        if (vs_base[0] == OBJNULL || i != token->st.st_fillp)
 
1594
                FEerror("Cannot parse the #B readmacro.", 0);
 
1595
        if (type_of(vs_base[0]) == t_shortfloat ||
 
1596
            type_of(vs_base[0]) == t_longfloat)
 
1597
                FEerror("The float ~S appeared after the #B readmacro.",
 
1598
                        1, vs_base[0]);
 
1599
}
 
1600
 
 
1601
static void
 
1602
Lsharp_O_reader()
 
1603
{
 
1604
        int i;
 
1605
 
 
1606
        if(vs_base[2] != Cnil && !READsuppress)
 
1607
                extra_argument('O');
 
1608
        vs_popp;
 
1609
        vs_popp;
 
1610
        read_constituent(vs_base[0]);
 
1611
        if (READsuppress) {
 
1612
                vs_base[0] = Cnil;
 
1613
                return;
 
1614
        }
 
1615
        vs_base[0]
 
1616
        = parse_number(token_buffer, token->st.st_fillp, &i, 8);
 
1617
        if (vs_base[0] == OBJNULL || i != token->st.st_fillp)
 
1618
                FEerror("Cannot parse the #O readmacro.", 0);
 
1619
        if (type_of(vs_base[0]) == t_shortfloat ||
 
1620
            type_of(vs_base[0]) == t_longfloat)
 
1621
                FEerror("The float ~S appeared after the #O readmacro.",
 
1622
                        1, vs_base[0]);
 
1623
}
 
1624
 
 
1625
static void
 
1626
Lsharp_X_reader()
 
1627
{
 
1628
        int i;
 
1629
 
 
1630
        if(vs_base[2] != Cnil && !READsuppress)
 
1631
                extra_argument('X');
 
1632
        vs_popp;
 
1633
        vs_popp;
 
1634
        read_constituent(vs_base[0]);
 
1635
        if (READsuppress) {
 
1636
                vs_base[0] = Cnil;
 
1637
                return;
 
1638
        }
 
1639
        vs_base[0]
 
1640
        = parse_number(token_buffer, token->st.st_fillp, &i, 16);
 
1641
        if (vs_base[0] == OBJNULL || i != token->st.st_fillp)
 
1642
                FEerror("Cannot parse the #X readmacro.", 0);
 
1643
        if (type_of(vs_base[0]) == t_shortfloat ||
 
1644
            type_of(vs_base[0]) == t_longfloat)
 
1645
                FEerror("The float ~S appeared after the #X readmacro.",
 
1646
                        1, vs_base[0]);
 
1647
}
 
1648
 
 
1649
static void
 
1650
Lsharp_R_reader()
 
1651
{
 
1652
        int radix=0, i;
 
1653
 
 
1654
        check_arg(3);
 
1655
        if (READsuppress)
 
1656
                radix = 10;
 
1657
        else if (type_of(vs_base[2]) == t_fixnum) {
 
1658
                radix = fix(vs_base[2]);
 
1659
                if (radix > 36 || radix < 2)
 
1660
                        FEerror("~S is an illegal radix.", 1, vs_base[2]);
 
1661
        } else
 
1662
                FEerror("No radix was supplied in the #R readmacro.", 0);
 
1663
        vs_popp;
 
1664
        vs_popp;
 
1665
        read_constituent(vs_base[0]);
 
1666
        if (READsuppress) {
 
1667
                vs_base[0] = Cnil;
 
1668
                return;
 
1669
        }
 
1670
        vs_base[0]
 
1671
        = parse_number(token_buffer, token->st.st_fillp, &i, radix);
 
1672
        if (vs_base[0] == OBJNULL || i != token->st.st_fillp)
 
1673
                FEerror("Cannot parse the #R readmacro.", 0);
 
1674
        if (type_of(vs_base[0]) == t_shortfloat ||
 
1675
            type_of(vs_base[0]) == t_longfloat)
 
1676
                FEerror("The float ~S appeared after the #R readmacro.",
 
1677
                        1, vs_base[0]);
 
1678
}
 
1679
 
 
1680
/*static void Lsharp_A_reader(){}*/
 
1681
 
 
1682
/*static void Lsharp_S_reader(){}*/
 
1683
 
 
1684
static void
 
1685
Lsharp_eq_reader()
 
1686
{
 
1687
        int i;
 
1688
 
 
1689
        check_arg(3);
 
1690
        if (READsuppress) {
 
1691
                vs_top = vs_base;
 
1692
                return;
 
1693
        }
 
1694
        if (vs_base[2] == Cnil)
 
1695
                FEerror("The #= readmacro requires an argument.", 0);
 
1696
        for (i = 0;  i < sharp_eq_context_max;  i++)
 
1697
                if (eql(sharp_eq_context[i].sharp_index, vs_base[2]))
 
1698
                        FEerror("Duplicate definitions for #~D=.",
 
1699
                                1, vs_base[2]);
 
1700
        if (sharp_eq_context_max >= SHARP_EQ_CONTEXT_SIZE)
 
1701
                FEerror("Too many #= definitions.", 0);
 
1702
        i = sharp_eq_context_max++;
 
1703
        sharp_eq_context[i].sharp_index = vs_base[2];
 
1704
        sharp_eq_context[i].sharp_sharp = OBJNULL;
 
1705
        vs_base[0]
 
1706
        = sharp_eq_context[i].sharp_eq
 
1707
        = read_object(vs_base[0]);
 
1708
        if (sharp_eq_context[i].sharp_eq
 
1709
            == sharp_eq_context[i].sharp_sharp)
 
1710
                FEerror("#~D# is defined by itself.",
 
1711
                        1, sharp_eq_context[i].sharp_index);
 
1712
        vs_top = vs_base+1;
 
1713
}
 
1714
 
 
1715
static void
 
1716
Lsharp_sharp_reader()
 
1717
{
 
1718
        int i;
 
1719
 
 
1720
        check_arg(3);
 
1721
        if (READsuppress) {
 
1722
                vs_popp;
 
1723
                vs_popp;
 
1724
                vs_base[0] = Cnil;
 
1725
        }
 
1726
        if (vs_base[2] == Cnil)
 
1727
                FEerror("The ## readmacro requires an argument.", 0);
 
1728
        for (i = 0;  ;  i++)
 
1729
                if (i >= sharp_eq_context_max)
 
1730
                        FEerror("#~D# is undefined.", 1, vs_base[2]);
 
1731
                else if (eql(sharp_eq_context[i].sharp_index,
 
1732
                             vs_base[2]))
 
1733
                        break;
 
1734
        if (sharp_eq_context[i].sharp_sharp == OBJNULL) {
 
1735
                sharp_eq_context[i].sharp_sharp
 
1736
                = alloc_object(t_spice);
 
1737
        }
 
1738
        vs_base[0] = sharp_eq_context[i].sharp_sharp;
 
1739
        vs_top = vs_base+1;
 
1740
}
 
1741
 
 
1742
static void
 
1743
patch_sharp_cons(x)
 
1744
object x;
 
1745
{
 
1746
        for (;;) {
 
1747
                x->c.c_car = patch_sharp(x->c.c_car);
 
1748
                if (type_of(x->c.c_cdr) == t_cons)
 
1749
                        x = x->c.c_cdr;
 
1750
                else {
 
1751
                        x->c.c_cdr = patch_sharp(x->c.c_cdr);
 
1752
                        break;
 
1753
                }
 
1754
        }
 
1755
}
 
1756
 
 
1757
static object
 
1758
patch_sharp(x)
 
1759
object x;
 
1760
{
 
1761
        cs_check(x);
 
1762
 
 
1763
        switch (type_of(x)) {
 
1764
        case t_spice:
 
1765
        {
 
1766
                int i;
 
1767
 
 
1768
                for (i = 0;  i < sharp_eq_context_max;  i++)
 
1769
                        if (sharp_eq_context[i].sharp_sharp == x)
 
1770
                                return(sharp_eq_context[i].sharp_eq);
 
1771
                break;
 
1772
        }
 
1773
        case t_cons:
 
1774
        /*
 
1775
                x->c.c_car = patch_sharp(x->c.c_car);
 
1776
                x->c.c_cdr = patch_sharp(x->c.c_cdr);
 
1777
        */
 
1778
                patch_sharp_cons(x);
 
1779
                break;
 
1780
 
 
1781
        case t_vector:
 
1782
        {
 
1783
                int i;
 
1784
 
 
1785
                if ((enum aelttype)x->v.v_elttype != aet_object)
 
1786
                  break;
 
1787
 
 
1788
                for (i = 0;  i < x->v.v_fillp;  i++)
 
1789
                        x->v.v_self[i] = patch_sharp(x->v.v_self[i]);
 
1790
                break;
 
1791
        }
 
1792
        case t_array:
 
1793
        {
 
1794
                int i, j;
 
1795
                
 
1796
                if ((enum aelttype)x->a.a_elttype != aet_object)
 
1797
                  break;
 
1798
 
 
1799
                for (i = 0, j = 1;  i < x->a.a_rank;  i++)
 
1800
                        j *= x->a.a_dims[i];
 
1801
                for (i = 0;  i < j;  i++)
 
1802
                        x->a.a_self[i] = patch_sharp(x->a.a_self[i]);
 
1803
                break;
 
1804
        }
 
1805
        case t_structure:
 
1806
        {object def = x->str.str_def;
 
1807
         int i;
 
1808
         i=S_DATA(def)->length;
 
1809
         while (i--> 0)
 
1810
           structure_set(x,def,i,patch_sharp(structure_ref(x,def,i)));
 
1811
         break;
 
1812
       }
 
1813
        
 
1814
        default:
 
1815
                break;
 
1816
        }
 
1817
        return(x);
 
1818
}
 
1819
 
 
1820
static void Lsharp_plus_reader(){}
 
1821
 
 
1822
static void Lsharp_minus_reader(){}
 
1823
 
 
1824
/*static void Lsharp_less_than_reader(){}*/
 
1825
 
 
1826
/*static void Lsharp_whitespace_reader(){}*/
 
1827
 
 
1828
/*static void Lsharp_right_parenthesis_reader(){}*/
 
1829
 
 
1830
static void
 
1831
Lsharp_vertical_bar_reader()
 
1832
{
 
1833
        int c;
 
1834
        int level = 0;
 
1835
 
 
1836
        check_arg(3);
 
1837
        if (vs_base[2] != Cnil && !READsuppress)
 
1838
                extra_argument('|');
 
1839
        vs_popp;
 
1840
        vs_popp;
 
1841
        for (;;) {
 
1842
                c = readc_stream(vs_base[0]);
 
1843
        L:
 
1844
                if (c == '#') {
 
1845
                        c = readc_stream(vs_base[0]);
 
1846
                        if (c == '|')
 
1847
                                level++;
 
1848
                } else if (c == '|') {
 
1849
                        c = readc_stream(vs_base[0]);
 
1850
                        if (c == '#') {
 
1851
                                if (level == 0)
 
1852
                                        break;
 
1853
                                else
 
1854
                                        --level;
 
1855
                        } else
 
1856
                                goto L;
 
1857
                }
 
1858
        }
 
1859
        vs_popp;
 
1860
        vs_base[0] = Cnil;
 
1861
        /*  no result  */
 
1862
}
 
1863
 
 
1864
static void
 
1865
Ldefault_dispatch_macro()
 
1866
{
 
1867
        FEerror("The default dispatch macro signalled an error.", 0);
 
1868
}
 
1869
 
 
1870
/*
 
1871
        #p" ... " returns the pathname with namestring ... .
 
1872
*/
 
1873
static void
 
1874
Lsharp_p_reader()
 
1875
{
 
1876
        check_arg(3);
 
1877
        if (vs_base[2] != Cnil && !READsuppress)
 
1878
                extra_argument('p');
 
1879
        vs_popp;
 
1880
        vs_popp;
 
1881
        vs_base[0] = read_object(vs_base[0]);
 
1882
        vs_base[0] = coerce_to_pathname(vs_base[0]);
 
1883
}
 
1884
 
 
1885
/*
 
1886
        #" ... " returns the pathname with namestring ... .
 
1887
*/
 
1888
static void
 
1889
Lsharp_double_quote_reader()
 
1890
{
 
1891
        check_arg(3);
 
1892
 
 
1893
        if (vs_base[2] != Cnil && !READsuppress)
 
1894
                extra_argument('"');
 
1895
        vs_popp;
 
1896
        unread_char(vs_base[1], vs_base[0]);
 
1897
        vs_popp;
 
1898
        vs_base[0] = read_object(vs_base[0]);
 
1899
        vs_base[0] = coerce_to_pathname(vs_base[0]);
 
1900
}
 
1901
 
 
1902
/*
 
1903
        #$ fixnum returns a random-state with the fixnum
 
1904
        as its content.
 
1905
*/
 
1906
static void
 
1907
Lsharp_dollar_reader()
 
1908
{
 
1909
        int i;
 
1910
 
 
1911
        check_arg(3);
 
1912
        if (vs_base[2] != Cnil && !READsuppress)
 
1913
                extra_argument('$');
 
1914
        vs_popp;
 
1915
        vs_popp;
 
1916
        vs_base[0] = read_object(vs_base[0]);
 
1917
        if (type_of(vs_base[0]) != t_fixnum)
 
1918
                FEerror("Cannot make a random-state with the value ~S.",
 
1919
                        1, vs_base[0]);
 
1920
        i = fix(vs_base[0]);
 
1921
        vs_base[0] = alloc_object(t_random);
 
1922
        vs_base[0]->rnd.rnd_value = i;
 
1923
}
 
1924
 
 
1925
/*
 
1926
        readtable routines
 
1927
*/
 
1928
 
 
1929
static object
 
1930
copy_readtable(from, to)
 
1931
object from, to;
 
1932
{
 
1933
        struct rtent *rtab;
 
1934
        int i, j;
 
1935
        vs_mark;
 
1936
        {BEGIN_NO_INTERRUPT;
 
1937
        if (to == Cnil) {
 
1938
                to = alloc_object(t_readtable);
 
1939
                to->rt.rt_self = NULL;
 
1940
                        /*  For GBC not to go mad.  */
 
1941
                vs_push(to);
 
1942
                        /*  Saving for GBC.  */
 
1943
                to->rt.rt_self
 
1944
                = rtab
 
1945
                = (struct rtent *)
 
1946
                alloc_contblock(RTABSIZE * sizeof(struct rtent));
 
1947
                for (i = 0;  i < RTABSIZE;  i++)
 
1948
                        rtab[i] = from->rt.rt_self[i];
 
1949
                                /*  structure assignment  */
 
1950
        } else
 
1951
         rtab=to->rt.rt_self;
 
1952
        for (i = 0;  i < RTABSIZE;  i++)
 
1953
                if (from->rt.rt_self[i].rte_dtab != NULL) {
 
1954
                        rtab[i].rte_dtab
 
1955
                        = (object *)
 
1956
                          alloc_contblock(RTABSIZE * sizeof(object));
 
1957
                        for (j = 0;  j < RTABSIZE;  j++)
 
1958
                                rtab[i].rte_dtab[j]
 
1959
                                = from->rt.rt_self[i].rte_dtab[j];
 
1960
                }
 
1961
        vs_reset;
 
1962
        END_NO_INTERRUPT;}
 
1963
        return(to);
 
1964
}
 
1965
 
 
1966
static object
 
1967
current_readtable()
 
1968
{
 
1969
        object r;
 
1970
 
 
1971
        r = symbol_value(Vreadtable);
 
1972
        if (type_of(r) != t_readtable) {
 
1973
                Vreadtable->s.s_dbind = copy_readtable(standard_readtable,sLnil);
 
1974
                FEerror("The value of *READTABLE*, ~S, was not a readtable.",
 
1975
                        1, r);
 
1976
        }
 
1977
        return(r);
 
1978
}
 
1979
 
 
1980
 
 
1981
@(defun read (&optional (strm `symbol_value(sLAstandard_inputA)`)
 
1982
                        (eof_errorp Ct)
 
1983
                        eof_value
 
1984
                        recursivep
 
1985
              &aux x)
 
1986
@
 
1987
        if (strm == Cnil)
 
1988
                strm = symbol_value(sLAstandard_inputA);
 
1989
        else if (strm == Ct)
 
1990
                strm = symbol_value(sLAterminal_ioA);
 
1991
        check_type_stream(&strm);
 
1992
        if (recursivep == Cnil)
 
1993
                preserving_whitespace_flag = FALSE;
 
1994
        detect_eos_flag = TRUE;
 
1995
        if (recursivep == Cnil)
 
1996
                x = read_object_non_recursive(strm);
 
1997
        else
 
1998
                x = read_object_recursive(strm);
 
1999
        if (x == OBJNULL) {
 
2000
                if (eof_errorp == Cnil && recursivep == Cnil)
 
2001
                        @(return eof_value)
 
2002
                end_of_stream(strm);
 
2003
        }
 
2004
        @(return x)
 
2005
@)
 
2006
 
 
2007
@(static defun read_preserving_whitespace
 
2008
        (&optional (strm `symbol_value(sLAstandard_inputA)`)
 
2009
                   (eof_errorp Ct)
 
2010
                   eof_value
 
2011
                   recursivep
 
2012
         &aux x)
 
2013
        object c;
 
2014
@
 
2015
        if (strm == Cnil)
 
2016
                strm = symbol_value(sLAstandard_inputA);
 
2017
        else if (strm == Ct)
 
2018
                strm = symbol_value(sLAterminal_ioA);
 
2019
        check_type_stream(&strm);
 
2020
        while (!stream_at_end(strm)) {
 
2021
                c = read_char(strm);
 
2022
                if (cat(c) != cat_whitespace) {
 
2023
                        unread_char(c, strm);
 
2024
                        goto READ;
 
2025
                }
 
2026
        }
 
2027
        if (eof_errorp == Cnil && recursivep == Cnil)
 
2028
                @(return eof_value)
 
2029
        end_of_stream(strm);
 
2030
 
 
2031
READ:
 
2032
        if (recursivep == Cnil)
 
2033
                preserving_whitespace_flag = TRUE;
 
2034
        if (recursivep == Cnil)
 
2035
                x = read_object_non_recursive(strm);
 
2036
        else
 
2037
                x = read_object_recursive(strm);
 
2038
        @(return x)
 
2039
@)
 
2040
 
 
2041
@(defun read_delimited_list
 
2042
        (d
 
2043
         &optional (strm `symbol_value(sLAstandard_inputA)`)
 
2044
                   recursivep
 
2045
         &aux l x)
 
2046
 
 
2047
        object *p;
 
2048
 
 
2049
        int i;
 
2050
        bool e;
 
2051
        volatile int old_sharp_eq_context_max=0;
 
2052
        struct sharp_eq_context_struct
 
2053
                old_sharp_eq_context[SHARP_EQ_CONTEXT_SIZE];
 
2054
        volatile int old_backq_level=0;
 
2055
 
 
2056
@
 
2057
 
 
2058
        check_type_character(&d);
 
2059
        if (strm == Cnil)
 
2060
                strm = symbol_value(sLAstandard_inputA);
 
2061
        else if (strm == Ct)
 
2062
                strm = symbol_value(sLAterminal_ioA);
 
2063
        check_type_stream(&strm);
 
2064
        if (recursivep == Cnil) {
 
2065
                old_sharp_eq_context_max = sharp_eq_context_max;
 
2066
                for (i = 0;  i < sharp_eq_context_max;  i++)
 
2067
                        old_sharp_eq_context[i] = sharp_eq_context[i];
 
2068
                old_backq_level = backq_level;
 
2069
                setup_READ();
 
2070
                frs_push(FRS_PROTECT, Cnil);
 
2071
                if (nlj_active) {
 
2072
                        e = TRUE;
 
2073
                        goto L;
 
2074
                }
 
2075
        }
 
2076
        l = Cnil;
 
2077
        p = &l;
 
2078
        preserving_whitespace_flag = FALSE;     /*  necessary?  */
 
2079
        for (;;) {
 
2080
                delimiting_char = d;
 
2081
                x = read_object_recursive(strm);
 
2082
                if (x == OBJNULL)
 
2083
                        break;
 
2084
                *p = make_cons(x, Cnil);
 
2085
                p = &((*p)->c.c_cdr);
 
2086
        }
 
2087
        if (recursivep == Cnil) {
 
2088
                if (sharp_eq_context_max > 0)
 
2089
                        l = patch_sharp(l);
 
2090
                e = FALSE;
 
2091
        L:
 
2092
                frs_pop();
 
2093
                sharp_eq_context_max = old_sharp_eq_context_max;
 
2094
                for (i = 0;  i < sharp_eq_context_max;  i++)
 
2095
                        sharp_eq_context[i] = old_sharp_eq_context[i];
 
2096
                backq_level = old_backq_level;
 
2097
                if (e) {
 
2098
                        nlj_active = FALSE;
 
2099
                        unwind(nlj_fr, nlj_tag);
 
2100
                }
 
2101
        }
 
2102
        @(return l)
 
2103
@)
 
2104
 
 
2105
@(defun read_line (&optional (strm `symbol_value(sLAstandard_inputA)`)
 
2106
                             (eof_errorp Ct)
 
2107
                             eof_value
 
2108
                             recursivep
 
2109
                   &aux c)
 
2110
        int i;
 
2111
@
 
2112
        if (strm == Cnil)
 
2113
                strm = symbol_value(sLAstandard_inputA);
 
2114
        else if (strm == Ct)
 
2115
                strm = symbol_value(sLAterminal_ioA);
 
2116
        check_type_stream(&strm);
 
2117
        if (stream_at_end(strm)) {
 
2118
                if (eof_errorp == Cnil && recursivep == Cnil)
 
2119
                        @(return eof_value)
 
2120
                else
 
2121
                        end_of_stream(strm);
 
2122
        }
 
2123
        i = 0;
 
2124
        for (;;) {
 
2125
                read_char_to(c,strm,c = Ct; goto FINISH);
 
2126
                if (char_code(c) == '\n') {
 
2127
                        c = Cnil;
 
2128
                        break;
 
2129
                }
 
2130
                if (i >= token->st.st_dim)
 
2131
                        too_long_string();
 
2132
                token->st.st_self[i++] = char_code(c);
 
2133
        }
 
2134
 FINISH:
 
2135
#ifdef DOES_CRLF
 
2136
        if (i > 0 && token->st.st_self[i-1] == '\r') i--;
 
2137
#endif
 
2138
        token->st.st_fillp = i;
 
2139
  /* no disadvantage to returning an adjustable string */
 
2140
  
 
2141
  {object uu= copy_simple_string(token);
 
2142
/*   uu->st.st_hasfillp=TRUE;
 
2143
   uu->st.st_adjustable=TRUE;
 
2144
*/
 
2145
   @(return uu c)
 
2146
   }
 
2147
@)
 
2148
 
 
2149
@(defun read_char (&optional (strm `symbol_value(sLAstandard_inputA)`)
 
2150
                             (eof_errorp Ct)
 
2151
                             eof_value
 
2152
                             recursivep)
 
2153
@
 
2154
        if (strm == Cnil)
 
2155
                strm = symbol_value(sLAstandard_inputA);
 
2156
        else if (strm == Ct)
 
2157
                strm = symbol_value(sLAterminal_ioA);
 
2158
        check_type_stream(&strm);
 
2159
        {object x ;
 
2160
        read_char_to(x,strm,goto AT_EOF);
 
2161
        @(return `x`)
 
2162
          AT_EOF:
 
2163
         if (eof_errorp == Cnil && recursivep == Cnil)
 
2164
                @(return eof_value)
 
2165
         else
 
2166
                end_of_stream(strm);
 
2167
       }
 
2168
@)
 
2169
 
 
2170
@(defun unread_char (c &optional (strm `symbol_value(sLAstandard_inputA)`))
 
2171
@
 
2172
        check_type_character(&c);
 
2173
        if (strm == Cnil)
 
2174
                strm = symbol_value(sLAstandard_inputA);
 
2175
        else if (strm == Ct)
 
2176
                strm = symbol_value(sLAterminal_ioA);
 
2177
        check_type_stream(&strm);
 
2178
        unread_char(c, strm);
 
2179
        @(return Cnil)
 
2180
@)
 
2181
 
 
2182
@(defun peek_char (&optional peek_type
 
2183
                             (strm `symbol_value(sLAstandard_inputA)`)
 
2184
                             (eof_errorp Ct)
 
2185
                             eof_value
 
2186
                             recursivep)
 
2187
        object c;
 
2188
@
 
2189
        if (strm == Cnil)
 
2190
                strm = symbol_value(sLAstandard_inputA);
 
2191
        else if (strm == Ct)
 
2192
                strm = symbol_value(sLAterminal_ioA);
 
2193
        check_type_stream(&strm);
 
2194
        setup_READtable();
 
2195
        if (peek_type == Cnil) {
 
2196
                if (stream_at_end(strm)) {
 
2197
                        if (eof_errorp == Cnil && recursivep == Cnil)
 
2198
                                @(return eof_value)
 
2199
                        else
 
2200
                                end_of_stream(strm);
 
2201
                }
 
2202
                c = read_char(strm);
 
2203
                unread_char(c, strm);
 
2204
                @(return c)
 
2205
        }
 
2206
        if (peek_type == Ct) {
 
2207
                while (!stream_at_end(strm)) {
 
2208
                        c = read_char(strm);
 
2209
                        if (cat(c) != cat_whitespace) {
 
2210
                                unread_char(c, strm);
 
2211
                                @(return c)
 
2212
                        }
 
2213
                }
 
2214
                if (eof_errorp == Cnil)
 
2215
                        @(return eof_value)
 
2216
                else
 
2217
                        end_of_stream(strm);
 
2218
        }
 
2219
        check_type_character(&peek_type);
 
2220
        while (!stream_at_end(strm)) {
 
2221
                c = read_char(strm);
 
2222
                if (char_eq(c, peek_type)) {
 
2223
                        unread_char(c, strm);
 
2224
                        @(return c)
 
2225
                }
 
2226
        }
 
2227
        if (eof_errorp == Cnil)
 
2228
                @(return eof_value)
 
2229
        else
 
2230
                end_of_stream(strm);
 
2231
@)
 
2232
 
 
2233
@(defun listen (&optional (strm `symbol_value(sLAstandard_inputA)`))
 
2234
@
 
2235
        if (strm == Cnil)
 
2236
                strm = symbol_value(sLAstandard_inputA);
 
2237
        else if (strm == Ct)
 
2238
                strm = symbol_value(sLAterminal_ioA);
 
2239
        check_type_stream(&strm);
 
2240
        if (listen_stream(strm))
 
2241
                @(return Ct)
 
2242
        else
 
2243
                @(return Cnil)
 
2244
@)
 
2245
 
 
2246
@(defun read_char_no_hang (&optional (strm `symbol_value(sLAstandard_inputA)`)
 
2247
                                     (eof_errorp Ct)
 
2248
                                     eof_value
 
2249
                                     recursivep)
 
2250
@
 
2251
        if (strm == Cnil)
 
2252
                strm = symbol_value(sLAstandard_inputA);
 
2253
        else if (strm == Ct)
 
2254
                strm = symbol_value(sLAterminal_ioA);
 
2255
        check_type_stream(&strm);
 
2256
        if (!listen_stream(strm))
 
2257
                /* Incomplete! */
 
2258
                @(return Cnil)
 
2259
        @(return `read_char(strm)`)
 
2260
@)
 
2261
 
 
2262
@(defun clear_input (&optional (strm `symbol_value(sLAstandard_inputA)`))
 
2263
@
 
2264
        if (strm == Cnil)
 
2265
                strm = symbol_value(sLAstandard_inputA);
 
2266
        else if (strm == Ct)
 
2267
                strm = symbol_value(sLAterminal_ioA);
 
2268
        check_type_stream(&strm);
 
2269
#ifdef LISTEN_FOR_INPUT
 
2270
        while(listen_stream(strm)) {readc_stream(strm);}
 
2271
#endif
 
2272
        @(return Cnil)
 
2273
@)
 
2274
 
 
2275
@(defun parse_integer (strng
 
2276
                       &key start
 
2277
                            end
 
2278
                            (radix `make_fixnum(10)`)
 
2279
                            junk_allowed
 
2280
                       &aux x)
 
2281
        int s, e, ep;
 
2282
@
 
2283
        if (junk_allowed==Cnil)
 
2284
            check_type_string(&strng);
 
2285
        get_string_start_end(strng, start, end, &s, &e);
 
2286
        if (type_of(radix) != t_fixnum ||
 
2287
            fix(radix) < 2 || fix(radix) > 36)
 
2288
                FEerror("~S is an illegal radix.", 1, radix);
 
2289
        setup_READtable();
 
2290
        while (READtable->rt.rt_self[(unsigned char)strng->st.st_self[s]].rte_chattrib
 
2291
               == cat_whitespace && s < e)
 
2292
                s++;
 
2293
        if (s >= e) {
 
2294
                if (junk_allowed != Cnil)
 
2295
                        @(return Cnil `make_fixnum(s)`)
 
2296
                else
 
2297
                        goto CANNOT_PARSE;
 
2298
        }
 
2299
        {char *tmp = OUR_ALLOCA(e-s);
 
2300
         bcopy( strng->st.st_self+s,tmp,e-s);
 
2301
          x = parse_integer(tmp, e-s, &ep, fix(radix));
 
2302
         ALLOCA_FREE(tmp);
 
2303
         }
 
2304
        if (x == OBJNULL) {
 
2305
                if (junk_allowed != Cnil)
 
2306
                        @(return Cnil `make_fixnum(ep+s)`)
 
2307
                else
 
2308
                        goto CANNOT_PARSE;
 
2309
        }
 
2310
        if (junk_allowed != Cnil)
 
2311
                @(return x `make_fixnum(ep+s)`)
 
2312
        for (s += ep ;  s < e;  s++)
 
2313
                if (READtable->rt.rt_self[(unsigned char)strng->st.st_self[s]]
 
2314
                    .rte_chattrib
 
2315
                    != cat_whitespace)
 
2316
                        goto CANNOT_PARSE;
 
2317
        @(return x `make_fixnum(e)`)
 
2318
 
 
2319
CANNOT_PARSE:
 
2320
        Icall_error_handler(sKparse_error,
 
2321
                            make_simple_string("Cannot parse an integer in the string ~S."), 
 
2322
                            1, strng);
 
2323
@)
 
2324
 
 
2325
@(defun read_byte (binary_input_stream
 
2326
                   &optional eof_errorp eof_value)
 
2327
        int c;
 
2328
@
 
2329
        check_type_stream(&binary_input_stream);
 
2330
        if (stream_at_end(binary_input_stream)) {
 
2331
                if (eof_errorp == Cnil)
 
2332
                        @(return eof_value)
 
2333
                else
 
2334
                        end_of_stream(binary_input_stream);
 
2335
        }
 
2336
        c = readc_stream(binary_input_stream);
 
2337
        @(return `make_fixnum(c)`)
 
2338
@)
 
2339
 
 
2340
object
 
2341
read_byte1(strm,eof)
 
2342
object strm,eof;
 
2343
{
 
2344
  if (strm == Cnil)
 
2345
    strm = symbol_value(sLAstandard_inputA);
 
2346
  else if (strm == Ct)
 
2347
    strm = symbol_value(sLAterminal_ioA);
 
2348
  if (stream_at_end(strm))
 
2349
    return eof;
 
2350
  return make_fixnum(readc_stream(strm));
 
2351
}
 
2352
 
 
2353
object
 
2354
read_char1(strm,eof)
 
2355
object strm,eof;
 
2356
{
 
2357
  if (strm == Cnil)
 
2358
    strm = symbol_value(sLAstandard_inputA);
 
2359
  else if (strm == Ct)
 
2360
    strm = symbol_value(sLAterminal_ioA);
 
2361
  if (stream_at_end(strm))
 
2362
    return eof;
 
2363
  return code_char(readc_stream(strm));
 
2364
}
 
2365
 
 
2366
@(defun copy_readtable (&optional (from `current_readtable()`) to)
 
2367
@
 
2368
        if (from == Cnil) {
 
2369
                from = standard_readtable;
 
2370
                if (to != Cnil)
 
2371
                        check_type_readtable(&to);
 
2372
                to = copy_readtable(from, to);
 
2373
                to->rt.rt_self['#'].rte_dtab['!']
 
2374
                = default_dispatch_macro;
 
2375
                /*  We must forget #! macro.  */
 
2376
                @(return to)
 
2377
        }
 
2378
        check_type_readtable(&from);
 
2379
        if (to != Cnil)
 
2380
                check_type_readtable(&to);
 
2381
        @(return `copy_readtable(from, to)`)
 
2382
@)
 
2383
 
 
2384
LFD(Lreadtablep)()
 
2385
{
 
2386
        check_arg(1);
 
2387
 
 
2388
        if (type_of(vs_base[0]) == t_readtable)
 
2389
                vs_base[0] = Ct;
 
2390
        else
 
2391
                vs_base[0] = Cnil;
 
2392
}
 
2393
 
 
2394
@(defun set_syntax_from_char (tochr fromchr
 
2395
                              &optional (tordtbl `current_readtable()`)
 
2396
                                 fromrdtbl)
 
2397
        int i;
 
2398
@
 
2399
        check_type_character(&tochr);
 
2400
        check_type_character(&fromchr);
 
2401
        check_type_readtable(&tordtbl);
 
2402
        {BEGIN_NO_INTERRUPT;    
 
2403
        if (fromrdtbl == Cnil)
 
2404
                fromrdtbl = standard_readtable;
 
2405
        else
 
2406
                check_type_readtable(&fromrdtbl);
 
2407
        tordtbl->rt.rt_self[char_code(tochr)].rte_chattrib
 
2408
        = fromrdtbl->rt.rt_self[char_code(fromchr)].rte_chattrib;
 
2409
        tordtbl->rt.rt_self[char_code(tochr)].rte_macro
 
2410
        = fromrdtbl->rt.rt_self[char_code(fromchr)].rte_macro;
 
2411
        if ((tordtbl->rt.rt_self[char_code(tochr)].rte_dtab
 
2412
             = fromrdtbl->rt.rt_self[char_code(fromchr)].rte_dtab)
 
2413
            != NULL) {
 
2414
                tordtbl->rt.rt_self[char_code(tochr)].rte_dtab
 
2415
                = (object *)
 
2416
                  alloc_contblock(RTABSIZE * sizeof(object));
 
2417
                for (i = 0;  i < RTABSIZE;  i++)
 
2418
                        tordtbl->rt.rt_self[char_code(tochr)]
 
2419
                        .rte_dtab[i]
 
2420
                        = fromrdtbl->rt.rt_self[char_code(fromchr)]
 
2421
                          .rte_dtab[i];
 
2422
        }
 
2423
        END_NO_INTERRUPT;}
 
2424
        @(return Ct)
 
2425
@)
 
2426
 
 
2427
@(defun set_macro_character (chr fnc
 
2428
                             &optional ntp
 
2429
                                       (rdtbl `current_readtable()`))
 
2430
        int c;
 
2431
@
 
2432
        check_type_character(&chr);
 
2433
        check_type_readtable(&rdtbl);
 
2434
        c = char_code(chr);
 
2435
        if (ntp != Cnil)
 
2436
                rdtbl->rt.rt_self[c].rte_chattrib
 
2437
                = cat_non_terminating;
 
2438
        else
 
2439
                rdtbl->rt.rt_self[c].rte_chattrib
 
2440
                = cat_terminating;
 
2441
        rdtbl->rt.rt_self[c].rte_macro = fnc;
 
2442
        @(return Ct)
 
2443
@)
 
2444
 
 
2445
@(defun get_macro_character (chr &optional (rdtbl `current_readtable()`))
 
2446
        object m;
 
2447
@
 
2448
        check_type_character(&chr);
 
2449
        check_type_readtable(&rdtbl);
 
2450
        if ((m = rdtbl->rt.rt_self[char_code(chr)].rte_macro)
 
2451
            == OBJNULL)
 
2452
                @(return Cnil)
 
2453
        if (rdtbl->rt.rt_self[char_code(chr)].rte_chattrib
 
2454
            == cat_non_terminating)
 
2455
                @(return m Ct)
 
2456
        else
 
2457
                @(return m Cnil)
 
2458
@)
 
2459
 
 
2460
@(static defun make_dispatch_macro_character (chr
 
2461
        &optional ntp (rdtbl `current_readtable()`))
 
2462
        int i;
 
2463
@
 
2464
        check_type_character(&chr);
 
2465
        check_type_readtable(&rdtbl);
 
2466
        {BEGIN_NO_INTERRUPT;
 
2467
        if (ntp != Cnil)
 
2468
                rdtbl->rt.rt_self[char_code(chr)].rte_chattrib
 
2469
                = cat_non_terminating;
 
2470
        else
 
2471
                rdtbl->rt.rt_self[char_code(chr)].rte_chattrib
 
2472
                = cat_terminating;
 
2473
        rdtbl->rt.rt_self[char_code(chr)].rte_dtab
 
2474
        = (object *)
 
2475
          alloc_contblock(RTABSIZE * sizeof(object));
 
2476
        for (i = 0;  i < RTABSIZE;  i++)
 
2477
                rdtbl->rt.rt_self[char_code(chr)].rte_dtab[i]
 
2478
                = default_dispatch_macro;
 
2479
        rdtbl->rt.rt_self[char_code(chr)].rte_macro = dispatch_reader;
 
2480
        END_NO_INTERRUPT;}
 
2481
        @(return Ct)
 
2482
@)
 
2483
 
 
2484
@(static defun set_dispatch_macro_character (dspchr subchr fnc
 
2485
        &optional (rdtbl `current_readtable()`))
 
2486
@
 
2487
        check_type_character(&dspchr);
 
2488
        check_type_character(&subchr);
 
2489
        check_type_readtable(&rdtbl);
 
2490
        if (rdtbl->rt.rt_self[char_code(dspchr)].rte_macro != dispatch_reader
 
2491
            || rdtbl->rt.rt_self[char_code(dspchr)].rte_dtab == NULL)
 
2492
                FEerror("~S is not a dispatch character.", 1, dspchr);
 
2493
        rdtbl->rt.rt_self[char_code(dspchr)]
 
2494
        .rte_dtab[char_code(subchr)] = fnc;
 
2495
        if ('a' <= char_code(subchr) && char_code(subchr) <= 'z')
 
2496
                rdtbl->rt.rt_self[char_code(dspchr)]
 
2497
                .rte_dtab[char_code(subchr) - ('a' - 'A')] = fnc;
 
2498
 
 
2499
        @(return Ct)
 
2500
@)
 
2501
 
 
2502
@(static defun get_dispatch_macro_character (dspchr subchr
 
2503
        &optional (rdtbl `current_readtable()`))
 
2504
@
 
2505
        check_type_character(&dspchr);
 
2506
        check_type_character(&subchr);
 
2507
        check_type_readtable(&rdtbl);
 
2508
        if (rdtbl->rt.rt_self[char_code(dspchr)].rte_macro != dispatch_reader
 
2509
            || rdtbl->rt.rt_self[char_code(dspchr)].rte_dtab == NULL)
 
2510
                FEerror("~S is not a dispatch character.", 1, dspchr);
 
2511
        if (digitp(char_code(subchr),10) >= 0) @(return Cnil)
 
2512
        else @(return `rdtbl->rt.rt_self[char_code(dspchr)]
 
2513
                  .rte_dtab[char_code(subchr)]`)
 
2514
@)
 
2515
 
 
2516
static object
 
2517
string_to_object(x)
 
2518
object x;
 
2519
{
 
2520
        object in;
 
2521
        vs_mark;
 
2522
 
 
2523
        in = make_string_input_stream(x, 0, x->st.st_fillp);
 
2524
        vs_push(in);
 
2525
        preserving_whitespace_flag = FALSE;
 
2526
        detect_eos_flag = FALSE;
 
2527
        x = read_object_non_recursive(in);
 
2528
        vs_reset;
 
2529
        return(x);
 
2530
}
 
2531
        
 
2532
LFD(siLstring_to_object)()
 
2533
{
 
2534
        check_arg(1);
 
2535
 
 
2536
        check_type_string(&vs_base[0]);
 
2537
        vs_base[0] = string_to_object(vs_base[0]);
 
2538
}
 
2539
 
 
2540
 
 
2541
static void
 
2542
FFN(siLstandard_readtable)()
 
2543
{
 
2544
        check_arg(0);
 
2545
 
 
2546
        vs_push(standard_readtable);
 
2547
}
 
2548
 
 
2549
static void
 
2550
too_long_token(void)
 
2551
{
 
2552
        char *q;
 
2553
        int i;
 
2554
 
 
2555
        {BEGIN_NO_INTERRUPT;
 
2556
        q = alloc_contblock(token->st.st_dim*2);
 
2557
        for (i = 0;  i < token->st.st_dim;  i++)
 
2558
                q[i] = token->st.st_self[i];
 
2559
        token->st.st_self = q;
 
2560
        token->st.st_dim *= 2;
 
2561
        END_NO_INTERRUPT;}
 
2562
/*
 
2563
        token->st.st_fillp = token->st.st_dim;
 
2564
        FEerror("Too long a token: ~A.", 1, token);
 
2565
*/
 
2566
}
 
2567
 
 
2568
static void
 
2569
too_long_string(void)
 
2570
{
 
2571
        char *q;
 
2572
        int i;
 
2573
        {BEGIN_NO_INTERRUPT;
 
2574
        q = alloc_contblock(token->st.st_dim*2);
 
2575
        for (i = 0;  i < token->st.st_dim;  i++)
 
2576
                q[i] = token->st.st_self[i];
 
2577
        token->st.st_self = q;
 
2578
        token->st.st_dim *= 2;
 
2579
        END_NO_INTERRUPT;}
 
2580
/*
 
2581
        token->st.st_fillp = token->st.st_dim;
 
2582
        FEerror("Too long a string: ~S.", 1, token);
 
2583
*/
 
2584
}
 
2585
 
 
2586
static void
 
2587
extra_argument(c)
 
2588
int c;
 
2589
{
 
2590
        FEerror("~S is an extra argument for the #~C readmacro.",
 
2591
                2, vs_base[2], code_char(c));
 
2592
}
 
2593
 
 
2594
 
 
2595
#define make_cf(f)      make_cfun((f), Cnil, Cnil, NULL, 0)
 
2596
 
 
2597
DEFVAR("*READ-DEFAULT-FLOAT-FORMAT*",sLAread_default_float_formatA,
 
2598
   LISP,sLsingle_float,"");
 
2599
DEFVAR("*READ-BASE*",sLAread_baseA,LISP,make_fixnum(10),"");
 
2600
DEFVAR("*READ-SUPPRESS*",sLAread_suppressA,LISP,Cnil,"");
 
2601
 
 
2602
 
 
2603
void
 
2604
gcl_init_read()
 
2605
{
 
2606
        struct rtent *rtab;
 
2607
        object *dtab;
 
2608
        int i;
 
2609
 
 
2610
        standard_readtable = alloc_object(t_readtable);
 
2611
        enter_mark_origin(&standard_readtable);
 
2612
 
 
2613
        standard_readtable->rt.rt_self
 
2614
        = rtab
 
2615
        = (struct rtent *)
 
2616
          alloc_contblock(RTABSIZE * sizeof(struct rtent));
 
2617
        for (i = 0;  i < RTABSIZE;  i++) {
 
2618
                rtab[i].rte_chattrib = cat_constituent;
 
2619
                rtab[i].rte_macro = OBJNULL;
 
2620
                rtab[i].rte_dtab = NULL;
 
2621
        }
 
2622
 
 
2623
        dispatch_reader = make_cf(Ldispatch_reader);
 
2624
        enter_mark_origin(&dispatch_reader);
 
2625
 
 
2626
        rtab['\t'].rte_chattrib = cat_whitespace;
 
2627
        rtab['\n'].rte_chattrib = cat_whitespace;
 
2628
        rtab['\f'].rte_chattrib = cat_whitespace;
 
2629
        rtab['\r'].rte_chattrib = cat_whitespace;
 
2630
        rtab[' '].rte_chattrib = cat_whitespace;
 
2631
        rtab['"'].rte_chattrib = cat_terminating;
 
2632
        rtab['"'].rte_macro = make_cf(Ldouble_quote_reader);
 
2633
        rtab['#'].rte_chattrib = cat_non_terminating;
 
2634
        rtab['#'].rte_macro = dispatch_reader;
 
2635
        rtab['\''].rte_chattrib = cat_terminating;
 
2636
        rtab['\''].rte_macro = make_cf(Lsingle_quote_reader);
 
2637
        rtab['('].rte_chattrib = cat_terminating;
 
2638
        rtab['('].rte_macro = make_cf(Lleft_parenthesis_reader);
 
2639
        rtab[')'].rte_chattrib = cat_terminating;
 
2640
        rtab[')'].rte_macro = make_cf(Lright_parenthesis_reader);
 
2641
/*
 
2642
        rtab[','].rte_chattrib = cat_terminating;
 
2643
        rtab[','].rte_macro = make_cf(Lcomma_reader);
 
2644
*/
 
2645
        rtab[';'].rte_chattrib = cat_terminating;
 
2646
        rtab[';'].rte_macro = make_cf(Lsemicolon_reader);
 
2647
        rtab['\\'].rte_chattrib = cat_single_escape;
 
2648
/*
 
2649
        rtab['`'].rte_chattrib = cat_terminating;
 
2650
        rtab['`'].rte_macro = make_cf(Lbackquote_reader);
 
2651
*/
 
2652
        rtab['|'].rte_chattrib = cat_multiple_escape;
 
2653
/*
 
2654
        rtab['|'].rte_macro = make_cf(Lvertical_bar_reader);
 
2655
*/
 
2656
 
 
2657
        default_dispatch_macro = make_cf(Ldefault_dispatch_macro);
 
2658
 
 
2659
        rtab['#'].rte_dtab
 
2660
        = dtab
 
2661
        = (object *)alloc_contblock(RTABSIZE * sizeof(object));
 
2662
        for (i = 0;  i < RTABSIZE;  i++)
 
2663
                dtab[i] = default_dispatch_macro;
 
2664
        dtab['C'] = dtab['c'] = make_cf(Lsharp_C_reader);
 
2665
        dtab['\\'] = make_cf(Lsharp_backslash_reader);
 
2666
        dtab['\''] = make_cf(Lsharp_single_quote_reader);
 
2667
        dtab['('] = make_cf(Lsharp_left_parenthesis_reader);
 
2668
        dtab['*'] = make_cf(Lsharp_asterisk_reader);
 
2669
        dtab[':'] = make_cf(Lsharp_colon_reader);
 
2670
        dtab['.'] = make_cf(Lsharp_dot_reader);
 
2671
        dtab['!'] = make_cf(Lsharp_exclamation_reader);
 
2672
        /*  Used for fasload only. */
 
2673
        dtab[','] = make_cf(Lsharp_comma_reader);
 
2674
        dtab['B'] = dtab['b'] = make_cf(Lsharp_B_reader);
 
2675
        dtab['O'] = dtab['o'] = make_cf(Lsharp_O_reader);
 
2676
        dtab['X'] = dtab['x'] = make_cf(Lsharp_X_reader);
 
2677
        dtab['R'] = dtab['r'] = make_cf(Lsharp_R_reader);
 
2678
/*
 
2679
        dtab['A'] = dtab['a'] = make_cf(Lsharp_A_reader);
 
2680
        dtab['S'] = dtab['s'] = make_cf(Lsharp_S_reader);
 
2681
*/
 
2682
        dtab['A'] = dtab['a'] = make_si_ordinary("SHARP-A-READER");
 
2683
        dtab['S'] = dtab['s'] = make_si_ordinary("SHARP-S-READER");
 
2684
 
 
2685
        dtab['='] = make_cf(Lsharp_eq_reader);
 
2686
        dtab['#'] = make_cf(Lsharp_sharp_reader);
 
2687
        dtab['+'] = make_cf(Lsharp_plus_reader);
 
2688
        dtab['-'] = make_cf(Lsharp_minus_reader);
 
2689
/*
 
2690
        dtab['<'] = make_cf(Lsharp_less_than_reader);
 
2691
*/
 
2692
        dtab['|'] = make_cf(Lsharp_vertical_bar_reader);
 
2693
        dtab['"'] = make_cf(Lsharp_double_quote_reader);
 
2694
        dtab['p'] = make_cf(Lsharp_p_reader);
 
2695
        dtab['P'] = make_cf(Lsharp_p_reader);
 
2696
        /*  This is specific to this implimentation  */
 
2697
        dtab['$'] = make_cf(Lsharp_dollar_reader);
 
2698
        /*  This is specific to this implimentation  */
 
2699
/*
 
2700
        dtab[' '] = dtab['\t'] = dtab['\n'] = dtab['\f']
 
2701
        = make_cf(Lsharp_whitespace_reader);
 
2702
        dtab[')'] = make_cf(Lsharp_right_parenthesis_reader);
 
2703
*/
 
2704
 
 
2705
        gcl_init_backq();
 
2706
 
 
2707
        Vreadtable
 
2708
        = make_special("*READTABLE*",
 
2709
                       copy_readtable(standard_readtable, Cnil));
 
2710
        Vreadtable->s.s_dbind->rt.rt_self['#'].rte_dtab['!']
 
2711
        = default_dispatch_macro;
 
2712
        /*  We must forget #! macro.  */
 
2713
 
 
2714
 
 
2715
        sKstart = make_keyword("START");
 
2716
        sKend = make_keyword("END");
 
2717
        sKradix = make_keyword("RADIX");
 
2718
        sKjunk_allowed = make_keyword("JUNK-ALLOWED");
 
2719
 
 
2720
        READtable = symbol_value(Vreadtable);
 
2721
        enter_mark_origin(&READtable);
 
2722
        READdefault_float_format = 'F';
 
2723
        READbase = 10;
 
2724
        READsuppress = FALSE;
 
2725
 
 
2726
        sharp_eq_context_max = 0;
 
2727
 
 
2728
        siSsharp_comma = make_si_ordinary("#,");
 
2729
        enter_mark_origin(&siSsharp_comma);
 
2730
 
 
2731
        delimiting_char = OBJNULL;
 
2732
        enter_mark_origin(&delimiting_char);
 
2733
 
 
2734
        detect_eos_flag = FALSE;
 
2735
        in_list_flag = FALSE;
 
2736
        dot_flag = FALSE;
 
2737
 
 
2738
        big_register_0 = new_bignum();
 
2739
        zero_big(big_register_0);
 
2740
 
 
2741
        enter_mark_origin(&big_register_0);
 
2742
/*
 
2743
        NOTE:
 
2744
 
 
2745
                The value of big_register_0 changes
 
2746
                along the execution of the read routines.
 
2747
*/
 
2748
}
 
2749
 
 
2750
void
 
2751
gcl_init_read_function()
 
2752
{
 
2753
        make_function("READ", Lread);
 
2754
        make_function("READ-PRESERVING-WHITESPACE",
 
2755
                      Lread_preserving_whitespace);
 
2756
        make_function("READ-DELIMITED-LIST", Lread_delimited_list);
 
2757
        make_function("READ-LINE", Lread_line);
 
2758
        make_function("READ-CHAR", Lread_char);
 
2759
        make_function("UNREAD-CHAR", Lunread_char);
 
2760
        make_function("PEEK-CHAR", Lpeek_char);
 
2761
        make_function("LISTEN", Llisten);
 
2762
        make_function("READ-CHAR-NO-HANG", Lread_char_no_hang);
 
2763
        make_function("CLEAR-INPUT", Lclear_input);
 
2764
 
 
2765
        make_function("PARSE-INTEGER", Lparse_integer);
 
2766
 
 
2767
        make_function("READ-BYTE", Lread_byte);
 
2768
 
 
2769
        make_function("COPY-READTABLE", Lcopy_readtable);
 
2770
        make_function("READTABLEP", Lreadtablep);
 
2771
        make_function("SET-SYNTAX-FROM-CHAR", Lset_syntax_from_char);
 
2772
        make_function("SET-MACRO-CHARACTER", Lset_macro_character);
 
2773
        make_function("GET-MACRO-CHARACTER", Lget_macro_character);
 
2774
        make_function("MAKE-DISPATCH-MACRO-CHARACTER",
 
2775
                      Lmake_dispatch_macro_character);
 
2776
        make_function("SET-DISPATCH-MACRO-CHARACTER",
 
2777
                      Lset_dispatch_macro_character);
 
2778
        make_function("GET-DISPATCH-MACRO-CHARACTER",
 
2779
                      Lget_dispatch_macro_character);
 
2780
 
 
2781
        make_si_function("SHARP-COMMA-READER-FOR-COMPILER",
 
2782
                         siLsharp_comma_reader_for_compiler);
 
2783
 
 
2784
        make_si_function("STRING-TO-OBJECT", siLstring_to_object);
 
2785
 
 
2786
        make_si_function("STANDARD-READTABLE", siLstandard_readtable);
 
2787
}
 
2788
 
 
2789
object sSPinit;
 
2790
 
 
2791
object
 
2792
read_fasl_vector1(in)
 
2793
object in;
 
2794
{
 
2795
        int dimcount, dim;
 
2796
        VOL object *vsp;
 
2797
        object vspo;
 
2798
        VOL object x;
 
2799
        long i;
 
2800
        bool e;
 
2801
        object old_READtable;
 
2802
        int old_READdefault_float_format;
 
2803
        int old_READbase;
 
2804
        int old_READsuppress;
 
2805
        int old_sharp_eq_context_max;
 
2806
        struct sharp_eq_context_struct
 
2807
                old_sharp_eq_context[SHARP_EQ_CONTEXT_SIZE];
 
2808
        int old_backq_level;
 
2809
 
 
2810
        /* to prevent longjmp clobber */
 
2811
        i=(long)&vsp;
 
2812
        vsp=&vspo;
 
2813
        old_READtable = READtable;
 
2814
        old_READdefault_float_format = READdefault_float_format;
 
2815
        old_READbase = READbase;
 
2816
        old_READsuppress = READsuppress;
 
2817
        old_sharp_eq_context_max = sharp_eq_context_max;
 
2818
        /* BUG FIX by Toshiba */
 
2819
        vs_push(old_READtable);
 
2820
        for (i = 0;  i < sharp_eq_context_max;  i++)
 
2821
                old_sharp_eq_context[i] = sharp_eq_context[i];
 
2822
        old_backq_level = backq_level;
 
2823
 
 
2824
        setup_standard_READ();
 
2825
 
 
2826
        frs_push(FRS_PROTECT, Cnil);
 
2827
        if (nlj_active) {
 
2828
                e = TRUE;
 
2829
                goto L;
 
2830
        }
 
2831
 
 
2832
        while (readc_stream(in) != '#')
 
2833
                ;
 
2834
        while (readc_stream(in) != '(')
 
2835
                ;
 
2836
        vsp = vs_top;
 
2837
        dimcount = 0;
 
2838
        for (;;) {
 
2839
                sharp_eq_context_max = 0;
 
2840
                backq_level = 0;
 
2841
                delimiting_char = code_char(')');
 
2842
                preserving_whitespace_flag = FALSE;
 
2843
                detect_eos_flag = FALSE;
 
2844
                x = read_object(in);
 
2845
                if (x == OBJNULL)
 
2846
                        break;
 
2847
                vs_check_push(x);
 
2848
                if (sharp_eq_context_max > 0)
 
2849
                        x = vs_head = patch_sharp(x);
 
2850
                dimcount++;
 
2851
        }
 
2852
        if(dimcount==1 && type_of(vs_head)==t_vector)
 
2853
          {/* new style where all read at once */
 
2854
            x=vs_head;
 
2855
            goto DONE;}
 
2856
        /* old style separately sharped, and no %init */
 
2857
        {BEGIN_NO_INTERRUPT;
 
2858
        x=alloc_simple_vector(dimcount,aet_object);
 
2859
        vs_push(x);
 
2860
        x->v.v_self
 
2861
        = (object *)alloc_relblock(dimcount * sizeof(object));
 
2862
        END_NO_INTERRUPT;}
 
2863
        for (dim = 0; dim < dimcount; dim++)
 
2864
                {SGC_TOUCH(x);
 
2865
                 x->cfd.cfd_self[dim] = vsp[dim];}
 
2866
        
 
2867
                 
 
2868
          DONE:
 
2869
        e = FALSE;
 
2870
 
 
2871
L:
 
2872
        frs_pop();
 
2873
 
 
2874
        READtable = old_READtable;
 
2875
        READdefault_float_format = old_READdefault_float_format;
 
2876
        READbase = old_READbase;
 
2877
        READsuppress = old_READsuppress;
 
2878
        sharp_eq_context_max = old_sharp_eq_context_max;
 
2879
        for (i = 0;  i < sharp_eq_context_max;  i++)
 
2880
                sharp_eq_context[i] = old_sharp_eq_context[i];
 
2881
        backq_level = old_backq_level;
 
2882
        if (e) {
 
2883
                nlj_active = FALSE;
 
2884
                unwind(nlj_fr, nlj_tag);
 
2885
        }
 
2886
        vs_top = (object *)vsp;
 
2887
        return(x);
 
2888
}