home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_200 / 229_01 / sources.bun < prev    next >
Text File  |  1987-05-27  |  216KB  |  7,943 lines

  1. : To unbundle, sh this file
  2. echo unbundling disclaim 1>&2
  3. cat >disclaim <<'End'
  4. /*
  5.     The source code for the Little Smalltalk System may be freely
  6.     copied provided that the source of all files is acknowledged
  7.     and that this condition is copied with each file.
  8.  
  9.     The Little Smalltalk System is distributed without responsibility
  10.     for the performance of the program and without any guarantee of
  11.     maintenance.
  12.  
  13.     All questions concerning Little Smalltalk should be addressed to:
  14.  
  15.         Professor Tim Budd
  16.         Department of Computer Science
  17.         Oregon State University
  18.         Corvallis, Oregon
  19.         97331
  20.         USA
  21. */
  22. End
  23. echo unbundling Makefile 1>&2
  24. cat >Makefile <<'End'
  25. CFLAGS =
  26. LFLAGS =
  27. LIB = -lm
  28.  
  29. BINDIR = ../bin
  30. PARSEDIR = ../parser
  31.  
  32. Objects = main.o object.o line.o \
  33. class.o number.o symbol.o string.o byte.o array.o file.o \
  34. primitive.o syms.o cldict.o process.o interp.o block.o courier.o \
  35. lex.o drive.o lexcmd.o
  36. Objects.c = main.c object.c line.c \
  37. class.c number.c symbol.c string.c byte.c array.c file.c \
  38. primitive.c syms.c cldict.c process.c interp.c block.c courier.c \
  39. lex.c drive.c lexcmd.c
  40. MISC = disclaim Makefile *.h sstr.c symbols newmal.c
  41.  
  42. st: sstr drive.h cmds.h env.h $(Objects)
  43.     cc $(LFLAGS) -o st $(Objects) $(LIB)
  44.  
  45. newst: sstr drive.h cmds.h env.h $(Objects)
  46.     cc $(LFLAGS) -o newst $(Objects) $(LIB)
  47.  
  48. # the following is used by st make script for installation on the DecPro 350
  49. #    ld -o st -X -u __doprnt -u fltused -u fptrap -m \
  50. # -lfpsim /lib/fcrt0.o $(Objects) -lm -lc
  51.  
  52. install: st
  53.     mv st $(BINDIR)
  54.  
  55. bundle: $(MISC) $(Objects.c)
  56.     rm -f drive.h cmds.h env.h
  57.     bundle $(MISC) $(Objects.c) >../sources.bundle
  58.  
  59. lint.out:$(Objects.c)
  60.     lint $(Objects.c)
  61.  
  62. syms.c: sstr symbols
  63.     sstr -t symbols SYMTABMAX '# include "object.h"' '# include "symbol.h"' >syms.c
  64.  
  65. sstr: sstr.c
  66.     cc $(LFLAGS) -o sstr sstr.c
  67.  
  68. drive.h: $(PARSEDIR)/drive.h symbols
  69.     cp $(PARSEDIR)/drive.h .
  70.  
  71. cmds.h: $(PARSEDIR)/cmds.h symbols
  72.     sstr symbols <$(PARSEDIR)/cmds.h >cmds.h
  73.  
  74. env.h: $(PARSEDIR)/env.h
  75.     cp $(PARSEDIR)/env.h .
  76.  
  77. number.o: number.c number.h
  78. interp.o: drive.h cmds.h
  79. primitive.o: *.h
  80. main.o: *.h
  81.  
  82. clean:
  83.     -rm *.o drive.h cmds.h env.h
  84. End
  85. echo unbundling block.h 1>&2
  86. cat >block.h <<'End'
  87. /*
  88.     Little Smalltalk
  89.         
  90.         block definitions
  91.         timothy a. budd, 10/84
  92. */
  93. /*
  94.     for blocks
  95.  
  96.         b_size = BLOCKSIZE
  97.  
  98.         b_interpreter is an instance of interpreter that will
  99.         actually execute the bytecodes for the block.
  100.  
  101.         b_numargs and b_arglocation are the number of arguments and
  102.         the starting argument location in the context array.
  103.  
  104. */
  105.  
  106. struct block_struct {
  107.     int    b_ref_count;
  108.     int    b_size;
  109.     interpreter    *b_interpreter;
  110.     int    b_numargs;
  111.     int    b_arglocation;
  112.     } ;
  113.  
  114. typedef struct block_struct block;
  115.  
  116. extern object *new_block();
  117. extern interpreter *block_execute();
  118. End
  119. echo unbundling byte.h 1>&2
  120. cat >byte.h <<'End'
  121. /*
  122.     Little Smalltalk
  123.         Bytearray definitions
  124. */
  125.  
  126. struct byte_struct {
  127.     int     a_ref_count;
  128.     int     a_size;
  129.     int    a_bsize;
  130.     uchar    *a_bytes;
  131.     } ;
  132.  
  133. typedef struct byte_struct bytearray;
  134.  
  135. # define byte_value(x) (((bytearray *)(x))->a_bytes)
  136.  
  137. /*
  138.     bytearrays of size less than MAXBSAVE are kept on a free list
  139. */
  140. # define MAXBSAVE 50
  141.  
  142. /*
  143.     in order to avoid a large number of small mallocs, especially
  144.     while reading the standard prelude, a fixed area of MAXBTABSIZE is
  145.     allocated and used for bytecodes until it is full.  Thereafter
  146.     bytecodes are allocated using malloc.  This area should be large
  147.     enough to hold at least all the bytecodes for the standard prelude.
  148. */
  149. # define MAXBTABSIZE 5500
  150.  
  151. /*
  152.     for the same reason, a number of bytearrays structs are statically
  153.     allocated and placed on a free list
  154. */
  155. # define MAXBYINIT 400
  156.  
  157. extern object *new_bytearray();
  158. End
  159. echo unbundling file.h 1>&2
  160. cat >file.h <<'End'
  161. /*
  162.     Little Smalltalk
  163.  
  164.         class File definitions
  165.         timothy a. budd, 11/84
  166. */
  167. /*
  168.     files use standard i/o package
  169. */
  170.  
  171. struct file_struct {
  172.     int l_ref_count;
  173.     int l_size;
  174.     int file_mode;
  175.     FILE *fp;
  176.     };
  177.  
  178. typedef struct file_struct file;
  179.  
  180. extern object *new_file();
  181. extern object *file_read();
  182.  
  183. /* files can be opened in one of three modes, modes are either
  184.     0 - char mode - each read gets one char
  185.     1 - string mode - each read gets a string
  186.     2 - integer mode - each read gets an integer
  187. */
  188. # define CHARMODE 0
  189. # define STRMODE  1
  190. # define INTMODE  2
  191. End
  192. echo unbundling interp.h 1>&2
  193. cat >interp.h <<'End'
  194. /*
  195.         Little Smalltalk interpeter definitions
  196. */
  197. /*
  198.     for interpreters
  199.         t_size = INTERPSIZE
  200.          
  201.         creator is a pointer to the interpreter which created
  202.         the current interpreter.  it is zero except in the case
  203.         of blocks, in which case it points to the creating
  204.         interpreter for a block.  it is NOT a reference, ie,
  205.         the ref_count field of the creator is not incremented when
  206.         this field is set - this avoids memory reference loops.
  207.  
  208.         stacktop is a pointer to a pointer to an object, however it
  209.         is not considered a reference.   ie, changing stacktop does
  210.         not alter reference counts.
  211. */
  212.  
  213. struct interp_struct {
  214.         int    t_ref_count;
  215.     int    t_size;    /* should always be INTERPSIZE */
  216.     struct interp_struct *creator;
  217.     struct interp_struct *sender;
  218.     object     *bytecodes;
  219.     object    *receiver;
  220.     object  *literals;
  221.     object    *context;
  222.     object  *stack;
  223.     object    **stacktop;
  224.     uchar   *currentbyte;
  225.         };
  226.  
  227. typedef struct interp_struct interpreter;
  228.  
  229. extern interpreter *cr_interpreter();
  230.  
  231. extern object *o_drive;
  232.  
  233. # define is_driver(x) (o_drive == (object *) x)
  234. End
  235. echo unbundling number.h 1>&2
  236. cat >number.h <<'End'
  237. /*
  238.     Little Smalltalk number definitions
  239.  
  240. */
  241. /*
  242.     integer and character definitions
  243.     for integers
  244.         i_size = INTEGERSIZE
  245.  
  246.     for characters
  247.         i_size = CHARSIZE
  248.  
  249. */
  250.  
  251. struct int_struct {
  252.         int     i_ref_count;
  253.     int     i_size;
  254.     int    i_value;
  255.     };
  256.  
  257. typedef struct int_struct integer;
  258.  
  259. # define int_value(x) (((integer *)x)->i_value)
  260. # define char_value(x) ((char) int_value(x))
  261.  
  262. extern object *new_cori();    /* new Character OR Integer */
  263.  
  264. # define new_int(x) new_cori(x, 1)
  265. # define new_char(x) new_cori(x, 0)
  266.  
  267. # define INTINITMAX 50
  268.  
  269. /*
  270.     floating point definitions
  271.     size should always be FLOATSIZE
  272. */
  273.  
  274. struct float_struct {
  275.     int    f_ref_count;
  276.     int    f_size;
  277.     double    f_value;
  278.     };
  279.  
  280. typedef struct float_struct sfloat;
  281.  
  282. # define float_value(x) (((sfloat *)x)->f_value)
  283.  
  284. extern object *new_float();
  285. End
  286. echo unbundling object.h 1>&2
  287. cat >object.h <<'End'
  288. /*
  289.         Little Smalltalk object definitions
  290. */
  291. # include "env.h"
  292. /*
  293.     for objects the inst_var array is actually made as large as
  294.     necessary (as large as the size field).  since C does not do
  295.     subscript bounds checking array indexing can be used
  296. */
  297.  
  298. struct obj_struct {
  299.         int                   ref_count;
  300.     int                   size;
  301.         struct class_struct   *class;
  302.         struct obj_struct     *super_obj;
  303.         struct obj_struct     *inst_var[1];
  304.         };
  305.  
  306. /*
  307.     for classes
  308.         c_size = CLASSSIZE
  309.  
  310.         class_name and super_class should be SYMBOLs
  311.         containing the names of the class and superclass,
  312.         respectively.
  313.  
  314.         c_inst_vars should be an array of symbols, containing the
  315.         names of the instance variables
  316.  
  317.         context size is the size of the context that should be
  318.         created each time a message is sent to objects of this
  319.         class.
  320.  
  321.         message_names should be an array of symbols, corresponding
  322.         to the messages accepted by objects of this class.
  323.  
  324.         methods should be an array of arrays, each element being a
  325.         two element array of bytecodes and literals.
  326. */
  327.  
  328. struct class_struct {
  329.     int            c_ref_count;
  330.     int            c_size;
  331.     struct obj_struct    *class_name;
  332.     struct obj_struct    *super_class;
  333.     struct obj_struct    *file_name;
  334.     struct obj_struct    *c_inst_vars;
  335.     int            context_size;
  336.     struct obj_struct    *message_names;
  337.     struct obj_struct    *methods;
  338.     int            stack_max;
  339.     };
  340.  
  341. typedef struct class_struct class;
  342. typedef struct obj_struct object;
  343.  
  344. /*
  345.     objects with non-object value (classes, integers, etc) have a
  346.     negative size field, the particular value being used to indicate
  347.     the type of object (the class field cannot be used for this purpose
  348.     since all classes, even those for built in objects, can be redefined)
  349.  
  350.     check_bltin is a macro that tests the size field for a particular
  351.     value.  it is used to define other macros, such as is_class, that
  352.     test each particular type of object.
  353.  
  354.     The following classes are builtin
  355.  
  356.         Block
  357.         ByteArray
  358.         Char
  359.         Class
  360.         Float
  361.         Integer
  362.         Interpreter
  363.         String
  364.         Symbol
  365. */
  366.  
  367. # define BLOCKSIZE     -83
  368. # define BYTEARRAYSIZE     -567
  369. # define CHARSIZE     -33
  370. # define CLASSSIZE     -3
  371. # define FILESIZE     -5
  372. # define FLOATSIZE     -31415
  373. # define INTEGERSIZE     -17
  374. # define INTERPSIZE     -15
  375. # define PROCSIZE      -100
  376. # define STRINGSIZE     -258
  377. # define SYMBOLSIZE     -14
  378.  
  379. # define is_bltin(x) (x && (((object *) x)->size < 0))
  380. # define check_bltin(obj, type) (obj && (((object *) obj)->size == type))
  381.  
  382. # define is_block(x)        check_bltin(x, BLOCKSIZE)
  383. # define is_bytearray(x)    check_bltin(x, BYTEARRAYSIZE)
  384. # define is_character(x)    check_bltin(x, CHARSIZE)
  385. # define is_class(x)        check_bltin(x, CLASSSIZE)
  386. # define is_file(x)        check_bltin(x, FILESIZE)
  387. # define is_float(x)        check_bltin(x, FLOATSIZE)
  388. # define is_integer(x)        check_bltin(x, INTEGERSIZE)
  389. # define is_interpreter(x)    check_bltin(x, INTERPSIZE)
  390. # define is_process(p)         check_bltin(p, PROCSIZE)
  391. # define is_string(x)        check_bltin(x, STRINGSIZE)
  392. # define is_symbol(x)        check_bltin(x, SYMBOLSIZE)
  393.  
  394. /*
  395.     mstruct is used (via casts) to store linked lists of structures of
  396.     various types for memory saving and recovering
  397. */
  398.  
  399. struct mem_struct {
  400.     struct mem_struct *mlink;
  401.     };
  402.  
  403. typedef struct mem_struct mstruct;
  404.  
  405. /*
  406.     sassign assigns val to obj, which should not have a valid
  407.     value in it already.
  408.     assign decrements an existing val field first, then assigns.
  409.     note this will not work for assign(x,x) if x ref count is 1.
  410.     safeassign, although producing less efficient code, will work even
  411.     in this case
  412. */
  413. # define sassign(obj, val) obj_inc((object *) (obj = val))
  414. # define assign(obj, val)  {obj_dec((object *) obj); sassign(obj, val);}
  415. # define safeassign(obj, val) {obj_inc((object *) val); \
  416.     obj_dec((object *) obj); obj = val; }
  417.  
  418. /* structalloc calls alloc to allocate a block of memory
  419.    for a structure and casts the returned
  420.    pointer to the appropriate type */
  421. # define structalloc(type) (type *) o_alloc(sizeof(type))
  422.  
  423. /*
  424.     if INLINE is defined ( see env.h ) , inline code will be generated
  425.     for object increments.  inline code is generally faster, but
  426.     larger than using subroutine calls for incs and decs
  427. */
  428.  
  429. extern int  n_incs, n_decs;
  430.  
  431. # ifdef INLINE
  432.  
  433. # define obj_inc(x) n_incs++, (x)->ref_count++
  434. extern object *_dx;
  435. # define obj_dec(x) {n_decs++; if (--((_dx=x)->ref_count) <= 0) ob_dec(_dx);}
  436.  
  437. # endif
  438.  
  439. extern char   *o_alloc();    /* allocate a block of memory */
  440. extern object *new_inst();    /* make a new instance of a class */
  441. extern object *new_sinst();    /* an internal (system) version of new_inst*/
  442. extern object *new_obj();    /* allocate a new object */
  443. extern object *new_array();    /* make a new array */
  444. extern object *primitive();    /* perform a primitive operation */
  445.  
  446. extern object *o_nil;        /* current value of pseudo variable nil */
  447. extern object *o_true;        /* current value of pseudo variable true */
  448. extern object *o_false;        /* current value of pseudo variable false */
  449. extern object *o_smalltalk;    /* current value of pseudo var smalltalk */
  450.  
  451. extern int debug;        /* debugging toggle */
  452.  
  453. /* reference count macro, used during debugging */
  454. # define rc(x) ((object *)x)->ref_count
  455. End
  456. echo unbundling primitive.h 1>&2
  457. cat >primitive.h <<'End'
  458. /*
  459.     Little Smalltalk primitive definitions
  460.  
  461.     (only a subset of primitives are described here,
  462.     basically those used by the courier and other systems routines.
  463.     All other primitives are known only by number)
  464.  
  465. */
  466. # define EQTEST 7
  467. # define GAMMAFUN 77
  468. # define SYMEQTEST 91
  469. # define SYMPRINT  94
  470. # define FINDCLASS 99
  471. # define GROW 113
  472. # define BLKRETERROR 127
  473. # define REFCOUNTERROR 128
  474. # define NORESPONDERROR 129
  475. # define RAWPRINT 120
  476. # define PRINT 121
  477. # define ERRPRINT 123
  478. # define BLOCKEXECUTE 140
  479. # define DOPERFORM 143
  480. End
  481. echo unbundling process.h 1>&2
  482. cat >process.h <<'End'
  483. /*
  484.     Little Smalltalk
  485.  
  486.         process definitions
  487.         dennis a. vadner and michael t. benhase,  11/84
  488. */
  489. /*
  490.     the process
  491.  
  492.         interp = pointer to the head of the process'
  493.              interpreter chain
  494.         p_state = current state of the process
  495.  
  496.         next = link to the next process in the active list
  497.         prev = link to the previous process in the active list
  498. */
  499.  
  500.  
  501. struct  process_struct {
  502.     int        p_ref_count;
  503.     int        p_size;
  504.     interpreter    *interp;
  505.     int        p_state;
  506.     struct process_struct  *next;
  507.     struct process_struct  *prev;
  508.     } ;
  509.  
  510. typedef  struct process_struct  process;
  511.  
  512. extern int  atomcnt;            /* atomic action flag */
  513. extern process  *runningProcess;    /* currently running process */
  514.  
  515. extern process  *cr_process();        /* create a new process */
  516. extern int  set_state();        /* set the state on a process */
  517.  
  518.  
  519. /* process states */
  520.  
  521. # define  ACTIVE    0
  522. # define  SUSPENDED    1
  523. # define  READY        ~SUSPENDED
  524. # define  BLOCKED    2
  525. # define  UNBLOCKED    ~BLOCKED
  526. # define  TERMINATED    4
  527.  
  528. # define  CUR_STATE    10
  529.  
  530.  
  531. # define  terminate_process(aProcess)  {set_state(aProcess, TERMINATED); \
  532.                     if (aProcess == runningProcess)  \
  533.                         atomcnt = 0;}
  534. End
  535. echo unbundling string.h 1>&2
  536. cat >string.h <<'End'
  537. /*
  538.     Little Smalltalk string definitions
  539. */
  540. /*
  541.     for strings s_size = STRINGSIZE
  542.  
  543.     Unlike other special objects (integers, floats, etc), strings
  544.     must keep their own super_obj pointer, since the class
  545.     ArrayedCollection (a super class of String) contains instance
  546.     variables, and thus each instance of String must have a unique
  547.     super_obj.
  548. */
  549.  
  550. struct string_struct {
  551.     int    s_ref_count;
  552.     int    s_size;
  553.     object     *s_super_obj;
  554.     char    *s_value;
  555.     } ;
  556.  
  557. typedef struct string_struct string;
  558.  
  559. extern object *new_str();        /* make a new string object */
  560. extern string *new_istr();        /* internal form of new string */
  561. extern char   *walloc();        /* allocate a copy a word */
  562.  
  563. # define string_value(x) (((string *) x)->s_value)
  564. End
  565. echo unbundling symbol.h 1>&2
  566. cat >symbol.h <<'End'
  567. /*
  568.     Little Smalltalk string and symbol definitions
  569. */
  570. /*
  571.     for symbols y_size = SYMBOLSIZE
  572.  
  573.     only one text copy of each symbol is kept.
  574.     A global symbol table is searched each time a new symbol is
  575.     created, and symbols with the same character representation are
  576.     given the same entry.
  577.  
  578. */
  579.  
  580. struct symbol_struct {
  581.     int    y_ref_count;
  582.     int    y_size;
  583.     char    *y_value;
  584.     } ;
  585.  
  586. typedef struct symbol_struct symbol;
  587.  
  588. extern symbol *sy_search();    /* binary search for a symbol */
  589. extern char   *w_search();    /* binary search for a word */
  590.  
  591. # define symbol_value(x) (((symbol *) x)->y_value)
  592. # define new_sym(val) ((object *) sy_search(val, 1))
  593.  
  594.  
  595. # define SYMTABMAX 500
  596.  
  597. /* SYMINITSIZE symbol entries are allocated at the start of execution,
  598. which prevents malloc from being called too many times */
  599.  
  600. # define SYMINITSIZE 60
  601. End
  602. echo unbundling sstr.c 1>&2
  603. cat >sstr.c <<'End'
  604. /*
  605.     sstr - find and replace string occurrences
  606.         with common addresses,
  607.         can be used to share strings accross compiled boundaries
  608.         written by tim budd, 9/84
  609. */
  610. /*
  611.     The source code for the Little Smalltalk System may be freely
  612.     copied provided that the source of all files is acknowledged
  613.     and that this condition is copied with each file.
  614.  
  615.     The Little Smalltalk System is distributed without responsibility
  616.     for the performance of the program and without any guarantee of
  617.     maintenance.
  618.  
  619.     All questions concerning Little Smalltalk should be addressed to:
  620.  
  621.         Professor Tim Budd
  622.         Department of Computer Science
  623.         Oregon State University
  624.         Corvallis, Oregon
  625.         97331
  626.         USA
  627. */
  628. # include <stdio.h>
  629. # define WORDTABMAX 1000
  630. # define STRTABMAX 10000
  631.  
  632. int x_cmax = 0;
  633. int x_tmax = -1;
  634. char x_str[STRTABMAX];
  635. char *x_tab[WORDTABMAX];
  636.  
  637.  
  638. main(argc, argv)
  639. int argc;
  640. char **argv;
  641. {    int i;
  642.     FILE *fd;
  643.  
  644.     if (strcmp(argv[1], "-f") == 0) {
  645.         for (i = 2; i < argc; i++) {
  646.             fd = fopen(argv[i], "r");
  647.             if (fd != NULL) {
  648.                 findstrs(fd);
  649.                 fclose(fd);
  650.                 }
  651.             }
  652.         }
  653.     else if (strcmp(argv[1], "-t") == 0) {
  654.         for (i = 4; i < argc; i++)
  655.            puts(argv[i]);
  656.         fd = fopen(argv[2], "r");
  657.         if (fd == NULL) {
  658.             fprintf(stderr,"can't open string table\n");
  659.             exit(1);
  660.             }
  661.         maketab(fd, stdout, argv[3]);
  662.         }
  663.     else {
  664.         fd = fopen(argv[1], "r");
  665.         if (fd == NULL) {
  666.             fprintf(stderr,"can't open string table\n");
  667.             exit(1);
  668.             }
  669.         maketab(fd, 0, 0);
  670.         printf("extern char x_str[];\n");
  671.         replacestr(stdin);
  672.         }
  673.     exit(0);
  674. }
  675.  
  676. /* findstrs - find all strings and output them to stdout */
  677. findstrs(fd)
  678. FILE *fd;
  679. {
  680.     char *p, buffer[500];
  681.     int c;
  682.  
  683.     for (; (c = getc(fd)) != EOF; )
  684.         if (c == '\"') {
  685.             for (p = buffer; (c = getc(fd)) != '\"'; p++)
  686.                 if (c == EOF) {
  687.                     fprintf(stderr,"unexpected eof\n");
  688.                     exit(1);
  689.                     }
  690.                 else *p = c;
  691.             *p = '\0';
  692.             puts(buffer);
  693.             }
  694. }
  695.  
  696. /* replacestr - replace strings with their address in x_str */
  697. replacestr(fd)
  698. FILE *fd;
  699. {
  700.     char *p, buffer[500], *w_search();
  701.     int c;
  702.  
  703.     for (; (c = getc(fd)) != EOF; )
  704.         if (c != '\"') putchar(c);
  705.         else {
  706.             for (p = buffer; (c = getc(fd)) != '\"'; p++)
  707.                 if (c == EOF) {
  708.                     fprintf(stderr,"unexpected eof\n");
  709.                     exit(1);
  710.                     }
  711.                 else *p = c;
  712.             *p = '\0';
  713.             p = w_search(buffer, 0);
  714.             if (p) printf("&x_str[%d]", p - &x_str[0]);
  715.             else printf("\"%s\"", buffer);
  716.             }
  717. }
  718.  
  719. maketab(ifd, ofd, itab)
  720. FILE *ifd, *ofd;
  721. char *itab;
  722. {    char wbuf[100], *p;
  723.     int i;
  724.  
  725.     x_cmax = 0;
  726.     if (ofd)
  727.         fprintf(ofd, "char x_str[] = {");
  728.     while (fgets(wbuf, 100, ifd) != NULL) {
  729.         x_tab[++x_tmax] = &x_str[x_cmax];
  730.         for (p = wbuf; *p; p++) {
  731.             if (*p == '\n') {*p = '\0'; break;}
  732.             if (ofd)
  733.                 fprintf(ofd,"0%o, ", *p);
  734.             x_str[x_cmax++] = *p;
  735.             }
  736.         if (ofd)
  737.             fprintf(ofd, "0,   /* %s */\n", wbuf);
  738.         x_str[x_cmax++] = '\0';
  739.         }
  740.     if (ofd) {
  741.         fprintf(ofd, "0 };\n");
  742.         fprintf(ofd, "int x_cmax = %d;\n", x_cmax);
  743.         }
  744.     if (itab) {
  745.         fprintf(ofd, "static symbol x_sytab[] = {\n");
  746.         for (i = 0; i <= x_tmax; i++) {
  747.             fprintf(ofd, "{1, SYMBOLSIZE, &x_str[%d]}, /* ",
  748.                 x_tab[i]-x_tab[0]);
  749.             for (p = x_tab[i]; *p; p++)
  750.                 putc(*p, ofd);
  751.             fprintf(ofd," */\n");
  752.             }
  753.         fprintf(ofd, "0};\n");
  754.         fprintf(ofd, "symbol *x_tab[%s] = {\n", itab);
  755.         for (i = 0; i <= x_tmax; i++) {
  756.             fprintf(ofd, "&x_sytab[%d], /* ",i);
  757.             for (p = x_tab[i]; *p; p++)
  758.                 putc(*p, ofd);
  759.             fprintf(ofd," */\n");
  760.             }
  761.         fprintf(ofd, "0};\n");
  762.         fprintf(ofd,"int x_tmax = %d;\n", x_tmax);
  763.         }
  764. }
  765.  
  766. /*     
  767.     word search for table routines
  768. */
  769.  
  770. char *w_search(word, insert)
  771. char *word;
  772. int  insert;
  773. {    int i,j,k;
  774.  
  775.     for (i=1; i <= x_tmax; i <<= 1);
  776.     for (i >>= 1, j = i >>1, i--; ; j >>= 1) {
  777.         if (! (k = strcmp(word, x_tab[i])))
  778.             return(x_tab[i]);
  779.  
  780.         if (!j) break;
  781.         if (k < 0) i -= j;
  782.         else {
  783.             if ((i += j) > x_tmax) i = x_tmax;
  784.             }
  785.         }
  786.     if (insert) {
  787.         for (k = ++x_tmax; k > i; k--) {
  788.             x_tab[k] = x_tab[k-1];
  789.             }
  790.         if (!(x_tab[i] = (char *) malloc(1 + strlen(word))))
  791.             return((char *) 0);
  792.         strcpy(x_tab[i], word);
  793.         return(x_tab[i]);
  794.         }
  795.     else return((char *) 0);
  796. }
  797. End
  798. echo unbundling symbols 1>&2
  799. cat >symbols <<'End'
  800. !
  801. &
  802. (
  803. )
  804. *
  805. +
  806. ,
  807. -
  808. /
  809. //
  810. <
  811. <=
  812. =
  813. ==
  814. >
  815. >=
  816. @
  817. Array
  818. ArrayedCollection
  819. BLOCKED
  820. Bag
  821. Block
  822. Boolean
  823. ByteArray
  824. Char
  825. Class
  826. Collection
  827. Complex
  828. Dictionary
  829. False
  830. File
  831. Float
  832. Integer
  833. Interpreter
  834. Interval
  835. KeyedCollection
  836. List
  837. Little Smalltalk
  838. Magnitude
  839. Main
  840. Number
  841. Object
  842. OrderedCollection
  843. Point
  844. Process
  845. READY
  846. Radian
  847. Random
  848. SUSPENDED
  849. Semaphore
  850. SequenceableCollection
  851. Set
  852. Smalltalk
  853. String
  854. Symbol
  855. TERMINATED
  856. True
  857. UndefinedObject
  858. [
  859. \\
  860. \\\\
  861. ]
  862. ^
  863. abs
  864. add:
  865. add:after:
  866. add:before:
  867. add:withOccurrences:
  868. addAll:
  869. addAllFirst:
  870. addAllLast:
  871. addFirst:
  872. addLast:
  873. after:
  874. allMask:
  875. and:
  876. anyMask:
  877. arcCos
  878. arcSin
  879. arcTan
  880. argerror
  881. asArray
  882. asBag
  883. asCharacter
  884. asDictionary
  885. asFloat
  886. asFraction
  887. asInteger
  888. asList
  889. asLowercase
  890. asOrderedCollection
  891. asSet
  892. asString
  893. asSymbol
  894. asUppercase
  895. asciiValue
  896. at:
  897. at:ifAbsent:
  898. at:put:
  899. atAll:put:
  900. atAllPut:
  901. before:
  902. between:and:
  903. binaryDo:
  904. bitAnd:
  905. bitAt:
  906. bitInvert
  907. bitOr:
  908. bitShift:
  909. bitXor:
  910. block
  911. blockedProcessQueue
  912. ceiling
  913. checkBucket:
  914. class
  915. cleanUp
  916. coerce:
  917. collect:
  918. commands:
  919. compareError
  920. copy
  921. copyArguments:
  922. copyArguments:to:
  923. copyFrom:
  924. copyFrom:length:
  925. copyFrom:to:
  926. copyWith:
  927. copyWithout:
  928. cos
  929. count
  930. currAssoc
  931. currBucket
  932. current
  933. currentBucket
  934. currentKey
  935. currentList
  936. date
  937. debug:
  938. deepCopy
  939. deepCopy:
  940. detect:
  941. detect:ifAbsent:
  942. detect:ifNone:
  943. dict
  944. dictionary
  945. digitValue
  946. digitValue:
  947. display
  948. displayAssign
  949. dist:
  950. do:
  951. doPrimitive:
  952. doPrimitive:withArguments:
  953. edit
  954. equals:startingAt:
  955. eqv:
  956. error:
  957. even
  958. excessSignals
  959. executeWith:
  960. exp
  961. factorial
  962. findAssociation:inList:
  963. findFirst:
  964. findFirst:ifAbsent:
  965. findLast
  966. findLast:
  967. findLast:ifAbsent:
  968. first
  969. firstKey
  970. floor
  971. floorLog:
  972. fork
  973. forkWith:
  974. fractionPart
  975. free:
  976. from:
  977. from:to:
  978. from:to:by:
  979. gamma
  980. gcd:
  981. getList:
  982. grid:
  983. hashNumber:
  984. hashTab
  985. hashTable
  986. highBit
  987. i
  988. ifFalse:
  989. ifFalse:ifTrue:
  990. ifTrue:
  991. ifTrue:ifFalse:
  992. inRange:
  993. includes:
  994. includesKey:
  995. indexOf:
  996. indexOf:ifAbsent:
  997. indexOfSubCollection:startingAt:
  998. indexOfSubCollection:startingAt:ifAbsent:
  999. init:
  1000. init:super:
  1001. init:super:numVars:
  1002. inject:into:
  1003. integerPart
  1004. isAlphaNumeric
  1005. isDigit
  1006. isEmpty
  1007. isKindOf:
  1008. isLetter
  1009. isLowercase
  1010. isMemberOf:
  1011. isNil
  1012. isSeparator
  1013. isUppercase
  1014. isVowel
  1015. keys
  1016. keysDo:
  1017. keysSelect:
  1018. last
  1019. lastKey
  1020. lcm:
  1021. list
  1022. ln
  1023. log:
  1024. lower
  1025. main
  1026. max:
  1027. maxContext:
  1028. maxtype:
  1029. methods:
  1030. min:
  1031. modeCharacter
  1032. modeInteger
  1033. modeString
  1034. name:
  1035. negated
  1036. negative
  1037. new
  1038. new:
  1039. newProcess
  1040. newProcessWith:
  1041. next
  1042. next:
  1043. noDisplay
  1044. noMask:
  1045. not
  1046. notNil
  1047. nothing
  1048. occurrencesOf:
  1049. odd
  1050. opError
  1051. open:
  1052. open:for:
  1053. or:
  1054. perform:
  1055. perform:withArguments:
  1056. pi
  1057. positive
  1058. print
  1059. printString
  1060. put:
  1061. quo:
  1062. radians
  1063. radix:
  1064. raisedTo:
  1065. raisedToInteger:
  1066. randInteger:
  1067. randomize
  1068. read
  1069. reciprocal
  1070. reject:
  1071. rem:
  1072. remove:
  1073. remove:ifAbsent:
  1074. removeAll:
  1075. removeError
  1076. removeFirst
  1077. removeKey:
  1078. removeKey:ifAbsent:
  1079. removeLast
  1080. removed
  1081. replaceFrom:to:with:
  1082. replaceFrom:to:with:startingAt:
  1083. respondsTo
  1084. respondsTo:
  1085. resume
  1086. reverseDo:
  1087. reversed
  1088. roundTo:
  1089. rounded
  1090. sameAs:
  1091. seed
  1092. select:
  1093. setCurrentLocation:
  1094. sh:
  1095. shallowCopy
  1096. shallowCopy:
  1097. sign
  1098. signal
  1099. sin
  1100. size
  1101. smalltalk
  1102. sort
  1103. sort:
  1104. sqrt
  1105. squared
  1106. state
  1107. step
  1108. strictlyPositive
  1109. superClass
  1110. superClass:
  1111. suspend
  1112. tan
  1113. temp
  1114. termErr:
  1115. terminate
  1116. time:
  1117. timesRepeat:
  1118. to:
  1119. to:by:
  1120. transpose
  1121. truncateTo:
  1122. truncated
  1123. truncatedGrid:
  1124. unblock
  1125. upper
  1126. value
  1127. value:
  1128. value:value:
  1129. value:value:value:
  1130. value:value:value:value:
  1131. value:value:value:value:value:
  1132. values
  1133. variables
  1134. variables:
  1135. view
  1136. wait
  1137. whileFalse:
  1138. whileTrue:
  1139. with:do:
  1140. withArguments:
  1141. write:
  1142. x
  1143. x:
  1144. xor:
  1145. xvalue
  1146. y
  1147. y:
  1148. yield
  1149. yvalue
  1150. |
  1151. ~
  1152. ~=
  1153. ~~
  1154. End
  1155. echo unbundling newmal.c 1>&2
  1156. cat >newmal.c <<'End'
  1157. /*
  1158. From gi!sytek!menlo70!hao!seismo!harpo!utah-cs!thomas Thu Dec 16 14:08:48 1982
  1159. Subject: New malloc subroutine
  1160. Newsgroups: net.sources
  1161.  
  1162. This malloc works much better in a VAX (paging) environment.  I doubt it would
  1163. work very well on a PDP-11 (in fact, the copymem routine uses an asm, so it
  1164. will work only on a VAX without modification).  Defining MSTATS causes
  1165. some statistics to be kept, and the routine mstats(string) can be called
  1166. to print them out.  Defining rcheck causes more careful checking to be done,
  1167. may help find bugs in code (I haven't used it).  Note that the layout of
  1168. the arena is QUITE different from the old malloc, so anything that depends
  1169. on this will need to be rewritten.  I make no guarantees, and it's not my
  1170. code to begin with (I asked the author, whose name I have forgotten now,
  1171. for permission to redistribute).
  1172.  
  1173. -Spencer
  1174. ================================================================
  1175. */
  1176. /* @(#)nmalloc.c 1 (Caltech) 2/21/82
  1177.  *  This is a very fast storage allocator.  It allocates blocks of a small
  1178.  *  number of different sizes, and keeps free lists of each size.  Blocks that
  1179.  *  don't exactly fit are passed up to the next larger size.  In this
  1180.  *  implementation, the available sizes are (2^n)-4 (or -12) bytes long.
  1181.  *  This is designed for use in a program that uses vast quantities of memory,
  1182.  *  but bombs when it runs out.  To make it a little better, it warns the
  1183.  *  user when he starts to get near the end.
  1184.  */
  1185.  
  1186. /* nextf[i] is the pointer to the next free block of size 2^(i+3).  The
  1187.  * smallest allocatable block is 8 bytes.  The overhead information will
  1188.  * go in the first int of the block, and the returned pointer will point
  1189.  * to the second.
  1190.  *
  1191. #ifdef MSTATS
  1192.  * nmalloc[i] is the difference between the number of mallocs and frees
  1193.  * for a given block size.
  1194. #endif MSTATS
  1195.  */
  1196.  
  1197. static unsigned int *nextf[30];
  1198.  
  1199. #define MSTATS
  1200. #ifdef MSTATS
  1201. static unsigned int nmalloc[30];
  1202. #include "stdio.h"
  1203. #endif MSTATS
  1204.  
  1205. #include <sys/vlimit.h>     /* warn the user when near the end */
  1206. #ifdef debug
  1207. #define ASSERT(p)   if (!(p))botch("p"); else
  1208. #else
  1209. #define ASSERT(p)
  1210. #endif
  1211.  
  1212. extern char etext;           /* end of the program */
  1213. #define NULL 0
  1214.  
  1215. #ifdef rcheck
  1216. #define MAGIC 0x55555555
  1217. #endif
  1218.  
  1219. /*      The overhead on a block will be four bytes long.  When free, it will
  1220.  *  contain a pointer to the next free block, and the bottom two bits must
  1221.  *  be zero.  When in use, the first byte will be set to 0xFF, and the second
  1222.  *  byte will be the size index.  The other two bytes are only used for
  1223.  *  alignment.  If you are range checking, and the size of the block will fit
  1224.  *  into two bytes, then the top two bytes hold the size of the requested block
  1225.  *  plus the range checking words, and the header word MINUS ONE.
  1226.  */
  1227.  
  1228. static *morecore(nu)    /* ask system for more memory */
  1229. register int nu;        /* size index to get more of  */
  1230. {   char *sbrk();
  1231.     register unsigned int *cp;
  1232.     register int rnu;       /* 2^rnu bytes will be requested */
  1233.     register int nblks;     /* that becomes nblks blocks of the desired size */
  1234.     register int siz;       /* size in ints, not bytes */
  1235.     static int warnlevel=0;
  1236.     register int used;
  1237.  
  1238.     if (nextf[nu]!=NULL)
  1239.     return;
  1240.  
  1241.     siz=vlimit(LIM_DATA,-1);        /* find out how much we can get */
  1242.     cp=((unsigned int *)sbrk(0));
  1243.     used=(int)cp;
  1244.     used-= (int)&etext;
  1245.     switch (warnlevel){
  1246.     case 0:
  1247.     if (used>(siz/4)*3){
  1248.         write(2,"warning: past 75% of memory limit\7\n",35);
  1249.         warnlevel=1;}
  1250.     break;
  1251.     case 1:
  1252.     if (used>(siz/20)*17){
  1253.         write(2,"warning: past 85% of memory limit\7\n",35);
  1254.         warnlevel=2;}
  1255.     break;
  1256.     case 2:
  1257.     if (used>(siz/20)*19){
  1258.         write(2,"warning: past 95% of memory limit\7\n",35);
  1259.         warnlevel=3;}
  1260.     break;
  1261.     }       /* end of warning switch */
  1262.     if ((((int)cp)&0x3ff) != 0)       /* land on 1K boundaries */
  1263.     sbrk(1024-(((int)cp)&0x3ff));
  1264.  
  1265.     rnu=(nu<=8)?11:nu+3;    /* take 2k unless the block is bigger than that */
  1266.     nblks=1<<(rnu-(nu+3));  /* how many blocks to get */
  1267.     if (rnu<nu) rnu=nu;
  1268.     if ((int)(cp=(unsigned int*)sbrk(1<<rnu)) == -1)      /* no more room! */
  1269.     return;
  1270.     if ((((int)cp) & 7)!=0){
  1271.     cp=(unsigned int*)((((int)cp)+8)&~7);
  1272.     nblks--;}
  1273.     nextf[nu]=cp;
  1274.     siz= 1<<(nu+1);
  1275.     while (--nblks>0){
  1276.     ((unsigned int**)cp)[0]= &cp[siz];
  1277.     cp= (unsigned int*)&cp[siz];}
  1278. }
  1279.  
  1280. char *malloc(nbytes)    /* get a block */
  1281. register unsigned nbytes;
  1282. {
  1283.     register unsigned char *p;
  1284.     register int nunits=0;
  1285.     register unsigned shiftr;
  1286.  
  1287. #ifdef rcheck
  1288.     nbytes+=12;     /* make sure the range checkers will fit */
  1289. #else
  1290.     nbytes+=4;      /* add on for the overhead */
  1291. #endif
  1292.     nbytes=(nbytes+3)&~3;       /* round up, but still measure in bytes */
  1293.     shiftr=(nbytes-1)>>2;
  1294.     while ((shiftr>>=1)!=0)     /* apart from this loop, this is O(1) */
  1295.     nunits++;
  1296.     if (nextf[nunits]==NULL)    /* needed block, nunits is the size index */
  1297.     morecore(nunits);
  1298.     if ((p=(unsigned char*)(nextf[nunits]))==NULL)
  1299.     return(NULL);
  1300.     nextf[nunits]= (unsigned int*)*nextf[nunits];
  1301.     p[0]=0xff;
  1302.     p[1]=nunits;
  1303. #ifdef MSTATS
  1304.     nmalloc[nunits]++;
  1305. #endif MSTATS
  1306. #ifdef rcheck
  1307.     if (nbytes<=0x10000)
  1308.     ((unsigned short*)p)[1]=(unsigned short)nbytes-1;
  1309.     *((int*)(p+4))=MAGIC;
  1310.     *((int*)(p+nbytes-4))=MAGIC;
  1311.     return((char*)(p+8));
  1312. #else
  1313.     return((char*)(p+4));
  1314. #endif
  1315. }
  1316.  
  1317. free(ap)
  1318. register unsigned char *ap;
  1319. {   register int si;
  1320.  
  1321.     if (ap==NULL)
  1322.     return;
  1323. #ifdef rcheck
  1324.     ap-=4;
  1325.     ASSERT(*(int*)ap==MAGIC);
  1326. #endif
  1327.     ap-=4;                              /* point back to overhead word */
  1328. #ifdef debug
  1329.     ASSERT(ap[0]==0xff);                /* make sure it was in use */
  1330. #else
  1331.     if (ap[0]!=0xff)
  1332.     return;
  1333. #endif
  1334. #ifdef rcheck
  1335.     if (ap[1]<=13){
  1336.     si=((unsigned short *)ap)[1]-11;  /* get the size of the data */
  1337.     ASSERT(*((int*)(ap+si+8))==MAGIC);  /* check for overflow */
  1338.     }
  1339. #endif
  1340.     ASSERT(ap[1]<=29);
  1341.     si=ap[1];
  1342.     *((unsigned int**)ap)=nextf[si];
  1343.     nextf[si]=(unsigned int*)ap;
  1344. #ifdef MSTATS
  1345.     nmalloc[si]--;
  1346. #endif MSTATS
  1347. }
  1348.  
  1349. char *realloc(p, nbytes)
  1350. register char *p; register unsigned nbytes;
  1351. {   register char *res;
  1352.     register unsigned int onb;
  1353.  
  1354.     if (p==NULL)
  1355.     return(malloc(nbytes));
  1356. #ifdef rcheck
  1357.     if (p[-7]<13)
  1358.     onb= ((unsigned short*)p)[-3]-11;  /* old number of data bytes only */
  1359.     else
  1360.     onb=(1<<(p[-7]+3))-12;
  1361. #else
  1362.     onb=(1<<(p[-3]+3))-4;
  1363. #endif
  1364.     if ((res=malloc(nbytes))==NULL)
  1365.     return(NULL);
  1366.     copymem((nbytes<onb)?nbytes:onb,p,res);
  1367.     free(p);
  1368.     return(res);
  1369. }
  1370.  
  1371. copymem(n, from, to)
  1372. int n;
  1373. register char * from, * to;
  1374. {
  1375.     register int i;
  1376.  
  1377.     while (n > 0)
  1378.     {
  1379.     i = n > 65535L ? 65535L : n;
  1380.     asm("    movc3    r9,(r11),(r10)");    /* glug! */
  1381.     n -= i;
  1382.     from += i;
  1383.     to += i;
  1384.     }
  1385. }
  1386.  
  1387. #ifdef MSTATS
  1388. /* ****************************************************************
  1389.  * mstats - print out statistics about malloc
  1390.  *
  1391.  * Prints two lines of numbers, one showing the length of the free list
  1392.  * for each size category, the second showing the number of mallocs -
  1393.  * frees for each size category.
  1394.  */
  1395.  
  1396. mstats(s)
  1397. char *s;
  1398. {
  1399.     register int i, j;
  1400.     register unsigned int * p;
  1401.     int totfree = 0,
  1402.         totused = 0;
  1403.  
  1404.     fprintf(stderr, "Memory allocation statistics %s\nfree:\t", s);
  1405.     for (i=0; i<30; i++)
  1406.     {
  1407.     for (j=0, p=nextf[i]; p; p = (unsigned int *)*p, j++)
  1408.         ;
  1409.     fprintf(stderr, " %d", j);
  1410.     totfree += j * (1 << (i+3));
  1411.     }
  1412.     fprintf(stderr, "\nused:\t");
  1413.     for (i=0; i<30; i++)
  1414.     {
  1415.     fprintf(stderr, " %d", nmalloc[i]);
  1416.     totused += nmalloc[i] * (1 << (i+3));
  1417.     }
  1418.     fprintf(stderr, "\n\tTotal in use: %d, total free: %d\n");
  1419. }
  1420. #else
  1421. mstats()
  1422. {                    /* dummy to keep people happy */
  1423. }
  1424. #endif
  1425.  
  1426. End
  1427. echo unbundling main.c 1>&2
  1428. cat >main.c <<'End'
  1429. /*
  1430.     Little Smalltalk -
  1431.         main driver
  1432.  
  1433.         timothy a. budd
  1434.  
  1435. 1.     initializes various smalltalk constants and classes with
  1436.     legitimate values.  these values, however, will for the most part
  1437.     be overridden when the standard prelude is read in.
  1438.  
  1439. 2.    reads in the standard prelude, plus any additional files listed
  1440.     on the command line.
  1441.  
  1442. 3.    places the driver reading stdin on the process queue and starts
  1443.     the process driver running.
  1444. */
  1445. /*
  1446.     The source code for the Little Smalltalk System may be freely
  1447.     copied provided that the source of all files is acknowledged
  1448.     and that this condition is copied with each file.
  1449.  
  1450.     The Little Smalltalk System is distributed without responsibility
  1451.     for the performance of the program and without any guarantee of
  1452.     maintenance.
  1453.  
  1454.     All questions concerning Little Smalltalk should be addressed to:
  1455.  
  1456.         Professor Tim Budd
  1457.         Department of Computer Science
  1458.         Oregon State University
  1459.         Corvallis, Oregon
  1460.         97331
  1461.         USA
  1462. */
  1463.  
  1464. int version = 2; /* a Kludge to get us the start of the data segment.
  1465.             used to save and restore contexts */
  1466.  
  1467.  
  1468. # include <stdio.h>
  1469. # include "object.h"
  1470. # include "string.h"
  1471. # include "symbol.h"
  1472. # include "interp.h"
  1473. # include "primitive.h"
  1474.  
  1475. static object *null_object;    /* a totally classless object */
  1476. static char filebase[80];    /* base for forming temp file names */
  1477.  
  1478. extern int n_incs, n_decs, n_mallocs;    /* counters */
  1479. extern int opcount[], ohcount, spcount[];
  1480.  
  1481. extern int ca_block, ca_barray, ca_class, ca_terp, ca_int, ca_float;
  1482. extern int ca_obj, ca_str, ca_sym, ca_wal, ca_cdict;
  1483. extern int ca_cobj[];
  1484. extern int btabletop, wtop;    /* more counters */
  1485.  
  1486. # ifdef INLINE
  1487. object *_dx;        /* object pointer used for decrementing */
  1488. # endif
  1489.  
  1490. int silence = 0;        /* 1 if silence is desired on output */
  1491. int noload = 0;         /* 1 if no loading of standard prelude is desired */
  1492. int debug = 0;        /* debug flag, set by a primitive call */
  1493. int fastload = 0;    /* 1 if doing a fast load of saved image */
  1494. int lexprnt = 0;    /* 1 if printing during lex is desired (for debug) */
  1495. int prallocs = 0;    /* 1 if printing final allocation figures is wanted */
  1496. int started = 0;    /* 1 if we have started reading user commands */
  1497. int prntcmd = 1;    /* 1 or 2 and commands will be printed as evaled */
  1498.  
  1499. /* pseudo-variables */
  1500. object *o_acollection;        /* arrayed collection (used internally) */
  1501. object *o_drive;        /* driver interpreter */
  1502. object *o_empty;        /* the empty array (used during initial) */
  1503. object *o_false;        /* value for pseudo variable false */
  1504. object *o_magnitude;        /* instance of class Magnitude */
  1505. object *o_nil;            /* value for pseudo variable nil */
  1506. object *o_number;        /* instance of class Number */
  1507. object *o_object;        /* instance of class Object */
  1508. object *o_tab;            /* string with tab only */
  1509. object *o_true;            /* value of pseudo variable true */
  1510. object *o_smalltalk;        /* value of pseudo variable smalltalk */
  1511.  
  1512. /* classes to be initialized */
  1513. extern class *Array;
  1514. extern class *ArrayedCollection;
  1515.  
  1516. /* input stack */
  1517. extern FILE *fdstack[];
  1518. extern int fdtop;
  1519.  
  1520. /* main - main driver */
  1521. main(argc, argv)
  1522. int argc;
  1523. char **argv;
  1524. {    int i;
  1525.     class *null_class();
  1526.     object *tempobj;
  1527.     FILE *sfd;
  1528.  
  1529. # ifdef FASTDEFAULT
  1530.     fastload = 1;
  1531. # endif
  1532. # ifndef FASTDEFAULT
  1533.     fastload = 0;
  1534. # endif
  1535.  
  1536.     /* first check for flags */
  1537.     for (i = 1; i < argc; i++)
  1538.         if (argv[i][0] == '-')
  1539.             switch(argv[i][1]) {
  1540.                 case 'f': fastload = 1; break;
  1541.                 case 'l':         /* fall through */
  1542.                 case 'n': noload = 1; /* fall through */
  1543.                 case 'm': fastload = 0; break;
  1544.                 case 'z': lexprnt = 1; break;
  1545.             }
  1546.  
  1547.     if (fastload) {
  1548.         dofast();
  1549.         }
  1550.     else {            /* gotta do it the hard way */
  1551.         strcpy(filebase, TEMPFILE);
  1552.         mktemp(filebase);
  1553.  
  1554.         byte_init();
  1555.         class_init();
  1556.         cdic_init();
  1557.         int_init();
  1558.         str_init();
  1559.         sym_init();
  1560.         init_objs();
  1561.  
  1562.         null_object = new_obj((class *) 0, 0, 0);
  1563.  
  1564.         sassign(o_object, null_object);
  1565.         /* true is given a different object from others , so comparisons
  1566.                     work correctly */
  1567.         sassign(o_true, new_obj((class *) 0, 0, 0));
  1568.         sassign(o_false, null_object);
  1569.         sassign(o_nil, null_object);
  1570.         sassign(o_number, null_object);
  1571.         sassign(o_magnitude, null_object);
  1572.         sassign(o_empty, null_object);
  1573.         sassign(o_smalltalk, null_object);
  1574.         sassign(o_acollection, null_object);
  1575.  
  1576.         sassign(Array, null_class("Array"));
  1577.         sassign(ArrayedCollection, null_class("ArrayedCollection"));
  1578.  
  1579.         drv_init();    /* initialize the driver */
  1580.         sassign(o_drive, (object *) cr_interpreter((interpreter *) 0,
  1581.             null_object, null_object, null_object, null_object));
  1582.         init_process((interpreter *) o_drive);
  1583.  
  1584.         /* now read in standard prelude */
  1585.         if (! noload) {
  1586.             sfd = fopen(PRELUDE, "r");
  1587.             if (sfd == NULL) cant_happen(20);
  1588.             set_file(sfd);
  1589.             start_execution();
  1590.             fclose(sfd);
  1591.             }
  1592.  
  1593.         /* then set lexer up to read stdin */
  1594.         set_file(stdin);
  1595.         sassign(o_tab, new_str("\t"));
  1596.  
  1597. # ifdef CURSES
  1598.         /* finally initialize the curses window package */
  1599.         initscr();
  1600. # endif
  1601. # ifdef PLOT3
  1602.         /* initialize the plotting device */
  1603.         openpl();
  1604. # endif
  1605.         }
  1606.  
  1607.     /* announce that we're ready for action */
  1608.     sassign(tempobj, new_sym("Little Smalltalk"));
  1609.     primitive(SYMPRINT, 1, &tempobj);
  1610.     obj_dec(tempobj);
  1611.     started = 1;
  1612.  
  1613.     /* now read in the command line files */
  1614.     user_read(argc, argv);
  1615.  
  1616.     start_execution();
  1617.  
  1618.     /* print out one last newline - to move everything out of output
  1619.     queue */
  1620.     sassign(tempobj, new_sym("\n"));
  1621.     primitive(SYMPRINT, 1, &tempobj);
  1622.     obj_dec(tempobj);
  1623.  
  1624.     /* now free things up, hopefully keeping ref counts straight */
  1625.  
  1626.     drv_free();
  1627.  
  1628.     flush_processes();
  1629.  
  1630.     free_low_nums();
  1631.  
  1632.     obj_dec((object *) Array);
  1633.     obj_dec((object *) ArrayedCollection);
  1634.  
  1635.     free_all_classes();
  1636.     
  1637.     obj_dec(o_tab);
  1638.     obj_dec(o_drive);
  1639.     obj_dec(o_magnitude);
  1640.     obj_dec(o_number);
  1641.     obj_dec(o_nil);
  1642.     obj_dec(o_false);
  1643.     obj_dec(o_true);
  1644.     obj_dec(o_object);
  1645.     obj_dec(o_empty);
  1646.     obj_dec(o_smalltalk);
  1647.     obj_dec(o_acollection);
  1648.  
  1649.     if (! silence)
  1650.         fprintf(stderr,"incs %u decs %u difference %d allocs %d\n",
  1651.             n_incs, n_decs, n_incs - n_decs, n_mallocs);
  1652.     ohcount = 0;
  1653.     for (i = 0; i < 16; i++)
  1654.         ohcount += opcount[i];
  1655.     fprintf(stderr,"opcount %d\n", ohcount);
  1656.         /*fprintf(stderr,"opcode [%d] counts %d\n", i, opcount[i]);*/
  1657.     /*fprintf(stderr,"ohcount %d\n", ohcount);
  1658.     for (i = 0; i < 16; i++)
  1659.         fprintf(stderr,"sp count %d %d\n", i , spcount[i]);*/
  1660.     if (prallocs) {
  1661.         fprintf(stderr,"blocks allocated %d\n", ca_block);
  1662.         fprintf(stderr,"bytearrays allocated %d\n", ca_barray);
  1663.         fprintf(stderr,"classes allocated %d\n", ca_class);
  1664.         fprintf(stderr,"interpreters allocated %d\n", ca_terp);
  1665.         fprintf(stderr,"ints allocated %d\n", ca_int);
  1666.         fprintf(stderr,"floats allocated %d\n", ca_float);
  1667.         fprintf(stderr,"strings allocated %d\n", ca_str);
  1668.         fprintf(stderr,"symbols allocated %d\n", ca_sym);
  1669.         fprintf(stderr,"class entryies %d\n", ca_cdict);
  1670.         fprintf(stderr,"wallocs %d\n", ca_wal);
  1671.         fprintf(stderr,"wtop %d\n", wtop);
  1672.         fprintf(stderr,"byte table top %d\n", btabletop);
  1673.         fprintf(stderr,"smalltalk objects allocated %d\n", ca_obj);
  1674.         for (i = 0; i < 5; i++)
  1675.             fprintf(stderr,"size %d objects %d\n", i, ca_cobj[i]);
  1676.     }
  1677.     clean_files();
  1678.  
  1679. # ifdef PLOT3
  1680.     closepl();
  1681. # endif
  1682. # ifdef CURSES
  1683.     endwin();
  1684. # endif
  1685.  
  1686.     exit(0);    /* say good by gracie */
  1687. }
  1688.  
  1689. /* dofast - do a fast load of the standard prelude */
  1690. static dofast() {
  1691.     char buffer[100];
  1692.  
  1693.     sprintf(buffer,")l %s\n", FAST);
  1694.     dolexcommand(buffer);
  1695. }
  1696.  
  1697. /* null_class - create a null class for bootstrapping purposes */
  1698. static class *null_class(name)
  1699. char *name;
  1700. {    class *new, *new_class();
  1701.  
  1702.     new = new_class();
  1703.     assign(new->class_name, new_sym(name));
  1704.     enter_class(name, (object *) new);
  1705.     return(new);
  1706. }
  1707.  
  1708. /* user_read - read the user command line arguments */
  1709. static user_read(argc, argv)
  1710. int argc;
  1711. char **argv;
  1712. {    int i, count;
  1713.     char c, buffer[100];
  1714.     char name[100];
  1715.     FILE *fd = 0;
  1716.  
  1717.     gettemp(name);
  1718.     count = 0;
  1719.     fd = fopen(name, "w");
  1720.     if (fd == NULL)
  1721.         cant_happen(22);
  1722.     for (i = 1; i < argc; i++)
  1723.         if (argv[i][0] == '-') {
  1724.             switch(argv[i][1]) {
  1725.                 case 'a':
  1726.                     prallocs = 1; break;
  1727.                 case 'g': case 'l': case 'r':
  1728.                     c = argv[i][1];
  1729.                     sprintf(buffer,")%c %s\n",
  1730.                         c, argv[++i]);
  1731.                     count++;
  1732.                     fputs(buffer, fd);
  1733.                     break;
  1734.                 case 'd':
  1735.                     prntcmd = argv[i][1] - '0';
  1736.                     break;
  1737.                 case 's':
  1738.                     silence = 1;
  1739.                     break;
  1740.                 }
  1741.             }
  1742.         else {
  1743.             sprintf(buffer,")i %s\n", argv[i]);
  1744.             count++;
  1745.             fputs(buffer, fd);
  1746.             }
  1747.     fclose(fd);
  1748.     if (count) {
  1749.         fd = fopen(name, "r");
  1750.         if (fd == NULL)
  1751.             cant_happen(22);
  1752.         set_file(fd);
  1753.         }
  1754. }
  1755.  
  1756. /* gettemp makes a temp file name that can be deleted when finished */
  1757. static char c = 'a';
  1758. gettemp(buffer)
  1759. char *buffer;
  1760. {
  1761.     sprintf(buffer,"%s%c", filebase, c++);
  1762.     if (c > 'z') c = 'a';    /* wrap around forever */
  1763. }
  1764.  
  1765. /* clean_files - delete all temp files created */
  1766. static clean_files()
  1767. {
  1768.     char buffer[100];
  1769.  
  1770. # ifndef NOSYSTEM
  1771.     sprintf(buffer,"rm -f %s*", filebase);
  1772.     system(buffer);
  1773. # endif
  1774. }
  1775. End
  1776. echo unbundling object.c 1>&2
  1777. cat >object.c <<'End'
  1778. /*
  1779.         Little Smalltalk
  1780.  
  1781.             object memory management
  1782.  
  1783.         timothy a. budd, 10/84
  1784. */
  1785. /*
  1786.     The source code for the Little Smalltalk System may be freely
  1787.     copied provided that the source of all files is acknowledged
  1788.     and that this condition is copied with each file.
  1789.  
  1790.     The Little Smalltalk System is distributed without responsibility
  1791.     for the performance of the program and without any guarantee of
  1792.     maintenance.
  1793.  
  1794.     All questions concerning Little Smalltalk should be addressed to:
  1795.  
  1796.         Professor Tim Budd
  1797.         Department of Computer Science
  1798.         Oregon State University
  1799.         Corvallis, Oregon
  1800.         97331
  1801.         USA
  1802. */
  1803. # include <stdio.h>
  1804. # include "object.h"
  1805. # include "drive.h"
  1806. # include "string.h"
  1807. # include "symbol.h"
  1808. # include "byte.h"
  1809. # include "number.h"
  1810. # include "interp.h"
  1811. # include "process.h"
  1812. # include "block.h"
  1813. # include "file.h"
  1814. # include "primitive.h"
  1815.  
  1816. # define DEBUG 0
  1817.  
  1818. extern object *o_acollection;
  1819.  
  1820. int n_incs = 0;        /* number of increments counter */
  1821. int n_decs = 0;        /* number of decrements counter (should be equal)*/
  1822. int n_mallocs = 0;    /* number of mallocs counter */
  1823.  
  1824. /* o_alloc - allocate a block of memory, checking for end of memory */
  1825. char *o_alloc(n)
  1826. unsigned n;
  1827. {  char *p, *malloc();
  1828.  
  1829.    p = malloc(n);
  1830.    if (p == (char *) 0) cant_happen(1);    /* out of memory */
  1831.    n_mallocs++;
  1832.    return(p);
  1833. }
  1834.  
  1835. #ifndef INLINE
  1836.  
  1837. /* obj_inc - increment an object (usually expanded in-line) */
  1838. obj_inc(x)
  1839. register object *x;
  1840. {
  1841.     x->ref_count++;
  1842.     n_incs++;
  1843. }
  1844.  
  1845. /* obj_dec - decrement an object (usually half expanded in-line) */
  1846. obj_dec(x)
  1847. object *x;
  1848. {
  1849.     n_decs++;
  1850.     if (--(x->ref_count) > 0) return;
  1851. # endif
  1852. # ifdef INLINE
  1853. ob_dec(x)
  1854. object *x;
  1855. {
  1856. # endif
  1857.     if (x->ref_count < 0) {
  1858.         fprintf(stderr,"ref count %d %d\n", x->ref_count, x);
  1859.         primitive(REFCOUNTERROR, 1, &x);
  1860.         return;
  1861.         }
  1862.     if (is_bltin(x)) {    /* free a built-in object */
  1863.         switch(x->size) {
  1864.             case BLOCKSIZE:
  1865.                 free_block(x); break;
  1866.             case BYTEARRAYSIZE:
  1867.                 free_bytearray((bytearray *) x); break;
  1868.             case CLASSSIZE :
  1869.                 free_class((class *) x); break;
  1870.             case FILESIZE:
  1871.                 free_file((struct file_struct *) x);
  1872.                 break;
  1873.             case FLOATSIZE:
  1874.                 free_float((sfloat *) x); break;
  1875.             case INTEGERSIZE: case CHARSIZE:
  1876.                 free_integer((integer *) x); break;
  1877.             case INTERPSIZE:
  1878.                 free_terpreter((interpreter *) x); break;
  1879.             case PROCSIZE:
  1880.                 free_process((process *) x); break;
  1881.             case SYMBOLSIZE:
  1882.                 cant_happen(16);
  1883.             case STRINGSIZE:
  1884.                 free_string((string *) x); break;
  1885.             default: cant_happen(6);
  1886.             }
  1887.         }
  1888.     else {        /* free a normal (non-special) object */
  1889.         if (x->super_obj)
  1890.             obj_dec(x->super_obj);
  1891.         free_obj(x, 1);
  1892.         }
  1893. }
  1894.  
  1895. # define MAXOBJLIST 100
  1896. # define sizeobj(x) (sizeof(object) + ((x) - 1) * sizeof(object *) )
  1897.  
  1898. /* obj_free_list is a free list for memory blocks */
  1899.  
  1900. static object *obj_free_list[MAXOBJLIST]; /* better be initialized to zero! */
  1901.  
  1902. int ca_obj = 0;            /* count the number of allocations made */
  1903. int ca_cobj[5] = {0,0,0,0,0};    /* count how many allocations for small vals*/
  1904.  
  1905. /* make sure the following list is null terminated! */
  1906. int size_obj_init[] = {15, 75, 420, 10, 10, 5, 0};
  1907.  
  1908. /* init_objs - initialize the memory management module */
  1909. init_objs() {
  1910.     int i, j, max, size;
  1911.     char *p;
  1912.     object *new;
  1913.  
  1914.     for (i = 0; (max = size_obj_init[i]); i++) {
  1915.         size = sizeobj(i);
  1916.         p = o_alloc((unsigned int) (max * size));
  1917.         for (j = 0; j < max; j++) {
  1918.             new = (object *) p;
  1919.             new->super_obj = obj_free_list[i];
  1920.             obj_free_list[i] = new;
  1921.             p += size;
  1922.             }
  1923.         }
  1924. }
  1925.  
  1926. /* new_obj - create a new non-special object */
  1927. object *new_obj(nclass, nsize, alloc)
  1928. class *nclass;
  1929. int nsize, alloc;
  1930. {    register object *new;
  1931.     int i;
  1932.     
  1933.     if (nsize < 0)
  1934.         cant_happen(2);
  1935.     if (nsize < MAXOBJLIST && obj_free_list[nsize])
  1936.         obj_free_list[nsize] = (new = obj_free_list[nsize])->super_obj;
  1937.     else {
  1938.         new = (object *) o_alloc(sizeobj(nsize));
  1939.         ca_obj++;
  1940.         if (nsize < 5)
  1941.             ca_cobj[nsize]++;
  1942.     }
  1943.     new->super_obj = (object *) 0;
  1944.     new->class = nclass;
  1945.     if (nclass)
  1946.         obj_inc((object *) new->class );
  1947.     new->ref_count = 0;
  1948.     new->size = nsize;
  1949.     if (alloc)
  1950.         for (i = 0; i < nsize; i++) {
  1951.             sassign(new->inst_var[ i ], o_nil);
  1952.          }    
  1953.     return(new);
  1954. }
  1955.     
  1956. /* free_obj - free a non-special object */
  1957. free_obj(obj, dofree)
  1958. register object *obj;
  1959. int    dofree;
  1960. {    int size, i;
  1961.  
  1962.     size = obj->size;
  1963.     if (dofree)
  1964.         for (i = 0; i < size; i++)
  1965.             obj_dec(obj->inst_var[i]);
  1966.     if (obj->class)
  1967.         obj_dec((object *) obj->class);
  1968.     if (size < MAXOBJLIST) {
  1969.         obj->super_obj = obj_free_list[size];
  1970.         obj_free_list[size] = obj;
  1971.         }
  1972.     else {
  1973.         free(obj);
  1974.               }
  1975. }
  1976.  
  1977. /* fnd_class - find the class of a special object */
  1978. object *fnd_class(anObject)
  1979. object *anObject;
  1980. {    object *result, *lookup_class();
  1981.     char *name;
  1982.  
  1983.     if (is_bltin(anObject)) {
  1984.         switch(anObject->size) {
  1985.             case BLOCKSIZE:   name = "Block"; break;
  1986.             case CLASSSIZE:   name = "Class"; break;
  1987.             case FILESIZE:    name = "File"; break;
  1988.             case FLOATSIZE:   name = "Float"; break;
  1989.             case INTEGERSIZE: name = "Integer"; break;
  1990.             case CHARSIZE:    name = "Char"; break;
  1991.             case INTERPSIZE:  name = "Interp"; break;
  1992.             case PROCSIZE:    name = "Process"; break;
  1993.             case SYMBOLSIZE:  name = "Symbol"; break;
  1994.             case STRINGSIZE:  name = "String"; break;
  1995.             case BYTEARRAYSIZE: name = "ByteArray"; break;
  1996.             default: cant_happen(6);
  1997.             }
  1998.         result = lookup_class(name);
  1999.         }
  2000.     else
  2001.         result = (object *) anObject->class;
  2002.     return(result);
  2003. }
  2004.  
  2005. extern object *o_object, *o_magnitude, *o_number;
  2006.  
  2007. /* fnd_super - produce a super-object for a special object */
  2008. object *fnd_super(anObject)
  2009. object *anObject;
  2010. {    object *result;
  2011.  
  2012.     if (is_bltin(anObject)) {
  2013.         switch(anObject->size) {
  2014.             case BLOCKSIZE:   result = o_object; break;
  2015.             case CLASSSIZE:   result = o_object; break;
  2016.             case FILESIZE:    result = o_object; break;
  2017.             case FLOATSIZE:   result = o_number; break;
  2018.             case INTEGERSIZE: result = o_number; break;
  2019.             case CHARSIZE:    result = o_magnitude; break;
  2020.             case INTERPSIZE:  result = o_object; break;
  2021.             case PROCSIZE:    result = o_object; break;
  2022.             case SYMBOLSIZE:  result = o_object; break;
  2023.             case STRINGSIZE:   /* strings DO have superobjs*/
  2024.                 result = ((string *) anObject)->s_super_obj;
  2025.                 break;
  2026.             case BYTEARRAYSIZE: result = o_acollection; break;
  2027.             default: cant_happen(6);
  2028.             }
  2029.         }
  2030.     else
  2031.         result = anObject->super_obj;
  2032.     return(result);
  2033. }
  2034. End
  2035. echo unbundling line.c 1>&2
  2036. cat >line.c <<'End'
  2037. /*
  2038.     Little Smalltalk
  2039.  
  2040.         line grabber - does lowest level input for command lines.
  2041. */
  2042. /*
  2043.     The source code for the Little Smalltalk System may be freely
  2044.     copied provided that the source of all files is acknowledged
  2045.     and that this condition is copied with each file.
  2046.  
  2047.     The Little Smalltalk System is distributed without responsibility
  2048.     for the performance of the program and without any guarantee of
  2049.     maintenance.
  2050.  
  2051.     All questions concerning Little Smalltalk should be addressed to:
  2052.  
  2053.         Professor Tim Budd
  2054.         Department of Computer Science
  2055.         Oregon State University
  2056.         Corvallis, Oregon
  2057.         97331
  2058.         USA
  2059. */
  2060. # include <stdio.h>
  2061. # include "object.h"
  2062. # include "primitive.h"
  2063.  
  2064. # define MAXINCLUDE  10
  2065. # define MAXBUFFER  1200        /* text buffer */
  2066.  
  2067. static FILE *fdstack[MAXINCLUDE];
  2068. static int fdtop = -1;
  2069.  
  2070. static char buffer[MAXBUFFER];
  2071. static char *buftop = buffer;
  2072. char *lexptr = buffer;
  2073. static enum {empty, half, filled} bufstate = empty;
  2074. int inisstd = 0;
  2075. extern object *o_tab;
  2076.  
  2077. /* set file - set a file on the file descriptor stack */
  2078. set_file(fd)
  2079. FILE *fd;
  2080. {
  2081.     if ((++fdtop) > MAXINCLUDE)
  2082.         cant_happen(18);
  2083.     fdstack[fdtop] = fd;
  2084.     if (fd == stdin) inisstd = 1;
  2085.     else inisstd = 0;
  2086. }
  2087.  
  2088. /* line-grabber - read a line of text
  2089.     do blocked i/o if blocked is nonzero,
  2090.     otherwise do non-blocking i/o */
  2091.  
  2092. int line_grabber(block)
  2093. int block;
  2094. {
  2095.     /* if it was filled last time, it is now empty */
  2096.     if (bufstate == filled) {
  2097.         bufstate = empty;
  2098.         buftop = buffer;
  2099.         lexptr = buffer;
  2100.         }
  2101.  
  2102.     if ( ! block)
  2103.         return(0); /* for now, only respond to blocked requests*/
  2104.     else while (bufstate != filled) {
  2105.         if (fdtop < 0) {
  2106.             fprintf(stderr,"no files to read\n");
  2107.             return(-1);
  2108.             }
  2109.         if (inisstd && o_tab)
  2110.             primitive(RAWPRINT, 1, &o_tab);
  2111.         if (fgets(buftop, MAXBUFFER, fdstack[fdtop]) == NULL) {
  2112.             bufstate = empty;
  2113.             if (fdstack[fdtop] != stdin)
  2114.                 fclose(fdstack[fdtop]);
  2115.             if (--fdtop < 0) return(-1);
  2116.             inisstd = (fdstack[fdtop] == stdin);
  2117.             }
  2118.         else {
  2119.             bufstate = half;
  2120.             while (*buftop) buftop++;
  2121.             if (*(buftop-1) == '\n') {
  2122.                 if (*(buftop-2) == '\\') {
  2123.                     buftop -= 2;
  2124.                     }
  2125.                 else {
  2126.                     if ((buftop - buffer) > MAXBUFFER)
  2127.                         cant_happen(18);
  2128.                     *buftop = '\0';
  2129.                     bufstate = filled;
  2130.                     }
  2131.                 }
  2132.             }    
  2133.         }
  2134.     return(bufstate == filled);
  2135. }
  2136. End
  2137. echo unbundling class.c 1>&2
  2138. cat >class.c <<'End'
  2139. /*
  2140.     Little Smalltalk
  2141.         class instance creation and deletion
  2142.  
  2143.         timothy a. budd  10/84
  2144. */
  2145. /*
  2146.     The source code for the Little Smalltalk System may be freely
  2147.     copied provided that the source of all files is acknowledged
  2148.     and that this condition is copied with each file.
  2149.  
  2150.     The Little Smalltalk System is distributed without responsibility
  2151.     for the performance of the program and without any guarantee of
  2152.     maintenance.
  2153.  
  2154.     All questions concerning Little Smalltalk should be addressed to:
  2155.  
  2156.         Professor Tim Budd
  2157.         Department of Computer Science
  2158.         Oregon State University
  2159.         Corvallis, Oregon
  2160.         97331
  2161.         USA
  2162. */
  2163. # include <stdio.h>
  2164. # include "object.h"
  2165. # include "file.h"
  2166. # include "number.h"
  2167. # include "symbol.h"
  2168. # include "string.h"
  2169. # include "primitive.h"
  2170. # define streq(x,y) (strcmp(x,y) == 0)
  2171.  
  2172. extern class *Array, *ArrayedCollection;
  2173.  
  2174. extern object *o_object, *o_empty, *o_number, *o_magnitude;
  2175. extern object *o_smalltalk, *o_acollection;
  2176.  
  2177. static mstruct *fr_class = 0;
  2178. int ca_class = 0;    /* count class allocations */
  2179.  
  2180. # define CLASSINITMAX 30
  2181.  
  2182. static class cl_table[CLASSINITMAX];
  2183.  
  2184. class_init()
  2185. {    class *p;
  2186.     mstruct *new;
  2187.     int i;
  2188.  
  2189.     for (p = cl_table, i = 0; i < CLASSINITMAX; i++, p++) {
  2190.         new = (mstruct *) p;
  2191.         new->mlink = fr_class;
  2192.         fr_class = new;
  2193.         }
  2194. }
  2195.  
  2196. class *new_class()
  2197. {    class *new;
  2198.  
  2199.     if (fr_class) {
  2200.         new = (class *) fr_class;
  2201.         fr_class = fr_class->mlink;
  2202.         }
  2203.     else {
  2204.         new = structalloc(class);
  2205.         ca_class++;
  2206.         }
  2207.  
  2208.     new->c_ref_count = 0;
  2209.     new->c_size = CLASSSIZE;
  2210.     sassign(new->file_name, o_nil);
  2211.     sassign(new->class_name, o_nil);
  2212.     new->super_class = (object *) 0;
  2213.     sassign(new->c_inst_vars, o_nil);
  2214.     new->context_size = 0;
  2215.     sassign(new->message_names, o_nil);
  2216.     sassign(new->methods, o_nil);
  2217.     return(new);
  2218. }
  2219.  
  2220. class *mk_class(classname, args)
  2221. char *classname;
  2222. object **args;
  2223. {    class *new;
  2224.     object *new_iarray();
  2225.  
  2226.     new = new_class();
  2227.     assign(new->class_name, args[0]);
  2228.     if (! streq(classname, "Object"))
  2229.         sassign(new->super_class, args[1]);
  2230.     assign(new->file_name, args[2]);
  2231.     assign(new->c_inst_vars, args[3]);
  2232.     assign(new->message_names, args[4]);
  2233.     assign(new->methods, args[5]);
  2234.     new->context_size = int_value(args[6]);
  2235.     new->stack_max = int_value(args[7]);
  2236.  
  2237.     if (streq(classname, "Array")) {
  2238.         assign(Array, new);
  2239.         assign(o_empty, new_iarray(0));
  2240.         }
  2241.     else if (streq(classname, "ArrayedCollection")) {
  2242.         assign(ArrayedCollection, new);
  2243.         assign(o_acollection, new_inst(new));
  2244.         assign(o_empty, new_iarray(0));
  2245.         }
  2246.     else if (streq(classname, "False"))
  2247.         assign(o_false, new_inst(new))
  2248.     else if (streq(classname, "Magnitude"))
  2249.         assign(o_magnitude, new_inst(new))
  2250.     else if (streq(classname, "Number"))
  2251.         assign(o_number, new_inst(new))
  2252.     else if (streq(classname, "Object"))
  2253.         assign(o_object, new_inst(new))
  2254.     else if (streq(classname, "Smalltalk"))
  2255.         assign(o_smalltalk, new_inst(new))
  2256.     else if (streq(classname, "True"))
  2257.         assign(o_true, new_inst(new))
  2258.     else if (streq(classname, "UndefinedObject"))
  2259.         assign(o_nil, new_inst(new))
  2260.     return(new);
  2261. }
  2262.  
  2263. /* new_sinst - new instance with explicit super object */
  2264. object *new_sinst(aclass, super)
  2265. class *aclass;
  2266. object *super;
  2267. {    object *new;
  2268.     char *classname, buffer[80];
  2269.  
  2270.     if (! is_class(aclass))
  2271.         cant_happen(4);
  2272.     classname = symbol_value(aclass->class_name);
  2273.     if (    streq(classname, "Block") ||
  2274.         streq(classname, "Char") ||
  2275.         streq(classname, "Class") ||
  2276.         streq(classname, "Float") ||
  2277.         streq(classname, "Integer") ||
  2278.         streq(classname, "Process") ||
  2279.         streq(classname, "Symbol") ) {
  2280.         sprintf(buffer,"%s: does not respond to new", classname);
  2281.         sassign(new, new_str(buffer));
  2282.         primitive(ERRPRINT, 1, &new);
  2283.         obj_dec(new);
  2284.         if (super) /* get rid of unwanted object */
  2285.             {obj_inc((object *) super);
  2286.              obj_dec((object *) super);}
  2287.         new = o_nil;
  2288.         }
  2289.     else if (streq(classname, "File")) {
  2290.         new = new_file();
  2291.         if (super) /* get rid of unwanted object */
  2292.             {obj_inc((object *) super);
  2293.              obj_dec((object *) super);}
  2294.         }
  2295.     else if (streq(classname, "String")) {
  2296.         new = new_str("");
  2297.         if (super)
  2298.             assign(((string *) new)->s_super_obj, super);
  2299.         }
  2300.     else {
  2301.         new = new_obj(aclass, (aclass->c_inst_vars)->size, 1);
  2302.         if (super)
  2303.             sassign(new->super_obj, super);
  2304.         }
  2305.     return(new);
  2306. }
  2307.  
  2308. object *new_inst(aclass)
  2309. class *aclass;
  2310. {    object *super, *sp_class_name, *lookup_class();
  2311.     class *super_class;
  2312.  
  2313.     if (! is_class(aclass))
  2314.         cant_happen(4);
  2315.     if (aclass == o_object->class)
  2316.         return(o_object);
  2317.     super = (object *) 0;
  2318.     sp_class_name = aclass->super_class;
  2319.     if (sp_class_name && is_symbol(sp_class_name)) {
  2320.         super_class = (class *)
  2321.             lookup_class(symbol_value(sp_class_name));
  2322.         if (super_class && is_class(super_class))
  2323.             super = new_inst(super_class);
  2324.         }
  2325.     return(new_sinst(aclass, super));
  2326. }
  2327.  
  2328. free_class(c)
  2329. class *c;
  2330. {
  2331.     if (! is_class(c))
  2332.         cant_happen(8);
  2333.     obj_dec(c->class_name);
  2334.     if (c->super_class)
  2335.         obj_dec((object *) c->super_class);
  2336.     obj_dec(c->file_name);
  2337.     obj_dec(c->c_inst_vars);
  2338.     obj_dec(c->message_names);
  2339.     obj_dec(c->methods);
  2340.     ((mstruct *) c )->mlink = fr_class;
  2341.     fr_class = (mstruct *) c;
  2342. }
  2343. End
  2344. echo unbundling number.c 1>&2
  2345. cat >number.c <<'End'
  2346. /*
  2347.     Little Smalltalk
  2348.  
  2349.         number definitions
  2350.         timothy a. budd, 10/84
  2351. */
  2352. /*
  2353.     The source code for the Little Smalltalk System may be freely
  2354.     copied provided that the source of all files is acknowledged
  2355.     and that this condition is copied with each file.
  2356.  
  2357.     The Little Smalltalk System is distributed without responsibility
  2358.     for the performance of the program and without any guarantee of
  2359.     maintenance.
  2360.  
  2361.     All questions concerning Little Smalltalk should be addressed to:
  2362.  
  2363.         Professor Tim Budd
  2364.         Department of Computer Science
  2365.         Oregon State University
  2366.         Corvallis, Oregon
  2367.         97331
  2368.         USA
  2369. */
  2370. # include <stdio.h>
  2371. # include "object.h"
  2372. # include "number.h"
  2373.  
  2374. # define MAXLOW 100    /* maximum low numbers kept */
  2375.  
  2376. static integer *low_nums[MAXLOW];  /* better be initialized to zero ! */
  2377.  
  2378. static mstruct *fr_integer = 0;
  2379. static mstruct *fr_float = 0;
  2380.  
  2381. static integer init_itable[INTINITMAX];
  2382.  
  2383. int_init() {
  2384.     integer *p;
  2385.     mstruct *new;
  2386.     int i;
  2387.  
  2388.     for (p = init_itable, i = 0; i < INTINITMAX; i++, p++) {
  2389.         new = (mstruct *) p;
  2390.         new->mlink = fr_integer;
  2391.         /*fprintf(stderr,"init int %d %d\n", new, new->mlink);*/
  2392.         fr_integer = new;
  2393.         }
  2394. }
  2395.  
  2396. int ca_int = 0;    /* count the number of integer allocations */
  2397.  
  2398. extern object *o_magnitude;
  2399. extern object *o_number;
  2400.  
  2401. /* new_cori - new character or integer */
  2402. object *new_cori(val, type)
  2403. int val, type;
  2404. {    register integer *new;
  2405.  
  2406.     if ((type == 1) && (val >= 0 && val < MAXLOW) && low_nums[val])
  2407.         return( (struct obj_struct *) low_nums[val]);
  2408.  
  2409.     if (fr_integer) {
  2410.         new = (integer *) fr_integer;
  2411.         /*fprintf(stderr,"int off list %d %d\n", fr_integer,
  2412.         fr_integer->mlink);*/
  2413.         fr_integer = fr_integer->mlink;
  2414.         }
  2415.     else {
  2416.         new = structalloc(integer);
  2417.         /*fprintf(stderr,"allocating new int %d\n", new);*/
  2418.         ca_int++;
  2419.         }
  2420.  
  2421.     new->i_ref_count = 0;
  2422.     new->i_value = val;
  2423.     switch(type) {
  2424.         case 0: /* chars */
  2425.             new->i_size = CHARSIZE;
  2426.               break;
  2427.  
  2428.         case 1: /* integers */
  2429.             new->i_size = INTEGERSIZE;
  2430.             if (val >= 0 && val < MAXLOW)
  2431.                 sassign(low_nums[val], new);
  2432.               break;
  2433.  
  2434.         default: cant_happen(5);
  2435.         }
  2436.     return ((object *) new);
  2437. }
  2438.  
  2439. free_integer(i)
  2440. integer *i;
  2441. {
  2442.     if ((! is_integer(i)) && (! is_character(i)))
  2443.         cant_happen(8);
  2444.     ((mstruct *) i)->mlink = fr_integer;
  2445.     fr_integer = (mstruct *) i;
  2446.     /*fprintf(stderr,"freeing integer %d %d\n", fr_integer,
  2447.     fr_integer->mlink);*/
  2448. }
  2449.  
  2450. free_low_nums()
  2451. {    int i;
  2452.  
  2453.     for (i = 0; i < MAXLOW; i++)
  2454.         if (low_nums[i]) {
  2455.             obj_dec((object *) low_nums[i]);
  2456.             low_nums[i] = (integer *) 0;
  2457.             }
  2458. }
  2459.  
  2460. int ca_float = 0;
  2461.  
  2462. /* new_float - produce a new floating point number */
  2463. object *new_float(val)
  2464. double val;
  2465. {    register sfloat *new;
  2466.  
  2467.     if (fr_float) {
  2468.         new = (sfloat *) fr_float;
  2469.         fr_float = fr_float->mlink;
  2470.         }
  2471.     else {
  2472.         new = structalloc(sfloat);
  2473.         ca_float++;
  2474.         }
  2475.  
  2476.     new->f_ref_count = 0;
  2477.     new->f_size = FLOATSIZE;
  2478.     new->f_value = val;
  2479.     return( (object *) new);
  2480. }
  2481.  
  2482. free_float(f)
  2483. sfloat *f;
  2484. {
  2485.     if (! is_float(f))
  2486.         cant_happen(8);
  2487.     ((mstruct *) f)->mlink = fr_float;
  2488.     fr_float = (mstruct *) f;
  2489. }
  2490. End
  2491. echo unbundling symbol.c 1>&2
  2492. cat >symbol.c <<'End'
  2493. /*
  2494.     Little Smalltalk
  2495.  
  2496.         symbol creation - symbols are never deleted once created.
  2497.         timothy a. budd, 10/84
  2498. */
  2499. /*
  2500.     The source code for the Little Smalltalk System may be freely
  2501.     copied provided that the source of all files is acknowledged
  2502.     and that this condition is copied with each file.
  2503.  
  2504.     The Little Smalltalk System is distributed without responsibility
  2505.     for the performance of the program and without any guarantee of
  2506.     maintenance.
  2507.  
  2508.     All questions concerning Little Smalltalk should be addressed to:
  2509.  
  2510.         Professor Tim Budd
  2511.         Department of Computer Science
  2512.         Oregon State University
  2513.         Corvallis, Oregon
  2514.         97331
  2515.         USA
  2516. */
  2517. # include <stdio.h>
  2518. # include "object.h"
  2519. # include "symbol.h"
  2520.  
  2521. /*
  2522.     only one copy of symbol values are kept.
  2523.     multiple copies of the same symbol point to the same
  2524.     location.
  2525.     sy_search will find, and if necessary insert, a string into
  2526.     this common table
  2527. */
  2528.  
  2529. extern char x_str[];        /* initialized common string table */
  2530. extern symbol *x_tab[];        /* initialized common symbols table */
  2531. extern int x_tmax;        /* top of symbols table */
  2532. extern char *walloc();        /* routine to allocate a new word */
  2533. int ca_sym = 0;            /* symbol allocation counter */
  2534.  
  2535. /* sy_search performs a binary search of a symbol, is the main interface to
  2536. the symbols routines */
  2537. symbol *sy_search(word, insert)
  2538. char *word;
  2539. int  insert;
  2540. {    register int i;
  2541.     register int j;
  2542.     register int k;
  2543.     char *p;
  2544.     symbol *new_y();
  2545.  
  2546.     for (i=1; i <= x_tmax; i <<= 1);
  2547.     for (i >>= 1, j = i >>1, i--; ; j >>= 1) {
  2548.         p = symbol_value(x_tab[i]);
  2549.         if (word == p) return(x_tab[i]);
  2550.         k = *word - *p;
  2551.         if (!k) k = *(word+1) - *(p+1);
  2552.         if (!k) k = strcmp(word, p);
  2553.         if (!k)
  2554.             return(x_tab[i]);
  2555.         if (!j) break;
  2556.         if (k < 0) i -= j;
  2557.         else {
  2558.             if ((i += j) > x_tmax) i = x_tmax;
  2559.             }
  2560.         }
  2561.     if (insert) {
  2562.         if (k > 0) i++;
  2563.         if ((k = ++x_tmax) >= SYMTABMAX)
  2564.             cant_happen(12);
  2565.         for (; k > i; k--) {
  2566.             x_tab[k] = x_tab[k-1];
  2567.             }
  2568.         /*fprintf(stderr,"adding %s\n", word);*/
  2569.         x_tab[i] = new_y(walloc(word));
  2570.         x_tab[i]->y_ref_count++; /* make sure not freed */
  2571.         return(x_tab[i]);
  2572.         }
  2573.     else return((symbol *) 0);
  2574. }
  2575.  
  2576. /* w_search performs a search for a word, not a symbol */
  2577. char *w_search(word, insert)
  2578. char *word;
  2579. int insert;
  2580. {    symbol *sym;
  2581.  
  2582.     sym = sy_search(word, insert);
  2583.     if (sym)
  2584.         return(symbol_value(sym));
  2585.     else
  2586.         return((char *) 0);
  2587. }
  2588.  
  2589. /*---------------------------------------*/
  2590.  
  2591. static mstruct *fr_symbol = 0;        /* symbols free list */
  2592. static symbol strspace[SYMINITSIZE];    /* initial symbols free list */
  2593.  
  2594. extern object *o_object;        /* common instance of Object */
  2595. extern class *ArrayedCollection;
  2596.  
  2597. /* sym_init - initialize the symbols routine */
  2598. sym_init() {
  2599.     int  i;
  2600.     symbol *p;
  2601.     mstruct   *new;
  2602.  
  2603.     p = strspace;
  2604.     for (i = 0; i < SYMINITSIZE; i++) {
  2605.         new = (mstruct *) p;
  2606.         new->mlink = fr_symbol;
  2607.         fr_symbol = new;
  2608.         p++;
  2609.         }
  2610. }
  2611.  
  2612. /* new_y is the internal routine for making new symbols */
  2613. symbol *new_y(text)
  2614. char *text;
  2615. {    symbol *new;
  2616.  
  2617.     if (fr_symbol) {
  2618.         new = (symbol *) fr_symbol;
  2619.         fr_symbol = fr_symbol->mlink;
  2620.         }
  2621.     else {
  2622.         ca_sym++;
  2623.         new = structalloc(symbol);
  2624.         }
  2625.  
  2626.     new->y_ref_count = 0;
  2627.     new->y_size = SYMBOLSIZE;
  2628.     new->y_value = text;
  2629.     return(new);
  2630. }
  2631. End
  2632. echo unbundling string.c 1>&2
  2633. cat >string.c <<'End'
  2634. /*
  2635.     Little Smalltalk
  2636.  
  2637.         string creation and deletion
  2638.         timothy a. budd, 10/84
  2639. */
  2640. /*
  2641.     The source code for the Little Smalltalk System may be freely
  2642.     copied provided that the source of all files is acknowledged
  2643.     and that this condition is copied with each file.
  2644.  
  2645.     The Little Smalltalk System is distributed without responsibility
  2646.     for the performance of the program and without any guarantee of
  2647.     maintenance.
  2648.  
  2649.     All questions concerning Little Smalltalk should be addressed to:
  2650.  
  2651.         Professor Tim Budd
  2652.         Department of Computer Science
  2653.         Oregon State University
  2654.         Corvallis, Oregon
  2655.         97331
  2656.         USA
  2657. */
  2658. # include <stdio.h>
  2659. # include "object.h"
  2660. # include "string.h"
  2661.  
  2662. int ca_str = 0;
  2663. int ca_wal = 0;
  2664.  
  2665. /* walloc allocates a string containing the same chars as the arg */
  2666.  
  2667. # define WALLOCINITSIZE 1000
  2668.  
  2669. static char wtable[WALLOCINITSIZE];
  2670. int wtop = 0;
  2671.  
  2672. char *walloc(val)
  2673. char *val;
  2674. {    char *p;
  2675.     int  size;
  2676.  
  2677.     size = 1 + strlen(val);
  2678.     if ((size < 40) && ((wtop + size) < WALLOCINITSIZE)) {
  2679.         p = &wtable[wtop];
  2680.         wtop += size;
  2681.         }
  2682.     else {
  2683.         p = o_alloc((unsigned) size);
  2684.         ca_wal++;
  2685.         }
  2686.     strcpy(p, val);
  2687.     return(p);
  2688. }
  2689.  
  2690. /*---------------------------------------*/
  2691. extern class *ArrayedCollection;
  2692. extern object *o_acollection;
  2693.  
  2694. static mstruct *fr_string = 0;
  2695.  
  2696. # define STRINITSIZE 50
  2697.  
  2698. static string st_init_table[STRINITSIZE];
  2699.  
  2700. str_init() {
  2701.     string *p;
  2702.     mstruct *new;
  2703.     int i;
  2704.  
  2705.     for (p = st_init_table, i = 0; i < STRINITSIZE; i++, p++) {
  2706.         new = (mstruct *) p;
  2707.         new->mlink = fr_string;
  2708.         fr_string = new;
  2709.         }
  2710. }
  2711.  
  2712. extern int started;
  2713. static new_rstr(new)
  2714. string *new;
  2715. {
  2716.     new->s_ref_count = 0;
  2717.     new->s_size = STRINGSIZE;
  2718.     if (! started)
  2719.         sassign(new->s_super_obj, o_acollection);
  2720.     else if (ArrayedCollection)
  2721.         sassign(new->s_super_obj, new_inst(ArrayedCollection));
  2722.     else
  2723.         new->s_super_obj = (object *) 0;
  2724. }
  2725.  
  2726. string *new_istr(text)
  2727. char *text;
  2728. {    register string *new;
  2729.  
  2730.     if (fr_string) {
  2731.         new = (string *) fr_string;
  2732.         fr_string = fr_string->mlink;
  2733.         }
  2734.     else {
  2735.         ca_str++;
  2736.         new = structalloc(string);
  2737.         }
  2738.  
  2739.     new->s_value = text;
  2740.     new_rstr(new);
  2741.     return(new);
  2742. }
  2743.  
  2744. # define STRLISTMAX 100
  2745.  
  2746. mstruct *frl_str[STRLISTMAX];
  2747.  
  2748. object *new_str(text)
  2749. char *text;
  2750. {    int size;
  2751.     string *new;
  2752.  
  2753.     size = 1 + strlen(text);
  2754.     if ((size < STRLISTMAX) && frl_str[size]) {
  2755.         new = (string *) frl_str[size];
  2756.         frl_str[size] = frl_str[size]->mlink;
  2757.         strcpy(new->s_value, text);
  2758.         new_rstr(new);
  2759.         }
  2760.     else {
  2761.         new = new_istr(walloc(text));
  2762.         }
  2763.     return((object *) new);
  2764. }
  2765.  
  2766. free_string(s)
  2767. string *s;
  2768. {    int size;
  2769.  
  2770.     if (s->s_super_obj)
  2771.         obj_dec(s->s_super_obj);
  2772.     size = 1 + strlen(s->s_value);
  2773.     if (size < STRLISTMAX) {
  2774.         ((mstruct *)s)->mlink = frl_str[size];
  2775.         frl_str[size] = (mstruct *) s;
  2776.         }
  2777.     else {
  2778.         ((mstruct *)s)->mlink = fr_string;
  2779.         fr_string = (mstruct *) s;
  2780.         }
  2781. }
  2782. End
  2783. echo unbundling byte.c 1>&2
  2784. cat >byte.c <<'End'
  2785. /*
  2786.     Little Smalltalk
  2787.  
  2788.         bytearray manipulation.
  2789.         bytearrays are used almost entirely for storing bytecodes.
  2790.  
  2791.     timothy a. budd, 11/84
  2792. */
  2793. /*
  2794.     The source code for the Little Smalltalk System may be freely
  2795.     copied provided that the source of all files is acknowledged
  2796.     and that this condition is copied with each file.
  2797.  
  2798.     The Little Smalltalk System is distributed without responsibility
  2799.     for the performance of the program and without any guarantee of
  2800.     maintenance.
  2801.  
  2802.     All questions concerning Little Smalltalk should be addressed to:
  2803.  
  2804.         Professor Tim Budd
  2805.         Department of Computer Science
  2806.         Oregon State University
  2807.         Corvallis, Oregon
  2808.         97331
  2809.         USA
  2810. */
  2811.  
  2812. # include <stdio.h>
  2813. # include "object.h"
  2814. # include "byte.h"
  2815.  
  2816. /*
  2817.     bytearrays of less than MAXBSAVE are kept on a free list
  2818. */
  2819.  
  2820. static mstruct *fr_bytearray[MAXBSAVE];     /* better be initialized to zero ! */
  2821.  
  2822. /*
  2823.     in order to avoid a large number of small mallocs, a table is used
  2824.     for the first new bytearrays.  After the table becomes full,
  2825.     malloc is used to get more space.
  2826.     table should be large enough for the standard prelude, at least
  2827. */
  2828.  
  2829. static uchar btable[MAXBTABSIZE];
  2830. int btabletop = 0;
  2831.  
  2832. /*
  2833.     for the same reason, a number of bytearray bases are statically
  2834.     allocated and kept on a free list
  2835. */
  2836.  
  2837. int ca_barray = 0;
  2838. static mstruct *fr_bybase = 0;
  2839.  
  2840. static bytearray by_init[MAXBYINIT];
  2841.  
  2842. byte_init()
  2843. {    int i;
  2844.     bytearray *p;
  2845.     mstruct *new;
  2846.  
  2847.     p = by_init;
  2848.     for (i = 0; i < MAXBYINIT; i++) {
  2849.         new = (mstruct *) p;
  2850.         new->mlink = fr_bybase;
  2851.         fr_bybase = new;
  2852.         p++;
  2853.         }
  2854. }
  2855.  
  2856. object *new_bytearray(values, size)
  2857. uchar *values;
  2858. int size;
  2859. {    bytearray *new;
  2860.     uchar *p, *q;
  2861.  
  2862.     if (size < MAXBSAVE && fr_bytearray[size]) {
  2863.         new = (bytearray *) fr_bytearray[size];
  2864.         fr_bytearray[size] = fr_bytearray[size]->mlink;
  2865.         }
  2866.     else {
  2867.         if (fr_bybase) {
  2868.             new = (bytearray *) fr_bybase;
  2869.             fr_bybase = fr_bybase->mlink;
  2870.             }
  2871.         else {
  2872.             new = structalloc(bytearray);
  2873.             ca_barray++;
  2874.             }
  2875.         if ((btabletop + size) < MAXBTABSIZE) {
  2876.             new->a_bytes = &btable[btabletop];
  2877.             btabletop += size;
  2878.             }
  2879.         else {
  2880.             new->a_bytes = (uchar *) o_alloc((unsigned) size);
  2881.             }
  2882.         }
  2883.     new->a_ref_count = 0;
  2884.     new->a_size = BYTEARRAYSIZE;
  2885.     new->a_bsize = size;
  2886.     for (p = new->a_bytes, q = values; size; size--) {
  2887.         *p++ = *q++;
  2888.         }
  2889.     return((object *) new);
  2890. }
  2891.  
  2892. free_bytearray(obj)
  2893. bytearray *obj;
  2894. {    int size;
  2895.  
  2896.     if (! is_bytearray(obj))
  2897.         cant_happen(8);
  2898.     size = obj->a_bsize;
  2899.     if (size < MAXBSAVE) {
  2900.         ((mstruct *) obj)->mlink = fr_bytearray[size];
  2901.         fr_bytearray[size] = ((mstruct *) obj);
  2902.         }
  2903. }
  2904. End
  2905. echo unbundling array.c 1>&2
  2906. cat >array.c <<'End'
  2907. /*
  2908.     Little Smalltalk
  2909.         Array creation
  2910.  
  2911.         timothy a. budd 10/84
  2912.  
  2913.     builds a new instance of class array.
  2914.     called mostly by the driver to construct array constants.
  2915. */
  2916. /*
  2917.     The source code for the Little Smalltalk System may be freely
  2918.     copied provided that the source of all files is acknowledged
  2919.     and that this condition is copied with each file.
  2920.  
  2921.     The Little Smalltalk System is distributed without responsibility
  2922.     for the performance of the program and without any guarantee of
  2923.     maintenance.
  2924.  
  2925.     All questions concerning Little Smalltalk should be addressed to:
  2926.  
  2927.         Professor Tim Budd
  2928.         Department of Computer Science
  2929.         Oregon State University
  2930.         Corvallis, Oregon
  2931.         97331
  2932.         USA
  2933. */
  2934. # include <stdio.h>
  2935. # include "object.h"
  2936.  
  2937. class *Array = (class *) 0;
  2938. class *ArrayedCollection = (class *) 0;
  2939.  
  2940. extern object *o_nil, *o_empty, *o_acollection;
  2941. extern int started;        /* gets set after reading std prelude */
  2942.  
  2943. /* new_iarray - internal form of new array */
  2944. object *new_iarray(size)
  2945. int size;
  2946. {    object *new;
  2947.  
  2948.     if (size < 0) cant_happen(2);
  2949.     new = new_obj(Array, size, 0);
  2950.     if (! started) {
  2951.         sassign(new->super_obj, o_acollection);
  2952.         }
  2953.     else if (ArrayedCollection)
  2954.         sassign(new->super_obj, new_inst(ArrayedCollection));
  2955.     return(new);
  2956. }
  2957.  
  2958. /* new_array - create a new array */
  2959. object *new_array(size, initial)
  2960. int size, initial;
  2961. {    int i;
  2962.     object *new;
  2963.  
  2964.     if (size == 0) return(o_empty);
  2965.     new = new_iarray(size);
  2966.     if (initial) {
  2967.         for (i = 0; i < size; i++)
  2968.             sassign(new->inst_var[ i ], o_nil);
  2969.         }
  2970.     return(new);
  2971. }
  2972. End
  2973. echo unbundling file.c 1>&2
  2974. cat >file.c <<'End'
  2975. /*
  2976.     Little Smalltalk
  2977.  
  2978.         programs used by class File
  2979.         timothy a. budd 11/84
  2980. */
  2981. /*
  2982.     The source code for the Little Smalltalk System may be freely
  2983.     copied provided that the source of all files is acknowledged
  2984.     and that this condition is copied with each file.
  2985.  
  2986.     The Little Smalltalk System is distributed without responsibility
  2987.     for the performance of the program and without any guarantee of
  2988.     maintenance.
  2989.  
  2990.     All questions concerning Little Smalltalk should be addressed to:
  2991.  
  2992.         Professor Tim Budd
  2993.         Department of Computer Science
  2994.         Oregon State University
  2995.         Corvallis, Oregon
  2996.         97331
  2997.         USA
  2998. */
  2999. # include <stdio.h>
  3000. # include "object.h"
  3001. # include "file.h"
  3002. # include "string.h"
  3003. # include "number.h"
  3004. # include "primitive.h"
  3005.  
  3006. static mstruct *fr_file = 0;    /* free file list */
  3007.  
  3008. object *new_file()
  3009. {    struct file_struct *new;
  3010.  
  3011.     if (fr_file) {
  3012.         new = (struct file_struct *) fr_file;
  3013.         fr_file = fr_file->mlink;
  3014.         }
  3015.     else {
  3016.         new = structalloc(struct file_struct);
  3017.         }
  3018.  
  3019.     new->l_size = FILESIZE;
  3020.     new->l_ref_count = 0;
  3021.     new->file_mode = STRMODE;
  3022.     new->fp = NULL;
  3023.     return((object *) new);
  3024. }
  3025.  
  3026. free_file(phil)
  3027. struct file_struct *phil;
  3028. {
  3029.     if (! is_file(phil))
  3030.         cant_happen(8);
  3031.     if (phil->fp != NULL)
  3032.         fclose(phil->fp);
  3033.     ((mstruct *) phil)->mlink = fr_file;
  3034.     fr_file = (mstruct *) phil;
  3035. }
  3036.  
  3037. file_err(message)
  3038. char *message;
  3039. {    object *errp;
  3040.     char buffer[150];
  3041.  
  3042.     sprintf(buffer,"File: %s", message);
  3043.     sassign(errp, new_str(buffer));
  3044.     primitive(ERRPRINT, 1, &errp);
  3045.     obj_dec(errp);
  3046. }
  3047.  
  3048. file_open(phil, name, type)
  3049. struct file_struct *phil;
  3050. char *name, *type;
  3051. {    char buffer[100];
  3052.  
  3053.     if (phil->fp != NULL)
  3054.         fclose(phil->fp);
  3055.     phil->fp = fopen(name, type);
  3056.     if (phil->fp == NULL) {
  3057.         sprintf(buffer,"can't open: %s\n", name);
  3058.         file_err(buffer);
  3059.         }
  3060. }
  3061.  
  3062. # define BUFLENGTH 250
  3063.  
  3064. object *file_read(phil)
  3065. struct file_struct *phil;
  3066. {    object *new;
  3067.     int c;
  3068.     char buffer[BUFLENGTH], *p;
  3069.  
  3070.     if (phil->fp == NULL) {
  3071.         file_err("attempt to read from unopened file");
  3072.         return(o_nil);
  3073.         }
  3074.     switch(phil->file_mode) {
  3075.         case CHARMODE:
  3076.             if (EOF == (c = fgetc(phil->fp)))
  3077.                 new = o_nil;
  3078.             else
  3079.                 new = new_char(c);
  3080.             break;
  3081.         case STRMODE:
  3082.             if (NULL == fgets(buffer, BUFLENGTH, phil->fp))
  3083.                 new = o_nil;
  3084.             else {
  3085.                 p = &buffer[strlen(buffer) - 1];
  3086.                 if (*p == '\n') *p = '\0';
  3087.                 new = new_str(buffer);
  3088.                 }
  3089.             break;
  3090.         case INTMODE:
  3091.             if (EOF == (c = getw(phil->fp)))
  3092.                 new = o_nil;
  3093.             else
  3094.                 new = new_int(c);
  3095.             break;
  3096.         default:
  3097.             file_err("unknown mode");
  3098.             new = o_nil;
  3099.         }
  3100.     return(new);
  3101. }
  3102.  
  3103. file_write(phil, obj)
  3104. struct file_struct *phil;
  3105. object *obj;
  3106. {
  3107.     if (phil->fp == NULL) {
  3108.         file_err("attempt to write to unopened file");
  3109.         return;
  3110.         }
  3111.     switch(phil->file_mode) {
  3112.         case CHARMODE:
  3113.             if (! is_character(obj)) goto modeerr;
  3114.             fputc(int_value(obj), phil->fp);
  3115.             break;
  3116.         case STRMODE:
  3117.             if (! is_string(obj)) goto modeerr;
  3118.             fputs(string_value(obj), phil->fp);
  3119.             fputc('\n', phil->fp);
  3120.             break;
  3121.         case INTMODE:
  3122.             if (! is_integer(obj)) goto modeerr;
  3123.             putw(int_value(obj), phil->fp);
  3124.             break;
  3125.         }
  3126.     return;
  3127. modeerr:
  3128.     file_err("attempt to write object of wrong type for mode");
  3129. }
  3130. End
  3131. echo unbundling primitive.c 1>&2
  3132. cat >primitive.c <<'End'
  3133. /*
  3134.     Little Smalltalk
  3135.  
  3136.     Primitive manager
  3137.     timothy a. budd
  3138.     10/84
  3139.  
  3140.         hashcode code written by Robert McConeghy
  3141.             (who also wrote classes Dictionary, et al).
  3142. */
  3143. /*
  3144.     The source code for the Little Smalltalk System may be freely
  3145.     copied provided that the source of all files is acknowledged
  3146.     and that this condition is copied with each file.
  3147.  
  3148.     The Little Smalltalk System is distributed without responsibility
  3149.     for the performance of the program and without any guarantee of
  3150.     maintenance.
  3151.  
  3152.     All questions concerning Little Smalltalk should be addressed to:
  3153.  
  3154.         Professor Tim Budd
  3155.         Department of Computer Science
  3156.         Oregon State University
  3157.         Corvallis, Oregon
  3158.         97331
  3159.         USA
  3160. */
  3161.  
  3162. # include "object.h"
  3163.  
  3164. # ifdef CURSES
  3165. # include <curses.h>
  3166. # endif
  3167.  
  3168. # include <stdio.h>
  3169. # include <ctype.h>
  3170. # include <math.h>
  3171. # include <errno.h>
  3172. # include "drive.h"
  3173. # include "interp.h"
  3174. # include "process.h"
  3175. # include "block.h"
  3176. # include "string.h"
  3177. # include "symbol.h"
  3178. # include "number.h"
  3179. # include "file.h"
  3180. # include "byte.h"
  3181. # include "primitive.h"
  3182.  
  3183. extern int errno;
  3184. extern int prntcmd;
  3185. extern double modf();
  3186. extern long time();
  3187. extern object *lookup_class();
  3188. extern process *runningProcess;
  3189. extern int responds_to(), generality();
  3190. extern class  *mk_class();
  3191. extern object *o_object, *o_true, *o_false, *o_nil, *o_number, *o_magnitude;
  3192.  
  3193. object *primitive(primnumber, numargs, args)
  3194. int primnumber, numargs;
  3195. object **args;
  3196. {    object *resultobj;
  3197.     object *leftarg, *rightarg, *fnd_class(), *fnd_super();
  3198.     int    leftint, rightint, i, j;
  3199.     double leftfloat, rightfloat;
  3200.     long   clock;
  3201.     char   *leftp, *rightp, *errp;
  3202.     class  *aClass;
  3203.     bytearray *byarray;
  3204.     struct file_struct *phil;
  3205.     int    opnumber = primnumber % 10;
  3206.     char   strbuffer[300], tempname[100];
  3207.  
  3208.     errno = 0;
  3209.     /* first do argument type checking */
  3210.     switch(i = (primnumber / 10)) {
  3211.         case 0: /* misc operations */
  3212.             if (opnumber <= 5 && numargs != 1) goto argcerror;
  3213.             leftarg = args[0];
  3214.             break;
  3215.  
  3216.         case 1: /* integer operations */
  3217.         case 2:
  3218.             if (numargs != 2) goto argcerror;
  3219.             rightarg = args[1];
  3220.             if (! is_integer(rightarg)) goto argterror;
  3221.             rightint = int_value(rightarg);
  3222.         case 3:
  3223.             if (i == 3 && opnumber && numargs != 1)
  3224.                 goto argcerror;
  3225.             leftarg = args[0];
  3226.             if (! is_integer(leftarg)) goto argterror;
  3227.             leftint = int_value(leftarg);
  3228.             break;
  3229.  
  3230.         case 4: /* character operations */
  3231.             if (numargs != 2) goto argcerror;
  3232.             rightarg = args[1];
  3233.             if (! is_character(rightarg)) goto argterror;
  3234.             rightint = int_value(rightarg);
  3235.         case 5:
  3236.             if (i == 5 && numargs != 1) goto argcerror;
  3237.             leftarg = args[0];
  3238.             if (! is_character(leftarg)) goto argterror;
  3239.             leftint = int_value(leftarg);
  3240.             break;
  3241.  
  3242.         case 6: /* floating point operations */
  3243.             if (numargs != 2) goto argcerror;
  3244.             rightarg = args[1];
  3245.             if (! is_float(rightarg)) goto argterror;
  3246.             rightfloat = float_value(rightarg);
  3247.         case 7:
  3248.             if (i == 7 && numargs != 1) goto argcerror;
  3249.         case 8:
  3250.             if (i == 8 && opnumber < 8 && numargs != 1)
  3251.                 goto argcerror;
  3252.             leftarg = args[0];
  3253.             if (! is_float(leftarg)) goto argterror;
  3254.             leftfloat = float_value(leftarg);
  3255.             break;
  3256.  
  3257.         case 9: /* symbol operations */
  3258.             leftarg = args[0];
  3259.             if (! is_symbol(leftarg)) goto argterror;
  3260.             leftp = symbol_value(leftarg);
  3261.             break;
  3262.  
  3263.         case 10: /* string operations */
  3264.             if (numargs < 1) goto argcerror;
  3265.             leftarg = args[0];
  3266.             if (! is_string(leftarg)) goto argterror;
  3267.             leftp = string_value(leftarg);
  3268.             if (opnumber && opnumber <= 3) {
  3269.                 if (numargs != 2) goto argcerror;
  3270.                 rightarg = args[1];
  3271.                 if (! is_string(rightarg)) goto argterror;
  3272.                 rightp = string_value(rightarg);
  3273.                 }
  3274.             else if ((opnumber >= 4) && (opnumber <= 6)) {
  3275.                 if (numargs < 2) goto argcerror;
  3276.                 if (! is_integer(args[1])) goto argterror;
  3277.                 i = int_value(args[1])-1;
  3278.                 if ((i < 0) || (i >= strlen(leftp)))
  3279.                     goto indexerror;
  3280.                 }
  3281.             else if ((opnumber >= 7) && (numargs != 1))
  3282.                 goto argcerror;
  3283.             break;
  3284.  
  3285.         case 11: /* misc operations */
  3286.             if ((opnumber == 1) || (opnumber == 2)) {
  3287.                 if (is_bltin(args[0])) goto argterror;
  3288.                 if (numargs < 2) goto argcerror;
  3289.                 if (! is_integer(args[1])) goto argterror;
  3290.                 i = int_value(args[1]);
  3291.                 if (i < 1 || i > args[0]->size)
  3292.                     goto indexerror;
  3293.                 }
  3294.             else if ((opnumber >= 4) && (opnumber <= 6)) {
  3295.                 if (numargs != 1) goto argcerror;
  3296.                 if (! is_integer(args[0])) goto argterror;
  3297.                 i = int_value(args[0]);
  3298.                 if (i < 0) goto indexerror;
  3299.                 }
  3300.             else if (opnumber >= 7) {
  3301.                 if (numargs < 1) goto argcerror;
  3302.                 if (! is_bytearray(args[0])) goto argterror;
  3303.                 byarray = (bytearray *) args[0];
  3304.                 if (opnumber >= 8) {
  3305.                     if (numargs < 2) goto argcerror;
  3306.                     if (! is_integer(args[1]))
  3307.                         goto argterror;
  3308.                     i = int_value(args[1]) - 1;
  3309.                     if (i < 0 || i >= byarray->a_bsize)
  3310.                         goto indexerror;
  3311.                     }
  3312.                 }
  3313.             break;
  3314.  
  3315.         case 12: /* string i/o operations */
  3316.             if (opnumber < 6) {
  3317.                 if (numargs < 1) goto argcerror;
  3318.                 leftarg = args[0];
  3319.                 if (! is_string(leftarg)) goto argterror;
  3320.                 leftp = string_value(leftarg);
  3321.                 }
  3322.             break;
  3323.  
  3324.         case 13: /* operations on file */
  3325.             if (numargs < 1) goto argcerror;
  3326.             if (! is_file(args[0])) goto argterror;
  3327.             phil = (struct file_struct *) args[0];
  3328.             if (opnumber && (phil->fp == (FILE *) NULL)) {
  3329.                 errp = "file must be open for operation";
  3330.                 goto return_error;
  3331.                 }
  3332.             break;
  3333.  
  3334.         case 15: /* operations on classes */
  3335.             if (opnumber < 3 && numargs != 1) goto argcerror;
  3336.             if (! is_class(args[0])) goto argterror;
  3337.             aClass = (class *) args[0];
  3338.             break;
  3339.  
  3340. # ifdef PLOT3
  3341.         case 17: /* plot(3) interface */
  3342.             if (opnumber && opnumber <= 3) {
  3343.                 if (numargs != 2) goto argcerror;
  3344.                 if ((! is_integer(args[0])) ||
  3345.                     (! is_integer(args[1])))
  3346.                     goto argterror;
  3347.                 leftint = int_value(args[0]);
  3348.                 rightint = int_value(args[1]);
  3349.                 }
  3350.             else if ((opnumber == 6) || (opnumber == 7)) {
  3351.                 if (numargs != 4) goto argcerror;
  3352.                 for (i = 0; i < 4; i++)
  3353.                     if (! is_integer(args[i]))
  3354.                         goto argterror;
  3355.                 leftint = int_value(args[0]);
  3356.                 rightint = int_value(args[1]);
  3357.                 i = int_value(args[2]);
  3358.                 j = int_value(args[3]);
  3359.                 }
  3360.             else if (opnumber >= 8) {
  3361.                 if (numargs != 1) goto argcerror;
  3362.                 if (! is_string(args[0])) goto argterror;
  3363.                 leftp = string_value(args[0]);
  3364.                 }
  3365.             break;
  3366. # endif
  3367.         }
  3368.  
  3369.  
  3370.     /* now do operation */
  3371.     switch(primnumber) {
  3372.  
  3373.         case 1:        /* class of object */
  3374.             resultobj = fnd_class(args[0]);
  3375.             if (resultobj) goto return_obj;
  3376.             else goto return_nil;
  3377.  
  3378.         case 2:        /* get super_object */
  3379.             resultobj = fnd_super(args[0]);
  3380.             if (resultobj) goto return_obj;
  3381.             else goto return_nil;
  3382.  
  3383.         case 3:        /* see if class responds to new */
  3384.             leftint = 0;
  3385.             if (! is_class(args[0])) goto return_boolean;
  3386.             leftint = responds_to("new", (class *) args[0]);
  3387.             goto return_boolean;
  3388.  
  3389.         case 4:        /* compute size of object */
  3390.             leftint = args[0]->size;
  3391.             goto return_integer;
  3392.  
  3393.         case 5:        /* return hashnum of object */
  3394.             if (is_integer(leftarg))
  3395.                 leftint = int_value(leftarg);
  3396.             else if (is_character(leftarg))
  3397.                 leftint = int_value(leftarg);
  3398.             else if (is_symbol(leftarg))
  3399.                 leftint = (int) symbol_value(leftarg);
  3400.             else if (is_string(leftarg)) {
  3401.                 leftp = string_value(leftarg);
  3402.                 leftint = 0;
  3403.                 for(i = 0; *leftp != 0; leftp++){
  3404.                     leftint += *leftp;
  3405.                     i++;
  3406.                     if(i > 5)
  3407.                        break;
  3408.                     }
  3409.                 }
  3410.             else /* for all other objects return address */
  3411.                 leftint = (int) &leftarg;
  3412.             if (leftint < 0)
  3413.                 leftint = -leftint;
  3414.             goto return_integer;
  3415.  
  3416.         case 6:        /* built in object type testing */
  3417.             if (numargs != 2) goto argcerror;
  3418.             leftint = 0;
  3419.             if (is_bltin(args[0]) == is_bltin(args[1]))
  3420.                 if (is_bltin(args[0]))
  3421.                     leftint = (args[0]->size == args[1]->size);
  3422.                 else leftint = (args[0]->class == args[1]->class);
  3423.             goto return_boolean;
  3424.  
  3425.         case 7:        /* object equality testing */
  3426.             if (numargs != 2) goto argcerror;
  3427.             leftint = (args[0] == args[1]);
  3428.             goto return_boolean;
  3429.  
  3430.         case 8:        /* toggle debugging flag */
  3431.             if (numargs == 0) {
  3432.                 debug = 1 - debug;
  3433.                 goto return_nil;
  3434.                 }
  3435.             if (numargs != 2) goto argcerror;
  3436.             if (! is_integer(args[0])) goto argterror;
  3437.             if (! is_integer(args[1])) goto argterror;
  3438.             leftint = int_value(args[0]);
  3439.             rightint = int_value(args[1]);
  3440.             switch(leftint) {
  3441.                 case 1: prntcmd = rightint; break;
  3442.                 case 2: debug = rightint; break;
  3443.                 }
  3444.             goto return_nil;
  3445.  
  3446.         case 9:        /* numerical generality comparison */
  3447.             if (numargs != 2) goto argcerror;
  3448.             leftint =
  3449.                 (generality(args[0]) > generality(args[1]));
  3450.             goto return_boolean;
  3451.  
  3452.         case 10:    /* integer addition */
  3453.             leftint += rightint;
  3454.             goto return_integer;
  3455.  
  3456.         case 11:    /* integer subtraction */
  3457.             leftint -= rightint;
  3458.             goto return_integer;
  3459.  
  3460.         case 12: case 42:
  3461.             leftint = (leftint < rightint);
  3462.             goto return_boolean;
  3463.  
  3464.         case 13: case 43:
  3465.             leftint = (leftint > rightint);
  3466.             goto return_boolean;
  3467.  
  3468.         case 14: case 44:
  3469.             leftint = (leftint <= rightint);
  3470.             goto return_boolean;
  3471.  
  3472.         case 15: case 45:
  3473.             leftint = (leftint >= rightint);
  3474.             goto return_boolean;
  3475.  
  3476.         case 16: case 46:
  3477.             leftint = (leftint == rightint);
  3478.             goto return_boolean;
  3479.  
  3480.         case 17: case 47:
  3481.             leftint = (leftint != rightint);
  3482.             goto return_boolean;
  3483.  
  3484.         case 18:
  3485.             leftint *= rightint;
  3486.             goto return_integer;
  3487.  
  3488.         case 19:    /* // integer */
  3489.             if (rightint == 0) goto numerror;
  3490.             i  = leftint / rightint;
  3491.             if ((leftint < 0) && (leftint % rightint))
  3492.                 i -= 1;
  3493.             leftint = i;
  3494.             goto return_integer;
  3495.  
  3496.         case 20:    /* gcd of two integers */
  3497.             if (leftint == 0 || rightint == 0) goto numerror;
  3498.             if (leftint < 0) leftint = -leftint;
  3499.             if (rightint < 0) rightint = -rightint;
  3500.             if (leftint > rightint)
  3501.                 {i = leftint; leftint = rightint; rightint = i;}
  3502.             while (i = rightint % leftint)
  3503.                 {rightint = leftint; leftint = i;}
  3504.             goto return_integer;
  3505.             
  3506.         case 21:    /* bitAt: */
  3507.             leftint = (leftint & (1 << rightint)) ? 1 : 0;
  3508.             goto return_integer;
  3509.  
  3510.         case 22:    /* logical bit-or */
  3511.             leftint |= rightint;
  3512.             goto return_integer;
  3513.  
  3514.         case 23:    /* logical bit-and */
  3515.             leftint &= rightint;
  3516.             goto return_integer;
  3517.  
  3518.         case 24:    /* logical bit-exclusive or */
  3519.             leftint ^= rightint;
  3520.             goto return_integer;
  3521.  
  3522.         case 25:    /* bit shift */
  3523.             if (rightint < 0)
  3524.                 leftint >>= - rightint;
  3525.             else
  3526.                 leftint <<= rightint;
  3527.             goto return_integer;
  3528.  
  3529.         case 26:    /* integer radix */
  3530.             if (rightint < 2 || rightint > 36) goto numerror;
  3531.             prnt_radix(leftint, rightint, strbuffer);
  3532.             goto return_string;
  3533.  
  3534.         case 28:
  3535.             if (rightint == 0) goto numerror;
  3536.             leftint /= rightint;
  3537.             goto return_integer;
  3538.  
  3539.         case 29:
  3540.             if (rightint == 0) goto numerror;
  3541.             leftint %= rightint;
  3542.             goto return_integer;
  3543.  
  3544.         case 30:    /* doPrimitive:withArguments: */
  3545.             if (numargs != 2) goto argcerror;
  3546.             resultobj = primitive(leftint, args[1]->size,
  3547.                 &args[1]->inst_var[0]);
  3548.             goto return_obj;
  3549.  
  3550.         case 32:    /* convert random int into random float */
  3551.             leftfloat = ((double) ((leftint/10) % 1000)) / 1000.0;
  3552.             goto return_float;
  3553.  
  3554.         case 33:    /* bit inverse */
  3555.             leftint ^= -1;
  3556.             goto return_integer;
  3557.  
  3558.         case 34:    /* highBit */
  3559.             rightint = leftint;
  3560.             for (leftint = 32; leftint >= 0; leftint--)
  3561.                 if (rightint & (1 << leftint))
  3562.                     goto return_integer;
  3563.             goto return_nil;
  3564.  
  3565.         case 35:    /* random number */
  3566.             srand(leftint);
  3567.             leftint = rand();
  3568.             goto return_integer;
  3569.  
  3570.         case 36:    /* convert integer to character */
  3571.             goto return_character;
  3572.  
  3573.         case 37:    /* convert integer to string */
  3574.             sprintf(strbuffer,"%d", leftint);
  3575.             goto return_string;
  3576.  
  3577.         case 38:    /* factorial */
  3578.             if (leftint < 0) goto numerror;
  3579.             if (leftint < FACTMAX) {
  3580.                 for (i = 1; leftint; leftint--)
  3581.                     i *= leftint;
  3582.                 leftint = i;
  3583.                 goto return_integer;
  3584.                 }
  3585. # ifndef GAMMA
  3586.             /* gamma not supported, use float multiply */
  3587.             leftfloat = 1.0;
  3588.             if (leftint < 30) {
  3589.                 for (i = 1; leftint; leftint--)
  3590.                     leftfloat *= leftint;
  3591.                 }
  3592.             goto return_float;
  3593. # endif
  3594. # ifdef GAMMA
  3595.             /* compute gamma */
  3596.             leftfloat = (double) (leftint + 1);
  3597.             sassign(leftarg, new_float(leftfloat));
  3598.             resultobj = primitive(GAMMAFUN, 1, &leftarg);
  3599.             obj_dec(leftarg);
  3600.             goto return_obj;
  3601. # endif
  3602.  
  3603.         case 39:    /* convert integer to float */
  3604.             leftfloat = (double) leftint;
  3605.             goto return_float;
  3606.  
  3607.         case 50:    /* digitValue */
  3608.             if (isdigit(leftint))
  3609.                 leftint -= '0';
  3610.             else if (isupper(leftint)) {
  3611.                 leftint -= 'A';
  3612.                 leftint += 10;
  3613.                 }
  3614.             else goto return_nil;
  3615.             goto return_integer;
  3616.  
  3617.         case 51:
  3618.             if (isupper(leftint)) leftint += 'a' - 'A';
  3619.             leftint = (leftint == 'a') || (leftint == 'e') ||
  3620.                   (leftint == 'i') || (leftint == 'o') ||
  3621.                   (leftint == 'u');
  3622.             goto return_boolean;
  3623.  
  3624.         case 52:
  3625.             leftint = isalpha(leftint);
  3626.             goto return_boolean;
  3627.  
  3628.         case 53:
  3629.             leftint = islower(leftint);
  3630.             goto return_boolean;
  3631.  
  3632.         case 54:
  3633.             leftint = isupper(leftint);
  3634.             goto return_boolean;
  3635.  
  3636.         case 55:
  3637.             leftint = isspace(leftint);
  3638.             goto return_boolean;
  3639.  
  3640.         case 56:
  3641.             leftint = isalnum(leftint);
  3642.             goto return_boolean;
  3643.  
  3644.         case 57:
  3645.             if (isupper(leftint)) leftint += 'a' - 'A';
  3646.             else if (islower(leftint)) leftint += 'A' - 'a';
  3647.             goto return_character;
  3648.  
  3649.         case 58:    /* convert character to string */
  3650.             sprintf(strbuffer,"%c", leftint);
  3651.             goto return_string;
  3652.  
  3653.         case 59:    /* convert character to integer */
  3654.             goto return_integer;
  3655.  
  3656.         case 60:    /* floating point addition */
  3657.             leftfloat += rightfloat;
  3658.             goto return_float;
  3659.  
  3660.         case 61:    /* floating point subtraction */
  3661.             leftfloat -= rightfloat;
  3662.             goto return_float;
  3663.  
  3664.         case 62:
  3665.             leftint = (leftfloat < rightfloat);
  3666.             goto return_boolean;
  3667.  
  3668.         case 63:
  3669.             leftint = (leftfloat > rightfloat);
  3670.             goto return_boolean;
  3671.  
  3672.         case 64:
  3673.             leftint = (leftfloat <= rightfloat);
  3674.             goto return_boolean;
  3675.  
  3676.         case 65:
  3677.             leftint = (leftfloat >= rightfloat);
  3678.             goto return_boolean;
  3679.  
  3680.         case 66:
  3681.             leftint = (leftfloat == rightfloat);
  3682.             goto return_boolean;
  3683.  
  3684.         case 67:
  3685.             leftint = (leftfloat != rightfloat);
  3686.             goto return_boolean;
  3687.  
  3688.         case 68:
  3689.             leftfloat *= rightfloat;
  3690.             goto return_float;
  3691.  
  3692.         case 69:
  3693.             if (rightfloat == 0) goto numerror;
  3694.             leftfloat /= rightfloat;
  3695.             goto return_float;
  3696.  
  3697.         case 70:
  3698.             leftfloat = log(leftfloat);
  3699.             goto float_check;
  3700.  
  3701.         case 71:
  3702.             if (leftfloat < 0) goto numerror;
  3703.             leftfloat = sqrt(leftfloat);
  3704.             goto float_check;
  3705.  
  3706.         case 72:
  3707.             leftint = (int) floor(leftfloat);
  3708.             goto return_integer;
  3709.  
  3710.         case 73:    /* ceiling */
  3711.             leftint = (int) ceil(leftfloat);
  3712.             goto return_integer;
  3713.  
  3714.         case 75:    /* integer part */
  3715.             leftfloat = modf(leftfloat, &rightfloat);
  3716.             leftint = (int) rightfloat;
  3717.             goto return_integer;
  3718.  
  3719.         case 76:    /* fractional part */
  3720.             leftfloat = modf(leftfloat, &rightfloat);
  3721.             goto return_float;
  3722.  
  3723.         case 77:    /* gamma function */
  3724. # ifdef GAMMA
  3725.             leftfloat = gamma(leftfloat);
  3726.             if (leftfloat > 88.0) goto numerror;
  3727.             leftfloat = exp(leftfloat);
  3728.             goto float_check;
  3729. # endif
  3730. # ifndef GAMMA
  3731.             errp = "gamma function";
  3732.             goto not_implemented;
  3733. # endif
  3734.  
  3735.         case 78:
  3736.             sprintf(strbuffer,"%g", leftfloat);
  3737.             goto return_string;
  3738.  
  3739.         case 79:
  3740.             leftfloat = exp(leftfloat);
  3741.             goto return_float;
  3742.  
  3743.         case 80:    /* normalize radian value */
  3744. # define TWOPI (double) 6.2831853072
  3745.             rightfloat =
  3746.             floor(((leftfloat < 0) ? -leftfloat:leftfloat) / TWOPI);
  3747.             if (leftfloat < 0)
  3748.                 leftfloat += (1 + rightfloat) * TWOPI;
  3749.             else
  3750.                 leftfloat -= rightfloat * TWOPI;
  3751.             goto return_float;
  3752.  
  3753.         case 81:
  3754.             leftfloat = sin(leftfloat);
  3755.             goto float_check;
  3756.  
  3757.         case 82:
  3758.             leftfloat = cos(leftfloat);
  3759.             goto float_check;
  3760.  
  3761.         case 84:
  3762.             leftfloat = asin(leftfloat);
  3763.             goto float_check;
  3764.  
  3765.         case 85:
  3766.             leftfloat = acos(leftfloat);
  3767.             goto float_check;
  3768.  
  3769.         case 86:
  3770.             leftfloat = atan(leftfloat);
  3771.             goto float_check;
  3772.  
  3773.         case 88:
  3774.             if (numargs != 2) goto argcerror;
  3775.             if (! is_float(args[1])) goto argterror;
  3776.             leftfloat = pow(leftfloat, float_value(args[1]));
  3777.             goto float_check;
  3778.  
  3779.         case 89:    /* floating point radix */
  3780.             if (numargs != 2) goto argcerror;
  3781.             if (! is_integer(args[1])) goto argterror;
  3782.             i = int_value(args[1]); /* base */
  3783.             if (i < 2 || i > 36) goto numerror;
  3784.             fprnt_radix(leftfloat, i, strbuffer);
  3785.             goto return_string;
  3786.  
  3787.         case 91:    /* symbol comparison */
  3788.             if (numargs != 2) goto argcerror;
  3789.             if (! is_symbol(args[1])) goto argterror;
  3790.             leftint = (leftp == symbol_value(args[1]));
  3791.             goto return_boolean;
  3792.  
  3793.         case 92:    /* symbol printString */
  3794.             sprintf(strbuffer, "#%s", leftp);
  3795.             goto return_string;
  3796.  
  3797.         case 93:    /* symbol asString */
  3798.             sprintf(strbuffer, "%s", leftp);
  3799.             goto return_string;
  3800.  
  3801.         case 94:    /* symbol print ( with tabs) */
  3802.             if (numargs == 2) {
  3803.                 if (! is_integer(args[1])) goto argterror;
  3804.                 for (i = int_value(args[1]); i >= 0; i--)
  3805.                     putchar('\t');
  3806.             }
  3807.             printf("%s\n", leftp);
  3808. # ifdef FLUSHREQ
  3809.             fflush(stdout);
  3810. # endif
  3811.             goto return_nil;
  3812.  
  3813.         case 96:
  3814.             goto return_nil;
  3815.  
  3816.         case 97:    /* make a new class (generated by parser)*/
  3817.             if (numargs != 8) goto argcerror;
  3818.             if (! is_symbol(args[1])) goto argterror;
  3819.             if (! is_symbol(args[2])) goto argterror;
  3820.             if (! is_integer(args[6])) goto argterror;
  3821.             if (! is_integer(args[7])) goto argterror;
  3822.             resultobj = (object *) mk_class(leftp, args);
  3823.             goto return_obj;
  3824.  
  3825.         case 98:    /* install class in dictionary */
  3826.             if (numargs != 2) goto argcerror;
  3827.             if (! is_class(args[1])) goto argterror;
  3828.             enter_class(leftp, args[1]);
  3829.             goto return_nil;
  3830.  
  3831.         case 99:    /* find a class in class dictionary */
  3832.             if (numargs != 1) goto argcerror;
  3833.             resultobj = lookup_class(leftp);
  3834.             if (resultobj == (object *) 0) {
  3835.                 sprintf(strbuffer,"cannot find class %s",
  3836.                 leftp);
  3837.                 sassign(resultobj, new_str(strbuffer));
  3838.                 primitive(ERRPRINT, 1, &resultobj);
  3839.                 obj_dec(resultobj);
  3840.                 resultobj = lookup_class("Object");
  3841.                 if (! resultobj) cant_happen(7);
  3842.                 }
  3843.             goto return_obj;
  3844.  
  3845.         case 100:    /* string length */
  3846.             leftint = strlen(leftp);
  3847.             goto return_integer;
  3848.  
  3849.         case 101:     /* string compare, case dependent */
  3850.             leftint = strcmp(leftp, rightp);
  3851.             goto return_integer;
  3852.  
  3853.         case 102:    /* string compare, case independent */
  3854.             leftint = 1;
  3855.             while (*leftp || *rightp) {
  3856.                 i = *leftp++;
  3857.                 j = *rightp++;
  3858.                 if (i >= 'A' && i <= 'Z')
  3859.                     i = i - 'A' + 'a';
  3860.                 if (j >= 'A' && j <= 'Z')
  3861.                     j = j - 'A' + 'a';
  3862.                 if (i != j) {leftint = 0; break;}
  3863.                 }
  3864.             goto return_boolean;
  3865.  
  3866.         case 103:     /* string catenation */
  3867.             for (i = leftint = 0; i < numargs; i++) {
  3868.                 if (! is_string(args[i])) goto argterror;
  3869.                 leftint += strlen(string_value(args[i]));
  3870.                 }
  3871.             errp = (char *) o_alloc((unsigned) (1 + leftint));
  3872.             *errp = '\0';
  3873.             for (i = 0; i < numargs; i++)
  3874.                 strcat(errp, string_value(args[i]));
  3875.             resultobj = (object *) new_istr(errp);
  3876.             goto return_obj;
  3877.  
  3878.         case 104:    /* string at: */
  3879.             if (numargs != 2) goto argcerror;
  3880.             leftint = leftp[i];
  3881.             goto return_character;
  3882.  
  3883.         case 105:    /* string at: put: */
  3884.             if (numargs != 3) goto argcerror;
  3885.             if (! is_character(args[2])) goto argterror;
  3886.             leftp[i] = int_value(args[2]);
  3887.             goto return_nil;
  3888.  
  3889.         case 106:    /* copyFrom: length: */
  3890.             if (numargs != 3) goto argcerror;
  3891.             if (! is_integer(args[2])) goto argterror;
  3892.             j = int_value(args[2]);
  3893.             if (j < 0) goto indexerror;
  3894.             for (rightp = strbuffer; j; j--, i++)
  3895.                 *rightp++ = leftp[i];
  3896.             *rightp = '\0';
  3897.             goto return_string;
  3898.  
  3899.         case 107:    /* string copy */
  3900.             resultobj = new_str(leftp);
  3901.             goto return_obj;
  3902.  
  3903.         case 108:    /* string asSymbol */
  3904.             resultobj = new_sym(leftp);
  3905.             goto return_obj;
  3906.  
  3907.         case 109:    /* string printString */
  3908.             sprintf(strbuffer,"\'%s\'", leftp);
  3909.             goto return_string;
  3910.  
  3911.         case 110:    /* new untyped object */
  3912.             if (numargs != 1) goto argcerror;
  3913.             if (! is_integer(args[0])) goto argterror;
  3914.             leftint = int_value(args[0]);
  3915.             if (leftint < 0) goto numerror;
  3916.             resultobj = new_obj((class *) 0, leftint, 1);
  3917.             goto return_obj;
  3918.  
  3919.         case 111:    /* object at: */
  3920.             if (numargs != 2) goto argcerror;
  3921.             resultobj = args[0]->inst_var[ i - 1 ];
  3922.             goto return_obj;
  3923.  
  3924.         case 112:    /* object at:put: */
  3925.             if (numargs != 3) goto argcerror;
  3926.             assign(args[0]->inst_var[i - 1], args[2]);
  3927.             goto return_nil;
  3928.  
  3929.         case 113:    /*  object grow */
  3930.             leftarg = args[0];
  3931.             rightarg = args[1];
  3932.             if (is_bltin(leftarg)) goto argterror;
  3933.             resultobj = new_obj(leftarg->class,
  3934.                 leftarg->size+1, 0);
  3935.             if (leftarg->super_obj)
  3936.                 sassign(resultobj->super_obj,
  3937.                     leftarg->super_obj);
  3938.             for (i = 0; i < leftarg->size; i++)
  3939.                 sassign(resultobj->inst_var[i], leftarg->inst_var[i]);
  3940.             sassign(resultobj->inst_var[i], rightarg);
  3941.             goto return_obj;
  3942.  
  3943.  
  3944.         case 114:    /* new array */
  3945.             resultobj = new_array(i, 1);
  3946.             goto return_obj;
  3947.  
  3948.         case 115:    /* new string */
  3949.             for (j = 0; j < i; j++)
  3950.                 strbuffer[j] = ' ';
  3951.             strbuffer[j] = '\0';
  3952.             goto return_string;
  3953.  
  3954.         case 116:    /* bytearray new */
  3955.             /* initialize with random garbage */
  3956.             resultobj = new_bytearray(strbuffer, i);
  3957.             goto return_obj;
  3958.  
  3959.         case 117:    /* bytearray size */
  3960.             if (numargs != 1) goto argcerror;
  3961.             leftint = byarray->a_bsize;
  3962.             goto return_integer;
  3963.  
  3964.         case 118:    /* bytearray at: */
  3965.             if (numargs != 2) goto argcerror;
  3966.             leftint = uctoi(byarray->a_bytes[i]);
  3967.             goto return_integer;
  3968.  
  3969.         case 119:    /* bytearray at:put: */
  3970.             if (numargs != 3) goto argcerror;
  3971.             if (! int_value(args[2])) goto argterror;
  3972.             byarray->a_bytes[i] = itouc(int_value(args[2]));
  3973.             goto return_nil;
  3974.  
  3975.         case 120:    /* print, no return */
  3976.             printf("%s", leftp);
  3977. # ifdef FLUSHREQ
  3978.             fflush(stdout);
  3979. # endif
  3980.             goto return_nil;
  3981.  
  3982.         case 121:    /* print, with return */
  3983.             printf("%s\n", leftp);
  3984. # ifdef FLUSHREQ
  3985.             fflush(stdout);
  3986. # endif
  3987.             goto return_nil;
  3988.  
  3989.         case 122:    /* format for error printing */
  3990.             aClass = (class *) fnd_class(args[1]);
  3991.             sprintf(strbuffer,"%s: %s",
  3992.                 symbol_value(aClass->class_name), leftp);
  3993.             leftp = strbuffer;
  3994.  
  3995.         case 123:    /* print on error output */
  3996.             fprintf(stderr,"%s\n", leftp);
  3997. # ifdef FLUSHREQ
  3998.             fflush(stderr);
  3999. # endif
  4000.             goto return_nil;
  4001.  
  4002.         case 125:    /* unix system call */
  4003. # ifndef NOSYSTEM
  4004.             leftint = system(leftp);
  4005.             goto return_integer;
  4006. # endif
  4007. # ifdef NOSYSTEM
  4008.             errp = "system()";
  4009.             goto not_implemented;
  4010. # endif
  4011.  
  4012.         case 126:    /* printAt: */
  4013. # ifndef CURSES
  4014.             errp = "curses graphics package not available";
  4015.             goto return_error;
  4016. # endif
  4017. # ifdef CURSES
  4018.             if (numargs != 3) goto argcerror;
  4019.             if ((! is_string(args[0])) ||
  4020.                 (! is_integer(args[1])) ||
  4021.                 (! is_integer(args[2])) ) goto argterror;
  4022.             move(int_value(args[1]), int_value(args[2]));
  4023.             addstr(string_value(args[0]));
  4024.             refresh();
  4025.             move(0, LINES-1);
  4026.             goto return_nil;
  4027. # endif
  4028.  
  4029.         case 127:    /* block return */
  4030.             errp = "block return without surrounding context";
  4031.             goto return_error;
  4032.  
  4033.         case 128: /* reference count error */
  4034.             if (numargs != 1) goto argcerror;
  4035.             sprintf(strbuffer,"object %d reference count %d",
  4036.                 args[0], args[0]->ref_count);
  4037.             errp = strbuffer;
  4038.             goto return_error;
  4039.  
  4040.         case 129: /* does not respond error */
  4041.             if (numargs != 2) goto argcerror;
  4042.             if (! is_symbol(args[1])) goto argterror;
  4043.             fprintf(stderr,"respond error: %s\n",
  4044.             symbol_value(args[1]));
  4045.             aClass = (class *) fnd_class(args[0]);
  4046.             if (! is_class(aClass)) goto argterror;
  4047.             sprintf(strbuffer,"%s: does not respond to %s",
  4048.                 symbol_value(aClass->class_name),
  4049.                 symbol_value(args[1]));
  4050.             errp = strbuffer;
  4051.             goto return_error;
  4052.  
  4053.         case 130:    /* file open */
  4054.             if (numargs != 3) goto argcerror;
  4055.             if (! is_string(args[1])) goto argterror;
  4056.             if (! is_string(args[2])) goto argterror;
  4057.             file_open(phil,
  4058.                 string_value(args[1]), string_value(args[2]));
  4059.             goto return_nil;
  4060.  
  4061.         case 131:    /* file read */
  4062.             if (numargs != 1) goto argcerror;
  4063.             resultobj = file_read(phil);
  4064.             goto return_obj;
  4065.  
  4066.         case 132:    /* file write */
  4067.             if (numargs != 2) goto argcerror;
  4068.             file_write(phil, args[1]);
  4069.             goto return_nil;
  4070.  
  4071.         case 133:    /* set file mode */
  4072.             if (numargs != 2) goto argcerror;
  4073.             if (! is_integer(args[1])) goto argterror;
  4074.             phil->file_mode = int_value(args[1]);
  4075.             goto return_nil;
  4076.  
  4077.         case 134:    /* compute file size */
  4078.             fseek(phil->fp, (long) 0, 2);
  4079.             leftint = (int) ftell(phil->fp);
  4080.             goto return_integer;
  4081.  
  4082.         case 135:    /* set file position */
  4083.             if (numargs != 2) goto argcerror;
  4084.             if (! is_integer(args[1])) goto argterror;
  4085.             leftint = fseek(phil->fp, (long) int_value(args[1]), 0);
  4086.             goto return_integer;
  4087.  
  4088.         case 136:    /* find current position */
  4089.             if (numargs != 1) goto argcerror;
  4090.             leftint = (int) ftell(phil->fp);
  4091.             goto return_integer;
  4092.  
  4093.         case 140:
  4094.             errp = "block execute should be trapped by interp";
  4095.             goto return_error;
  4096.  
  4097.         case 141:    /* newProcess (withArguments:) */
  4098.             if (numargs < 1) goto argcerror;
  4099.             if (! is_block(args[0])) goto argterror;
  4100.             if (numargs == 1)
  4101.                 resultobj = (object *)
  4102.                     block_execute((interpreter *) 0,
  4103.                     (block *) args[0], 0, args);
  4104.             else if (numargs == 2)
  4105.                 resultobj = (object *)
  4106.                     block_execute((interpreter *) 0,
  4107.                     (block *) args[0], args[1]->size,
  4108.                     &(args[1]->inst_var[0]));
  4109.             else goto argcerror;
  4110.             if (((object *) 0) == resultobj) goto return_nil;
  4111.             resultobj = (object *) cr_process(resultobj);
  4112.             goto return_obj;
  4113.  
  4114.         case 142:    /* terminate a process */
  4115.             if (numargs != 1) goto argcerror;
  4116.             if (! is_process(args[0])) goto argterror;
  4117.             terminate_process( (process *) args[0]);
  4118.             goto return_nil;
  4119.  
  4120.         case 143:    /* perform:withArguments: */
  4121.             errp = "perform should be trapped by interpreter";
  4122.             goto return_error;
  4123.  
  4124.         case 145:    /* set the state of a process */
  4125.             if (numargs != 2) goto argcerror;
  4126.             if (! is_process(args[0])) goto argterror;
  4127.             if (! is_integer(args[1])) goto argterror;
  4128.             leftint = int_value(args[1]);
  4129.             switch (leftint) {
  4130.                 case 0:    leftint = READY;
  4131.                     break;
  4132.                 case 1:    leftint = SUSPENDED;
  4133.                     break;
  4134.                 case 2:    leftint = BLOCKED;
  4135.                     break;
  4136.                 case 3:    leftint = UNBLOCKED;
  4137.                     break;
  4138.                 default:  errp = "invalid state for process";
  4139.                       goto return_error;
  4140.  
  4141.                 }
  4142.             set_state((process *) args[0], leftint);
  4143.             goto return_integer;
  4144.  
  4145.         case 146:    /* return the state of a process */
  4146.             if (numargs != 1) goto argcerror;
  4147.             if (! is_process(args[0])) goto argterror;
  4148.             leftint = set_state((process *) args[0], CUR_STATE);
  4149.             goto return_integer;
  4150.  
  4151.         case 148:    /* begin atomic action */
  4152.             if (numargs != 0) goto argcerror;
  4153.             atomcnt++;
  4154.             goto return_nil;
  4155.  
  4156.         case 149:    /* end atomic action */
  4157.             if (numargs != 0) goto argcerror;
  4158.             if (atomcnt == 0) {
  4159.                 errp = "end atomic attempted while not in atomic action";
  4160.                 goto return_error;
  4161.                 }
  4162.             atomcnt--;
  4163.             goto return_nil;
  4164.  
  4165.         case 150:    /* class edit */
  4166.             leftp = symbol_value(aClass->file_name);
  4167.             if (! writeable(leftp)) {
  4168.                 gettemp(tempname);
  4169.                 sprintf(strbuffer,"cp %s %s", leftp, tempname);
  4170. # ifndef NOSYSTEM
  4171.                 system(strbuffer);
  4172. # endif
  4173.                 leftp = tempname;
  4174.                 }
  4175.             if (! lexedit(leftp)) lexinclude(leftp);
  4176.             goto return_nil;
  4177.  
  4178.         case 151:     /* superclass of a class */
  4179.             if (! aClass->super_class)
  4180.                 goto return_nil;
  4181.             resultobj = (object *) aClass->super_class;
  4182.             if (! is_symbol(resultobj)) goto return_nil;
  4183.             resultobj = lookup_class(symbol_value(resultobj));
  4184.             if (! resultobj) goto return_nil;
  4185.             goto return_obj;
  4186.  
  4187.         case 152: /* class name */
  4188.             resultobj = aClass->class_name;
  4189.             leftp = symbol_value(resultobj);
  4190.             resultobj = new_str(leftp);
  4191.             goto return_obj;
  4192.  
  4193.         case 153: /* new */
  4194.             if (numargs != 2) goto argcerror;
  4195.             if (args[1] == o_nil)
  4196.                 resultobj = new_inst(aClass);
  4197.             else
  4198.                 resultobj = new_sinst(aClass, args[1]);
  4199.             goto return_obj;
  4200.  
  4201.         case 154:    /* print message names list */
  4202.             prnt_messages(aClass);
  4203.             goto return_nil;
  4204.  
  4205.         case 155:     /* respondsTo: aMessage  */
  4206.             if (numargs != 2) goto argcerror;
  4207.             if (! is_symbol(args[1])) goto argterror;
  4208.             leftint = responds_to(symbol_value(args[1]), aClass);
  4209.             goto return_boolean;
  4210.  
  4211.         case 156:    /* class view */
  4212. # ifndef NOSYSTEM
  4213.             leftp = symbol_value(aClass->file_name);
  4214.             gettemp(tempname);
  4215.             sprintf(strbuffer,"cp %s %s", leftp, tempname);
  4216.             system(strbuffer);
  4217.             leftp = tempname;
  4218.             lexedit(leftp);
  4219.             goto return_nil;
  4220. # endif
  4221. # ifdef NOSYSTEM
  4222.             errp = "cannot view classes on this system";
  4223.             goto return_error;
  4224. # endif
  4225.  
  4226.         case 157:    /* class list */
  4227.             class_list(aClass, 0);
  4228.             goto return_nil;
  4229.  
  4230.  
  4231.         case 158:    /* variables */
  4232.             resultobj = aClass->c_inst_vars;
  4233.             goto return_obj;
  4234.  
  4235.         case 160:    /* current time */
  4236.             time(&clock);
  4237.             strcpy(strbuffer, ctime(&clock));
  4238.             goto return_string;
  4239.  
  4240.         case 161:    /* time, measure in seconds */
  4241.             leftint = (int) time((long *) 0);
  4242.             goto return_integer;
  4243.  
  4244.         case 162:    /* clear screen */
  4245. # ifdef CURSES
  4246.             clear();
  4247.             move(0,0);
  4248.             refresh();
  4249. # endif
  4250. # ifdef PLOT3
  4251.             erase();
  4252. # endif
  4253.             goto return_nil;
  4254.  
  4255.         case 163:    /* getString */
  4256.             gets(strbuffer);
  4257.             goto return_string;
  4258.  
  4259.         case 164:    /* string asInteger */
  4260.             if (! is_string(args[0])) goto argterror;
  4261.             leftint = atoi(string_value(args[0]));
  4262.             goto return_integer;
  4263.  
  4264.         case 165:    /* string asFloat */
  4265.             if (! is_string(args[0])) goto argterror;
  4266.             leftfloat = atof(string_value(args[0]));
  4267.             goto return_float;
  4268.  
  4269. # ifdef PLOT3
  4270.  
  4271. /**************************
  4272.     warning - the calls on the plot(3) routines are very device
  4273.     specific, and will probably require changes to work on any one
  4274.     particular new device
  4275. **********************************/
  4276.         case 170:    /* clear */
  4277.             erase();
  4278.             goto return_nil;
  4279.  
  4280.         case 171:    /* move(x,y) */
  4281.             move(leftint, rightint);
  4282.             goto return_nil;
  4283.  
  4284.         case 172:    /* cont(x,y) (draw line) */
  4285.             cont(leftint, rightint);
  4286.             goto return_nil;
  4287.  
  4288.         case 173:    /* point(x,y) (draw point) */
  4289.             point(leftint, rightint);
  4290.             goto return_nil;
  4291.  
  4292.         case 174:    /* circle(x, y, r) */
  4293.             if (numargs != 3) goto argcerror;
  4294.             for (i = 0; i < 3; i++)
  4295.                 if (! is_integer(args[i]))
  4296.                     goto argterror;
  4297.             circle(int_value(args[0]), int_value(args[1]),
  4298.                 int_value(args[2]));
  4299.             goto return_nil;
  4300.  
  4301.         case 175:    /* arg(x, y, x0, y0, x1, y1) */
  4302.             if (numargs != 6) goto argcerror;
  4303.             for (i = 0; i < 6; i++)
  4304.                 if (! is_integer(args[i])) goto argterror;
  4305.             arc(int_value(args[0]), int_value(args[1]),
  4306.                 int_value(args[2]), int_value(args[3]),
  4307.                 int_value(args[4]), int_value(args[5]));
  4308.             goto return_nil;
  4309.  
  4310.         case 176:    /* space */
  4311.             space(leftint, rightint, i, j);
  4312.             goto return_nil;
  4313.  
  4314.         case 177:    /* line */
  4315.             line(leftint, rightint, i, j);
  4316.             goto return_nil;
  4317.  
  4318.         case 178:    /* label */
  4319.             label(leftp);
  4320.             goto return_nil;
  4321.  
  4322.         case 179:    /* linemod */
  4323.             linemod(leftp);
  4324.             goto return_nil;
  4325. # endif
  4326.  
  4327.         default: fprintf(stderr,"Primitive number %d not implemented\n",
  4328.                         primnumber);
  4329.             goto return_nil;
  4330.     }
  4331.  
  4332. /* return different types of objects */
  4333.  
  4334. return_obj:
  4335.  
  4336.     return(resultobj);
  4337.  
  4338. return_nil:
  4339.  
  4340.     return(o_nil);
  4341.  
  4342. return_integer:
  4343.  
  4344.     return(new_int(leftint));
  4345.  
  4346. return_character:
  4347.  
  4348.     return(new_char(leftint));
  4349.  
  4350. return_boolean:
  4351.  
  4352.     return(leftint ? o_true : o_false);
  4353.  
  4354. float_check:
  4355.  
  4356.     if (errno == ERANGE || errno == EDOM) goto numerror;
  4357.  
  4358. return_float:
  4359.  
  4360.     return(new_float(leftfloat));
  4361.  
  4362. return_string:
  4363.  
  4364.     return(new_str(strbuffer));
  4365.  
  4366. /* error conditions */
  4367.  
  4368. not_implemented:
  4369.     sprintf(strbuffer,"%s not implemented yet", errp);
  4370.     errp = strbuffer;
  4371.     goto return_error;
  4372.  
  4373. argcerror:
  4374.     sprintf(strbuffer,"%d is wrong number of arguments for primitive %d",
  4375.         numargs, primnumber);
  4376.     errp = strbuffer;
  4377.     goto return_error;
  4378.  
  4379. argterror:
  4380.     sprintf(strbuffer,"argument type not correct for primitive %d",
  4381.         primnumber);
  4382.     errp = strbuffer;
  4383.     goto return_error;
  4384.  
  4385. numerror:
  4386.     errp = "numerical error in primitive";
  4387.     goto return_error;
  4388.  
  4389. indexerror:
  4390.     errp = "primitive index error";
  4391.     goto return_error;
  4392.  
  4393. return_error:
  4394.     sassign(resultobj, new_str(errp));
  4395.     primitive(ERRPRINT, 1, &resultobj);
  4396.     obj_dec(resultobj);
  4397.     goto return_nil;
  4398. }
  4399.  
  4400. static prnt_radix(n, r, buffer)
  4401. int n, r;
  4402. char buffer[];
  4403. {  char *p, *q, buffer2[60];
  4404.    int i, s;
  4405.  
  4406.    if (n < 0) {n = - n; s = 1;}
  4407.    else s = 0;
  4408.    p = buffer2; *p++ = '\0';
  4409.    if (n == 0) *p++ = '0';
  4410.    while (n) {
  4411.       i = n % r;
  4412.       *p++ = i + ((i < 10) ?  '0' : ('A' - 10));
  4413.       n = n / r;
  4414.       }
  4415.    sprintf(buffer,"%dr", r);
  4416.    for (q = buffer; *q; q++);
  4417.    if (s) *q++ = '-';
  4418.    for (*p = '0' ; *p ; ) *q++ = *--p;
  4419.    *q = '\0';
  4420. }
  4421.  
  4422. static fprnt_radix(f, n, buffer)
  4423. double f;
  4424. int n;
  4425. char buffer[];
  4426. {    int sign, exp, i, j;
  4427.     char *p, *q, tempbuffer[60];
  4428.     double ip;
  4429.  
  4430.     if (f < 0) {
  4431.         sign = 1;
  4432.         f = - f;
  4433.         }
  4434.     else sign = 0;
  4435.     exp = 0;
  4436.     if (f != 0) {
  4437.         exp = (int) floor(log(f) / log((double) n));
  4438.         if (exp < -4 || 4 < exp) {
  4439.             f *= pow((double) n, (double) - exp);
  4440.             }
  4441.         else exp = 0;
  4442.         }
  4443.     f = modf(f, &ip);
  4444.     if (sign) ip = - ip;
  4445.     prnt_radix((int) ip, n, buffer);
  4446.     for (p = buffer; *p; p++) ;
  4447.     if (f != 0) {
  4448.         *p++ = '.';
  4449.         for (j = 0; (f != 0) && (j < 6); j++){
  4450.             i = (int) (f *= n);
  4451.             *p++ = (i < 10) ? '0' + i : 'A' + (i-10) ;
  4452.             f -= i;
  4453.             }
  4454.         }
  4455.     if (exp) {
  4456.         *p++ = 'e';
  4457.         sprintf(tempbuffer,"%d", exp);
  4458.         for (q = tempbuffer; *q; )
  4459.             *p++ = *q++;
  4460.         }
  4461.     *p = '\0';
  4462.     return;
  4463. }
  4464.  
  4465. /* generalit - numerical generality */
  4466. static int generality(aNumber)
  4467. object *aNumber;
  4468. {    int i;
  4469.  
  4470.     if (is_integer(aNumber)) i = 1;
  4471.     else if (is_float(aNumber)) i = 2;
  4472.     else i = 3;
  4473.     return(i);
  4474. }
  4475.  
  4476. /* cant_happen - report that an impossible condition has occured */
  4477. cant_happen(n) int n;
  4478. {   char *s;
  4479.  
  4480. # ifdef SMALLDATA
  4481.     s = "what a pain!";
  4482. # endif
  4483. # ifndef SMALLDATA
  4484.     switch(n) {
  4485.        case 1:  s = "out of memory allocation space"; break;
  4486.        case 2:  s = "array size less than zero"; break;
  4487.        case 3:  s = "block return from call should not occur"; break;
  4488.        case 4:  s = "attempt to make instance of non class"; break;
  4489.        case 5:  s = "case error in new integer or string"; break;
  4490.        case 6:  s = "decrement on unknown built in object"; break;
  4491.        case 7:  s = "cannot find class Object"; break;
  4492.        case 8:  s = "primitive free of object of wrong type"; break;
  4493.        case 9:  s = "internal interpreter error"; break;
  4494.        case 11: s = "block execute on non-block"; break;
  4495.        case 12: s = "out of symbol space"; break;
  4496.        case 14: s = "out of standard bytecode space"; break;
  4497.        case 15: s = "system deadlocked - all processes blocked"; break;
  4498.        case 16: s = "attempt to free symbol"; break;
  4499.        case 17: s = "invalid process state passed to set_state"; break;
  4500.        case 18: s = "internal buffer overflow"; break;
  4501.        case 20: s = "can't open prelude file"; break;
  4502.        case 22: s = "system file open error"; break;
  4503.        case 23: s = "fastsave error"; break;
  4504.        default: s = "unknown, but impossible nonetheless, condition"; break;
  4505.        }
  4506. # endif
  4507.    fprintf(stderr,"Can't happen number %d: %s\n", n, s);
  4508.    exit(1);
  4509. }
  4510.  
  4511. /* writeable - see if a file can be written to */
  4512. int writeable(name)
  4513. char *name;
  4514. {    char buffer[150];
  4515.  
  4516.     sprintf(buffer,"test -w %s", name);
  4517. # ifdef NOSYSTEM
  4518.     return(0);
  4519. # endif
  4520. # ifndef NOSYSTEM
  4521.     return(! system(buffer));
  4522. # endif
  4523. }
  4524. End
  4525. echo unbundling syms.c 1>&2
  4526. cat >syms.c <<'End'
  4527. # include "object.h"
  4528. # include "symbol.h"
  4529. char x_str[] = {041, 0,   /* ! */
  4530. 046, 0,   /* & */
  4531. 050, 0,   /* ( */
  4532. 051, 0,   /* ) */
  4533. 052, 0,   /* * */
  4534. 053, 0,   /* + */
  4535. 054, 0,   /* , */
  4536. 055, 0,   /* - */
  4537. 057, 0,   /* / */
  4538. 057, 057, 0,   /* // */
  4539. 074, 0,   /* < */
  4540. 074, 075, 0,   /* <= */
  4541. 075, 0,   /* = */
  4542. 075, 075, 0,   /* == */
  4543. 076, 0,   /* > */
  4544. 076, 075, 0,   /* >= */
  4545. 0100, 0,   /* @ */
  4546. 0101, 0162, 0162, 0141, 0171, 0,   /* Array */
  4547. 0101, 0162, 0162, 0141, 0171, 0145, 0144, 0103, 0157, 0154, 0154, 0145, 0143, 0164, 0151, 0157, 0156, 0,   /* ArrayedCollection */
  4548. 0102, 0114, 0117, 0103, 0113, 0105, 0104, 0,   /* BLOCKED */
  4549. 0102, 0141, 0147, 0,   /* Bag */
  4550. 0102, 0154, 0157, 0143, 0153, 0,   /* Block */
  4551. 0102, 0157, 0157, 0154, 0145, 0141, 0156, 0,   /* Boolean */
  4552. 0102, 0171, 0164, 0145, 0101, 0162, 0162, 0141, 0171, 0,   /* ByteArray */
  4553. 0103, 0150, 0141, 0162, 0,   /* Char */
  4554. 0103, 0154, 0141, 0163, 0163, 0,   /* Class */
  4555. 0103, 0157, 0154, 0154, 0145, 0143, 0164, 0151, 0157, 0156, 0,   /* Collection */
  4556. 0103, 0157, 0155, 0160, 0154, 0145, 0170, 0,   /* Complex */
  4557. 0104, 0151, 0143, 0164, 0151, 0157, 0156, 0141, 0162, 0171, 0,   /* Dictionary */
  4558. 0106, 0141, 0154, 0163, 0145, 0,   /* False */
  4559. 0106, 0151, 0154, 0145, 0,   /* File */
  4560. 0106, 0154, 0157, 0141, 0164, 0,   /* Float */
  4561. 0111, 0156, 0164, 0145, 0147, 0145, 0162, 0,   /* Integer */
  4562. 0111, 0156, 0164, 0145, 0162, 0160, 0162, 0145, 0164, 0145, 0162, 0,   /* Interpreter */
  4563. 0111, 0156, 0164, 0145, 0162, 0166, 0141, 0154, 0,   /* Interval */
  4564. 0113, 0145, 0171, 0145, 0144, 0103, 0157, 0154, 0154, 0145, 0143, 0164, 0151, 0157, 0156, 0,   /* KeyedCollection */
  4565. 0114, 0151, 0163, 0164, 0,   /* List */
  4566. 0114, 0151, 0164, 0164, 0154, 0145, 040, 0123, 0155, 0141, 0154, 0154, 0164, 0141, 0154, 0153, 0,   /* Little Smalltalk */
  4567. 0115, 0141, 0147, 0156, 0151, 0164, 0165, 0144, 0145, 0,   /* Magnitude */
  4568. 0115, 0141, 0151, 0156, 0,   /* Main */
  4569. 0116, 0165, 0155, 0142, 0145, 0162, 0,   /* Number */
  4570. 0117, 0142, 0152, 0145, 0143, 0164, 0,   /* Object */
  4571. 0117, 0162, 0144, 0145, 0162, 0145, 0144, 0103, 0157, 0154, 0154, 0145, 0143, 0164, 0151, 0157, 0156, 0,   /* OrderedCollection */
  4572. 0120, 0157, 0151, 0156, 0164, 0,   /* Point */
  4573. 0120, 0162, 0157, 0143, 0145, 0163, 0163, 0,   /* Process */
  4574. 0122, 0105, 0101, 0104, 0131, 0,   /* READY */
  4575. 0122, 0141, 0144, 0151, 0141, 0156, 0,   /* Radian */
  4576. 0122, 0141, 0156, 0144, 0157, 0155, 0,   /* Random */
  4577. 0123, 0125, 0123, 0120, 0105, 0116, 0104, 0105, 0104, 0,   /* SUSPENDED */
  4578. 0123, 0145, 0155, 0141, 0160, 0150, 0157, 0162, 0145, 0,   /* Semaphore */
  4579. 0123, 0145, 0161, 0165, 0145, 0156, 0143, 0145, 0141, 0142, 0154, 0145, 0103, 0157, 0154, 0154, 0145, 0143, 0164, 0151, 0157, 0156, 0,   /* SequenceableCollection */
  4580. 0123, 0145, 0164, 0,   /* Set */
  4581. 0123, 0155, 0141, 0154, 0154, 0164, 0141, 0154, 0153, 0,   /* Smalltalk */
  4582. 0123, 0164, 0162, 0151, 0156, 0147, 0,   /* String */
  4583. 0123, 0171, 0155, 0142, 0157, 0154, 0,   /* Symbol */
  4584. 0124, 0105, 0122, 0115, 0111, 0116, 0101, 0124, 0105, 0104, 0,   /* TERMINATED */
  4585. 0124, 0162, 0165, 0145, 0,   /* True */
  4586. 0125, 0156, 0144, 0145, 0146, 0151, 0156, 0145, 0144, 0117, 0142, 0152, 0145, 0143, 0164, 0,   /* UndefinedObject */
  4587. 0133, 0,   /* [ */
  4588. 0134, 0134, 0,   /* \\ */
  4589. 0134, 0134, 0134, 0134, 0,   /* \\\\ */
  4590. 0135, 0,   /* ] */
  4591. 0136, 0,   /* ^ */
  4592. 0141, 0142, 0163, 0,   /* abs */
  4593. 0141, 0144, 0144, 072, 0,   /* add: */
  4594. 0141, 0144, 0144, 072, 0141, 0146, 0164, 0145, 0162, 072, 0,   /* add:after: */
  4595. 0141, 0144, 0144, 072, 0142, 0145, 0146, 0157, 0162, 0145, 072, 0,   /* add:before: */
  4596. 0141, 0144, 0144, 072, 0167, 0151, 0164, 0150, 0117, 0143, 0143, 0165, 0162, 0162, 0145, 0156, 0143, 0145, 0163, 072, 0,   /* add:withOccurrences: */
  4597. 0141, 0144, 0144, 0101, 0154, 0154, 072, 0,   /* addAll: */
  4598. 0141, 0144, 0144, 0101, 0154, 0154, 0106, 0151, 0162, 0163, 0164, 072, 0,   /* addAllFirst: */
  4599. 0141, 0144, 0144, 0101, 0154, 0154, 0114, 0141, 0163, 0164, 072, 0,   /* addAllLast: */
  4600. 0141, 0144, 0144, 0106, 0151, 0162, 0163, 0164, 072, 0,   /* addFirst: */
  4601. 0141, 0144, 0144, 0114, 0141, 0163, 0164, 072, 0,   /* addLast: */
  4602. 0141, 0146, 0164, 0145, 0162, 072, 0,   /* after: */
  4603. 0141, 0154, 0154, 0115, 0141, 0163, 0153, 072, 0,   /* allMask: */
  4604. 0141, 0156, 0144, 072, 0,   /* and: */
  4605. 0141, 0156, 0171, 0115, 0141, 0163, 0153, 072, 0,   /* anyMask: */
  4606. 0141, 0162, 0143, 0103, 0157, 0163, 0,   /* arcCos */
  4607. 0141, 0162, 0143, 0123, 0151, 0156, 0,   /* arcSin */
  4608. 0141, 0162, 0143, 0124, 0141, 0156, 0,   /* arcTan */
  4609. 0141, 0162, 0147, 0145, 0162, 0162, 0157, 0162, 0,   /* argerror */
  4610. 0141, 0163, 0101, 0162, 0162, 0141, 0171, 0,   /* asArray */
  4611. 0141, 0163, 0102, 0141, 0147, 0,   /* asBag */
  4612. 0141, 0163, 0103, 0150, 0141, 0162, 0141, 0143, 0164, 0145, 0162, 0,   /* asCharacter */
  4613. 0141, 0163, 0104, 0151, 0143, 0164, 0151, 0157, 0156, 0141, 0162, 0171, 0,   /* asDictionary */
  4614. 0141, 0163, 0106, 0154, 0157, 0141, 0164, 0,   /* asFloat */
  4615. 0141, 0163, 0106, 0162, 0141, 0143, 0164, 0151, 0157, 0156, 0,   /* asFraction */
  4616. 0141, 0163, 0111, 0156, 0164, 0145, 0147, 0145, 0162, 0,   /* asInteger */
  4617. 0141, 0163, 0114, 0151, 0163, 0164, 0,   /* asList */
  4618. 0141, 0163, 0114, 0157, 0167, 0145, 0162, 0143, 0141, 0163, 0145, 0,   /* asLowercase */
  4619. 0141, 0163, 0117, 0162, 0144, 0145, 0162, 0145, 0144, 0103, 0157, 0154, 0154, 0145, 0143, 0164, 0151, 0157, 0156, 0,   /* asOrderedCollection */
  4620. 0141, 0163, 0123, 0145, 0164, 0,   /* asSet */
  4621. 0141, 0163, 0123, 0164, 0162, 0151, 0156, 0147, 0,   /* asString */
  4622. 0141, 0163, 0123, 0171, 0155, 0142, 0157, 0154, 0,   /* asSymbol */
  4623. 0141, 0163, 0125, 0160, 0160, 0145, 0162, 0143, 0141, 0163, 0145, 0,   /* asUppercase */
  4624. 0141, 0163, 0143, 0151, 0151, 0126, 0141, 0154, 0165, 0145, 0,   /* asciiValue */
  4625. 0141, 0164, 072, 0,   /* at: */
  4626. 0141, 0164, 072, 0151, 0146, 0101, 0142, 0163, 0145, 0156, 0164, 072, 0,   /* at:ifAbsent: */
  4627. 0141, 0164, 072, 0160, 0165, 0164, 072, 0,   /* at:put: */
  4628. 0141, 0164, 0101, 0154, 0154, 072, 0160, 0165, 0164, 072, 0,   /* atAll:put: */
  4629. 0141, 0164, 0101, 0154, 0154, 0120, 0165, 0164, 072, 0,   /* atAllPut: */
  4630. 0142, 0145, 0146, 0157, 0162, 0145, 072, 0,   /* before: */
  4631. 0142, 0145, 0164, 0167, 0145, 0145, 0156, 072, 0141, 0156, 0144, 072, 0,   /* between:and: */
  4632. 0142, 0151, 0156, 0141, 0162, 0171, 0104, 0157, 072, 0,   /* binaryDo: */
  4633. 0142, 0151, 0164, 0101, 0156, 0144, 072, 0,   /* bitAnd: */
  4634. 0142, 0151, 0164, 0101, 0164, 072, 0,   /* bitAt: */
  4635. 0142, 0151, 0164, 0111, 0156, 0166, 0145, 0162, 0164, 0,   /* bitInvert */
  4636. 0142, 0151, 0164, 0117, 0162, 072, 0,   /* bitOr: */
  4637. 0142, 0151, 0164, 0123, 0150, 0151, 0146, 0164, 072, 0,   /* bitShift: */
  4638. 0142, 0151, 0164, 0130, 0157, 0162, 072, 0,   /* bitXor: */
  4639. 0142, 0154, 0157, 0143, 0153, 0,   /* block */
  4640. 0142, 0154, 0157, 0143, 0153, 0145, 0144, 0120, 0162, 0157, 0143, 0145, 0163, 0163, 0121, 0165, 0145, 0165, 0145, 0,   /* blockedProcessQueue */
  4641. 0143, 0145, 0151, 0154, 0151, 0156, 0147, 0,   /* ceiling */
  4642. 0143, 0150, 0145, 0143, 0153, 0102, 0165, 0143, 0153, 0145, 0164, 072, 0,   /* checkBucket: */
  4643. 0143, 0154, 0141, 0163, 0163, 0,   /* class */
  4644. 0143, 0154, 0145, 0141, 0156, 0125, 0160, 0,   /* cleanUp */
  4645. 0143, 0157, 0145, 0162, 0143, 0145, 072, 0,   /* coerce: */
  4646. 0143, 0157, 0154, 0154, 0145, 0143, 0164, 072, 0,   /* collect: */
  4647. 0143, 0157, 0155, 0155, 0141, 0156, 0144, 0163, 072, 0,   /* commands: */
  4648. 0143, 0157, 0155, 0160, 0141, 0162, 0145, 0105, 0162, 0162, 0157, 0162, 0,   /* compareError */
  4649. 0143, 0157, 0160, 0171, 0,   /* copy */
  4650. 0143, 0157, 0160, 0171, 0101, 0162, 0147, 0165, 0155, 0145, 0156, 0164, 0163, 072, 0,   /* copyArguments: */
  4651. 0143, 0157, 0160, 0171, 0101, 0162, 0147, 0165, 0155, 0145, 0156, 0164, 0163, 072, 0164, 0157, 072, 0,   /* copyArguments:to: */
  4652. 0143, 0157, 0160, 0171, 0106, 0162, 0157, 0155, 072, 0,   /* copyFrom: */
  4653. 0143, 0157, 0160, 0171, 0106, 0162, 0157, 0155, 072, 0154, 0145, 0156, 0147, 0164, 0150, 072, 0,   /* copyFrom:length: */
  4654. 0143, 0157, 0160, 0171, 0106, 0162, 0157, 0155, 072, 0164, 0157, 072, 0,   /* copyFrom:to: */
  4655. 0143, 0157, 0160, 0171, 0127, 0151, 0164, 0150, 072, 0,   /* copyWith: */
  4656. 0143, 0157, 0160, 0171, 0127, 0151, 0164, 0150, 0157, 0165, 0164, 072, 0,   /* copyWithout: */
  4657. 0143, 0157, 0163, 0,   /* cos */
  4658. 0143, 0157, 0165, 0156, 0164, 0,   /* count */
  4659. 0143, 0165, 0162, 0162, 0101, 0163, 0163, 0157, 0143, 0,   /* currAssoc */
  4660. 0143, 0165, 0162, 0162, 0102, 0165, 0143, 0153, 0145, 0164, 0,   /* currBucket */
  4661. 0143, 0165, 0162, 0162, 0145, 0156, 0164, 0,   /* current */
  4662. 0143, 0165, 0162, 0162, 0145, 0156, 0164, 0102, 0165, 0143, 0153, 0145, 0164, 0,   /* currentBucket */
  4663. 0143, 0165, 0162, 0162, 0145, 0156, 0164, 0113, 0145, 0171, 0,   /* currentKey */
  4664. 0143, 0165, 0162, 0162, 0145, 0156, 0164, 0114, 0151, 0163, 0164, 0,   /* currentList */
  4665. 0144, 0141, 0164, 0145, 0,   /* date */
  4666. 0144, 0145, 0142, 0165, 0147, 072, 0,   /* debug: */
  4667. 0144, 0145, 0145, 0160, 0103, 0157, 0160, 0171, 0,   /* deepCopy */
  4668. 0144, 0145, 0145, 0160, 0103, 0157, 0160, 0171, 072, 0,   /* deepCopy: */
  4669. 0144, 0145, 0164, 0145, 0143, 0164, 072, 0,   /* detect: */
  4670. 0144, 0145, 0164, 0145, 0143, 0164, 072, 0151, 0146, 0101, 0142, 0163, 0145, 0156, 0164, 072, 0,   /* detect:ifAbsent: */
  4671. 0144, 0145, 0164, 0145, 0143, 0164, 072, 0151, 0146, 0116, 0157, 0156, 0145, 072, 0,   /* detect:ifNone: */
  4672. 0144, 0151, 0143, 0164, 0,   /* dict */
  4673. 0144, 0151, 0143, 0164, 0151, 0157, 0156, 0141, 0162, 0171, 0,   /* dictionary */
  4674. 0144, 0151, 0147, 0151, 0164, 0126, 0141, 0154, 0165, 0145, 0,   /* digitValue */
  4675. 0144, 0151, 0147, 0151, 0164, 0126, 0141, 0154, 0165, 0145, 072, 0,   /* digitValue: */
  4676. 0144, 0151, 0163, 0160, 0154, 0141, 0171, 0,   /* display */
  4677. 0144, 0151, 0163, 0160, 0154, 0141, 0171, 0101, 0163, 0163, 0151, 0147, 0156, 0,   /* displayAssign */
  4678. 0144, 0151, 0163, 0164, 072, 0,   /* dist: */
  4679. 0144, 0157, 072, 0,   /* do: */
  4680. 0144, 0157, 0120, 0162, 0151, 0155, 0151, 0164, 0151, 0166, 0145, 072, 0,   /* doPrimitive: */
  4681. 0144, 0157, 0120, 0162, 0151, 0155, 0151, 0164, 0151, 0166, 0145, 072, 0167, 0151, 0164, 0150, 0101, 0162, 0147, 0165, 0155, 0145, 0156, 0164, 0163, 072, 0,   /* doPrimitive:withArguments: */
  4682. 0145, 0144, 0151, 0164, 0,   /* edit */
  4683. 0145, 0161, 0165, 0141, 0154, 0163, 072, 0163, 0164, 0141, 0162, 0164, 0151, 0156, 0147, 0101, 0164, 072, 0,   /* equals:startingAt: */
  4684. 0145, 0161, 0166, 072, 0,   /* eqv: */
  4685. 0145, 0162, 0162, 0157, 0162, 072, 0,   /* error: */
  4686. 0145, 0166, 0145, 0156, 0,   /* even */
  4687. 0145, 0170, 0143, 0145, 0163, 0163, 0123, 0151, 0147, 0156, 0141, 0154, 0163, 0,   /* excessSignals */
  4688. 0145, 0170, 0145, 0143, 0165, 0164, 0145, 0127, 0151, 0164, 0150, 072, 0,   /* executeWith: */
  4689. 0145, 0170, 0160, 0,   /* exp */
  4690. 0146, 0141, 0143, 0164, 0157, 0162, 0151, 0141, 0154, 0,   /* factorial */
  4691. 0146, 0151, 0156, 0144, 0101, 0163, 0163, 0157, 0143, 0151, 0141, 0164, 0151, 0157, 0156, 072, 0151, 0156, 0114, 0151, 0163, 0164, 072, 0,   /* findAssociation:inList: */
  4692. 0146, 0151, 0156, 0144, 0106, 0151, 0162, 0163, 0164, 072, 0,   /* findFirst: */
  4693. 0146, 0151, 0156, 0144, 0106, 0151, 0162, 0163, 0164, 072, 0151, 0146, 0101, 0142, 0163, 0145, 0156, 0164, 072, 0,   /* findFirst:ifAbsent: */
  4694. 0146, 0151, 0156, 0144, 0114, 0141, 0163, 0164, 0,   /* findLast */
  4695. 0146, 0151, 0156, 0144, 0114, 0141, 0163, 0164, 072, 0,   /* findLast: */
  4696. 0146, 0151, 0156, 0144, 0114, 0141, 0163, 0164, 072, 0151, 0146, 0101, 0142, 0163, 0145, 0156, 0164, 072, 0,   /* findLast:ifAbsent: */
  4697. 0146, 0151, 0162, 0163, 0164, 0,   /* first */
  4698. 0146, 0151, 0162, 0163, 0164, 0113, 0145, 0171, 0,   /* firstKey */
  4699. 0146, 0154, 0157, 0157, 0162, 0,   /* floor */
  4700. 0146, 0154, 0157, 0157, 0162, 0114, 0157, 0147, 072, 0,   /* floorLog: */
  4701. 0146, 0157, 0162, 0153, 0,   /* fork */
  4702. 0146, 0157, 0162, 0153, 0127, 0151, 0164, 0150, 072, 0,   /* forkWith: */
  4703. 0146, 0162, 0141, 0143, 0164, 0151, 0157, 0156, 0120, 0141, 0162, 0164, 0,   /* fractionPart */
  4704. 0146, 0162, 0145, 0145, 072, 0,   /* free: */
  4705. 0146, 0162, 0157, 0155, 072, 0,   /* from: */
  4706. 0146, 0162, 0157, 0155, 072, 0164, 0157, 072, 0,   /* from:to: */
  4707. 0146, 0162, 0157, 0155, 072, 0164, 0157, 072, 0142, 0171, 072, 0,   /* from:to:by: */
  4708. 0147, 0141, 0155, 0155, 0141, 0,   /* gamma */
  4709. 0147, 0143, 0144, 072, 0,   /* gcd: */
  4710. 0147, 0145, 0164, 0114, 0151, 0163, 0164, 072, 0,   /* getList: */
  4711. 0147, 0162, 0151, 0144, 072, 0,   /* grid: */
  4712. 0150, 0141, 0163, 0150, 0116, 0165, 0155, 0142, 0145, 0162, 072, 0,   /* hashNumber: */
  4713. 0150, 0141, 0163, 0150, 0124, 0141, 0142, 0,   /* hashTab */
  4714. 0150, 0141, 0163, 0150, 0124, 0141, 0142, 0154, 0145, 0,   /* hashTable */
  4715. 0150, 0151, 0147, 0150, 0102, 0151, 0164, 0,   /* highBit */
  4716. 0151, 0,   /* i */
  4717. 0151, 0146, 0106, 0141, 0154, 0163, 0145, 072, 0,   /* ifFalse: */
  4718. 0151, 0146, 0106, 0141, 0154, 0163, 0145, 072, 0151, 0146, 0124, 0162, 0165, 0145, 072, 0,   /* ifFalse:ifTrue: */
  4719. 0151, 0146, 0124, 0162, 0165, 0145, 072, 0,   /* ifTrue: */
  4720. 0151, 0146, 0124, 0162, 0165, 0145, 072, 0151, 0146, 0106, 0141, 0154, 0163, 0145, 072, 0,   /* ifTrue:ifFalse: */
  4721. 0151, 0156, 0122, 0141, 0156, 0147, 0145, 072, 0,   /* inRange: */
  4722. 0151, 0156, 0143, 0154, 0165, 0144, 0145, 0163, 072, 0,   /* includes: */
  4723. 0151, 0156, 0143, 0154, 0165, 0144, 0145, 0163, 0113, 0145, 0171, 072, 0,   /* includesKey: */
  4724. 0151, 0156, 0144, 0145, 0170, 0117, 0146, 072, 0,   /* indexOf: */
  4725. 0151, 0156, 0144, 0145, 0170, 0117, 0146, 072, 0151, 0146, 0101, 0142, 0163, 0145, 0156, 0164, 072, 0,   /* indexOf:ifAbsent: */
  4726. 0151, 0156, 0144, 0145, 0170, 0117, 0146, 0123, 0165, 0142, 0103, 0157, 0154, 0154, 0145, 0143, 0164, 0151, 0157, 0156, 072, 0163, 0164, 0141, 0162, 0164, 0151, 0156, 0147, 0101, 0164, 072, 0,   /* indexOfSubCollection:startingAt: */
  4727. 0151, 0156, 0144, 0145, 0170, 0117, 0146, 0123, 0165, 0142, 0103, 0157, 0154, 0154, 0145, 0143, 0164, 0151, 0157, 0156, 072, 0163, 0164, 0141, 0162, 0164, 0151, 0156, 0147, 0101, 0164, 072, 0151, 0146, 0101, 0142, 0163, 0145, 0156, 0164, 072, 0,   /* indexOfSubCollection:startingAt:ifAbsent: */
  4728. 0151, 0156, 0151, 0164, 072, 0,   /* init: */
  4729. 0151, 0156, 0151, 0164, 072, 0163, 0165, 0160, 0145, 0162, 072, 0,   /* init:super: */
  4730. 0151, 0156, 0151, 0164, 072, 0163, 0165, 0160, 0145, 0162, 072, 0156, 0165, 0155, 0126, 0141, 0162, 0163, 072, 0,   /* init:super:numVars: */
  4731. 0151, 0156, 0152, 0145, 0143, 0164, 072, 0151, 0156, 0164, 0157, 072, 0,   /* inject:into: */
  4732. 0151, 0156, 0164, 0145, 0147, 0145, 0162, 0120, 0141, 0162, 0164, 0,   /* integerPart */
  4733. 0151, 0163, 0101, 0154, 0160, 0150, 0141, 0116, 0165, 0155, 0145, 0162, 0151, 0143, 0,   /* isAlphaNumeric */
  4734. 0151, 0163, 0104, 0151, 0147, 0151, 0164, 0,   /* isDigit */
  4735. 0151, 0163, 0105, 0155, 0160, 0164, 0171, 0,   /* isEmpty */
  4736. 0151, 0163, 0113, 0151, 0156, 0144, 0117, 0146, 072, 0,   /* isKindOf: */
  4737. 0151, 0163, 0114, 0145, 0164, 0164, 0145, 0162, 0,   /* isLetter */
  4738. 0151, 0163, 0114, 0157, 0167, 0145, 0162, 0143, 0141, 0163, 0145, 0,   /* isLowercase */
  4739. 0151, 0163, 0115, 0145, 0155, 0142, 0145, 0162, 0117, 0146, 072, 0,   /* isMemberOf: */
  4740. 0151, 0163, 0116, 0151, 0154, 0,   /* isNil */
  4741. 0151, 0163, 0123, 0145, 0160, 0141, 0162, 0141, 0164, 0157, 0162, 0,   /* isSeparator */
  4742. 0151, 0163, 0125, 0160, 0160, 0145, 0162, 0143, 0141, 0163, 0145, 0,   /* isUppercase */
  4743. 0151, 0163, 0126, 0157, 0167, 0145, 0154, 0,   /* isVowel */
  4744. 0153, 0145, 0171, 0163, 0,   /* keys */
  4745. 0153, 0145, 0171, 0163, 0104, 0157, 072, 0,   /* keysDo: */
  4746. 0153, 0145, 0171, 0163, 0123, 0145, 0154, 0145, 0143, 0164, 072, 0,   /* keysSelect: */
  4747. 0154, 0141, 0163, 0164, 0,   /* last */
  4748. 0154, 0141, 0163, 0164, 0113, 0145, 0171, 0,   /* lastKey */
  4749. 0154, 0143, 0155, 072, 0,   /* lcm: */
  4750. 0154, 0151, 0163, 0164, 0,   /* list */
  4751. 0154, 0156, 0,   /* ln */
  4752. 0154, 0157, 0147, 072, 0,   /* log: */
  4753. 0154, 0157, 0167, 0145, 0162, 0,   /* lower */
  4754. 0155, 0141, 0151, 0156, 0,   /* main */
  4755. 0155, 0141, 0170, 072, 0,   /* max: */
  4756. 0155, 0141, 0170, 0103, 0157, 0156, 0164, 0145, 0170, 0164, 072, 0,   /* maxContext: */
  4757. 0155, 0141, 0170, 0164, 0171, 0160, 0145, 072, 0,   /* maxtype: */
  4758. 0155, 0145, 0164, 0150, 0157, 0144, 0163, 072, 0,   /* methods: */
  4759. 0155, 0151, 0156, 072, 0,   /* min: */
  4760. 0155, 0157, 0144, 0145, 0103, 0150, 0141, 0162, 0141, 0143, 0164, 0145, 0162, 0,   /* modeCharacter */
  4761. 0155, 0157, 0144, 0145, 0111, 0156, 0164, 0145, 0147, 0145, 0162, 0,   /* modeInteger */
  4762. 0155, 0157, 0144, 0145, 0123, 0164, 0162, 0151, 0156, 0147, 0,   /* modeString */
  4763. 0156, 0141, 0155, 0145, 072, 0,   /* name: */
  4764. 0156, 0145, 0147, 0141, 0164, 0145, 0144, 0,   /* negated */
  4765. 0156, 0145, 0147, 0141, 0164, 0151, 0166, 0145, 0,   /* negative */
  4766. 0156, 0145, 0167, 0,   /* new */
  4767. 0156, 0145, 0167, 072, 0,   /* new: */
  4768. 0156, 0145, 0167, 0120, 0162, 0157, 0143, 0145, 0163, 0163, 0,   /* newProcess */
  4769. 0156, 0145, 0167, 0120, 0162, 0157, 0143, 0145, 0163, 0163, 0127, 0151, 0164, 0150, 072, 0,   /* newProcessWith: */
  4770. 0156, 0145, 0170, 0164, 0,   /* next */
  4771. 0156, 0145, 0170, 0164, 072, 0,   /* next: */
  4772. 0156, 0157, 0104, 0151, 0163, 0160, 0154, 0141, 0171, 0,   /* noDisplay */
  4773. 0156, 0157, 0115, 0141, 0163, 0153, 072, 0,   /* noMask: */
  4774. 0156, 0157, 0164, 0,   /* not */
  4775. 0156, 0157, 0164, 0116, 0151, 0154, 0,   /* notNil */
  4776. 0156, 0157, 0164, 0150, 0151, 0156, 0147, 0,   /* nothing */
  4777. 0157, 0143, 0143, 0165, 0162, 0162, 0145, 0156, 0143, 0145, 0163, 0117, 0146, 072, 0,   /* occurrencesOf: */
  4778. 0157, 0144, 0144, 0,   /* odd */
  4779. 0157, 0160, 0105, 0162, 0162, 0157, 0162, 0,   /* opError */
  4780. 0157, 0160, 0145, 0156, 072, 0,   /* open: */
  4781. 0157, 0160, 0145, 0156, 072, 0146, 0157, 0162, 072, 0,   /* open:for: */
  4782. 0157, 0162, 072, 0,   /* or: */
  4783. 0160, 0145, 0162, 0146, 0157, 0162, 0155, 072, 0,   /* perform: */
  4784. 0160, 0145, 0162, 0146, 0157, 0162, 0155, 072, 0167, 0151, 0164, 0150, 0101, 0162, 0147, 0165, 0155, 0145, 0156, 0164, 0163, 072, 0,   /* perform:withArguments: */
  4785. 0160, 0151, 0,   /* pi */
  4786. 0160, 0157, 0163, 0151, 0164, 0151, 0166, 0145, 0,   /* positive */
  4787. 0160, 0162, 0151, 0156, 0164, 0,   /* print */
  4788. 0160, 0162, 0151, 0156, 0164, 0123, 0164, 0162, 0151, 0156, 0147, 0,   /* printString */
  4789. 0160, 0165, 0164, 072, 0,   /* put: */
  4790. 0161, 0165, 0157, 072, 0,   /* quo: */
  4791. 0162, 0141, 0144, 0151, 0141, 0156, 0163, 0,   /* radians */
  4792. 0162, 0141, 0144, 0151, 0170, 072, 0,   /* radix: */
  4793. 0162, 0141, 0151, 0163, 0145, 0144, 0124, 0157, 072, 0,   /* raisedTo: */
  4794. 0162, 0141, 0151, 0163, 0145, 0144, 0124, 0157, 0111, 0156, 0164, 0145, 0147, 0145, 0162, 072, 0,   /* raisedToInteger: */
  4795. 0162, 0141, 0156, 0144, 0111, 0156, 0164, 0145, 0147, 0145, 0162, 072, 0,   /* randInteger: */
  4796. 0162, 0141, 0156, 0144, 0157, 0155, 0151, 0172, 0145, 0,   /* randomize */
  4797. 0162, 0145, 0141, 0144, 0,   /* read */
  4798. 0162, 0145, 0143, 0151, 0160, 0162, 0157, 0143, 0141, 0154, 0,   /* reciprocal */
  4799. 0162, 0145, 0152, 0145, 0143, 0164, 072, 0,   /* reject: */
  4800. 0162, 0145, 0155, 072, 0,   /* rem: */
  4801. 0162, 0145, 0155, 0157, 0166, 0145, 072, 0,   /* remove: */
  4802. 0162, 0145, 0155, 0157, 0166, 0145, 072, 0151, 0146, 0101, 0142, 0163, 0145, 0156, 0164, 072, 0,   /* remove:ifAbsent: */
  4803. 0162, 0145, 0155, 0157, 0166, 0145, 0101, 0154, 0154, 072, 0,   /* removeAll: */
  4804. 0162, 0145, 0155, 0157, 0166, 0145, 0105, 0162, 0162, 0157, 0162, 0,   /* removeError */
  4805. 0162, 0145, 0155, 0157, 0166, 0145, 0106, 0151, 0162, 0163, 0164, 0,   /* removeFirst */
  4806. 0162, 0145, 0155, 0157, 0166, 0145, 0113, 0145, 0171, 072, 0,   /* removeKey: */
  4807. 0162, 0145, 0155, 0157, 0166, 0145, 0113, 0145, 0171, 072, 0151, 0146, 0101, 0142, 0163, 0145, 0156, 0164, 072, 0,   /* removeKey:ifAbsent: */
  4808. 0162, 0145, 0155, 0157, 0166, 0145, 0114, 0141, 0163, 0164, 0,   /* removeLast */
  4809. 0162, 0145, 0155, 0157, 0166, 0145, 0144, 0,   /* removed */
  4810. 0162, 0145, 0160, 0154, 0141, 0143, 0145, 0106, 0162, 0157, 0155, 072, 0164, 0157, 072, 0167, 0151, 0164, 0150, 072, 0,   /* replaceFrom:to:with: */
  4811. 0162, 0145, 0160, 0154, 0141, 0143, 0145, 0106, 0162, 0157, 0155, 072, 0164, 0157, 072, 0167, 0151, 0164, 0150, 072, 0163, 0164, 0141, 0162, 0164, 0151, 0156, 0147, 0101, 0164, 072, 0,   /* replaceFrom:to:with:startingAt: */
  4812. 0162, 0145, 0163, 0160, 0157, 0156, 0144, 0163, 0124, 0157, 0,   /* respondsTo */
  4813. 0162, 0145, 0163, 0160, 0157, 0156, 0144, 0163, 0124, 0157, 072, 0,   /* respondsTo: */
  4814. 0162, 0145, 0163, 0165, 0155, 0145, 0,   /* resume */
  4815. 0162, 0145, 0166, 0145, 0162, 0163, 0145, 0104, 0157, 072, 0,   /* reverseDo: */
  4816. 0162, 0145, 0166, 0145, 0162, 0163, 0145, 0144, 0,   /* reversed */
  4817. 0162, 0157, 0165, 0156, 0144, 0124, 0157, 072, 0,   /* roundTo: */
  4818. 0162, 0157, 0165, 0156, 0144, 0145, 0144, 0,   /* rounded */
  4819. 0163, 0141, 0155, 0145, 0101, 0163, 072, 0,   /* sameAs: */
  4820. 0163, 0145, 0145, 0144, 0,   /* seed */
  4821. 0163, 0145, 0154, 0145, 0143, 0164, 072, 0,   /* select: */
  4822. 0163, 0145, 0164, 0103, 0165, 0162, 0162, 0145, 0156, 0164, 0114, 0157, 0143, 0141, 0164, 0151, 0157, 0156, 072, 0,   /* setCurrentLocation: */
  4823. 0163, 0150, 072, 0,   /* sh: */
  4824. 0163, 0150, 0141, 0154, 0154, 0157, 0167, 0103, 0157, 0160, 0171, 0,   /* shallowCopy */
  4825. 0163, 0150, 0141, 0154, 0154, 0157, 0167, 0103, 0157, 0160, 0171, 072, 0,   /* shallowCopy: */
  4826. 0163, 0151, 0147, 0156, 0,   /* sign */
  4827. 0163, 0151, 0147, 0156, 0141, 0154, 0,   /* signal */
  4828. 0163, 0151, 0156, 0,   /* sin */
  4829. 0163, 0151, 0172, 0145, 0,   /* size */
  4830. 0163, 0155, 0141, 0154, 0154, 0164, 0141, 0154, 0153, 0,   /* smalltalk */
  4831. 0163, 0157, 0162, 0164, 0,   /* sort */
  4832. 0163, 0157, 0162, 0164, 072, 0,   /* sort: */
  4833. 0163, 0161, 0162, 0164, 0,   /* sqrt */
  4834. 0163, 0161, 0165, 0141, 0162, 0145, 0144, 0,   /* squared */
  4835. 0163, 0164, 0141, 0164, 0145, 0,   /* state */
  4836. 0163, 0164, 0145, 0160, 0,   /* step */
  4837. 0163, 0164, 0162, 0151, 0143, 0164, 0154, 0171, 0120, 0157, 0163, 0151, 0164, 0151, 0166, 0145, 0,   /* strictlyPositive */
  4838. 0163, 0165, 0160, 0145, 0162, 0103, 0154, 0141, 0163, 0163, 0,   /* superClass */
  4839. 0163, 0165, 0160, 0145, 0162, 0103, 0154, 0141, 0163, 0163, 072, 0,   /* superClass: */
  4840. 0163, 0165, 0163, 0160, 0145, 0156, 0144, 0,   /* suspend */
  4841. 0164, 0141, 0156, 0,   /* tan */
  4842. 0164, 0145, 0155, 0160, 0,   /* temp */
  4843. 0164, 0145, 0162, 0155, 0105, 0162, 0162, 072, 0,   /* termErr: */
  4844. 0164, 0145, 0162, 0155, 0151, 0156, 0141, 0164, 0145, 0,   /* terminate */
  4845. 0164, 0151, 0155, 0145, 072, 0,   /* time: */
  4846. 0164, 0151, 0155, 0145, 0163, 0122, 0145, 0160, 0145, 0141, 0164, 072, 0,   /* timesRepeat: */
  4847. 0164, 0157, 072, 0,   /* to: */
  4848. 0164, 0157, 072, 0142, 0171, 072, 0,   /* to:by: */
  4849. 0164, 0162, 0141, 0156, 0163, 0160, 0157, 0163, 0145, 0,   /* transpose */
  4850. 0164, 0162, 0165, 0156, 0143, 0141, 0164, 0145, 0124, 0157, 072, 0,   /* truncateTo: */
  4851. 0164, 0162, 0165, 0156, 0143, 0141, 0164, 0145, 0144, 0,   /* truncated */
  4852. 0164, 0162, 0165, 0156, 0143, 0141, 0164, 0145, 0144, 0107, 0162, 0151, 0144, 072, 0,   /* truncatedGrid: */
  4853. 0165, 0156, 0142, 0154, 0157, 0143, 0153, 0,   /* unblock */
  4854. 0165, 0160, 0160, 0145, 0162, 0,   /* upper */
  4855. 0166, 0141, 0154, 0165, 0145, 0,   /* value */
  4856. 0166, 0141, 0154, 0165, 0145, 072, 0,   /* value: */
  4857. 0166, 0141, 0154, 0165, 0145, 072, 0166, 0141, 0154, 0165, 0145, 072, 0,   /* value:value: */
  4858. 0166, 0141, 0154, 0165, 0145, 072, 0166, 0141, 0154, 0165, 0145, 072, 0166, 0141, 0154, 0165, 0145, 072, 0,   /* value:value:value: */
  4859. 0166, 0141, 0154, 0165, 0145, 072, 0166, 0141, 0154, 0165, 0145, 072, 0166, 0141, 0154, 0165, 0145, 072, 0166, 0141, 0154, 0165, 0145, 072, 0,   /* value:value:value:value: */
  4860. 0166, 0141, 0154, 0165, 0145, 072, 0166, 0141, 0154, 0165, 0145, 072, 0166, 0141, 0154, 0165, 0145, 072, 0166, 0141, 0154, 0165, 0145, 072, 0166, 0141, 0154, 0165, 0145, 072, 0,   /* value:value:value:value:value: */
  4861. 0166, 0141, 0154, 0165, 0145, 0163, 0,   /* values */
  4862. 0166, 0141, 0162, 0151, 0141, 0142, 0154, 0145, 0163, 0,   /* variables */
  4863. 0166, 0141, 0162, 0151, 0141, 0142, 0154, 0145, 0163, 072, 0,   /* variables: */
  4864. 0166, 0151, 0145, 0167, 0,   /* view */
  4865. 0167, 0141, 0151, 0164, 0,   /* wait */
  4866. 0167, 0150, 0151, 0154, 0145, 0106, 0141, 0154, 0163, 0145, 072, 0,   /* whileFalse: */
  4867. 0167, 0150, 0151, 0154, 0145, 0124, 0162, 0165, 0145, 072, 0,   /* whileTrue: */
  4868. 0167, 0151, 0164, 0150, 072, 0144, 0157, 072, 0,   /* with:do: */
  4869. 0167, 0151, 0164, 0150, 0101, 0162, 0147, 0165, 0155, 0145, 0156, 0164, 0163, 072, 0,   /* withArguments: */
  4870. 0167, 0162, 0151, 0164, 0145, 072, 0,   /* write: */
  4871. 0170, 0,   /* x */
  4872. 0170, 072, 0,   /* x: */
  4873. 0170, 0157, 0162, 072, 0,   /* xor: */
  4874. 0170, 0166, 0141, 0154, 0165, 0145, 0,   /* xvalue */
  4875. 0171, 0,   /* y */
  4876. 0171, 072, 0,   /* y: */
  4877. 0171, 0151, 0145, 0154, 0144, 0,   /* yield */
  4878. 0171, 0166, 0141, 0154, 0165, 0145, 0,   /* yvalue */
  4879. 0174, 0,   /* | */
  4880. 0176, 0,   /* ~ */
  4881. 0176, 075, 0,   /* ~= */
  4882. 0176, 0176, 0,   /* ~~ */
  4883. 0 };
  4884. int x_cmax = 3253;
  4885. static symbol x_sytab[] = {
  4886. {1, SYMBOLSIZE, &x_str[0]}, /* ! */
  4887. {1, SYMBOLSIZE, &x_str[2]}, /* & */
  4888. {1, SYMBOLSIZE, &x_str[4]}, /* ( */
  4889. {1, SYMBOLSIZE, &x_str[6]}, /* ) */
  4890. {1, SYMBOLSIZE, &x_str[8]}, /* * */
  4891. {1, SYMBOLSIZE, &x_str[10]}, /* + */
  4892. {1, SYMBOLSIZE, &x_str[12]}, /* , */
  4893. {1, SYMBOLSIZE, &x_str[14]}, /* - */
  4894. {1, SYMBOLSIZE, &x_str[16]}, /* / */
  4895. {1, SYMBOLSIZE, &x_str[18]}, /* // */
  4896. {1, SYMBOLSIZE, &x_str[21]}, /* < */
  4897. {1, SYMBOLSIZE, &x_str[23]}, /* <= */
  4898. {1, SYMBOLSIZE, &x_str[26]}, /* = */
  4899. {1, SYMBOLSIZE, &x_str[28]}, /* == */
  4900. {1, SYMBOLSIZE, &x_str[31]}, /* > */
  4901. {1, SYMBOLSIZE, &x_str[33]}, /* >= */
  4902. {1, SYMBOLSIZE, &x_str[36]}, /* @ */
  4903. {1, SYMBOLSIZE, &x_str[38]}, /* Array */
  4904. {1, SYMBOLSIZE, &x_str[44]}, /* ArrayedCollection */
  4905. {1, SYMBOLSIZE, &x_str[62]}, /* BLOCKED */
  4906. {1, SYMBOLSIZE, &x_str[70]}, /* Bag */
  4907. {1, SYMBOLSIZE, &x_str[74]}, /* Block */
  4908. {1, SYMBOLSIZE, &x_str[80]}, /* Boolean */
  4909. {1, SYMBOLSIZE, &x_str[88]}, /* ByteArray */
  4910. {1, SYMBOLSIZE, &x_str[98]}, /* Char */
  4911. {1, SYMBOLSIZE, &x_str[103]}, /* Class */
  4912. {1, SYMBOLSIZE, &x_str[109]}, /* Collection */
  4913. {1, SYMBOLSIZE, &x_str[120]}, /* Complex */
  4914. {1, SYMBOLSIZE, &x_str[128]}, /* Dictionary */
  4915. {1, SYMBOLSIZE, &x_str[139]}, /* False */
  4916. {1, SYMBOLSIZE, &x_str[145]}, /* File */
  4917. {1, SYMBOLSIZE, &x_str[150]}, /* Float */
  4918. {1, SYMBOLSIZE, &x_str[156]}, /* Integer */
  4919. {1, SYMBOLSIZE, &x_str[164]}, /* Interpreter */
  4920. {1, SYMBOLSIZE, &x_str[176]}, /* Interval */
  4921. {1, SYMBOLSIZE, &x_str[185]}, /* KeyedCollection */
  4922. {1, SYMBOLSIZE, &x_str[201]}, /* List */
  4923. {1, SYMBOLSIZE, &x_str[206]}, /* Little Smalltalk */
  4924. {1, SYMBOLSIZE, &x_str[223]}, /* Magnitude */
  4925. {1, SYMBOLSIZE, &x_str[233]}, /* Main */
  4926. {1, SYMBOLSIZE, &x_str[238]}, /* Number */
  4927. {1, SYMBOLSIZE, &x_str[245]}, /* Object */
  4928. {1, SYMBOLSIZE, &x_str[252]}, /* OrderedCollection */
  4929. {1, SYMBOLSIZE, &x_str[270]}, /* Point */
  4930. {1, SYMBOLSIZE, &x_str[276]}, /* Process */
  4931. {1, SYMBOLSIZE, &x_str[284]}, /* READY */
  4932. {1, SYMBOLSIZE, &x_str[290]}, /* Radian */
  4933. {1, SYMBOLSIZE, &x_str[297]}, /* Random */
  4934. {1, SYMBOLSIZE, &x_str[304]}, /* SUSPENDED */
  4935. {1, SYMBOLSIZE, &x_str[314]}, /* Semaphore */
  4936. {1, SYMBOLSIZE, &x_str[324]}, /* SequenceableCollection */
  4937. {1, SYMBOLSIZE, &x_str[347]}, /* Set */
  4938. {1, SYMBOLSIZE, &x_str[351]}, /* Smalltalk */
  4939. {1, SYMBOLSIZE, &x_str[361]}, /* String */
  4940. {1, SYMBOLSIZE, &x_str[368]}, /* Symbol */
  4941. {1, SYMBOLSIZE, &x_str[375]}, /* TERMINATED */
  4942. {1, SYMBOLSIZE, &x_str[386]}, /* True */
  4943. {1, SYMBOLSIZE, &x_str[391]}, /* UndefinedObject */
  4944. {1, SYMBOLSIZE, &x_str[407]}, /* [ */
  4945. {1, SYMBOLSIZE, &x_str[409]}, /* \\ */
  4946. {1, SYMBOLSIZE, &x_str[412]}, /* \\\\ */
  4947. {1, SYMBOLSIZE, &x_str[417]}, /* ] */
  4948. {1, SYMBOLSIZE, &x_str[419]}, /* ^ */
  4949. {1, SYMBOLSIZE, &x_str[421]}, /* abs */
  4950. {1, SYMBOLSIZE, &x_str[425]}, /* add: */
  4951. {1, SYMBOLSIZE, &x_str[430]}, /* add:after: */
  4952. {1, SYMBOLSIZE, &x_str[441]}, /* add:before: */
  4953. {1, SYMBOLSIZE, &x_str[453]}, /* add:withOccurrences: */
  4954. {1, SYMBOLSIZE, &x_str[474]}, /* addAll: */
  4955. {1, SYMBOLSIZE, &x_str[482]}, /* addAllFirst: */
  4956. {1, SYMBOLSIZE, &x_str[495]}, /* addAllLast: */
  4957. {1, SYMBOLSIZE, &x_str[507]}, /* addFirst: */
  4958. {1, SYMBOLSIZE, &x_str[517]}, /* addLast: */
  4959. {1, SYMBOLSIZE, &x_str[526]}, /* after: */
  4960. {1, SYMBOLSIZE, &x_str[533]}, /* allMask: */
  4961. {1, SYMBOLSIZE, &x_str[542]}, /* and: */
  4962. {1, SYMBOLSIZE, &x_str[547]}, /* anyMask: */
  4963. {1, SYMBOLSIZE, &x_str[556]}, /* arcCos */
  4964. {1, SYMBOLSIZE, &x_str[563]}, /* arcSin */
  4965. {1, SYMBOLSIZE, &x_str[570]}, /* arcTan */
  4966. {1, SYMBOLSIZE, &x_str[577]}, /* argerror */
  4967. {1, SYMBOLSIZE, &x_str[586]}, /* asArray */
  4968. {1, SYMBOLSIZE, &x_str[594]}, /* asBag */
  4969. {1, SYMBOLSIZE, &x_str[600]}, /* asCharacter */
  4970. {1, SYMBOLSIZE, &x_str[612]}, /* asDictionary */
  4971. {1, SYMBOLSIZE, &x_str[625]}, /* asFloat */
  4972. {1, SYMBOLSIZE, &x_str[633]}, /* asFraction */
  4973. {1, SYMBOLSIZE, &x_str[644]}, /* asInteger */
  4974. {1, SYMBOLSIZE, &x_str[654]}, /* asList */
  4975. {1, SYMBOLSIZE, &x_str[661]}, /* asLowercase */
  4976. {1, SYMBOLSIZE, &x_str[673]}, /* asOrderedCollection */
  4977. {1, SYMBOLSIZE, &x_str[693]}, /* asSet */
  4978. {1, SYMBOLSIZE, &x_str[699]}, /* asString */
  4979. {1, SYMBOLSIZE, &x_str[708]}, /* asSymbol */
  4980. {1, SYMBOLSIZE, &x_str[717]}, /* asUppercase */
  4981. {1, SYMBOLSIZE, &x_str[729]}, /* asciiValue */
  4982. {1, SYMBOLSIZE, &x_str[740]}, /* at: */
  4983. {1, SYMBOLSIZE, &x_str[744]}, /* at:ifAbsent: */
  4984. {1, SYMBOLSIZE, &x_str[757]}, /* at:put: */
  4985. {1, SYMBOLSIZE, &x_str[765]}, /* atAll:put: */
  4986. {1, SYMBOLSIZE, &x_str[776]}, /* atAllPut: */
  4987. {1, SYMBOLSIZE, &x_str[786]}, /* before: */
  4988. {1, SYMBOLSIZE, &x_str[794]}, /* between:and: */
  4989. {1, SYMBOLSIZE, &x_str[807]}, /* binaryDo: */
  4990. {1, SYMBOLSIZE, &x_str[817]}, /* bitAnd: */
  4991. {1, SYMBOLSIZE, &x_str[825]}, /* bitAt: */
  4992. {1, SYMBOLSIZE, &x_str[832]}, /* bitInvert */
  4993. {1, SYMBOLSIZE, &x_str[842]}, /* bitOr: */
  4994. {1, SYMBOLSIZE, &x_str[849]}, /* bitShift: */
  4995. {1, SYMBOLSIZE, &x_str[859]}, /* bitXor: */
  4996. {1, SYMBOLSIZE, &x_str[867]}, /* block */
  4997. {1, SYMBOLSIZE, &x_str[873]}, /* blockedProcessQueue */
  4998. {1, SYMBOLSIZE, &x_str[893]}, /* ceiling */
  4999. {1, SYMBOLSIZE, &x_str[901]}, /* checkBucket: */
  5000. {1, SYMBOLSIZE, &x_str[914]}, /* class */
  5001. {1, SYMBOLSIZE, &x_str[920]}, /* cleanUp */
  5002. {1, SYMBOLSIZE, &x_str[928]}, /* coerce: */
  5003. {1, SYMBOLSIZE, &x_str[936]}, /* collect: */
  5004. {1, SYMBOLSIZE, &x_str[945]}, /* commands: */
  5005. {1, SYMBOLSIZE, &x_str[955]}, /* compareError */
  5006. {1, SYMBOLSIZE, &x_str[968]}, /* copy */
  5007. {1, SYMBOLSIZE, &x_str[973]}, /* copyArguments: */
  5008. {1, SYMBOLSIZE, &x_str[988]}, /* copyArguments:to: */
  5009. {1, SYMBOLSIZE, &x_str[1006]}, /* copyFrom: */
  5010. {1, SYMBOLSIZE, &x_str[1016]}, /* copyFrom:length: */
  5011. {1, SYMBOLSIZE, &x_str[1033]}, /* copyFrom:to: */
  5012. {1, SYMBOLSIZE, &x_str[1046]}, /* copyWith: */
  5013. {1, SYMBOLSIZE, &x_str[1056]}, /* copyWithout: */
  5014. {1, SYMBOLSIZE, &x_str[1069]}, /* cos */
  5015. {1, SYMBOLSIZE, &x_str[1073]}, /* count */
  5016. {1, SYMBOLSIZE, &x_str[1079]}, /* currAssoc */
  5017. {1, SYMBOLSIZE, &x_str[1089]}, /* currBucket */
  5018. {1, SYMBOLSIZE, &x_str[1100]}, /* current */
  5019. {1, SYMBOLSIZE, &x_str[1108]}, /* currentBucket */
  5020. {1, SYMBOLSIZE, &x_str[1122]}, /* currentKey */
  5021. {1, SYMBOLSIZE, &x_str[1133]}, /* currentList */
  5022. {1, SYMBOLSIZE, &x_str[1145]}, /* date */
  5023. {1, SYMBOLSIZE, &x_str[1150]}, /* debug: */
  5024. {1, SYMBOLSIZE, &x_str[1157]}, /* deepCopy */
  5025. {1, SYMBOLSIZE, &x_str[1166]}, /* deepCopy: */
  5026. {1, SYMBOLSIZE, &x_str[1176]}, /* detect: */
  5027. {1, SYMBOLSIZE, &x_str[1184]}, /* detect:ifAbsent: */
  5028. {1, SYMBOLSIZE, &x_str[1201]}, /* detect:ifNone: */
  5029. {1, SYMBOLSIZE, &x_str[1216]}, /* dict */
  5030. {1, SYMBOLSIZE, &x_str[1221]}, /* dictionary */
  5031. {1, SYMBOLSIZE, &x_str[1232]}, /* digitValue */
  5032. {1, SYMBOLSIZE, &x_str[1243]}, /* digitValue: */
  5033. {1, SYMBOLSIZE, &x_str[1255]}, /* display */
  5034. {1, SYMBOLSIZE, &x_str[1263]}, /* displayAssign */
  5035. {1, SYMBOLSIZE, &x_str[1277]}, /* dist: */
  5036. {1, SYMBOLSIZE, &x_str[1283]}, /* do: */
  5037. {1, SYMBOLSIZE, &x_str[1287]}, /* doPrimitive: */
  5038. {1, SYMBOLSIZE, &x_str[1300]}, /* doPrimitive:withArguments: */
  5039. {1, SYMBOLSIZE, &x_str[1327]}, /* edit */
  5040. {1, SYMBOLSIZE, &x_str[1332]}, /* equals:startingAt: */
  5041. {1, SYMBOLSIZE, &x_str[1351]}, /* eqv: */
  5042. {1, SYMBOLSIZE, &x_str[1356]}, /* error: */
  5043. {1, SYMBOLSIZE, &x_str[1363]}, /* even */
  5044. {1, SYMBOLSIZE, &x_str[1368]}, /* excessSignals */
  5045. {1, SYMBOLSIZE, &x_str[1382]}, /* executeWith: */
  5046. {1, SYMBOLSIZE, &x_str[1395]}, /* exp */
  5047. {1, SYMBOLSIZE, &x_str[1399]}, /* factorial */
  5048. {1, SYMBOLSIZE, &x_str[1409]}, /* findAssociation:inList: */
  5049. {1, SYMBOLSIZE, &x_str[1433]}, /* findFirst: */
  5050. {1, SYMBOLSIZE, &x_str[1444]}, /* findFirst:ifAbsent: */
  5051. {1, SYMBOLSIZE, &x_str[1464]}, /* findLast */
  5052. {1, SYMBOLSIZE, &x_str[1473]}, /* findLast: */
  5053. {1, SYMBOLSIZE, &x_str[1483]}, /* findLast:ifAbsent: */
  5054. {1, SYMBOLSIZE, &x_str[1502]}, /* first */
  5055. {1, SYMBOLSIZE, &x_str[1508]}, /* firstKey */
  5056. {1, SYMBOLSIZE, &x_str[1517]}, /* floor */
  5057. {1, SYMBOLSIZE, &x_str[1523]}, /* floorLog: */
  5058. {1, SYMBOLSIZE, &x_str[1533]}, /* fork */
  5059. {1, SYMBOLSIZE, &x_str[1538]}, /* forkWith: */
  5060. {1, SYMBOLSIZE, &x_str[1548]}, /* fractionPart */
  5061. {1, SYMBOLSIZE, &x_str[1561]}, /* free: */
  5062. {1, SYMBOLSIZE, &x_str[1567]}, /* from: */
  5063. {1, SYMBOLSIZE, &x_str[1573]}, /* from:to: */
  5064. {1, SYMBOLSIZE, &x_str[1582]}, /* from:to:by: */
  5065. {1, SYMBOLSIZE, &x_str[1594]}, /* gamma */
  5066. {1, SYMBOLSIZE, &x_str[1600]}, /* gcd: */
  5067. {1, SYMBOLSIZE, &x_str[1605]}, /* getList: */
  5068. {1, SYMBOLSIZE, &x_str[1614]}, /* grid: */
  5069. {1, SYMBOLSIZE, &x_str[1620]}, /* hashNumber: */
  5070. {1, SYMBOLSIZE, &x_str[1632]}, /* hashTab */
  5071. {1, SYMBOLSIZE, &x_str[1640]}, /* hashTable */
  5072. {1, SYMBOLSIZE, &x_str[1650]}, /* highBit */
  5073. {1, SYMBOLSIZE, &x_str[1658]}, /* i */
  5074. {1, SYMBOLSIZE, &x_str[1660]}, /* ifFalse: */
  5075. {1, SYMBOLSIZE, &x_str[1669]}, /* ifFalse:ifTrue: */
  5076. {1, SYMBOLSIZE, &x_str[1685]}, /* ifTrue: */
  5077. {1, SYMBOLSIZE, &x_str[1693]}, /* ifTrue:ifFalse: */
  5078. {1, SYMBOLSIZE, &x_str[1709]}, /* inRange: */
  5079. {1, SYMBOLSIZE, &x_str[1718]}, /* includes: */
  5080. {1, SYMBOLSIZE, &x_str[1728]}, /* includesKey: */
  5081. {1, SYMBOLSIZE, &x_str[1741]}, /* indexOf: */
  5082. {1, SYMBOLSIZE, &x_str[1750]}, /* indexOf:ifAbsent: */
  5083. {1, SYMBOLSIZE, &x_str[1768]}, /* indexOfSubCollection:startingAt: */
  5084. {1, SYMBOLSIZE, &x_str[1801]}, /* indexOfSubCollection:startingAt:ifAbsent: */
  5085. {1, SYMBOLSIZE, &x_str[1843]}, /* init: */
  5086. {1, SYMBOLSIZE, &x_str[1849]}, /* init:super: */
  5087. {1, SYMBOLSIZE, &x_str[1861]}, /* init:super:numVars: */
  5088. {1, SYMBOLSIZE, &x_str[1881]}, /* inject:into: */
  5089. {1, SYMBOLSIZE, &x_str[1894]}, /* integerPart */
  5090. {1, SYMBOLSIZE, &x_str[1906]}, /* isAlphaNumeric */
  5091. {1, SYMBOLSIZE, &x_str[1921]}, /* isDigit */
  5092. {1, SYMBOLSIZE, &x_str[1929]}, /* isEmpty */
  5093. {1, SYMBOLSIZE, &x_str[1937]}, /* isKindOf: */
  5094. {1, SYMBOLSIZE, &x_str[1947]}, /* isLetter */
  5095. {1, SYMBOLSIZE, &x_str[1956]}, /* isLowercase */
  5096. {1, SYMBOLSIZE, &x_str[1968]}, /* isMemberOf: */
  5097. {1, SYMBOLSIZE, &x_str[1980]}, /* isNil */
  5098. {1, SYMBOLSIZE, &x_str[1986]}, /* isSeparator */
  5099. {1, SYMBOLSIZE, &x_str[1998]}, /* isUppercase */
  5100. {1, SYMBOLSIZE, &x_str[2010]}, /* isVowel */
  5101. {1, SYMBOLSIZE, &x_str[2018]}, /* keys */
  5102. {1, SYMBOLSIZE, &x_str[2023]}, /* keysDo: */
  5103. {1, SYMBOLSIZE, &x_str[2031]}, /* keysSelect: */
  5104. {1, SYMBOLSIZE, &x_str[2043]}, /* last */
  5105. {1, SYMBOLSIZE, &x_str[2048]}, /* lastKey */
  5106. {1, SYMBOLSIZE, &x_str[2056]}, /* lcm: */
  5107. {1, SYMBOLSIZE, &x_str[2061]}, /* list */
  5108. {1, SYMBOLSIZE, &x_str[2066]}, /* ln */
  5109. {1, SYMBOLSIZE, &x_str[2069]}, /* log: */
  5110. {1, SYMBOLSIZE, &x_str[2074]}, /* lower */
  5111. {1, SYMBOLSIZE, &x_str[2080]}, /* main */
  5112. {1, SYMBOLSIZE, &x_str[2085]}, /* max: */
  5113. {1, SYMBOLSIZE, &x_str[2090]}, /* maxContext: */
  5114. {1, SYMBOLSIZE, &x_str[2102]}, /* maxtype: */
  5115. {1, SYMBOLSIZE, &x_str[2111]}, /* methods: */
  5116. {1, SYMBOLSIZE, &x_str[2120]}, /* min: */
  5117. {1, SYMBOLSIZE, &x_str[2125]}, /* modeCharacter */
  5118. {1, SYMBOLSIZE, &x_str[2139]}, /* modeInteger */
  5119. {1, SYMBOLSIZE, &x_str[2151]}, /* modeString */
  5120. {1, SYMBOLSIZE, &x_str[2162]}, /* name: */
  5121. {1, SYMBOLSIZE, &x_str[2168]}, /* negated */
  5122. {1, SYMBOLSIZE, &x_str[2176]}, /* negative */
  5123. {1, SYMBOLSIZE, &x_str[2185]}, /* new */
  5124. {1, SYMBOLSIZE, &x_str[2189]}, /* new: */
  5125. {1, SYMBOLSIZE, &x_str[2194]}, /* newProcess */
  5126. {1, SYMBOLSIZE, &x_str[2205]}, /* newProcessWith: */
  5127. {1, SYMBOLSIZE, &x_str[2221]}, /* next */
  5128. {1, SYMBOLSIZE, &x_str[2226]}, /* next: */
  5129. {1, SYMBOLSIZE, &x_str[2232]}, /* noDisplay */
  5130. {1, SYMBOLSIZE, &x_str[2242]}, /* noMask: */
  5131. {1, SYMBOLSIZE, &x_str[2250]}, /* not */
  5132. {1, SYMBOLSIZE, &x_str[2254]}, /* notNil */
  5133. {1, SYMBOLSIZE, &x_str[2261]}, /* nothing */
  5134. {1, SYMBOLSIZE, &x_str[2269]}, /* occurrencesOf: */
  5135. {1, SYMBOLSIZE, &x_str[2284]}, /* odd */
  5136. {1, SYMBOLSIZE, &x_str[2288]}, /* opError */
  5137. {1, SYMBOLSIZE, &x_str[2296]}, /* open: */
  5138. {1, SYMBOLSIZE, &x_str[2302]}, /* open:for: */
  5139. {1, SYMBOLSIZE, &x_str[2312]}, /* or: */
  5140. {1, SYMBOLSIZE, &x_str[2316]}, /* perform: */
  5141. {1, SYMBOLSIZE, &x_str[2325]}, /* perform:withArguments: */
  5142. {1, SYMBOLSIZE, &x_str[2348]}, /* pi */
  5143. {1, SYMBOLSIZE, &x_str[2351]}, /* positive */
  5144. {1, SYMBOLSIZE, &x_str[2360]}, /* print */
  5145. {1, SYMBOLSIZE, &x_str[2366]}, /* printString */
  5146. {1, SYMBOLSIZE, &x_str[2378]}, /* put: */
  5147. {1, SYMBOLSIZE, &x_str[2383]}, /* quo: */
  5148. {1, SYMBOLSIZE, &x_str[2388]}, /* radians */
  5149. {1, SYMBOLSIZE, &x_str[2396]}, /* radix: */
  5150. {1, SYMBOLSIZE, &x_str[2403]}, /* raisedTo: */
  5151. {1, SYMBOLSIZE, &x_str[2413]}, /* raisedToInteger: */
  5152. {1, SYMBOLSIZE, &x_str[2430]}, /* randInteger: */
  5153. {1, SYMBOLSIZE, &x_str[2443]}, /* randomize */
  5154. {1, SYMBOLSIZE, &x_str[2453]}, /* read */
  5155. {1, SYMBOLSIZE, &x_str[2458]}, /* reciprocal */
  5156. {1, SYMBOLSIZE, &x_str[2469]}, /* reject: */
  5157. {1, SYMBOLSIZE, &x_str[2477]}, /* rem: */
  5158. {1, SYMBOLSIZE, &x_str[2482]}, /* remove: */
  5159. {1, SYMBOLSIZE, &x_str[2490]}, /* remove:ifAbsent: */
  5160. {1, SYMBOLSIZE, &x_str[2507]}, /* removeAll: */
  5161. {1, SYMBOLSIZE, &x_str[2518]}, /* removeError */
  5162. {1, SYMBOLSIZE, &x_str[2530]}, /* removeFirst */
  5163. {1, SYMBOLSIZE, &x_str[2542]}, /* removeKey: */
  5164. {1, SYMBOLSIZE, &x_str[2553]}, /* removeKey:ifAbsent: */
  5165. {1, SYMBOLSIZE, &x_str[2573]}, /* removeLast */
  5166. {1, SYMBOLSIZE, &x_str[2584]}, /* removed */
  5167. {1, SYMBOLSIZE, &x_str[2592]}, /* replaceFrom:to:with: */
  5168. {1, SYMBOLSIZE, &x_str[2613]}, /* replaceFrom:to:with:startingAt: */
  5169. {1, SYMBOLSIZE, &x_str[2645]}, /* respondsTo */
  5170. {1, SYMBOLSIZE, &x_str[2656]}, /* respondsTo: */
  5171. {1, SYMBOLSIZE, &x_str[2668]}, /* resume */
  5172. {1, SYMBOLSIZE, &x_str[2675]}, /* reverseDo: */
  5173. {1, SYMBOLSIZE, &x_str[2686]}, /* reversed */
  5174. {1, SYMBOLSIZE, &x_str[2695]}, /* roundTo: */
  5175. {1, SYMBOLSIZE, &x_str[2704]}, /* rounded */
  5176. {1, SYMBOLSIZE, &x_str[2712]}, /* sameAs: */
  5177. {1, SYMBOLSIZE, &x_str[2720]}, /* seed */
  5178. {1, SYMBOLSIZE, &x_str[2725]}, /* select: */
  5179. {1, SYMBOLSIZE, &x_str[2733]}, /* setCurrentLocation: */
  5180. {1, SYMBOLSIZE, &x_str[2753]}, /* sh: */
  5181. {1, SYMBOLSIZE, &x_str[2757]}, /* shallowCopy */
  5182. {1, SYMBOLSIZE, &x_str[2769]}, /* shallowCopy: */
  5183. {1, SYMBOLSIZE, &x_str[2782]}, /* sign */
  5184. {1, SYMBOLSIZE, &x_str[2787]}, /* signal */
  5185. {1, SYMBOLSIZE, &x_str[2794]}, /* sin */
  5186. {1, SYMBOLSIZE, &x_str[2798]}, /* size */
  5187. {1, SYMBOLSIZE, &x_str[2803]}, /* smalltalk */
  5188. {1, SYMBOLSIZE, &x_str[2813]}, /* sort */
  5189. {1, SYMBOLSIZE, &x_str[2818]}, /* sort: */
  5190. {1, SYMBOLSIZE, &x_str[2824]}, /* sqrt */
  5191. {1, SYMBOLSIZE, &x_str[2829]}, /* squared */
  5192. {1, SYMBOLSIZE, &x_str[2837]}, /* state */
  5193. {1, SYMBOLSIZE, &x_str[2843]}, /* step */
  5194. {1, SYMBOLSIZE, &x_str[2848]}, /* strictlyPositive */
  5195. {1, SYMBOLSIZE, &x_str[2865]}, /* superClass */
  5196. {1, SYMBOLSIZE, &x_str[2876]}, /* superClass: */
  5197. {1, SYMBOLSIZE, &x_str[2888]}, /* suspend */
  5198. {1, SYMBOLSIZE, &x_str[2896]}, /* tan */
  5199. {1, SYMBOLSIZE, &x_str[2900]}, /* temp */
  5200. {1, SYMBOLSIZE, &x_str[2905]}, /* termErr: */
  5201. {1, SYMBOLSIZE, &x_str[2914]}, /* terminate */
  5202. {1, SYMBOLSIZE, &x_str[2924]}, /* time: */
  5203. {1, SYMBOLSIZE, &x_str[2930]}, /* timesRepeat: */
  5204. {1, SYMBOLSIZE, &x_str[2943]}, /* to: */
  5205. {1, SYMBOLSIZE, &x_str[2947]}, /* to:by: */
  5206. {1, SYMBOLSIZE, &x_str[2954]}, /* transpose */
  5207. {1, SYMBOLSIZE, &x_str[2964]}, /* truncateTo: */
  5208. {1, SYMBOLSIZE, &x_str[2976]}, /* truncated */
  5209. {1, SYMBOLSIZE, &x_str[2986]}, /* truncatedGrid: */
  5210. {1, SYMBOLSIZE, &x_str[3001]}, /* unblock */
  5211. {1, SYMBOLSIZE, &x_str[3009]}, /* upper */
  5212. {1, SYMBOLSIZE, &x_str[3015]}, /* value */
  5213. {1, SYMBOLSIZE, &x_str[3021]}, /* value: */
  5214. {1, SYMBOLSIZE, &x_str[3028]}, /* value:value: */
  5215. {1, SYMBOLSIZE, &x_str[3041]}, /* value:value:value: */
  5216. {1, SYMBOLSIZE, &x_str[3060]}, /* value:value:value:value: */
  5217. {1, SYMBOLSIZE, &x_str[3085]}, /* value:value:value:value:value: */
  5218. {1, SYMBOLSIZE, &x_str[3116]}, /* values */
  5219. {1, SYMBOLSIZE, &x_str[3123]}, /* variables */
  5220. {1, SYMBOLSIZE, &x_str[3133]}, /* variables: */
  5221. {1, SYMBOLSIZE, &x_str[3144]}, /* view */
  5222. {1, SYMBOLSIZE, &x_str[3149]}, /* wait */
  5223. {1, SYMBOLSIZE, &x_str[3154]}, /* whileFalse: */
  5224. {1, SYMBOLSIZE, &x_str[3166]}, /* whileTrue: */
  5225. {1, SYMBOLSIZE, &x_str[3177]}, /* with:do: */
  5226. {1, SYMBOLSIZE, &x_str[3186]}, /* withArguments: */
  5227. {1, SYMBOLSIZE, &x_str[3201]}, /* write: */
  5228. {1, SYMBOLSIZE, &x_str[3208]}, /* x */
  5229. {1, SYMBOLSIZE, &x_str[3210]}, /* x: */
  5230. {1, SYMBOLSIZE, &x_str[3213]}, /* xor: */
  5231. {1, SYMBOLSIZE, &x_str[3218]}, /* xvalue */
  5232. {1, SYMBOLSIZE, &x_str[3225]}, /* y */
  5233. {1, SYMBOLSIZE, &x_str[3227]}, /* y: */
  5234. {1, SYMBOLSIZE, &x_str[3230]}, /* yield */
  5235. {1, SYMBOLSIZE, &x_str[3236]}, /* yvalue */
  5236. {1, SYMBOLSIZE, &x_str[3243]}, /* | */
  5237. {1, SYMBOLSIZE, &x_str[3245]}, /* ~ */
  5238. {1, SYMBOLSIZE, &x_str[3247]}, /* ~= */
  5239. {1, SYMBOLSIZE, &x_str[3250]}, /* ~~ */
  5240. 0};
  5241. symbol *x_tab[SYMTABMAX] = {
  5242. &x_sytab[0], /* ! */
  5243. &x_sytab[1], /* & */
  5244. &x_sytab[2], /* ( */
  5245. &x_sytab[3], /* ) */
  5246. &x_sytab[4], /* * */
  5247. &x_sytab[5], /* + */
  5248. &x_sytab[6], /* , */
  5249. &x_sytab[7], /* - */
  5250. &x_sytab[8], /* / */
  5251. &x_sytab[9], /* // */
  5252. &x_sytab[10], /* < */
  5253. &x_sytab[11], /* <= */
  5254. &x_sytab[12], /* = */
  5255. &x_sytab[13], /* == */
  5256. &x_sytab[14], /* > */
  5257. &x_sytab[15], /* >= */
  5258. &x_sytab[16], /* @ */
  5259. &x_sytab[17], /* Array */
  5260. &x_sytab[18], /* ArrayedCollection */
  5261. &x_sytab[19], /* BLOCKED */
  5262. &x_sytab[20], /* Bag */
  5263. &x_sytab[21], /* Block */
  5264. &x_sytab[22], /* Boolean */
  5265. &x_sytab[23], /* ByteArray */
  5266. &x_sytab[24], /* Char */
  5267. &x_sytab[25], /* Class */
  5268. &x_sytab[26], /* Collection */
  5269. &x_sytab[27], /* Complex */
  5270. &x_sytab[28], /* Dictionary */
  5271. &x_sytab[29], /* False */
  5272. &x_sytab[30], /* File */
  5273. &x_sytab[31], /* Float */
  5274. &x_sytab[32], /* Integer */
  5275. &x_sytab[33], /* Interpreter */
  5276. &x_sytab[34], /* Interval */
  5277. &x_sytab[35], /* KeyedCollection */
  5278. &x_sytab[36], /* List */
  5279. &x_sytab[37], /* Little Smalltalk */
  5280. &x_sytab[38], /* Magnitude */
  5281. &x_sytab[39], /* Main */
  5282. &x_sytab[40], /* Number */
  5283. &x_sytab[41], /* Object */
  5284. &x_sytab[42], /* OrderedCollection */
  5285. &x_sytab[43], /* Point */
  5286. &x_sytab[44], /* Process */
  5287. &x_sytab[45], /* READY */
  5288. &x_sytab[46], /* Radian */
  5289. &x_sytab[47], /* Random */
  5290. &x_sytab[48], /* SUSPENDED */
  5291. &x_sytab[49], /* Semaphore */
  5292. &x_sytab[50], /* SequenceableCollection */
  5293. &x_sytab[51], /* Set */
  5294. &x_sytab[52], /* Smalltalk */
  5295. &x_sytab[53], /* String */
  5296. &x_sytab[54], /* Symbol */
  5297. &x_sytab[55], /* TERMINATED */
  5298. &x_sytab[56], /* True */
  5299. &x_sytab[57], /* UndefinedObject */
  5300. &x_sytab[58], /* [ */
  5301. &x_sytab[59], /* \\ */
  5302. &x_sytab[60], /* \\\\ */
  5303. &x_sytab[61], /* ] */
  5304. &x_sytab[62], /* ^ */
  5305. &x_sytab[63], /* abs */
  5306. &x_sytab[64], /* add: */
  5307. &x_sytab[65], /* add:after: */
  5308. &x_sytab[66], /* add:before: */
  5309. &x_sytab[67], /* add:withOccurrences: */
  5310. &x_sytab[68], /* addAll: */
  5311. &x_sytab[69], /* addAllFirst: */
  5312. &x_sytab[70], /* addAllLast: */
  5313. &x_sytab[71], /* addFirst: */
  5314. &x_sytab[72], /* addLast: */
  5315. &x_sytab[73], /* after: */
  5316. &x_sytab[74], /* allMask: */
  5317. &x_sytab[75], /* and: */
  5318. &x_sytab[76], /* anyMask: */
  5319. &x_sytab[77], /* arcCos */
  5320. &x_sytab[78], /* arcSin */
  5321. &x_sytab[79], /* arcTan */
  5322. &x_sytab[80], /* argerror */
  5323. &x_sytab[81], /* asArray */
  5324. &x_sytab[82], /* asBag */
  5325. &x_sytab[83], /* asCharacter */
  5326. &x_sytab[84], /* asDictionary */
  5327. &x_sytab[85], /* asFloat */
  5328. &x_sytab[86], /* asFraction */
  5329. &x_sytab[87], /* asInteger */
  5330. &x_sytab[88], /* asList */
  5331. &x_sytab[89], /* asLowercase */
  5332. &x_sytab[90], /* asOrderedCollection */
  5333. &x_sytab[91], /* asSet */
  5334. &x_sytab[92], /* asString */
  5335. &x_sytab[93], /* asSymbol */
  5336. &x_sytab[94], /* asUppercase */
  5337. &x_sytab[95], /* asciiValue */
  5338. &x_sytab[96], /* at: */
  5339. &x_sytab[97], /* at:ifAbsent: */
  5340. &x_sytab[98], /* at:put: */
  5341. &x_sytab[99], /* atAll:put: */
  5342. &x_sytab[100], /* atAllPut: */
  5343. &x_sytab[101], /* before: */
  5344. &x_sytab[102], /* between:and: */
  5345. &x_sytab[103], /* binaryDo: */
  5346. &x_sytab[104], /* bitAnd: */
  5347. &x_sytab[105], /* bitAt: */
  5348. &x_sytab[106], /* bitInvert */
  5349. &x_sytab[107], /* bitOr: */
  5350. &x_sytab[108], /* bitShift: */
  5351. &x_sytab[109], /* bitXor: */
  5352. &x_sytab[110], /* block */
  5353. &x_sytab[111], /* blockedProcessQueue */
  5354. &x_sytab[112], /* ceiling */
  5355. &x_sytab[113], /* checkBucket: */
  5356. &x_sytab[114], /* class */
  5357. &x_sytab[115], /* cleanUp */
  5358. &x_sytab[116], /* coerce: */
  5359. &x_sytab[117], /* collect: */
  5360. &x_sytab[118], /* commands: */
  5361. &x_sytab[119], /* compareError */
  5362. &x_sytab[120], /* copy */
  5363. &x_sytab[121], /* copyArguments: */
  5364. &x_sytab[122], /* copyArguments:to: */
  5365. &x_sytab[123], /* copyFrom: */
  5366. &x_sytab[124], /* copyFrom:length: */
  5367. &x_sytab[125], /* copyFrom:to: */
  5368. &x_sytab[126], /* copyWith: */
  5369. &x_sytab[127], /* copyWithout: */
  5370. &x_sytab[128], /* cos */
  5371. &x_sytab[129], /* count */
  5372. &x_sytab[130], /* currAssoc */
  5373. &x_sytab[131], /* currBucket */
  5374. &x_sytab[132], /* current */
  5375. &x_sytab[133], /* currentBucket */
  5376. &x_sytab[134], /* currentKey */
  5377. &x_sytab[135], /* currentList */
  5378. &x_sytab[136], /* date */
  5379. &x_sytab[137], /* debug: */
  5380. &x_sytab[138], /* deepCopy */
  5381. &x_sytab[139], /* deepCopy: */
  5382. &x_sytab[140], /* detect: */
  5383. &x_sytab[141], /* detect:ifAbsent: */
  5384. &x_sytab[142], /* detect:ifNone: */
  5385. &x_sytab[143], /* dict */
  5386. &x_sytab[144], /* dictionary */
  5387. &x_sytab[145], /* digitValue */
  5388. &x_sytab[146], /* digitValue: */
  5389. &x_sytab[147], /* display */
  5390. &x_sytab[148], /* displayAssign */
  5391. &x_sytab[149], /* dist: */
  5392. &x_sytab[150], /* do: */
  5393. &x_sytab[151], /* doPrimitive: */
  5394. &x_sytab[152], /* doPrimitive:withArguments: */
  5395. &x_sytab[153], /* edit */
  5396. &x_sytab[154], /* equals:startingAt: */
  5397. &x_sytab[155], /* eqv: */
  5398. &x_sytab[156], /* error: */
  5399. &x_sytab[157], /* even */
  5400. &x_sytab[158], /* excessSignals */
  5401. &x_sytab[159], /* executeWith: */
  5402. &x_sytab[160], /* exp */
  5403. &x_sytab[161], /* factorial */
  5404. &x_sytab[162], /* findAssociation:inList: */
  5405. &x_sytab[163], /* findFirst: */
  5406. &x_sytab[164], /* findFirst:ifAbsent: */
  5407. &x_sytab[165], /* findLast */
  5408. &x_sytab[166], /* findLast: */
  5409. &x_sytab[167], /* findLast:ifAbsent: */
  5410. &x_sytab[168], /* first */
  5411. &x_sytab[169], /* firstKey */
  5412. &x_sytab[170], /* floor */
  5413. &x_sytab[171], /* floorLog: */
  5414. &x_sytab[172], /* fork */
  5415. &x_sytab[173], /* forkWith: */
  5416. &x_sytab[174], /* fractionPart */
  5417. &x_sytab[175], /* free: */
  5418. &x_sytab[176], /* from: */
  5419. &x_sytab[177], /* from:to: */
  5420. &x_sytab[178], /* from:to:by: */
  5421. &x_sytab[179], /* gamma */
  5422. &x_sytab[180], /* gcd: */
  5423. &x_sytab[181], /* getList: */
  5424. &x_sytab[182], /* grid: */
  5425. &x_sytab[183], /* hashNumber: */
  5426. &x_sytab[184], /* hashTab */
  5427. &x_sytab[185], /* hashTable */
  5428. &x_sytab[186], /* highBit */
  5429. &x_sytab[187], /* i */
  5430. &x_sytab[188], /* ifFalse: */
  5431. &x_sytab[189], /* ifFalse:ifTrue: */
  5432. &x_sytab[190], /* ifTrue: */
  5433. &x_sytab[191], /* ifTrue:ifFalse: */
  5434. &x_sytab[192], /* inRange: */
  5435. &x_sytab[193], /* includes: */
  5436. &x_sytab[194], /* includesKey: */
  5437. &x_sytab[195], /* indexOf: */
  5438. &x_sytab[196], /* indexOf:ifAbsent: */
  5439. &x_sytab[197], /* indexOfSubCollection:startingAt: */
  5440. &x_sytab[198], /* indexOfSubCollection:startingAt:ifAbsent: */
  5441. &x_sytab[199], /* init: */
  5442. &x_sytab[200], /* init:super: */
  5443. &x_sytab[201], /* init:super:numVars: */
  5444. &x_sytab[202], /* inject:into: */
  5445. &x_sytab[203], /* integerPart */
  5446. &x_sytab[204], /* isAlphaNumeric */
  5447. &x_sytab[205], /* isDigit */
  5448. &x_sytab[206], /* isEmpty */
  5449. &x_sytab[207], /* isKindOf: */
  5450. &x_sytab[208], /* isLetter */
  5451. &x_sytab[209], /* isLowercase */
  5452. &x_sytab[210], /* isMemberOf: */
  5453. &x_sytab[211], /* isNil */
  5454. &x_sytab[212], /* isSeparator */
  5455. &x_sytab[213], /* isUppercase */
  5456. &x_sytab[214], /* isVowel */
  5457. &x_sytab[215], /* keys */
  5458. &x_sytab[216], /* keysDo: */
  5459. &x_sytab[217], /* keysSelect: */
  5460. &x_sytab[218], /* last */
  5461. &x_sytab[219], /* lastKey */
  5462. &x_sytab[220], /* lcm: */
  5463. &x_sytab[221], /* list */
  5464. &x_sytab[222], /* ln */
  5465. &x_sytab[223], /* log: */
  5466. &x_sytab[224], /* lower */
  5467. &x_sytab[225], /* main */
  5468. &x_sytab[226], /* max: */
  5469. &x_sytab[227], /* maxContext: */
  5470. &x_sytab[228], /* maxtype: */
  5471. &x_sytab[229], /* methods: */
  5472. &x_sytab[230], /* min: */
  5473. &x_sytab[231], /* modeCharacter */
  5474. &x_sytab[232], /* modeInteger */
  5475. &x_sytab[233], /* modeString */
  5476. &x_sytab[234], /* name: */
  5477. &x_sytab[235], /* negated */
  5478. &x_sytab[236], /* negative */
  5479. &x_sytab[237], /* new */
  5480. &x_sytab[238], /* new: */
  5481. &x_sytab[239], /* newProcess */
  5482. &x_sytab[240], /* newProcessWith: */
  5483. &x_sytab[241], /* next */
  5484. &x_sytab[242], /* next: */
  5485. &x_sytab[243], /* noDisplay */
  5486. &x_sytab[244], /* noMask: */
  5487. &x_sytab[245], /* not */
  5488. &x_sytab[246], /* notNil */
  5489. &x_sytab[247], /* nothing */
  5490. &x_sytab[248], /* occurrencesOf: */
  5491. &x_sytab[249], /* odd */
  5492. &x_sytab[250], /* opError */
  5493. &x_sytab[251], /* open: */
  5494. &x_sytab[252], /* open:for: */
  5495. &x_sytab[253], /* or: */
  5496. &x_sytab[254], /* perform: */
  5497. &x_sytab[255], /* perform:withArguments: */
  5498. &x_sytab[256], /* pi */
  5499. &x_sytab[257], /* positive */
  5500. &x_sytab[258], /* print */
  5501. &x_sytab[259], /* printString */
  5502. &x_sytab[260], /* put: */
  5503. &x_sytab[261], /* quo: */
  5504. &x_sytab[262], /* radians */
  5505. &x_sytab[263], /* radix: */
  5506. &x_sytab[264], /* raisedTo: */
  5507. &x_sytab[265], /* raisedToInteger: */
  5508. &x_sytab[266], /* randInteger: */
  5509. &x_sytab[267], /* randomize */
  5510. &x_sytab[268], /* read */
  5511. &x_sytab[269], /* reciprocal */
  5512. &x_sytab[270], /* reject: */
  5513. &x_sytab[271], /* rem: */
  5514. &x_sytab[272], /* remove: */
  5515. &x_sytab[273], /* remove:ifAbsent: */
  5516. &x_sytab[274], /* removeAll: */
  5517. &x_sytab[275], /* removeError */
  5518. &x_sytab[276], /* removeFirst */
  5519. &x_sytab[277], /* removeKey: */
  5520. &x_sytab[278], /* removeKey:ifAbsent: */
  5521. &x_sytab[279], /* removeLast */
  5522. &x_sytab[280], /* removed */
  5523. &x_sytab[281], /* replaceFrom:to:with: */
  5524. &x_sytab[282], /* replaceFrom:to:with:startingAt: */
  5525. &x_sytab[283], /* respondsTo */
  5526. &x_sytab[284], /* respondsTo: */
  5527. &x_sytab[285], /* resume */
  5528. &x_sytab[286], /* reverseDo: */
  5529. &x_sytab[287], /* reversed */
  5530. &x_sytab[288], /* roundTo: */
  5531. &x_sytab[289], /* rounded */
  5532. &x_sytab[290], /* sameAs: */
  5533. &x_sytab[291], /* seed */
  5534. &x_sytab[292], /* select: */
  5535. &x_sytab[293], /* setCurrentLocation: */
  5536. &x_sytab[294], /* sh: */
  5537. &x_sytab[295], /* shallowCopy */
  5538. &x_sytab[296], /* shallowCopy: */
  5539. &x_sytab[297], /* sign */
  5540. &x_sytab[298], /* signal */
  5541. &x_sytab[299], /* sin */
  5542. &x_sytab[300], /* size */
  5543. &x_sytab[301], /* smalltalk */
  5544. &x_sytab[302], /* sort */
  5545. &x_sytab[303], /* sort: */
  5546. &x_sytab[304], /* sqrt */
  5547. &x_sytab[305], /* squared */
  5548. &x_sytab[306], /* state */
  5549. &x_sytab[307], /* step */
  5550. &x_sytab[308], /* strictlyPositive */
  5551. &x_sytab[309], /* superClass */
  5552. &x_sytab[310], /* superClass: */
  5553. &x_sytab[311], /* suspend */
  5554. &x_sytab[312], /* tan */
  5555. &x_sytab[313], /* temp */
  5556. &x_sytab[314], /* termErr: */
  5557. &x_sytab[315], /* terminate */
  5558. &x_sytab[316], /* time: */
  5559. &x_sytab[317], /* timesRepeat: */
  5560. &x_sytab[318], /* to: */
  5561. &x_sytab[319], /* to:by: */
  5562. &x_sytab[320], /* transpose */
  5563. &x_sytab[321], /* truncateTo: */
  5564. &x_sytab[322], /* truncated */
  5565. &x_sytab[323], /* truncatedGrid: */
  5566. &x_sytab[324], /* unblock */
  5567. &x_sytab[325], /* upper */
  5568. &x_sytab[326], /* value */
  5569. &x_sytab[327], /* value: */
  5570. &x_sytab[328], /* value:value: */
  5571. &x_sytab[329], /* value:value:value: */
  5572. &x_sytab[330], /* value:value:value:value: */
  5573. &x_sytab[331], /* value:value:value:value:value: */
  5574. &x_sytab[332], /* values */
  5575. &x_sytab[333], /* variables */
  5576. &x_sytab[334], /* variables: */
  5577. &x_sytab[335], /* view */
  5578. &x_sytab[336], /* wait */
  5579. &x_sytab[337], /* whileFalse: */
  5580. &x_sytab[338], /* whileTrue: */
  5581. &x_sytab[339], /* with:do: */
  5582. &x_sytab[340], /* withArguments: */
  5583. &x_sytab[341], /* write: */
  5584. &x_sytab[342], /* x */
  5585. &x_sytab[343], /* x: */
  5586. &x_sytab[344], /* xor: */
  5587. &x_sytab[345], /* xvalue */
  5588. &x_sytab[346], /* y */
  5589. &x_sytab[347], /* y: */
  5590. &x_sytab[348], /* yield */
  5591. &x_sytab[349], /* yvalue */
  5592. &x_sytab[350], /* | */
  5593. &x_sytab[351], /* ~ */
  5594. &x_sytab[352], /* ~= */
  5595. &x_sytab[353], /* ~~ */
  5596. 0};
  5597. int x_tmax = 353;
  5598. End
  5599. echo unbundling cldict.c 1>&2
  5600. cat >cldict.c <<'End'
  5601. /*
  5602.     Little Smalltalk
  5603.         Internal class dictionary
  5604.  
  5605.         timothy a. budd, 10/84
  5606.  
  5607.     In order to facilitate lookup, classes are kept in an internal data
  5608.     dictionary.  Classes are inserted into this dictionary using a
  5609.     primtitive, and are removed by either being overridden, or being
  5610.     flushed at the end of execution.
  5611. */
  5612. /*
  5613.     The source code for the Little Smalltalk System may be freely
  5614.     copied provided that the source of all files is acknowledged
  5615.     and that this condition is copied with each file.
  5616.  
  5617.     The Little Smalltalk System is distributed without responsibility
  5618.     for the performance of the program and without any guarantee of
  5619.     maintenance.
  5620.  
  5621.     All questions concerning Little Smalltalk should be addressed to:
  5622.  
  5623.         Professor Tim Budd
  5624.         Department of Computer Science
  5625.         Oregon State University
  5626.         Corvallis, Oregon
  5627.         97331
  5628.         USA
  5629. */
  5630. # include <stdio.h>
  5631. # include "object.h"
  5632. # include "number.h"
  5633. # include "symbol.h"
  5634. # include "primitive.h"
  5635.  
  5636. struct class_entry {        /* structure for internal dictionary */
  5637.     char *cl_name;
  5638.     object *cl_description;
  5639.     struct class_entry *cl_link;
  5640.     };
  5641.  
  5642. static struct class_entry *class_dictionary = 0;
  5643. int ca_cdict = 0;
  5644. static mstruct *fr_cdict = 0;        /* class dictionary free list */
  5645.  
  5646. # define CDICTINIT 30
  5647. static struct class_entry cdsinit[CDICTINIT];
  5648.  
  5649. /* cdic_init - initialize the internal class dictionary */
  5650. cdic_init() {
  5651.     struct class_entry *p;
  5652.     mstruct *new;
  5653.     int i;
  5654.  
  5655.     for (p = cdsinit, i = 0; i < CDICTINIT; i++, p++) {
  5656.         new = (mstruct *) p;
  5657.         new->mlink = fr_cdict;
  5658.         fr_cdict = new;
  5659.         }
  5660. }
  5661.  
  5662. /* enter_class - enter a class into the internal class dictionary */
  5663. enter_class(name, description)
  5664. char *name;
  5665. object *description;
  5666. {    struct class_entry *p;
  5667.  
  5668.     for (p = class_dictionary; p; p = p->cl_link)
  5669.         if (strcmp(name, p->cl_name) == 0) {
  5670.             assign(p->cl_description, description);
  5671.             return;
  5672.             }
  5673.     /* not found, make a new entry */
  5674.     if (fr_cdict) {
  5675.         p = (struct class_entry *) fr_cdict;
  5676.         fr_cdict = fr_cdict->mlink;
  5677.         }
  5678.     else {
  5679.         p = structalloc(struct class_entry);
  5680.         ca_cdict++;
  5681.         }
  5682.     p->cl_name = name;
  5683.     sassign(p->cl_description, description);
  5684.     p->cl_link = class_dictionary;
  5685.     class_dictionary = p;
  5686. }
  5687.  
  5688. /* lookup - take a name and find the associated class object */
  5689. object *lookup_class(name)
  5690. char *name;
  5691. {    struct class_entry *p;
  5692.  
  5693.     for (p = class_dictionary; p; p = p->cl_link)
  5694.         if (strcmp(name, p->cl_name) == 0)
  5695.             return(p->cl_description);
  5696.     return((object *) 0);
  5697. }
  5698.  
  5699. /* free_all_classes - flush all references for the class dictionary */
  5700. free_all_classes()
  5701. {    struct class_entry *p;
  5702.  
  5703.     for (p = class_dictionary; p; p = p->cl_link) {
  5704.         obj_dec(p->cl_description);
  5705.         }
  5706. }
  5707.  
  5708. /* class_list - list all the subclasses of a class (recursively),
  5709.     indenting by a specified number of tab stops */
  5710. class_list(c, n)
  5711. class *c;
  5712. int n;
  5713. {    struct class_entry *p;
  5714.     object *prs[2];
  5715.     class *q;
  5716.     char *name;
  5717.  
  5718.     /* first print out this class name */
  5719.     if (! is_symbol(c->class_name))
  5720.         return;
  5721.     sassign(prs[0], c->class_name);
  5722.     name = symbol_value(c->class_name);
  5723.     sassign(prs[1], new_int(n));
  5724.     primitive(SYMPRINT, 2, prs);
  5725.     obj_dec(prs[0]);
  5726.     obj_dec(prs[1]);
  5727.  
  5728.     /* now find all subclasses and print them out */
  5729.     for (p = class_dictionary; p; p = p->cl_link) {
  5730.         q = (class *) p->cl_description;
  5731.         if ((is_symbol(q->super_class)) &&
  5732.            (strcmp(name, symbol_value(q->super_class)) == 0) )
  5733.             class_list(q, n+1);
  5734.         }
  5735. }
  5736. End
  5737. echo unbundling process.c 1>&2
  5738. cat >process.c <<'End'
  5739. /*
  5740.     Little Smalltalk
  5741.  
  5742.         process manager
  5743.         dennis a. vadner and michael t. benhase, 11/84
  5744.         modified by timothy a. budd 4/85
  5745. */
  5746. /*
  5747.     The source code for the Little Smalltalk System may be freely
  5748.     copied provided that the source of all files is acknowledged
  5749.     and that this condition is copied with each file.
  5750.  
  5751.     The Little Smalltalk System is distributed without responsibility
  5752.     for the performance of the program and without any guarantee of
  5753.     maintenance.
  5754.  
  5755.     All questions concerning Little Smalltalk should be addressed to:
  5756.  
  5757.         Professor Tim Budd
  5758.         Department of Computer Science
  5759.         Oregon State University
  5760.         Corvallis, Oregon
  5761.         97331
  5762.         USA
  5763. */
  5764.  
  5765. # include "object.h"
  5766.  
  5767. # include <stdio.h>
  5768.  
  5769. # ifdef SIGS
  5770. # include <signal.h>
  5771. # endif
  5772.  
  5773. # ifdef SETJUMP
  5774. # include <setjmp.h>
  5775. # endif
  5776.  
  5777. # include "drive.h"
  5778. # include "interp.h"
  5779. # include "process.h"
  5780.  
  5781. extern int  test_driver();    /* routine to test for user keystrokes*/
  5782.  
  5783. static process  *currentProcess;    /* current process */
  5784. static process  *fr_process = 0;    /* process memory free list */
  5785.  
  5786. int  atomcnt = 0;            /* atomic action flag */
  5787. process  *runningProcess;        /* currently running process,
  5788.                        may be different from
  5789.                        currentProcess during process
  5790.                        termination */
  5791.  
  5792. # define PROCINITMAX 6
  5793. static process prcinit[PROCINITMAX];    /* initial process free list */
  5794.  
  5795.  
  5796. /* init_process - initialize the process module */
  5797. init_process ()
  5798. {    process *p;
  5799.     int i;
  5800.  
  5801.     /* first make the initial process free list */
  5802.     for (p = prcinit, i = 0; i < PROCINITMAX; i++, p++) {
  5803.         p->next = fr_process;
  5804.         fr_process = p;
  5805.         }
  5806.  
  5807.     /* make the process associated with the driver */
  5808.     currentProcess = cr_process(o_drive);
  5809.     assign(currentProcess->next, currentProcess);
  5810.     assign(currentProcess->prev, currentProcess);
  5811.     currentProcess->p_state = ACTIVE;
  5812. }
  5813.  
  5814. /* cr_process - create a new process with the given interpreter */
  5815. process  *cr_process (anInterpreter)
  5816. interpreter  *anInterpreter;
  5817. {    process  *new;
  5818.  
  5819.     if (fr_process) {
  5820.         new = (process *) fr_process;
  5821.         fr_process = fr_process->next;
  5822.         }
  5823.     else
  5824.         new = structalloc(process);
  5825.  
  5826.     new->p_ref_count = 0;
  5827.     new->p_size = PROCSIZE;
  5828.  
  5829.     sassign(new->interp, anInterpreter);
  5830.     new->p_state = SUSPENDED;
  5831.     sassign(new->next, (process *) o_nil);
  5832.     sassign(new->prev, (process *) o_nil);
  5833.  
  5834.     return(new);
  5835. }
  5836.  
  5837.  
  5838. /* free_process - return an unused process to free list */
  5839. free_process (aProcess)
  5840. process  *aProcess;
  5841. {
  5842.     obj_dec((object *) aProcess->interp);
  5843.     obj_dec((object *) aProcess->next);
  5844.     obj_dec((object *) aProcess->prev);
  5845.     aProcess->p_state = TERMINATED;
  5846.     aProcess->next = fr_process;
  5847.     fr_process = aProcess;
  5848. }
  5849.  
  5850. /* flush_processes - flush out any remaining process from queue */
  5851. flush_processes ()
  5852. {
  5853.     while (currentProcess != currentProcess->next)
  5854.        remove_process(currentProcess);
  5855.  
  5856.     /* prev link and next link should point to the same place now.
  5857.        In order to avoid having memory recovered while we are
  5858.        manipulating pointers, we increment reference count, then change
  5859.        pointers, then decrement reference counts */
  5860.  
  5861.     obj_inc((object *) currentProcess);
  5862.     safeassign(currentProcess->prev, (process *) o_nil);
  5863.     safeassign(currentProcess->next, (process *) o_nil);
  5864.     obj_dec((object *) currentProcess);
  5865. }
  5866.  
  5867.  
  5868. /* link_to_process - change the interpreter for the current process */
  5869. link_to_process (anInterpreter)
  5870. interpreter  *anInterpreter;
  5871. {    object *temp;
  5872.  
  5873.     safeassign(runningProcess->interp, anInterpreter);
  5874. }
  5875.  
  5876.  
  5877. /* remove_process - remove a process from process queue */
  5878. static remove_process (aProcess)
  5879. process  *aProcess;
  5880. {
  5881.     if (aProcess == aProcess->next)
  5882.         cant_happen(15);        /* removing last active process */
  5883.  
  5884.     /* currentProcess must always point to a process that is on the
  5885.        process queue, make sure this remains true */
  5886.  
  5887.     if (aProcess == currentProcess)
  5888.         currentProcess = currentProcess->prev;
  5889.  
  5890.     /* In order to avoid having memory recovered while we are changing
  5891.     pointers, we increment the reference counts on both processes,
  5892.     change pointers, then decrement reference counts */
  5893.  
  5894.     obj_inc((object *) currentProcess); obj_inc((object *) aProcess);
  5895.     safeassign(aProcess->next->prev, aProcess->prev);
  5896.     safeassign(aProcess->prev->next, aProcess->next);
  5897.     obj_dec((object *) currentProcess); obj_dec((object *) aProcess);
  5898. }
  5899.  
  5900.  
  5901. /* schedule_process - add a new process to the process queue */
  5902. static schedule_process (aProcess)
  5903. process  *aProcess;
  5904. {
  5905.     safeassign(aProcess->next, currentProcess);
  5906.     safeassign(aProcess->prev, currentProcess->prev);
  5907.     safeassign(aProcess->prev->next, aProcess);
  5908.     safeassign(currentProcess->prev, aProcess);
  5909. }
  5910.  
  5911. /* set_state - set the state on a process, which may involve inserting or
  5912. removing it from the process queue */
  5913. int  set_state (aProcess, state)
  5914. process  *aProcess;
  5915. int  state;
  5916. {
  5917.     switch (state) {
  5918.         case BLOCKED:
  5919.         case SUSPENDED:
  5920.         case TERMINATED:    if (aProcess->p_state == ACTIVE)
  5921.                     remove_process(aProcess);
  5922.                 aProcess->p_state |= state;
  5923.                 break;
  5924.  
  5925.         case READY:
  5926.         case UNBLOCKED:    if ((aProcess->p_state ^ state) == ~ACTIVE)
  5927.                     schedule_process(aProcess);
  5928.                 aProcess->p_state &= state;
  5929.                 break;
  5930.  
  5931.         case CUR_STATE:    break;
  5932.         default:        cant_happen(17);
  5933.         }
  5934.     return(aProcess->p_state);
  5935. }
  5936.  
  5937. # ifdef SETJUMP
  5938. static jmp_buf intenv;
  5939. # endif
  5940.  
  5941. /* brkfun - what to do on a break key */
  5942. brkfun()
  5943. {    static int warn = 1;
  5944.  
  5945. # ifndef SETJUMP
  5946.     exit(1);
  5947. # endif
  5948.     if (warn) {
  5949.         fprintf(stderr,"warning: recovery from interrupt may cause\n");
  5950.         fprintf(stderr,"reference counts to be incorrect, and\n");
  5951.         fprintf(stderr,"some memory to be inaccessible\n");
  5952.         warn = 0;
  5953.         }
  5954. # ifdef SETJUMP
  5955.     longjmp(intenv, 1);
  5956. # endif
  5957. }
  5958.  
  5959. /* start_execution - main execution loop */
  5960. start_execution ()
  5961. {    interpreter  *presentInterpreter;
  5962.  
  5963.     atomcnt = 0;
  5964.  
  5965. # ifdef SIGS
  5966.     /* trap user interrupt signals and recover */
  5967.     signal(SIGINT, brkfun);
  5968. # endif
  5969.  
  5970. # ifdef SETJUMP
  5971.     if (setjmp(intenv)) {
  5972.         atomcnt = 0;
  5973.         link_to_process(o_drive);
  5974.         }
  5975. # endif
  5976.  
  5977.     while (1) {
  5978.         /* unless it is an atomic action get the next process */
  5979.         if (! atomcnt)
  5980.         runningProcess = currentProcess = currentProcess->next;
  5981.  
  5982.         if (! is_driver(runningProcess->interp)) {
  5983.         sassign(presentInterpreter, runningProcess->interp);
  5984.         resume(presentInterpreter);
  5985.         obj_dec((object *) presentInterpreter);
  5986.         }
  5987.         else if (! test_driver((currentProcess == currentProcess->next) ||
  5988.                    (atomcnt > 0)))
  5989.         break;
  5990.         }
  5991. }
  5992. End
  5993. echo unbundling interp.c 1>&2
  5994. cat >interp.c <<'End'
  5995. /*
  5996.     Little Smalltalk
  5997.         bytecode interpreter
  5998.         timothy a. budd
  5999. */
  6000. /*
  6001.     The source code for the Little Smalltalk System may be freely
  6002.     copied provided that the source of all files is acknowledged
  6003.     and that this condition is copied with each file.
  6004.  
  6005.     The Little Smalltalk System is distributed without responsibility
  6006.     for the performance of the program and without any guarantee of
  6007.     maintenance.
  6008.  
  6009.     All questions concerning Little Smalltalk should be addressed to:
  6010.  
  6011.         Professor Tim Budd
  6012.         Department of Computer Science
  6013.         Oregon State University
  6014.         Corvallis, Oregon
  6015.         97331
  6016.         USA
  6017. */
  6018. # include <stdio.h>
  6019. # include "object.h"
  6020. # include "drive.h"
  6021. # include "cmds.h"
  6022. # include "interp.h"
  6023. # include "process.h"
  6024. # include "number.h"
  6025. # include "string.h"
  6026. # include "symbol.h"
  6027. # include "byte.h"
  6028. # include "block.h"
  6029. # include "primitive.h"
  6030.  
  6031. int opcount[16], ohcount, spcount[16];
  6032. extern object *o_smalltalk;    /* value of pseudo variable smalltalk */
  6033. extern object *fnd_class();    /* used to find classes from names */
  6034.  
  6035. static mstruct *fr_interp = 0;    /* interpreter memory free list */
  6036. int ca_terp = 0;        /* counter for interpreter allocations */
  6037.  
  6038. /* cr_interpreter - create a new interpreter */
  6039. interpreter *cr_interpreter(sender, receiver, literals, bitearray, context)
  6040. interpreter *sender;
  6041. object *literals, *bitearray, *receiver, *context;
  6042. {    interpreter *new;
  6043.     class *rclass;
  6044.     int isize;
  6045.  
  6046.     if (fr_interp) {
  6047.         new = (interpreter *) fr_interp;
  6048.         fr_interp = fr_interp->mlink;
  6049.         }
  6050.     else {
  6051.         new = structalloc(interpreter);
  6052.         ca_terp++;
  6053.         }
  6054.  
  6055.     new->t_ref_count = 0;
  6056.     new->t_size = INTERPSIZE;
  6057.  
  6058.     new->creator = (interpreter *) 0;
  6059.     if (sender)
  6060.         sassign(new->sender, sender);
  6061.     else
  6062.         sassign(new->sender, (interpreter *) o_nil);
  6063.     sassign(new->literals, literals);
  6064.     sassign(new->bytecodes, bitearray);
  6065.     sassign(new->receiver, receiver);
  6066.     rclass = (class *) fnd_class(receiver);
  6067.     if ((! rclass) || ! is_class(rclass))
  6068.         isize = 25;
  6069.     else {
  6070.         isize = rclass->stack_max;
  6071.         }
  6072.     sassign(new->context, context);
  6073.     sassign(new->stack, new_obj((class *) 0, isize, 1));
  6074.     new->stacktop = &(new->stack)->inst_var[0];
  6075.     new->currentbyte = byte_value(new->bytecodes);
  6076.     return(new);
  6077. }
  6078.  
  6079. /* free_terpreter - return an unused interpreter to free list */
  6080. free_terpreter(anInterpreter)
  6081. interpreter *anInterpreter;
  6082. {
  6083.     if (! is_interpreter(anInterpreter))
  6084.         cant_happen(8);
  6085.  
  6086.     obj_dec((object *) anInterpreter->sender);
  6087.     obj_dec(anInterpreter->receiver);
  6088.     obj_dec(anInterpreter->bytecodes);
  6089.     obj_dec(anInterpreter->literals);
  6090.     obj_dec(anInterpreter->context);
  6091.     obj_dec(anInterpreter->stack);
  6092.  
  6093.     ((mstruct *) anInterpreter)->mlink = fr_interp;
  6094.     fr_interp = (mstruct *) anInterpreter;
  6095. }
  6096.  
  6097. /* copy_arguments - copy an array of arguments into the context */
  6098. copy_arguments(anInterpreter, argLocation, argCount, argArray)
  6099. interpreter *anInterpreter;
  6100. int argLocation, argCount;
  6101. object **argArray;
  6102. {    object *context = anInterpreter->context;
  6103.     int i;
  6104.  
  6105.     for (i = 0; i < argCount; argLocation++, i++) {
  6106.         assign(context->inst_var[ argLocation ], argArray[i]);
  6107.         }
  6108. }
  6109.  
  6110. # define push(x) {assign(*(anInterpreter->stacktop), x); \
  6111.             anInterpreter->stacktop++;}
  6112.  
  6113. /* push_object - push a returned value on to an interpreter stack */
  6114. push_object(anInterpreter, anObject)
  6115. interpreter *anInterpreter;
  6116. object *anObject;
  6117. {
  6118.     push(anObject); /* what? no bounds checking?!? */
  6119. }
  6120.  
  6121. # define nextbyte(x) {x = uctoi(*anInterpreter->currentbyte);\
  6122. anInterpreter->currentbyte++;}
  6123. # define instvar(x) (anInterpreter->receiver)->inst_var[ x ]
  6124. # define tempvar(x) (anInterpreter->context)->inst_var[ x ]
  6125. # define lit(x)     (anInterpreter->literals)->inst_var[ x ]
  6126. # define popstack() (*(--anInterpreter->stacktop))
  6127. # define decstack(x) (anInterpreter->stacktop -= x)
  6128. # define skip(x)    (anInterpreter->currentbyte += x )
  6129.  
  6130. /* resume - resume executing bytecodes associated with an interpreter */
  6131. resume(anInterpreter)
  6132. register interpreter *anInterpreter;
  6133. {
  6134.     int highBits;
  6135.     register int lowBits;
  6136.     object *tempobj, *receiver, *fnd_super();
  6137.     interpreter *sender;
  6138.     int i, j, numargs, arglocation;
  6139.     char *message;
  6140.  
  6141.     while(1) {
  6142.         nextbyte(highBits);
  6143.         lowBits = highBits % 16;
  6144.         highBits /= 16;
  6145.  
  6146.         switchtop:
  6147.         opcount[highBits]++;
  6148.         switch(highBits) {
  6149.             default: cant_happen(9);
  6150.                 break;
  6151.  
  6152.             case 0:    /* two bit form */
  6153.                 highBits = lowBits;
  6154.                 nextbyte(lowBits);
  6155.                 goto switchtop;
  6156.  
  6157.             case 1: /* push instance variable */
  6158.                 push(instvar(lowBits));
  6159.                 break;
  6160.  
  6161.             case 2: /* push context value */
  6162.                 push(tempvar(lowBits));
  6163.                 break;
  6164.  
  6165.             case 3: /* literals */
  6166.                 push(lit(lowBits));
  6167.                 break;
  6168.  
  6169.             case 4: /* push class */
  6170.                 tempobj = lit(lowBits);
  6171.                 if (! is_symbol(tempobj)) cant_happen(9);
  6172.                 tempobj = primitive(FINDCLASS, 1, &tempobj);
  6173.                 push(tempobj);
  6174.                 break;
  6175.  
  6176.             case 5: /* special literals */
  6177.                 if (lowBits < 10)
  6178.                     tempobj = new_int(lowBits);
  6179.                 else if (lowBits == 10)
  6180.                     tempobj = new_int(-1);
  6181.                 else if (lowBits == 11)
  6182.                     tempobj = o_true;
  6183.                 else if (lowBits == 12)
  6184.                     tempobj = o_false;
  6185.                 else if (lowBits == 13)
  6186.                     tempobj = o_nil;
  6187.                 else if (lowBits == 14)
  6188.                     tempobj = o_smalltalk;
  6189.                 else if (lowBits == 15)
  6190.                     tempobj = (object *) runningProcess;
  6191.                 else if ((lowBits >= 30) && (lowBits < 60)) {
  6192.                     /* get class */
  6193.                     tempobj =
  6194.                         new_sym(classpecial[lowBits-30]);
  6195.                     tempobj = primitive(FINDCLASS, 1,
  6196.                         &tempobj);
  6197.                     }
  6198.                 else tempobj = new_int(lowBits);
  6199.                 push(tempobj);
  6200.                 break;
  6201.  
  6202.             case 6: /* pop and store instance variable */
  6203.                 assign(instvar(lowBits), popstack());
  6204.                 break;
  6205.  
  6206.             case 7: /* pop and store in context */
  6207.                 assign(tempvar(lowBits), popstack());
  6208.                 break;
  6209.  
  6210.             case 8: /* send a message */
  6211.                 numargs = lowBits;
  6212.                 nextbyte(i);
  6213.                 tempobj = lit(i);
  6214.                 if (! is_symbol(tempobj)) cant_happen(9);
  6215.                 message = symbol_value(tempobj);
  6216.                 goto do_send;
  6217.  
  6218.             case 9: /* send a superclass message */
  6219.                 numargs = lowBits;
  6220.                 nextbyte(i);
  6221.                 tempobj = lit(i);
  6222.                 if (! is_symbol(tempobj)) cant_happen(9);
  6223.                 message = symbol_value(tempobj);
  6224.                 receiver =
  6225.                     fnd_super(anInterpreter->receiver);
  6226.                 goto do_send2;
  6227.  
  6228.             case 10: /* send a special unary message */
  6229.                 numargs = 0;
  6230.                 message = unspecial[lowBits];
  6231.                 goto do_send;
  6232.  
  6233.             case 11: /* send a special binary message */
  6234.                 numargs = 1;
  6235.                 message = binspecial[lowBits];
  6236.                 goto do_send;
  6237.  
  6238.             case 12: /* send a special arithmetic message */
  6239.                 tempobj = *(anInterpreter->stacktop - 2);
  6240.                 if (! is_integer(tempobj)) goto ohwell;
  6241.                 i = int_value(tempobj);
  6242.                 tempobj = *(anInterpreter->stacktop - 1);
  6243.                 if (! is_integer(tempobj)) goto ohwell;
  6244.                 j = int_value(tempobj);
  6245.                 decstack(2);
  6246.                 switch(lowBits) {
  6247.                     case 0: i += j; break;
  6248.                     case 1: i -= j; break;
  6249.                     case 2: i *= j; break;
  6250.                     case 3: if (i < 0) i = -i;
  6251.                         i %= j; break;
  6252.                     case 4: if (j < 0) i >>= (-j);
  6253.                         else i <<= j; break;
  6254.                     case 5: i &= j; break;
  6255.                     case 6: i |= j; break;
  6256.                     case 7: i = (i < j); break;
  6257.                     case 8: i = (i <= j); break;
  6258.                     case 9: i = (i == j); break;
  6259.                     case 10: i = (i != j); break;
  6260.                     case 11: i = (i >= j); break;
  6261.                     case 12: i = (i > j); break;
  6262.                     case 13: i %= j; break;
  6263.                     case 14: i /= j; break;
  6264.                     case 15: i = (i < j) ? i : j;
  6265.                         break;
  6266.                     case 16: i = (i < j) ? j : i;
  6267.                         break;
  6268.                     default: cant_happen(9);
  6269.                     }
  6270.                 if ((lowBits < 7) || (lowBits > 12))
  6271.                     tempobj = new_int(i);
  6272.                 else tempobj = (i ? o_true : o_false);
  6273.                 push(tempobj);
  6274.                 break;
  6275.  
  6276.                 ohwell: /* oh well, send message */
  6277.                 ohcount++;
  6278.                 numargs = 1;
  6279.                 message = arithspecial[lowBits];
  6280.                 goto do_send;
  6281.  
  6282.             case 13: /* send a special ternary keyword messae */
  6283.                 numargs = 2;
  6284.                 message = keyspecial[lowBits];
  6285.                 goto do_send;
  6286.  
  6287.             case 14: /* block creation */
  6288.                 numargs = lowBits;
  6289.                 if (numargs)
  6290.                     nextbyte(arglocation);
  6291.                 nextbyte(i);    /* size of block */
  6292.                 push(new_block(anInterpreter, numargs,
  6293.                     arglocation));
  6294.                 skip(i);
  6295.                 break;
  6296.  
  6297.             case 15: /* special bytecodes */
  6298.                 spcount[lowBits]++;
  6299.                 switch(lowBits) {
  6300.                 case 0: /* no - op */
  6301.                     break;
  6302.                 case 1: /* duplicate top of stack */
  6303.                     push(*(anInterpreter->stacktop - 1));
  6304.                     break;
  6305.                 case 2: /* pop top of stack */
  6306.                     anInterpreter->stacktop--;
  6307.                     break;
  6308.                 case 3: /* return top of stack */
  6309.                     tempobj = popstack();
  6310.                     goto do_return;
  6311.                 case 4: /* block return */
  6312.                     block_return(anInterpreter, popstack());
  6313.                     return;
  6314.                 case 5: /* self return */
  6315.                     tempobj = tempvar(0);
  6316.                     goto do_return;
  6317.                 case 6: /* skip on true */
  6318.                     nextbyte(i);
  6319.                     tempobj = popstack();
  6320.                     if (tempobj == o_true) {
  6321.                         skip(i);
  6322.                         push(o_nil);
  6323.                         }
  6324.                     break;
  6325.                 case 7: /* skip on false */
  6326.                     nextbyte(i);
  6327.                     tempobj = popstack();
  6328.                     if (tempobj == o_false) {
  6329.                         skip(i);
  6330.                         push(o_nil);
  6331.                         }
  6332.                     break;
  6333.                 case 8: /* just skip */
  6334.                     nextbyte(i);
  6335.                     skip(i);
  6336.                     break;
  6337.                 case 9: /* skip backward */
  6338.                     nextbyte(i);
  6339.                     skip( - i );
  6340.                     break;
  6341.                 case 10: /* execute a primitive */
  6342.                     nextbyte(numargs);
  6343.                     nextbyte(i); /* primitive number */
  6344.                     if (i == BLOCKEXECUTE)
  6345.                         goto blk_execute;
  6346.                     else if (i == DOPERFORM)
  6347.                         goto do_perform;
  6348.                     else {
  6349.                         decstack(numargs);
  6350.                         tempobj = primitive(i, numargs,
  6351.                         anInterpreter->stacktop);
  6352.                         push(tempobj);
  6353.                         }
  6354.                     break;
  6355.                 case 11: /* skip true, push true */
  6356.                     nextbyte(i);
  6357.                     tempobj = popstack();
  6358.                     if (tempobj == o_true) {
  6359.                         skip(i);
  6360.                         anInterpreter->stacktop++;
  6361.                         }
  6362.                     break;
  6363.                 case 12: /* skip on false, push false */
  6364.                     nextbyte(i);
  6365.                     tempobj = popstack();
  6366.                     if (tempobj == o_false) {
  6367.                         skip(i);
  6368.                         anInterpreter->stacktop++;
  6369.                         }
  6370.                     break;
  6371.                 default:
  6372.                     cant_happen(9);
  6373.                 }
  6374.                 break;
  6375.             }
  6376.         }
  6377.     /* sorry for the unstructured gotos.
  6378.         the sins of unstructuredness seemed less bothersome than
  6379.         the problems of not doing the same thing in all places
  6380.                         -tab
  6381.         */
  6382.     do_perform:    /* process perform:withArguments: */
  6383.         tempobj = popstack();
  6384.         message = symbol_value(tempobj);
  6385.         tempobj = popstack();
  6386.         numargs = tempobj->size - 1;
  6387.         for (i = 0; i <= numargs; i++)
  6388.             push(tempobj->inst_var[i]);
  6389.         /* fall through into do_send */
  6390.  
  6391.         /* do_send - call courier to send a message */
  6392.     do_send:
  6393.         receiver = *(anInterpreter->stacktop - (numargs + 1));
  6394.     do_send2:
  6395.         decstack(numargs + 1);
  6396.         send_mess(anInterpreter, receiver, message,
  6397.             anInterpreter->stacktop , numargs);
  6398.         return;
  6399.  
  6400.         /* do_return - return from a message */
  6401.     do_return:
  6402.         sender = anInterpreter->sender;
  6403.         if (is_interpreter(sender)) {
  6404.             if (! is_driver(sender))
  6405.                 push_object(sender, tempobj);
  6406.             link_to_process(sender);
  6407.             }
  6408.         else {
  6409.             terminate_process(runningProcess);
  6410.             }
  6411.         return;
  6412.  
  6413.         /* blk_execute - perform the block execute primitive */
  6414.     blk_execute:
  6415.         tempobj = popstack();
  6416.         if (! is_integer(tempobj)) cant_happen(9);
  6417.         numargs = int_value(tempobj);
  6418.         sender = block_execute(anInterpreter->sender,
  6419.             (block *) tempvar(0), numargs, &tempvar(1));
  6420.         link_to_process(sender);
  6421.         return;
  6422. }
  6423. End
  6424. echo unbundling block.c 1>&2
  6425. cat >block.c <<'End'
  6426. /*
  6427.     Little Smalltalk
  6428.  
  6429.         block creation and block return
  6430.         timothy a. budd, 10/84
  6431.  
  6432. */
  6433. /*
  6434.     The source code for the Little Smalltalk System may be freely
  6435.     copied provided that the source of all files is acknowledged
  6436.     and that this condition is copied with each file.
  6437.  
  6438.     The Little Smalltalk System is distributed without responsibility
  6439.     for the performance of the program and without any guarantee of
  6440.     maintenance.
  6441.  
  6442.     All questions concerning Little Smalltalk should be addressed to:
  6443.  
  6444.         Professor Tim Budd
  6445.         Department of Computer Science
  6446.         Oregon State University
  6447.         Corvallis, Oregon
  6448.         97331
  6449.         USA
  6450. */
  6451. # include <stdio.h>
  6452. # include "object.h"
  6453. # include "drive.h"
  6454. # include "interp.h"
  6455. # include "block.h"
  6456. # include "string.h"
  6457. # include "primitive.h"
  6458. # include "process.h"
  6459.  
  6460. extern object *o_object;    /* value of generic object */
  6461.  
  6462. static mstruct *fr_block = 0;    /* free list of unused blocks */
  6463.  
  6464. int ca_block = 0;        /* count block allocations */
  6465.  
  6466. /* cpyInterpreter - make a new copy of an existing interpreter */
  6467. static interpreter *cpyInterpreter(anInterpreter)
  6468. interpreter *anInterpreter;
  6469. {    interpreter *new;
  6470.  
  6471.     new = cr_interpreter((interpreter *) 0,
  6472.         anInterpreter->receiver,
  6473.         anInterpreter->literals,
  6474.         anInterpreter->bytecodes,
  6475.         anInterpreter->context);
  6476.  
  6477.     if (anInterpreter->creator)
  6478.         new->creator = anInterpreter->creator;
  6479.     else
  6480.         new->creator = anInterpreter;
  6481.  
  6482.     new->currentbyte = anInterpreter->currentbyte;
  6483.     return(new);
  6484. }
  6485.  
  6486. /* new_block - create a new instance of class Block */
  6487. object *new_block(anInterpreter, argcount, arglocation)
  6488. interpreter *anInterpreter;
  6489. int argcount, arglocation;
  6490. {    block *new;
  6491.  
  6492.     if (fr_block) {
  6493.         new = (block *) fr_block;
  6494.         fr_block = fr_block->mlink;
  6495.         }
  6496.     else {
  6497.         new = structalloc(block);
  6498.         ca_block++;
  6499.         }
  6500.  
  6501.     new->b_ref_count = 0;
  6502.     new->b_size = BLOCKSIZE;
  6503.  
  6504.     sassign(new->b_interpreter, cpyInterpreter(anInterpreter));
  6505.     new->b_numargs = argcount;
  6506.     new->b_arglocation = arglocation;
  6507.     return((object *) new);
  6508. }
  6509.  
  6510. /* free_block - return an unused block to the block free list */
  6511. free_block(b)
  6512. block *b;
  6513. {
  6514.     if (! is_block(b))
  6515.         cant_happen(8);
  6516.  
  6517.     obj_dec((object *)(b->b_interpreter));
  6518.  
  6519.     ((mstruct *) b)->mlink = fr_block;
  6520.     fr_block = (mstruct *) b;
  6521. }
  6522.  
  6523. /* block_execute - queue a block interpreter for execution */
  6524. interpreter *block_execute(sender, aBlock, numargs, args)
  6525. interpreter *sender;
  6526. block *aBlock;
  6527. int numargs;
  6528. object **args;
  6529. {    interpreter *newInt;
  6530.     object *tempobj;
  6531.  
  6532.     if (! is_block(aBlock)) cant_happen(11);
  6533.     if (numargs != aBlock->b_numargs) {
  6534.         sassign(tempobj,
  6535.             new_str("wrong number of arguments for block"));
  6536.         primitive(ERRPRINT, 1, &tempobj);
  6537.         obj_dec(tempobj);
  6538.         if (sender) {
  6539.             push_object(sender, o_nil);
  6540.             }
  6541.         return(sender); /* not sure about this ..... */
  6542.         }
  6543.  
  6544.     /* we copy the interpreter so as to not destroy the original and to
  6545.        avoid memory pointer cycles */
  6546.  
  6547.     newInt = cpyInterpreter(aBlock->b_interpreter);
  6548.     if (sender)
  6549.         assign(newInt->sender, sender);
  6550.     if (numargs)
  6551.         copy_arguments(newInt, aBlock->b_arglocation,
  6552.             numargs, args);
  6553.     return(newInt);
  6554. }
  6555.  
  6556. /* block_return - return an object from the context in which a block was
  6557. created */
  6558. block_return(blockInterpreter, anObject)
  6559. interpreter *blockInterpreter;
  6560. object *anObject;
  6561. {    interpreter *backchain, *parent;
  6562.     interpreter *creatorblock;
  6563.  
  6564.     creatorblock = blockInterpreter->creator;
  6565.     for (backchain = blockInterpreter->sender; backchain;
  6566.             backchain = backchain->sender) {
  6567.         if (! is_interpreter(backchain)) break;
  6568.         if (backchain == creatorblock) {
  6569.             /* found creating context, back up one more */
  6570.             parent = backchain->sender;
  6571.             if (parent) {
  6572.                 if (! is_driver(parent))
  6573.                     push_object(parent, anObject);
  6574.                 link_to_process(parent);
  6575.                 }
  6576.             else {
  6577.                 terminate_process(runningProcess);
  6578.                 }
  6579.             return;
  6580.             }
  6581.         }
  6582.  
  6583.     /* no block found, issue error message */
  6584.     primitive(BLKRETERROR, 1, (object **) &blockInterpreter);
  6585.     parent = blockInterpreter->sender;
  6586.     if (parent) {
  6587.         if (! is_driver(parent))
  6588.             push_object(parent, anObject);
  6589.         link_to_process(parent);
  6590.         }
  6591.     else {
  6592.         terminate_process(runningProcess);
  6593.         }
  6594. }
  6595. End
  6596. echo unbundling courier.c 1>&2
  6597. cat >courier.c <<'End'
  6598. /*
  6599.     Little Smalltalk
  6600.         courier - message passing interface
  6601.  
  6602.         timothy a. budd 10/84
  6603. */
  6604. /*
  6605.     The source code for the Little Smalltalk System may be freely
  6606.     copied provided that the source of all files is acknowledged
  6607.     and that this condition is copied with each file.
  6608.  
  6609.     The Little Smalltalk System is distributed without responsibility
  6610.     for the performance of the program and without any guarantee of
  6611.     maintenance.
  6612.  
  6613.     All questions concerning Little Smalltalk should be addressed to:
  6614.  
  6615.         Professor Tim Budd
  6616.         Department of Computer Science
  6617.         Oregon State University
  6618.         Corvallis, Oregon
  6619.         97331
  6620.         USA
  6621. */
  6622. # include <stdio.h>
  6623. # include "object.h"
  6624. # include "interp.h"
  6625. # include "string.h"
  6626. # include "symbol.h"
  6627. # include "primitive.h"
  6628. # define streq(x,y) (strcmp(x,y) == 0)
  6629.  
  6630. /* send_mess - find the method needed to respond to a message, create the
  6631.     proper context and interpreter for executing the method */
  6632. send_mess(sender, receiver, message, args, numargs)
  6633. interpreter *sender;
  6634. object *receiver, **args;
  6635. char *message;
  6636. int numargs;
  6637. {    object *robject, *method;
  6638.     register object *message_array;
  6639.     object *context, *fnd_super(), *fnd_class();
  6640.     class  *objclass;
  6641.     interpreter *anInterpreter;
  6642.     int    i, maxc;
  6643.  
  6644.     for (robject = receiver; robject; ) {
  6645.         if (is_bltin(robject))
  6646.             objclass = (class *) fnd_class(robject);
  6647.         else
  6648.             objclass = robject->class;
  6649.         if ((objclass == (class *) 0) || ! is_class(objclass))  break;
  6650.  
  6651.         message_array = objclass->message_names;
  6652.         for (i = 0; i < message_array->size; i++) {
  6653.             if (symbol_value(message_array->inst_var[i]) ==
  6654.                         message) {
  6655.                 method = (objclass->methods)->inst_var[ i ];
  6656.                 goto do_cmd;
  6657.                 }
  6658.             }
  6659.         if (is_bltin(robject))
  6660.             robject = fnd_super(robject);
  6661.         else
  6662.             robject = robject->super_obj;
  6663.         }
  6664.  
  6665. /* if we reach this point then no method has been found matching message */
  6666.     sassign(robject, new_obj((class *) 0, 2, 0));
  6667.     sassign(robject->inst_var[0], receiver);
  6668.     sassign(robject->inst_var[1], new_sym(message));
  6669.     primitive(NORESPONDERROR, 2, &(robject->inst_var[0]));
  6670.     obj_dec(robject);
  6671.     /* generate a message passing trace */
  6672.     backtrace(sender);
  6673.     /* return nil by default */
  6674.     if (is_interpreter(sender))
  6675.         push_object(sender, o_nil);
  6676.     goto clean_up;
  6677.  
  6678. /* do an interpreted method */
  6679. /* make a context and fill it in, make an interpeter and link it into
  6680. process queue */
  6681. do_cmd:
  6682.     maxc = objclass->context_size;
  6683.     sassign(context, new_obj((class *)0, maxc, 0));
  6684.     for (i = 0; i <= numargs; i++)
  6685.         sassign(context->inst_var[i], args[i]);
  6686.     for ( ; i < maxc ; i++ )
  6687.         sassign(context->inst_var[i], o_nil);
  6688.     anInterpreter = cr_interpreter(sender, robject, method->inst_var[1],
  6689.         method->inst_var[0], context);
  6690.     link_to_process(anInterpreter);
  6691.     obj_dec(context);
  6692.     goto clean_up;
  6693.  
  6694. /* clean up after yourself */
  6695. clean_up:
  6696.     return;
  6697. }
  6698.  
  6699. /* responds_to - see if a class responds to a message */
  6700. int responds_to(message, aClass)
  6701. char *message;
  6702. class *aClass;
  6703. {    object *message_names;
  6704.     int i;
  6705.  
  6706.     message_names = aClass->message_names;
  6707.     for (i = 0; i < message_names->size; i++)
  6708.         if (streq(symbol_value(message_names->inst_var[i]),
  6709.                 message))
  6710.             return(1);
  6711.     return(0);
  6712. }
  6713.  
  6714. /* backtrace - generate a backwards message passing trace */
  6715. static backtrace(current)
  6716. interpreter *current;
  6717. {
  6718.     while (is_interpreter(current->sender) &&
  6719.             ! is_driver(current->sender)) {
  6720.         fnd_message(current->receiver, current->bytecodes);
  6721.         current = current->sender;
  6722.         }
  6723. }
  6724.  
  6725. /* fnd_message - find the message associated with an interpreter */
  6726. static fnd_message(receiver, bytecodes)
  6727. object *receiver, *bytecodes;
  6728. {    int i;
  6729.     class *oclass;
  6730.     object *messar, *temp;
  6731.     char buffer[100];
  6732.  
  6733.     oclass = (class *) fnd_class(receiver);
  6734.  
  6735.     messar = oclass->methods;
  6736.     for (i = 0; i < messar->size; i++) {
  6737.         if ((messar->inst_var[i])->inst_var[0] == bytecodes) {
  6738.             sprintf(buffer,"%s: backtrace. message  %s",
  6739.                 symbol_value(oclass->class_name),
  6740.                 symbol_value(
  6741.                     (oclass->message_names)->inst_var[i]));
  6742.             sassign(temp, new_str(buffer));
  6743.             primitive(ERRPRINT, 1, &temp);
  6744.             obj_dec(temp);
  6745.             return;
  6746.             }
  6747.         }
  6748.     cant_happen(24);
  6749. }
  6750.  
  6751. /* prnt_messages - print all the messages a class responds to.
  6752.     needed because the messages names array for some of the classes is
  6753.     created before ArrayedCollection, and thus some do not respond to
  6754.     do: */
  6755. prnt_messages(aClass)
  6756. class *aClass;
  6757. {    object *message_names;
  6758.     int i;
  6759.  
  6760.     message_names = aClass->message_names;
  6761.     for (i = 0; i < message_names->size; i++)
  6762.         primitive(SYMPRINT, 1, &message_names->inst_var[i]);
  6763. }
  6764. End
  6765. echo unbundling lex.c 1>&2
  6766. cat >lex.c <<'End'
  6767. /*
  6768.     Little Smalltalk lexical analyzer for driver
  6769.         timothy a. budd 12/84
  6770. */
  6771. /*
  6772.     The source code for the Little Smalltalk System may be freely
  6773.     copied provided that the source of all files is acknowledged
  6774.     and that this condition is copied with each file.
  6775.  
  6776.     The Little Smalltalk System is distributed without responsibility
  6777.     for the performance of the program and without any guarantee of
  6778.     maintenance.
  6779.  
  6780.     All questions concerning Little Smalltalk should be addressed to:
  6781.  
  6782.         Professor Tim Budd
  6783.         Department of Computer Science
  6784.         Oregon State University
  6785.         Corvallis, Oregon
  6786.         97331
  6787.         USA
  6788. */
  6789. # include <stdio.h>
  6790. # include <ctype.h>
  6791. # include <math.h>
  6792. # define DRIVECODE
  6793. # include "drive.h"
  6794.  
  6795. # define MAXTOKEN 100
  6796. char toktext[MAXTOKEN];
  6797. tok_type t;
  6798. enum lextokens token;
  6799.  
  6800. extern char *lexptr;
  6801. extern double atof();
  6802.  
  6803. static char ocbuf = 0;
  6804. static int pbbuf[20];
  6805.  
  6806. # define input() (ocbuf ? pbbuf[--ocbuf] : *lexptr++ )
  6807. # define putbak(c) (pbbuf[ocbuf++] = c)
  6808.  
  6809. static char *psuvars[] = {"nil", "true", "false", "smalltalk", 0};
  6810. static enum pseuvars psuval[] = {nilvar, truevar, falsevar, smallvar};
  6811. static char symbols[] = "\n-()[]!|.;>" ;
  6812. static enum lextokens symval[] = {NL, MINUS, LP, RP, LB, RB, BAR, BAR,
  6813.     PERIOD, SEMI, PE};
  6814.  
  6815. static enum lextokens lexsave(type)
  6816. enum lextokens type;
  6817. {    char *w_search();
  6818.  
  6819.     if (! (t.c = w_search(toktext, 1)))
  6820.         lexerr("cannot create symbol %s", toktext);
  6821.     /* assign token, and return value */
  6822.     return(token = type);
  6823. }
  6824.  
  6825. enum lextokens nextlex() {
  6826.     register char c;
  6827.     register char *p;
  6828.     char *q;
  6829.     int  i, n, base;
  6830.     double d, denom;
  6831.  
  6832.     do {            /* read whitespace (including comments) */
  6833.         c = input();
  6834.         if (c == '\"') {
  6835.             while ((c = input()) && c != '\"') ;
  6836.             if (c == '\"') c = input();
  6837.             else lexerr("unterminated comment", "");
  6838.             }
  6839.         } while (c == ' ' || c == '\t') ;
  6840.  
  6841.     if (!c) return(token = nothing);
  6842.  
  6843.     p = toktext;
  6844.     *p = c;
  6845.     toktext[1] = '\0';
  6846.  
  6847.                         /* identifiers and keywords */
  6848.     if (( c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) {
  6849.         for (*p++ = c; (c = input()) && isalnum(c) ; *p++ = c) ;
  6850.         *p = '\0';
  6851.         lexsave(0);
  6852.         if (c == ':') {
  6853.             return(token = KEYWORD);
  6854.             }
  6855.         else {
  6856.             putbak(c);
  6857.             if (islower(toktext[0])) {
  6858.                 for (i = 0; psuvars[i]; i++)
  6859.                     if (strcmp(toktext, psuvars[i]) == 0) {
  6860.                         t.p = psuval[i];
  6861.                         return(token = PSEUDO);
  6862.                         }
  6863.                 return(token = LOWERCASEVAR);
  6864.                 }
  6865.             else {
  6866.                 return(token = UPPERCASEVAR);
  6867.                 }
  6868.             }
  6869.         }
  6870.     
  6871. # define scandigits(x) for(*p++ = c; (c = input()) && isdigit(c) ; *p++ = c) x
  6872.  
  6873.     if (c >= '0' && c <= '9') {        /* numbers */
  6874.         i = c - '0';
  6875.         scandigits( i = 10 * i + (c - '0') );
  6876.         if (c == '.' || c == 'e') {
  6877.             if (c == '.')
  6878.                 scandigits();
  6879.             if (c == 'e') {
  6880.                 *p++ = c;
  6881.                 c = input();
  6882.                 if (c == '+' || c == '-') {
  6883.                     *p++ = c; c = input(); }
  6884.                 scandigits();
  6885.                 }
  6886.             putbak(c);
  6887.             *p = '\0';
  6888.             t.f = atof(toktext);
  6889.             return(token = LITFNUM);
  6890.             }
  6891.         else if ((c == 'r') && ((i >= 2) && (i <= 36))) {
  6892.             base = i;
  6893.             i = 0;
  6894.             for (*p++ = c; c = input(); *p++ = c) {
  6895.                 if (isdigit(c)) n = c - '0';
  6896.                 else if (isupper(c)) n = (c - 'A') + 10;
  6897.                 else break;
  6898.                 if (n >= base) break;
  6899.                 i = base * i + n;
  6900.                 }
  6901.             if (c == '.' || c == 'e') {
  6902.                 d = (double) i;
  6903.                 if (c == '.') {
  6904.                     denom = 1.0 / (double) base;
  6905.                     for (*p++ = c; c = input(); *p++ = c) {
  6906.                         if (isdigit(c))
  6907.                             n = c - '0';
  6908.                         else if (isupper(c))
  6909.                             n = (c - 'A') + 10;
  6910.                         else break;
  6911.                         if (n >= base) break;
  6912.                         d += n * denom;
  6913.                         denom /= base;
  6914.                         }
  6915.                     }
  6916.                 if (c == 'e') {
  6917.                     *p++ = c;
  6918.                     c = input();
  6919.                     if (c == '+' || c == '-') {
  6920.                         n = c;
  6921.                         *p++ = c;
  6922.                         c = input();
  6923.                         }
  6924.                     else n = 0;
  6925.                     i = c - '0';
  6926.                     scandigits(i = 10 * i + (c - '0'));
  6927.                     if (n == '-') i = - i;
  6928.                     d *= pow((double) base, (double) i);
  6929.                     }
  6930.                 putbak(c);
  6931.                 *p = '\0';
  6932.                 t.f = d;
  6933.                 return(token = LITFNUM);
  6934.                 }
  6935.             }
  6936.         putbak(c);
  6937.         *p = '\0';
  6938.         t.i = i;
  6939.         return(token = LITNUM);
  6940.         }
  6941.  
  6942.     if (c == '#') {                /* symbol */
  6943.         i = 1;
  6944.         while (i)
  6945.             switch(c = input()) {
  6946.                 case '\0': case ' ': case '\t': case '\n':
  6947.                 case '(': case '[': case ')':
  6948.                     putbak(c);
  6949.                     i = 0;
  6950.                     break;
  6951.                 default:
  6952.                     *p++ = c;
  6953.                 }
  6954.         if (p == toktext)
  6955.             return(token = PS);
  6956.         else {
  6957.             *p = '\0';
  6958.             if ((p - toktext) >= MAXTOKEN) cant_happen(18);
  6959.             return(lexsave(LITSYM));
  6960.             }
  6961.         }
  6962.  
  6963.     if (c == '\'') {            /* quoted string */
  6964.         do {
  6965.             for ( ; (c = input()) && c != '\'' ; *p++ = c) ;
  6966.             c = input();
  6967.             if (c == '\'') *p++ = '\'';
  6968.             } while (c == '\'');
  6969.         putbak(c);
  6970.         *p = '\0';
  6971.         if ((p - toktext) >= MAXTOKEN) cant_happen(18);
  6972.         t.c = toktext;
  6973.         return(token = LITSTR);
  6974.         }
  6975.  
  6976.     if (c == ':') {                /* colon or argument name */
  6977.         c = input();
  6978.         if (c == '=')
  6979.             return(token = ASSIGN);
  6980.         else if (isalnum(c)) {
  6981.             for (*p++ = c; isalnum(c = input()); *p++ = c );
  6982.             putbak(c);
  6983.             *p = '\0';
  6984.             return(lexsave(COLONVAR));
  6985.             }
  6986.         putbak(c);
  6987.         return(lexsave(BINARY));
  6988.         }
  6989.  
  6990.     if (c == '<') {            /* assign, less than or primitive */
  6991.         *p++ = c; *p = '\0';
  6992.         c = input();
  6993.         if (c == '-')
  6994.             return(token = ASSIGN);
  6995.         for (p = q = "primitive"; *p && *p == c; p++)
  6996.             c = input();
  6997.         putbak(c);
  6998.         if (*p) {
  6999.             for (p--; p >= q; p--) putbak(*p);
  7000.             return(lexsave(BINARY));
  7001.             }
  7002.         else
  7003.             return(token = PRIMITIVE);
  7004.         }
  7005.  
  7006.     if (c == '.') {            /* number or period */
  7007.         c = input();
  7008.         if (c >= '0' && c <= '9') {
  7009.             putbak(c);        /* reparse with digit */
  7010.             putbak('.');        /* inserted on front */
  7011.             putbak('0');        /* so it looks like */
  7012.             return(nextlex());    /* a number */
  7013.             }
  7014.         putbak(c);
  7015.         return(token = PERIOD);
  7016.         }
  7017.  
  7018.     if (c == '\\') {        /* binary or hidden newline */
  7019.         c = input();
  7020.         if (c == '\n')
  7021.             return(nextlex());
  7022.         putbak(c);
  7023.         return(lexsave(BINARY));
  7024.         }
  7025.  
  7026.     if (c == '$') {            /* literal character or binary */
  7027.         c = input();
  7028.         if (c) {
  7029.             t.i = c;
  7030.             return(token = LITCHAR);
  7031.             }
  7032.         return(lexsave(BINARY));
  7033.         }
  7034.  
  7035.     for (i = 0; symbols[i]; i++)
  7036.         if (c == symbols[i])
  7037.             return(lexsave(symval[i]));
  7038.  
  7039.     return(lexsave(BINARY));
  7040. }
  7041. End
  7042. echo unbundling drive.c 1>&2
  7043. cat >drive.c <<'End'
  7044. /*
  7045.     Little Smalltalk
  7046.         command parser
  7047.  
  7048.         timothy a. budd, 12/84
  7049.  
  7050. */
  7051. /*
  7052.     The source code for the Little Smalltalk System may be freely
  7053.     copied provided that the source of all files is acknowledged
  7054.     and that this condition is copied with each file.
  7055.  
  7056.     The Little Smalltalk System is distributed without responsibility
  7057.     for the performance of the program and without any guarantee of
  7058.     maintenance.
  7059.  
  7060.     All questions concerning Little Smalltalk should be addressed to:
  7061.  
  7062.         Professor Tim Budd
  7063.         Department of Computer Science
  7064.         Oregon State University
  7065.         Corvallis, Oregon
  7066.         97331
  7067.         USA
  7068. */
  7069. # include <stdio.h>
  7070. # include "object.h"
  7071. # define DRIVECODE
  7072. # include "drive.h"
  7073. # include "cmds.h"
  7074. # include "number.h"
  7075. # include "symbol.h"
  7076. # include "string.h"
  7077. # include "byte.h"
  7078. # include "interp.h"
  7079. # include "primitive.h"
  7080.  
  7081. extern enum lextokens token, nextlex();
  7082. extern int prntcmd;
  7083. extern int inisstd;
  7084. extern int started;
  7085. extern char toktext[];
  7086. extern char *lexptr;
  7087. extern int line_grabber();
  7088. extern tok_type t;
  7089.  
  7090. /* test_driver - see if the driver should be invoked */
  7091. int test_driver(block)
  7092. int block;    /* indicates wheter to use block or non-blocking input */
  7093. {
  7094.     switch(line_grabber( block )) {
  7095.         default: cant_happen(17);
  7096.         case -1:
  7097.             /*  return end of file indication */
  7098.             return(0);
  7099.         case 0:
  7100.             /* enqueue driver process again */
  7101.             return(1);
  7102.         case 1:
  7103.             if (*lexptr == ')') {
  7104.                 dolexcommand(lexptr);
  7105.                 return(1);
  7106.                 }
  7107.             parse();
  7108.             return(1);
  7109.         }
  7110. }
  7111.  
  7112. /* ---- code generation routines  -------------- */
  7113. # define CODEMAX 500
  7114. static uchar code[CODEMAX];
  7115. static int codetop = 0;
  7116.  
  7117. static gencode(value)
  7118. register int value;
  7119. {
  7120.     if (value >= 256)
  7121.         lexerr("code word too big: %d", value);
  7122.     if (codetop > CODEMAX)
  7123.         lexerr("too many code words: %d", codetop);
  7124.     /*if (started)
  7125.     fprintf(stderr,"code %d (%d %d)\n", value, value/16, value%16);*/
  7126.     code[codetop++] = itouc(value);
  7127. }
  7128.  
  7129. static genhighlow(high, low)
  7130. register int high;
  7131. register int low;
  7132. {
  7133.     if (high < 0 || high > 16)
  7134.         lexerr("genhighlow error: %d", high);
  7135.     if (low < 0)
  7136.         lexerr("genhighlow low error: %d", low);
  7137.     if (low < 16) gencode(high * 16 + low);
  7138.     else {
  7139.         gencode(TWOBIT * 16 + high);
  7140.         gencode(low);
  7141.         }
  7142. }
  7143. /*-------------------------------------------------------*/
  7144.  
  7145. static int errflag;
  7146.  
  7147. /* parse - main parser */
  7148. int parse()
  7149. {    register int i;
  7150.  
  7151.     errflag = 0;
  7152.     reset();
  7153.  
  7154.     if (nextlex() == nothing) return(1);
  7155.     if (token == NL) return(1);
  7156.  
  7157.     i = aprimary();
  7158.     if (i >= 0) {
  7159.         asign(i);
  7160.         if ((prntcmd > 1) && inisstd)
  7161.             genhighlow(UNSEND, PRNTCMD);
  7162.         }
  7163.     else {
  7164.         cexpression();
  7165.         if (prntcmd && inisstd)
  7166.             genhighlow(UNSEND, PRNTCMD);
  7167.         }
  7168.     genhighlow(POPINSTANCE, 0);    /* assign to ``last'' */
  7169.     if (errflag)
  7170.         return(1);
  7171.     if (token == nothing || token == NL) {
  7172.         bld_interpreter();
  7173.         return(0);
  7174.         }
  7175.     expect("end of expression");
  7176.     return(1);
  7177. }
  7178.  
  7179. /* asign - code for an assignment statement - leaves result on stack */
  7180. static asign(pos)
  7181. int pos;
  7182. {    int i;
  7183.  
  7184.     i = aprimary();
  7185.     if (i >= 0) {
  7186.         asign(i);
  7187.         }
  7188.     else {
  7189.         cexpression();
  7190.         }
  7191.     genhighlow(SPECIAL, DUPSTACK);
  7192.     genhighlow(POPINSTANCE, pos);
  7193. }
  7194.  
  7195. /* expression - read an expression, leaving result on stack */
  7196. static expression()
  7197. {    int i;
  7198.  
  7199.     i = aprimary();
  7200.     if (i >= 0) {
  7201.         asign(i);
  7202.         }
  7203.     else {
  7204.         cexpression();
  7205.         }
  7206. }
  7207.  
  7208. /* cexpression - code for a (possibly cascaded) expression */
  7209. static cexpression()
  7210. {
  7211.     kcontinuation();
  7212.     while (token == SEMI) {
  7213.         genhighlow(SPECIAL, DUPSTACK);
  7214.         nextlex();
  7215.         kcontinuation();
  7216.         genhighlow(SPECIAL, POPSTACK);
  7217.         }
  7218. }
  7219.  
  7220. /* kcontinuation - keyword continuation */
  7221. static kcontinuation()
  7222. {    char kbuf[150];
  7223.     int  kcount;
  7224.  
  7225.     bcontinuation();
  7226.     if (token == KEYWORD) {
  7227.         kbuf[0] = '\0';
  7228.         kcount = 0;
  7229.         while (token == KEYWORD) {
  7230.             strcat(kbuf, t.c);
  7231.             strcat(kbuf, ":");
  7232.             kcount++;
  7233.             nextlex();
  7234.             primary(1);
  7235.             bcontinuation();
  7236.             }
  7237.         gensend(kbuf, kcount);
  7238.         }
  7239. }
  7240.  
  7241. /* isbinary - see if the current token(s) is a binary */
  7242. static int isbinary(bbuf)
  7243. char *bbuf;
  7244. {
  7245.     if (token == BINARY || token == MINUS ||
  7246.         token == BAR || token == PE) {
  7247.         strcpy(bbuf, t.c);
  7248.         nextlex();
  7249.         if (token == BINARY || token == MINUS ||
  7250.                 token == BAR || token == PE) {
  7251.             strcat(bbuf, t.c);
  7252.             nextlex();
  7253.             }
  7254.         return(1);
  7255.         }
  7256.     return(0);
  7257. }
  7258.  
  7259. /* bcontinuation - binary continuation */
  7260. static bcontinuation()
  7261. {    char bbuf[3];
  7262.  
  7263.     ucontinuation();
  7264.     while (isbinary(bbuf)) {
  7265.         primary(1);
  7266.         ucontinuation();
  7267.         gensend(bbuf, 1);
  7268.         }
  7269. }
  7270.  
  7271. /* ucontinuation - unary continuation */
  7272. static ucontinuation()
  7273. {
  7274.     while (token == LOWERCASEVAR) {
  7275.         gensend(t.c, 0);
  7276.         nextlex();
  7277.         }
  7278. }
  7279.  
  7280. /* aprimary - primary or beginning of assignment */
  7281. static int aprimary()
  7282. {    char *c;
  7283.  
  7284.     if (token == LOWERCASEVAR) {
  7285.         c = t.c;
  7286.         if (nextlex() == ASSIGN) {
  7287.             nextlex();
  7288.             return(findvar(c, 1));
  7289.             }
  7290.         else {
  7291.             genvar(c);
  7292.             return( -1 );
  7293.             }
  7294.         }
  7295.     primary(1);
  7296.     return( - 1 );
  7297. }
  7298.  
  7299. /* primary - find a primary expression */
  7300. static int primary(must)
  7301. int must;    /* must we find something ? */
  7302. {    int i, count;
  7303.  
  7304.     switch(token) {
  7305.         case UPPERCASEVAR:
  7306.             genhighlow(PUSHCLASS, aliteral(1));
  7307.             break;
  7308.  
  7309.         case LOWERCASEVAR:
  7310.             genvar(t.c);
  7311.             nextlex();
  7312.             break;
  7313.  
  7314.         case LITNUM:
  7315.             if (t.i >= 0 && t.i < 10) {
  7316.                 genhighlow(PUSHSPECIAL, t.i);
  7317.                 nextlex();
  7318.                 }
  7319.             else {
  7320.                 genhighlow(PUSHLIT, aliteral(1));
  7321.                 }
  7322.             break;
  7323.  
  7324.         case MINUS:
  7325.         case LITFNUM:
  7326.         case LITCHAR:
  7327.         case LITSTR:
  7328.         case LITSYM:
  7329.         case PS:
  7330.             genhighlow(PUSHLIT, aliteral(1));
  7331.             break;
  7332.  
  7333.         case PSEUDO:
  7334.             switch(t.p) {
  7335.                 case nilvar: i = 13; break;
  7336.                 case truevar: i = 11; break;
  7337.                 case falsevar: i = 12; break;
  7338.                 case smallvar: i  = 14; break;
  7339.                 default: lexerr("unknown pseudo var %d", t.p);
  7340.                 }
  7341.             genhighlow(PUSHSPECIAL, i);
  7342.             nextlex();
  7343.             break;
  7344.  
  7345.         case PRIMITIVE:
  7346.             if (nextlex() != LITNUM) expect("primitive number");
  7347.             i = t.i;
  7348.             nextlex();
  7349.             count = 0;
  7350.             while (primary(0)) count++;
  7351.             if (token != PE) expect("primitive end");
  7352.             nextlex();
  7353.             genhighlow(SPECIAL, PRIMCMD);
  7354.             gencode(count);
  7355.             gencode(i);
  7356.             break;
  7357.  
  7358.         case LP:
  7359.             nextlex();
  7360.             expression();
  7361.             if (token != RP) expect("right parenthesis");
  7362.             nextlex();
  7363.             break;
  7364.  
  7365.         case LB:
  7366.             nextlex();
  7367.             block();
  7368.             break;
  7369.  
  7370.         default:
  7371.             if (must) expect("primary expression");
  7372.             return(0);
  7373.         }
  7374.     return(1);
  7375. }
  7376.  
  7377. static int maxtemps = 1;
  7378. static int temptop = 0;
  7379. static char *tempnames[20];
  7380.  
  7381. /* block - parse a block definition */
  7382. static block()
  7383. {    int count, i, position;
  7384.  
  7385.     count = 0;
  7386.     if (token == COLONVAR) {
  7387.         while (token == COLONVAR) {
  7388.             tempnames[temptop++] = t.c;
  7389.             if (temptop > maxtemps) maxtemps = temptop;
  7390.             count++;
  7391.             nextlex();
  7392.             }
  7393.         if (token != BAR)
  7394.             expect("bar following arguments in block");
  7395.         nextlex();
  7396.         }
  7397.     genhighlow(BLOCKCREATE, count);
  7398.     if (count)         /* where arguments go in context */
  7399.         gencode(1 + (temptop - count));    
  7400.     position = codetop;
  7401.     gencode(0);
  7402.  
  7403.     if (token == RB) {
  7404.         genhighlow(PUSHSPECIAL, 13);
  7405.         }
  7406.     else
  7407.         while (1) {
  7408.             i = aprimary();
  7409.             if (i >= 0) {
  7410.                 expression();
  7411.                 if (token != PERIOD)
  7412.                     genhighlow(SPECIAL, DUPSTACK);
  7413.                 genhighlow(POPINSTANCE, i);
  7414.                 }
  7415.             else {
  7416.                 cexpression();
  7417.                 if (token == PERIOD)
  7418.                     genhighlow(SPECIAL, POPSTACK);
  7419.                 }
  7420.             if (token != PERIOD)
  7421.                 break;
  7422.             nextlex();
  7423.             }
  7424.     genhighlow(SPECIAL, RETURN);
  7425.     if (token != RB) expect("end of block");
  7426.     temptop -= count;
  7427.     nextlex();
  7428.     i = (codetop - position) - 1;
  7429.     if (i > 255)
  7430.         lexerr("block too big %d", i);
  7431.     code[position] = itouc(i);
  7432. }
  7433.  
  7434. # define LITMAX 100
  7435. static object *lit_array[LITMAX];
  7436. static int littop = 0;
  7437.  
  7438. static int addliteral(lit)
  7439. object *lit;
  7440. {
  7441.     if (littop >= LITMAX)
  7442.         cant_happen(18);
  7443.     sassign(lit_array[littop++], lit);
  7444.     return(littop - 1);
  7445. }
  7446.  
  7447. /* aliteral - find a literal that is part of a literal array */
  7448. static int aliteral(must)
  7449. int must;    /* must we find something ? */
  7450. {    char *c;
  7451.     object *new;
  7452.     int count;
  7453.     int bytetop;
  7454.     uchar bytes[200];
  7455.  
  7456.     switch(token) {
  7457.         case MINUS:
  7458.             c = t.c;
  7459.             nextlex();
  7460.             if (token == LITNUM) {
  7461.                 new = new_int( - t.i );
  7462.                 nextlex();
  7463.                 }
  7464.             else if (token == LITFNUM) {
  7465.                 new = new_float( - t.f );
  7466.                 nextlex();
  7467.                 }
  7468.             else {
  7469.                 new = new_sym(c);
  7470.                 }
  7471.             break;
  7472.  
  7473.         case LITNUM:
  7474.             new = new_int(t.i);
  7475.             nextlex();
  7476.             break;
  7477.  
  7478.         case LITFNUM:
  7479.             new = new_float(t.f);
  7480.             nextlex();
  7481.             break;
  7482.  
  7483.         case LITCHAR:
  7484.             new = new_char(t.i);
  7485.             nextlex();
  7486.             break;
  7487.  
  7488.         case LITSTR:
  7489.             new = new_str(t.c);
  7490.             nextlex();
  7491.             break;
  7492.  
  7493.         case LITSYM:
  7494.             new = new_sym(t.c);
  7495.             nextlex();
  7496.             break;
  7497.  
  7498.         case PSEUDO:
  7499.             switch(t.p) {
  7500.                 case nilvar: new = o_nil; break;
  7501.                 case truevar: new = o_true; break;
  7502.                 case falsevar: new = o_false; break;
  7503.                 case smallvar: new = o_smalltalk; break;
  7504.                 default: lexerr("unknown peudo %d", t.p);
  7505.                 }
  7506.             nextlex();
  7507.             break;
  7508.  
  7509.         case PS:
  7510.             nextlex();
  7511.             if (token == LP) goto rdarray;
  7512.             else if (token == LB) {
  7513.                 bytetop = 0;
  7514.                 while (nextlex() == LITNUM)
  7515.                     bytes[bytetop++] = itouc(t.i);
  7516.                 if (token != RB)
  7517.                     expect("right bracket");
  7518.                 nextlex();
  7519.                 new = new_bytearray(bytes, bytetop);
  7520.                 }
  7521.             else expect("array or bytearray");
  7522.             break;
  7523.  
  7524.         case LP: rdarray:
  7525.             count = 0;
  7526.             nextlex();
  7527.             while (aliteral(0) >= 0) {
  7528.                 count++;
  7529.                 }
  7530.             if (token != RP) expect("right parenthesis");
  7531.             nextlex();
  7532.             new = new_array(count, 0);
  7533.             while (count)
  7534.                 new->inst_var[--count] = lit_array[--littop];
  7535.             break;
  7536.  
  7537.         case UPPERCASEVAR:
  7538.         case LOWERCASEVAR:
  7539.         case KEYWORD:
  7540.         case COLONVAR:
  7541.         case BINARY:
  7542.         case PE:
  7543.         case BAR:
  7544.         case SEMI:
  7545.             new = new_sym(t.c);
  7546.             nextlex();
  7547.             break;
  7548.  
  7549.         default:
  7550.             if (must)
  7551.                 expect("literal");
  7552.             else return( - 1 );
  7553.         }
  7554.     return(addliteral(new));
  7555. }
  7556.  
  7557. /* gensend - generate a message send */
  7558. static gensend(message, numargs)
  7559. char *message;
  7560. int  numargs;
  7561. {    int i;
  7562.     char **p, c;
  7563.     tok_type e;
  7564.  
  7565.     c = *message;
  7566.     if (numargs == 0) {
  7567.         for (p = unspecial, i = 0; *p; i++, p++)
  7568.             if ((**p == c) && (strcmp(*p, message) == 0)) {
  7569.                 genhighlow(UNSEND, i);
  7570.                 return;
  7571.                 }
  7572.         }
  7573.     else if (numargs == 1) {
  7574.         for (p = binspecial, i = 0; *p; i++, p++)
  7575.             if ((**p == c) && (strcmp(*p, message) == 0)) {
  7576.                 genhighlow(BINSEND, i);
  7577.                 return;
  7578.                 }
  7579.         for (p = arithspecial, i = 0; *p; i++, p++)
  7580.             if ((**p == c) && (strcmp(*p, message) == 0)) {
  7581.                 genhighlow(ARITHSEND, i);
  7582.                 return;
  7583.                 }
  7584.         }
  7585.     else if (numargs == 2) {
  7586.         for (p = keyspecial, i = 0; *p; i++, p++)
  7587.             if ((**p == c) && (strcmp(*p, message) == 0)) {
  7588.                 genhighlow(KEYSEND, i);
  7589.                 return;
  7590.                 }
  7591.         }
  7592.     genhighlow(SEND, numargs);
  7593.     gencode(addliteral(new_sym(message)));
  7594. }
  7595.  
  7596. static object *var_names;
  7597. static object *var_values;
  7598.  
  7599. extern object *o_nil, *o_true;
  7600.  
  7601. static int findvar(str, make)
  7602. char *str;
  7603. int make;
  7604. {  int i;
  7605.    object *comp_obj;
  7606.  
  7607.    sassign(comp_obj, new_obj((class *) 0, 2, 0));
  7608.    sassign(comp_obj->inst_var[0], o_nil);
  7609.    sassign(comp_obj->inst_var[1], new_sym(str));
  7610.    for (i = 0; i < var_names->size; i++) {
  7611.     assign(comp_obj->inst_var[0], var_names->inst_var[i]);
  7612.     if (o_true == primitive(SYMEQTEST, 2, &(comp_obj->inst_var[0]))) {
  7613.         obj_dec(comp_obj);
  7614.         return(i);
  7615.         }
  7616.     }
  7617.    /* not found, perhaps it's new */
  7618.    if (make) {
  7619.     assign(comp_obj->inst_var[0], var_names);
  7620.     assign(var_names, primitive(GROW, 2, &(comp_obj->inst_var[0])));
  7621.     assign(comp_obj->inst_var[0], var_values);
  7622.     assign(comp_obj->inst_var[1], o_nil);
  7623.     assign(var_values, primitive(GROW, 2, &(comp_obj->inst_var[0])));
  7624.     }
  7625.    else {
  7626.     lexerr("unknown variable %s", str);
  7627.     i = 0;
  7628.     }
  7629.    obj_dec(comp_obj);
  7630.    return(i);
  7631. }
  7632.  
  7633. genvar(name)
  7634. char *name;
  7635. {    int i;
  7636.  
  7637.     for (i = 0; i < temptop; i++)
  7638.         if (strcmp(name, tempnames[i]) == 0) {
  7639.             genhighlow(PUSHTEMP, i+1);
  7640.             return;
  7641.             }
  7642.     genhighlow(PUSHINSTANCE, findvar(name, 0));
  7643. }
  7644.  
  7645. /* lexerr - error printing with limited reformatting */
  7646. lexerr(s, v)
  7647. char *s, *v;
  7648. {
  7649.     char e1[500], e2[500];
  7650.     object *new;
  7651.  
  7652.     errflag = 1;
  7653.     sprintf(e1, s, v); /* format error message */
  7654.     sprintf(e2, "error: %s\n", e1);
  7655.     sassign(new, new_str(e2));
  7656.     primitive(ERRPRINT, 1, &new);
  7657.     obj_dec(new);
  7658. }
  7659.  
  7660. expect(str)
  7661. char *str;
  7662. {    char ebuf[150];
  7663.  
  7664.     /*fprintf(stderr,"expected %s\n", str);
  7665.     fprintf(stderr,"current token type %d\n", token);
  7666.     fprintf(stderr,"remainder of line %s\n", lexptr);
  7667.     fprintf(stderr,"current text %s\n", toktext);*/
  7668.     sprintf(ebuf,"expected %s found %s", str, toktext);
  7669.     lexerr(ebuf,"");
  7670. }
  7671.  
  7672. extern object *o_drive;    /* ``driver'' interpreter */
  7673.  
  7674. bld_interpreter()
  7675. {  interpreter *interp;
  7676.    object *literals, *bytecodes, *context;
  7677.    int i;
  7678.  
  7679.    if (codetop == 0) {
  7680.     return;
  7681.     }
  7682.    genhighlow(SPECIAL, SELFRETURN);
  7683.    gencode(0);            /* mark end of bytecodes */
  7684.    sassign(literals, new_array(littop, 0));
  7685.    for (i = 0; i < littop; i++)
  7686.     literals->inst_var[ i ] = lit_array[i];
  7687.    sassign(bytecodes, new_bytearray(code, codetop));
  7688.    sassign(context, new_obj((class *) 0, 1 + maxtemps, 1));
  7689.    interp = cr_interpreter((interpreter *) o_drive, var_values,
  7690.         literals, bytecodes, context);
  7691.    link_to_process(interp);
  7692.    obj_dec(context);
  7693.    obj_dec(bytecodes);
  7694.    obj_dec(literals);
  7695. }
  7696.  
  7697. reset(){
  7698.     codetop = littop = temptop = 0;
  7699.     maxtemps = 1;
  7700. }
  7701.  
  7702. /* drv_init initializes the driver, should be called only once */
  7703. drv_init() {
  7704.     sassign(var_names, new_obj((class *) 0, 0, 0));
  7705.     sassign(var_values, new_obj((class *) 0, 0, 0));
  7706.     reset();
  7707.     findvar("last", 1);     /* create variable "last" */
  7708.     }
  7709.  
  7710. drv_free() {
  7711.     int i;
  7712.  
  7713.     for (i = 0; i < var_values->size; i++)
  7714.         assign(var_values->inst_var[ i ], o_nil);
  7715.     obj_dec(var_names);
  7716.     obj_dec(var_values);
  7717.     }
  7718. End
  7719. echo unbundling lexcmd.c 1>&2
  7720. cat >lexcmd.c <<'End'
  7721. /*
  7722.     Little Smalltalk
  7723.         misc lexer related routines
  7724.         timothy a. budd 12/84
  7725. */
  7726. /*
  7727.     The source code for the Little Smalltalk System may be freely
  7728.     copied provided that the source of all files is acknowledged
  7729.     and that this condition is copied with each file.
  7730.  
  7731.     The Little Smalltalk System is distributed without responsibility
  7732.     for the performance of the program and without any guarantee of
  7733.     maintenance.
  7734.  
  7735.     All questions concerning Little Smalltalk should be addressed to:
  7736.  
  7737.         Professor Tim Budd
  7738.         Department of Computer Science
  7739.         Oregon State University
  7740.         Corvallis, Oregon
  7741.         97331
  7742.         USA
  7743. */
  7744. # include <stdio.h>
  7745. # include "env.h"
  7746. # include <ctype.h>
  7747.  
  7748. extern char toktext[];
  7749.  
  7750. /* dolexcommand - read a ) type directive, and process it */
  7751. dolexcommand(p)
  7752. char *p;
  7753. {       char *q, buffer[100];
  7754.  
  7755.     /* replace trailing newline with end of string */
  7756.     for (q = p; *q && *q != '\n'; q++);
  7757.     if (*q == '\n') *q = '\0';
  7758.  
  7759.         switch( *++p) {
  7760.            case '!':
  7761. # ifndef NOSYSTEM
  7762.         system(++p);
  7763. # endif
  7764.         break;
  7765.  
  7766.            case 'e': for (++p; isspace(*p); p++);
  7767.              if (! lexedit(p)) lexinclude(p);
  7768.                      break;
  7769.  
  7770.        case 'g': for (++p; isspace(*p); p++);
  7771.              sprintf(buffer,"%s/%s", LIBLOC, p);
  7772.              lexread(buffer);
  7773.              break;
  7774.  
  7775.            case 'i': for (++p; isspace(*p); p++);
  7776.                      lexinclude(p);
  7777.                      break;
  7778.  
  7779.            case 'r': for (++p; isspace(*p); p++);
  7780.                      lexread(p);
  7781.                      break;
  7782.  
  7783.        case 's': for(++p; isspace(*p); p++);
  7784.              dosave(p);
  7785.              break;
  7786.  
  7787.        case 'l': for(++p; isspace(*p); p++);
  7788.              doload(p);
  7789.              break;
  7790.  
  7791.            default:  lexerr("unknown command %s", toktext);
  7792.            }
  7793. }
  7794.  
  7795. /* doload/dosave routines written by nick buchholz */
  7796. /*
  7797.     doload and dosave routines make the following assumptions
  7798.     1. version is the first global variable declared in main.
  7799.     2. main is the first procedure seen by the loader
  7800.     3. the loader allocates memory in the order it sees the procedures
  7801.     4. memory is laid out as on the vax 780 under 4.2
  7802.  
  7803.     on other machines any or all of these might be false and the
  7804.     doload/dosave routines will not work
  7805. */
  7806. extern int version;
  7807.  
  7808. dosave(p) char *p;{
  7809.     int fd;
  7810.     char *start, *end, *sbrk();
  7811.     unsigned int length, len;
  7812.     int dlen;
  7813.  
  7814. # ifdef OPEN3ARG
  7815.     if ((fd = open(p, O_WRONLY|O_CREAT|O_TRUNC, 0666)) == -1)
  7816. # endif
  7817. # ifndef OPEN3ARG
  7818.     if ((fd = creat(p, 0666)) == -1)
  7819. # endif
  7820.        fprintf(stderr,"can't open: %s\n",p);
  7821.  
  7822.     start = (char *) &version;
  7823.     end = sbrk(0);
  7824.     length = end - start;
  7825.  
  7826.     write(fd, &version, sizeof(int));
  7827.     write(fd, &start, sizeof(char *));
  7828.     write(fd, &length, sizeof(unsigned int));
  7829.  
  7830.     for (len = 0; len < length; len += dlen) {
  7831.     dlen = ((length - len) > 512) ? 512 : (length - len);
  7832.     if (dlen != write(fd, start + len, dlen)) {
  7833.         cant_happen(23);
  7834.         }
  7835.     }
  7836.  
  7837.     fprintf(stderr,"%u bytes written\n",len);
  7838.  
  7839.     close(fd);
  7840. }
  7841.  
  7842. # ifdef ENVSAVE
  7843. extern char **environ;
  7844. # endif
  7845.  
  7846. doload(p) char *p;{
  7847.     int fd;
  7848.     char *start, *end, *brk();
  7849.     unsigned int length, len;
  7850.     int dlen;
  7851.     int test;
  7852. # ifdef ENVSAVE
  7853.     char **evsave;
  7854. # endif
  7855.  
  7856. # ifdef OPEN3ARG
  7857.     if ((fd = open(p, O_RDONLY, 0)) == -1)
  7858. # endif
  7859. # ifndef OPEN3ARG
  7860.     if ((fd = open(p, 0 )) == -1)
  7861. # endif
  7862.     fprintf(stderr,"no such context as: %s\n", p);
  7863.  
  7864.     else {
  7865.     read(fd, &test, sizeof(int));
  7866.     read(fd, &start, sizeof(char *));
  7867.     read(fd, &length, sizeof(unsigned int));
  7868.  
  7869.     if ((test != version) || (start != (char *) &version))
  7870.         fprintf(stderr,"%s: not a valid context file for version %d\n",
  7871.                 p, version);
  7872.     else {
  7873.         start = (char *) &version;
  7874.         end = brk(start + length + 1);
  7875. # ifdef ENVSAVE
  7876.         evsave = environ;
  7877. # endif
  7878.  
  7879.             for (len = 0; len < length; len += dlen) {
  7880.         dlen = ((length - len) > 512) ? 512 : (length - len);
  7881.         if (dlen != read(fd, start + len, dlen)) {
  7882.             cant_happen(23);
  7883.             }
  7884.         }
  7885. # ifdef ENVSAVE
  7886.        environ = evsave;
  7887. # endif
  7888.         fprintf(stderr,"%u bytes read\n",len);
  7889.     }
  7890.     close(fd);
  7891.     }
  7892. }
  7893.  
  7894. /* lexread - read commands from a file */
  7895. lexread(name)
  7896. char *name;
  7897. {    FILE *fd;
  7898.  
  7899.     fd = fopen(name, "r");
  7900.     if (fd == NULL) {
  7901.         fprintf(stderr,"can't open %s\n", name);
  7902.         }
  7903.     else {
  7904.         set_file(fd);
  7905.         }
  7906. }
  7907.  
  7908. /* lexinclude - parse a class and include the class description */
  7909. lexinclude(name)
  7910. char *name;
  7911. {  char template[60], cmdbuf[120];
  7912.    int  i;
  7913.  
  7914. # ifndef NOSYSTEM
  7915.    gettemp(template);
  7916.    sprintf(cmdbuf,"%s %s >%s", PARSER, name, template);
  7917.    i = system(cmdbuf);
  7918.    if (i == 0)
  7919.        lexread(template);
  7920. # endif
  7921. # ifdef NOSYSTEM
  7922.    fprintf(stderr,")i does not work on this system\n");
  7923. # endif
  7924. }
  7925.  
  7926. /* lexedit - edit a class description */
  7927. int lexedit(name)
  7928. char *name;
  7929. {    char *e, buffer[100], *getenv();
  7930.  
  7931. # ifndef NOSYSTEM
  7932.     e = getenv("EDITOR");
  7933.     if (!e) e = "ed";
  7934.     sprintf(buffer,"%s %s", e, name);
  7935.     return(system(buffer));
  7936. # endif
  7937. # ifdef NOSYSTEM
  7938.     fprintf(stderr,")e does not work on this system\n");
  7939.     return(1);
  7940. # endif
  7941. }
  7942. End
  7943.