home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 018.lha / sources / primitive.c < prev    next >
C/C++ Source or Header  |  1986-10-19  |  34KB  |  1,387 lines

  1. /* 
  2.     Little Smalltalk
  3.  
  4.     Primitive manager
  5.     timothy a. budd
  6.     10/84
  7.  
  8.         hashcode code written by Robert McConeghy
  9.             (who also wrote classes Dictionary, et al).
  10. */
  11. /*
  12.     The source code for the Little Smalltalk System may be freely
  13.     copied provided that the source of all files is acknowledged
  14.     and that this condition is copied with each file.
  15.  
  16.     The Little Smalltalk System is distributed without responsibility
  17.     for the performance of the program and without any guarantee of
  18.     maintenance.
  19.  
  20.     All questions concerning Little Smalltalk should be addressed to:
  21.  
  22.         Professor Tim Budd
  23.         Department of Computer Science
  24.         The University of Arizona
  25.         Tucson, Arizona
  26.         85721
  27.         USA
  28. */
  29.  
  30. # include "object.h"
  31.  
  32. # ifdef CURSES
  33. # include <curses.h>
  34. # endif
  35.  
  36. # include <stdio.h>
  37. # include <ctype.h>
  38. # include <math.h>
  39. # include <errno.h>
  40. # include "drive.h"
  41. # include "interp.h"
  42. # include "process.h"
  43. # include "block.h"
  44. # include "string.h"
  45. # include "symbol.h"
  46. # include "number.h"
  47. # include "file.h"
  48. # include "byte.h"
  49. # include "primitive.h"
  50.  
  51. extern int errno;
  52. extern int prntcmd;
  53. extern double modf();
  54. extern long time();
  55. extern char *ctime();
  56. extern object *lookup_class();
  57. extern process *runningProcess;
  58. extern int responds_to(), generality();
  59. extern class  *mk_class();
  60. extern object *o_object, *o_true, *o_false, *o_nil, *o_number, *o_magnitude;
  61.  
  62. object *primitive(primnumber, numargs, args)
  63. int primnumber, numargs;
  64. object **args;
  65. {    object *resultobj;
  66.     object *leftarg, *rightarg, *fnd_class(), *fnd_super();
  67.     int    leftint, rightint, i, j;
  68.     double leftfloat, rightfloat;
  69.     long   clock;
  70.     char   *leftp, *rightp, *errp;
  71.     class  *aClass;
  72.     bytearray *byarray;
  73.     struct file_struct *phil;
  74.     int    opnumber = primnumber % 10;
  75.     char   strbuffer[300], tempname[100];
  76.  
  77.     errno = 0;
  78.     /* first do argument type checking */
  79.     switch(i = (primnumber / 10)) {
  80.         case 0: /* misc operations */
  81.             if (opnumber <= 5 && numargs != 1) goto argcerror;
  82.             leftarg = args[0];
  83.             break;
  84.  
  85.         case 1: /* integer operations */
  86.         case 2: 
  87.             if (numargs != 2) goto argcerror;
  88.             rightarg = args[1];
  89.             if (! is_integer(rightarg)) goto argterror;
  90.             rightint = int_value(rightarg);
  91.         case 3: 
  92.             if (i == 3 && opnumber && numargs != 1) 
  93.                 goto argcerror;
  94.             leftarg = args[0];
  95.             if (! is_integer(leftarg)) goto argterror;
  96.             leftint = int_value(leftarg);
  97.             break;
  98.  
  99.         case 4: /* character operations */
  100.             if (numargs != 2) goto argcerror;
  101.             rightarg = args[1];
  102.             if (! is_character(rightarg)) goto argterror;
  103.             rightint = int_value(rightarg);
  104.         case 5: 
  105.             if (i == 5 && numargs != 1) goto argcerror;
  106.             leftarg = args[0];
  107.             if (! is_character(leftarg)) goto argterror;
  108.             leftint = int_value(leftarg);
  109.             break;
  110.  
  111.         case 6: /* floating point operations */
  112.             if (numargs != 2) goto argcerror;
  113.             rightarg = args[1];
  114.             if (! is_float(rightarg)) goto argterror;
  115.             rightfloat = float_value(rightarg);
  116.         case 7: 
  117.             if (i == 7 && numargs != 1) goto argcerror;
  118.         case 8:
  119.             if (i == 8 && opnumber < 8 && numargs != 1) 
  120.                 goto argcerror;
  121.             leftarg = args[0];
  122.             if (! is_float(leftarg)) goto argterror;
  123.             leftfloat = float_value(leftarg);
  124.             break;
  125.  
  126.         case 9: /* symbol operations */
  127.             leftarg = args[0];
  128.             if (! is_symbol(leftarg)) goto argterror;
  129.             leftp = symbol_value(leftarg);
  130.             break;
  131.  
  132.         case 10: /* string operations */
  133.             if (numargs < 1) goto argcerror;
  134.             leftarg = args[0];
  135.             if (! is_string(leftarg)) goto argterror;
  136.             leftp = string_value(leftarg);
  137.             if (opnumber && opnumber <= 3) {
  138.                 if (numargs != 2) goto argcerror;
  139.                 rightarg = args[1];
  140.                 if (! is_string(rightarg)) goto argterror;
  141.                 rightp = string_value(rightarg);
  142.                 }
  143.             else if ((opnumber >= 4) && (opnumber <= 6)) {
  144.                 if (numargs < 2) goto argcerror;
  145.                 if (! is_integer(args[1])) goto argterror;
  146.                 i = int_value(args[1])-1;
  147.                 if ((i < 0) || (i >= strlen(leftp)))
  148.                     goto indexerror;
  149.                 }
  150.             else if ((opnumber >= 7) && (numargs != 1))
  151.                 goto argcerror;
  152.             break;
  153.  
  154.         case 11: /* misc operations */
  155.             if ((opnumber == 1) || (opnumber == 2)) {
  156.                 if (is_bltin(args[0])) goto argterror;
  157.                 if (numargs < 2) goto argcerror;
  158.                 if (! is_integer(args[1])) goto argterror;
  159.                 i = int_value(args[1]);
  160.                 if (i < 1 || i > args[0]->size)
  161.                     goto indexerror;
  162.                 }
  163.             else if ((opnumber >= 4) && (opnumber <= 6)) {
  164.                 if (numargs != 1) goto argcerror;
  165.                 if (! is_integer(args[0])) goto argterror;
  166.                 i = int_value(args[0]);
  167.                 if (i < 0) goto indexerror;
  168.                 }
  169.             else if (opnumber >= 7) {
  170.                 if (numargs < 1) goto argcerror;
  171.                 if (! is_bytearray(args[0])) goto argterror;
  172.                 byarray = (bytearray *) args[0];
  173.                 if (opnumber >= 8) {
  174.                     if (numargs < 2) goto argcerror;
  175.                     if (! is_integer(args[1]))
  176.                         goto argterror;
  177.                     i = int_value(args[1]) - 1;
  178.                     if (i < 0 || i >= byarray->a_bsize)
  179.                         goto indexerror;
  180.                     }
  181.                 }
  182.             break;
  183.  
  184.         case 12: /* string i/o operations */
  185.             if (opnumber < 6) {
  186.                 if (numargs < 1) goto argcerror;
  187.                 leftarg = args[0];
  188.                 if (! is_string(leftarg)) goto argterror;
  189.                 leftp = string_value(leftarg);
  190.                 }
  191.             break;
  192.  
  193.         case 13: /* operations on file */
  194.             if (numargs < 1) goto argcerror;
  195.             if (! is_file(args[0])) goto argterror;
  196.             phil = (struct file_struct *) args[0];
  197.             if (opnumber && (phil->fp == (FILE *) NULL)) {
  198.                 errp = "file must be open for operation";
  199.                 goto return_error;
  200.                 }
  201.             break;
  202.  
  203.         case 15: /* operations on classes */
  204.             if (opnumber < 3 && numargs != 1) goto argcerror;
  205.             if (! is_class(args[0])) goto argterror;
  206.             aClass = (class *) args[0];
  207.             break;
  208.  
  209. # ifdef PLOT3
  210.         case 17: /* plot(3) interface */
  211.             if (opnumber && opnumber <= 3) {
  212.                 if (numargs != 2) goto argcerror;
  213.                 if ((! is_integer(args[0])) || 
  214.                     (! is_integer(args[1])))
  215.                     goto argterror;
  216.                 leftint = int_value(args[0]);
  217.                 rightint = int_value(args[1]);
  218.                 }
  219.             else if ((opnumber == 6) || (opnumber == 7)) {
  220.                 if (numargs != 4) goto argcerror;
  221.                 for (i = 0; i < 4; i++)
  222.                     if (! is_integer(args[i]))
  223.                         goto argterror;
  224.                 leftint = int_value(args[0]);
  225.                 rightint = int_value(args[1]);
  226.                 i = int_value(args[2]);
  227.                 j = int_value(args[3]);
  228.                 }
  229.             else if (opnumber >= 8) {
  230.                 if (numargs != 1) goto argcerror;
  231.                 if (! is_string(args[0])) goto argterror;
  232.                 leftp = string_value(args[0]);
  233.                 }
  234.             break;
  235. # endif
  236.         }
  237.  
  238.  
  239.     /* now do operation */
  240.     switch(primnumber) {
  241.  
  242.         case 1:        /* class of object */
  243.             resultobj = fnd_class(args[0]);
  244.             if (resultobj) goto return_obj;
  245.             else goto return_nil;
  246.  
  247.         case 2:        /* get super_object */
  248.             resultobj = fnd_super(args[0]);
  249.             if (resultobj) goto return_obj;
  250.             else goto return_nil;
  251.  
  252.         case 3:        /* see if class responds to new */
  253.             leftint = 0;
  254.             if (! is_class(args[0])) goto return_boolean;
  255.             leftint = responds_to("new", (class *) args[0]);
  256.             goto return_boolean;
  257.  
  258.         case 4:        /* compute size of object */
  259.             leftint = args[0]->size;
  260.             goto return_integer;
  261.  
  262.         case 5:        /* return hashnum of object */
  263.             if (is_integer(leftarg))
  264.                 leftint = int_value(leftarg);
  265.             else if (is_character(leftarg))
  266.                 leftint = int_value(leftarg);
  267.             else if (is_symbol(leftarg))
  268.                 leftint = (int) symbol_value(leftarg);
  269.             else if (is_string(leftarg)) {
  270.                 leftp = string_value(leftarg);
  271.                 leftint = 0;
  272.                 for(i = 0; *leftp != 0; leftp++){
  273.                     leftint += *leftp;
  274.                     i++;
  275.                     if(i > 5)
  276.                        break;
  277.                     }
  278.                 }
  279.             else /* for all other objects return address */
  280.                 leftint = (int) &leftarg;
  281.             if (leftint < 0)
  282.                 leftint = -leftint;
  283.             goto return_integer;
  284.  
  285.         case 6:        /* built in object type testing */
  286.             if (numargs != 2) goto argcerror;
  287.             leftint = (args[0]->size == args[1]->size);
  288.             goto return_boolean;
  289.  
  290.         case 7:        /* object equality testing */
  291.             if (numargs != 2) goto argcerror;
  292.             leftint = (args[0] == args[1]);
  293.             goto return_boolean;
  294.  
  295.         case 8:        /* toggle debugging flag */
  296.             if (numargs == 0) {
  297.                 debug = 1 - debug;
  298.                 goto return_nil;
  299.                 }
  300.             if (numargs != 2) goto argcerror;
  301.             if (! is_integer(args[0])) goto argterror;
  302.             if (! is_integer(args[1])) goto argterror;
  303.             leftint = int_value(args[0]);
  304.             rightint = int_value(args[1]);
  305.             switch(leftint) {
  306.                 case 1: prntcmd = rightint; break;
  307.                 case 2: debug = rightint; break;
  308.                 }
  309.             goto return_nil;
  310.  
  311.         case 9:        /* numerical generality comparison */
  312.             if (numargs != 2) goto argcerror;
  313.             leftint = 
  314.                 (generality(args[0]) > generality(args[1]));
  315.             goto return_boolean;
  316.  
  317.         case 10:    /* integer addition */
  318.             leftint += rightint;
  319.             goto return_integer;
  320.  
  321.         case 11:    /* integer subtraction */
  322.             leftint -= rightint;
  323.             goto return_integer;
  324.  
  325.         case 12: case 42:
  326.             leftint = (leftint < rightint);
  327.             goto return_boolean;
  328.  
  329.         case 13: case 43:
  330.             leftint = (leftint > rightint);
  331.             goto return_boolean;
  332.  
  333.         case 14: case 44:
  334.             leftint = (leftint <= rightint);
  335.             goto return_boolean;
  336.  
  337.         case 15: case 45:
  338.             leftint = (leftint >= rightint);
  339.             goto return_boolean;
  340.  
  341.         case 16: case 46:
  342.             leftint = (leftint == rightint);
  343.             goto return_boolean;
  344.  
  345.         case 17: case 47:
  346.             leftint = (leftint != rightint);
  347.             goto return_boolean;
  348.  
  349.         case 18:
  350.             leftint *= rightint;
  351.             goto return_integer;
  352.  
  353.         case 19:    /* // integer */
  354.             if (rightint == 0) goto numerror;
  355.             i  = leftint / rightint;
  356.             if ((leftint < 0) && (leftint % rightint))
  357.                 i -= 1;
  358.             leftint = i;
  359.             goto return_integer;
  360.  
  361.         case 20:    /* gcd of two integers */
  362.             if (leftint == 0 || rightint == 0) goto numerror;
  363.             if (leftint < 0) leftint = -leftint;
  364.             if (rightint < 0) rightint = -rightint;
  365.             if (leftint > rightint) 
  366.                 {i = leftint; leftint = rightint; rightint = i;}
  367.             while (i = rightint % leftint)
  368.                 {rightint = leftint; leftint = i;}
  369.             goto return_integer;
  370.             
  371.         case 21:    /* bitAt: */
  372.             leftint = (leftint & (1 << rightint)) ? 1 : 0;
  373.             goto return_integer;
  374.  
  375.         case 22:    /* logical bit-or */
  376.             leftint |= rightint;
  377.             goto return_integer;
  378.  
  379.         case 23:    /* logical bit-and */
  380.             leftint &= rightint;
  381.             goto return_integer;
  382.  
  383.         case 24:    /* logical bit-exclusive or */
  384.             leftint ^= rightint;
  385.             goto return_integer;
  386.  
  387.         case 25:    /* bit shift */
  388.             if (rightint < 0)
  389.                 leftint >>= - rightint;
  390.             else
  391.                 leftint <<= rightint;
  392.             goto return_integer;
  393.  
  394.         case 26:    /* integer radix */
  395.             if (rightint < 2 || rightint > 36) goto numerror;
  396.             prnt_radix(leftint, rightint, strbuffer);
  397.             goto return_string;
  398.  
  399.         case 28:
  400.             if (rightint == 0) goto numerror;
  401.             leftint /= rightint;
  402.             goto return_integer;
  403.  
  404.         case 29:
  405.             if (rightint == 0) goto numerror;
  406.             leftint %= rightint;
  407.             goto return_integer;
  408.  
  409.         case 30:    /* doPrimitive:withArguments: */
  410.             if (numargs != 2) goto argcerror;
  411.             resultobj = primitive(leftint, args[1]->size, 
  412.                 &args[1]->inst_var[0]);
  413.             goto return_obj;
  414.  
  415.         case 32:    /* convert random int into random float */
  416. printf(" 32=%d ",leftint);
  417.             leftfloat = ((double)leftint)/32768.;
  418.         /* WMK - was ((double) ((leftint/10) % 1000)) / 1000.0; */
  419.             goto return_float;
  420.  
  421.         case 33:    /* bit inverse */
  422.             leftint ^= -1;
  423.             goto return_integer;
  424.  
  425.         case 34:    /* highBit */
  426.             rightint = leftint;
  427.             for (leftint = 32; leftint >= 0; leftint--)
  428.                 if (rightint & (1 << leftint))
  429.                     goto return_integer;
  430.             goto return_nil;
  431.  
  432.         case 35:    /* random number */
  433.             srand(leftint);
  434.             leftint = rand(leftint);
  435. printf("leftint=%d",leftint);
  436.             goto return_integer;
  437.  
  438.         case 36:    /* convert integer to character */
  439.             goto return_character;
  440.  
  441.         case 37:    /* convert integer to string */
  442.             sprintf(strbuffer,"%d", leftint);
  443.             goto return_string;
  444.  
  445.         case 38:    /* factorial */
  446.             if (leftint < 0) goto numerror;
  447.             if (leftint < FACTMAX) {
  448.                 for (i = 1; leftint; leftint--)
  449.                     i *= leftint;
  450.                 leftint = i;
  451.                 goto return_integer;
  452.                 }
  453. # ifndef GAMMA
  454.             /* gamma not supported, use float multiply */
  455.             leftfloat = 1.0;
  456.             if (leftint < 30) {
  457.                 for (i = 1; leftint; leftint--)
  458.                     leftfloat *= leftint;
  459.                 }
  460.             goto return_float;
  461. # endif
  462. # ifdef GAMMA
  463.             /* compute gamma */
  464.             leftfloat = (double) (leftint + 1);
  465.             sassign(leftarg, new_float(leftfloat));
  466.             resultobj = primitive(GAMMAFUN, 1, &leftarg);
  467.             obj_dec(leftarg);
  468.             goto return_obj;
  469. # endif
  470.  
  471.         case 39:    /* convert integer to float */
  472.             leftfloat = (double) leftint;
  473.             goto return_float;
  474.  
  475.         case 50:    /* digitValue */
  476.             if (isdigit(leftint))
  477.                 leftint -= '0';
  478.             else if (isupper(leftint)) {
  479.                 leftint -= 'A';
  480.                 leftint += 10;
  481.                 }
  482.             else goto return_nil;
  483.             goto return_integer;
  484.  
  485.         case 51:
  486.             if (isupper(leftint)) leftint += 'a' - 'A';
  487.             leftint = (leftint == 'a') || (leftint == 'e') ||
  488.                   (leftint == 'i') || (leftint == 'o') ||
  489.                   (leftint == 'u');
  490.             goto return_boolean;
  491.  
  492.         case 52:
  493.             leftint = isalpha(leftint);
  494.             goto return_boolean;
  495.  
  496.         case 53:
  497.             leftint = islower(leftint);
  498.             goto return_boolean;
  499.  
  500.         case 54:
  501.             leftint = isupper(leftint);
  502.             goto return_boolean;
  503.  
  504.         case 55:
  505.             leftint = isspace(leftint);
  506.             goto return_boolean;
  507.  
  508.         case 56:
  509.             leftint = isalnum(leftint);
  510.             goto return_boolean;
  511.  
  512.         case 57:
  513.             if (isupper(leftint)) leftint += 'a' - 'A';
  514.             else if (islower(leftint)) leftint += 'A' - 'a';
  515.             goto return_character;
  516.  
  517.         case 58:    /* convert character to string */
  518.             sprintf(strbuffer,"%c", leftint);
  519.             goto return_string;
  520.  
  521.         case 59:    /* convert character to integer */
  522.             goto return_integer;
  523.  
  524.         case 60:    /* floating point addition */
  525.             leftfloat += rightfloat;
  526.             goto return_float;
  527.  
  528.         case 61:    /* floating point subtraction */
  529.             leftfloat -= rightfloat;
  530.             goto return_float;
  531.  
  532.         case 62:
  533.             leftint = (leftfloat < rightfloat);
  534.             goto return_boolean;
  535.  
  536.         case 63:
  537.             leftint = (leftfloat > rightfloat);
  538.             goto return_boolean;
  539.  
  540.         case 64:
  541.             leftint = (leftfloat <= rightfloat);
  542.             goto return_boolean;
  543.  
  544.         case 65:
  545.             leftint = (leftfloat >= rightfloat);
  546.             goto return_boolean;
  547.  
  548.         case 66:
  549.             leftint = (leftfloat == rightfloat);
  550.             goto return_boolean;
  551.  
  552.         case 67:
  553.             leftint = (leftfloat != rightfloat);
  554.             goto return_boolean;
  555.  
  556.         case 68:
  557.             leftfloat *= rightfloat;
  558.             goto return_float;
  559.  
  560.         case 69:
  561.             if (rightfloat == 0) goto numerror;
  562.             leftfloat /= rightfloat;
  563.             goto return_float;
  564.  
  565.         case 70:
  566.             leftfloat = log(leftfloat);
  567.             goto float_check;
  568.  
  569.         case 71:
  570.             if (leftfloat < 0) goto numerror;
  571.             leftfloat = sqrt(leftfloat);
  572.             goto float_check;
  573.  
  574.         case 72:
  575.             leftint = (int) floor(leftfloat);
  576.             goto return_integer;
  577.  
  578.         case 73:    /* ceiling */
  579.             leftint = (int) ceil(leftfloat);
  580.             goto return_integer;
  581.  
  582.         case 75:    /* integer part */
  583.             leftfloat = modf(leftfloat, &rightfloat);
  584.             leftint = (int) rightfloat;
  585.             goto return_integer;
  586.  
  587.         case 76:    /* fractional part */
  588.             leftfloat = modf(leftfloat, &rightfloat);
  589.             goto return_float;
  590.  
  591.         case 77:    /* gamma function */
  592. # ifdef GAMMA
  593.             leftfloat = gamma(leftfloat);
  594.             if (leftfloat > 88.0) goto numerror;
  595.             leftfloat = exp(leftfloat);
  596.             goto float_check;
  597. # endif
  598. # ifndef GAMMA
  599.             errp = "gamma function";
  600.             goto not_implemented;
  601. # endif
  602.  
  603.         case 78:
  604.             sprintf(strbuffer,"%g", leftfloat);
  605.             goto return_string;
  606.  
  607.         case 79:
  608.             leftfloat = exp(leftfloat);
  609.             goto return_float;
  610.  
  611.         case 80:    /* normalize radian value */
  612. # define TWOPI (double) 6.2831853072
  613.             rightfloat = 
  614.             floor(((leftfloat < 0) ? -leftfloat:leftfloat) / TWOPI);
  615.             if (leftfloat < 0)
  616.                 leftfloat += (1 + rightfloat) * TWOPI;
  617.             else
  618.                 leftfloat -= rightfloat * TWOPI;
  619.             goto return_float;
  620.  
  621.         case 81:
  622.             leftfloat = sin(leftfloat);
  623.             goto float_check;
  624.  
  625.         case 82:
  626.             leftfloat = cos(leftfloat);
  627.             goto float_check;
  628.  
  629.         case 84:
  630.             leftfloat = asin(leftfloat);
  631.             goto float_check;
  632.  
  633.         case 85:
  634.             leftfloat = acos(leftfloat);
  635.             goto float_check;
  636.  
  637.         case 86:
  638.             leftfloat = atan(leftfloat);
  639.             goto float_check;
  640.  
  641.         case 88:
  642.             if (numargs != 2) goto argcerror;
  643.             if (! is_float(args[1])) goto argterror;
  644.             leftfloat = pow(leftfloat, float_value(args[1]));
  645.             goto float_check;
  646.  
  647.         case 89:    /* floating point radix */
  648.             if (numargs != 2) goto argcerror;
  649.             if (! is_integer(args[1])) goto argterror;
  650.             i = int_value(args[1]); /* base */
  651.             if (i < 2 || i > 36) goto numerror;
  652.             fprnt_radix(leftfloat, i, strbuffer);
  653.             goto return_string;
  654.  
  655.         case 91:    /* symbol comparison */
  656.             if (numargs != 2) goto argcerror;
  657.             if (! is_symbol(args[1])) goto argterror;
  658.             leftint = (leftp == symbol_value(args[1]));
  659.             goto return_boolean;
  660.  
  661.         case 92:    /* symbol printString */
  662.             sprintf(strbuffer, "#%s", leftp);
  663.             goto return_string;
  664.  
  665.         case 93:    /* symbol asString */
  666.             sprintf(strbuffer, "%s", leftp);
  667.             goto return_string;
  668.  
  669.         case 94:    /* symbol print ( with tabs) */
  670.             if (numargs == 2) {
  671.                 if (! is_integer(args[1])) goto argterror;
  672.                 for (i = int_value(args[1]); i >= 0; i--)
  673.                     putchar('\t');
  674.             }
  675.             printf("%s\n", leftp);
  676. # ifdef FLUSHREQ
  677.             fflush(stdout);
  678. # endif
  679.             goto return_nil;
  680.  
  681.         case 96:
  682.             goto return_nil;
  683.  
  684.         case 97:    /* make a new class (generated by parser)*/
  685.             if (numargs != 8) goto argcerror;
  686.             if (! is_symbol(args[1])) goto argterror;
  687.             if (! is_symbol(args[2])) goto argterror;
  688.             if (! is_integer(args[6])) goto argterror;
  689.             if (! is_integer(args[7])) goto argterror;
  690.             resultobj = (object *) mk_class(leftp, args);
  691.             goto return_obj;
  692.  
  693.         case 98:    /* install class in dictionary */
  694.             if (numargs != 2) goto argcerror;
  695.             if (! is_class(args[1])) goto argterror;
  696.             enter_class(leftp, args[1]);
  697.             goto return_nil;
  698.  
  699.         case 99:    /* find a class in class dictionary */
  700.             if (numargs != 1) goto argcerror;
  701.             resultobj = lookup_class(leftp);
  702.             if (resultobj == (object *) 0) {
  703.                 sprintf(strbuffer,"cannot find class %s",
  704.                 leftp);
  705.                 sassign(resultobj, new_str(strbuffer));
  706.                 primitive(ERRPRINT, 1, &resultobj);
  707.                 obj_dec(resultobj);
  708.                 resultobj = lookup_class("Object");
  709.                 if (! resultobj) cant_happen(7);
  710.                 }
  711.             goto return_obj;
  712.  
  713.         case 100:    /* string length */
  714.             leftint = strlen(leftp);
  715.             goto return_integer;
  716.  
  717.         case 101:     /* string compare, case dependent */
  718.             leftint = strcmp(leftp, rightp);
  719.             goto return_integer;
  720.  
  721.         case 102:    /* string compare, case independent */
  722.             leftint = 1;
  723.             while (*leftp || *rightp) {
  724.                 i = *leftp++;
  725.                 j = *rightp++;
  726.                 if (i >= 'A' && i <= 'Z')
  727.                     i = i - 'A' + 'a';
  728.                 if (j >= 'A' && j <= 'Z')
  729.                     j = j - 'A' + 'a';
  730.                 if (i != j) {leftint = 0; break;}
  731.                 }
  732.             goto return_boolean;
  733.  
  734.         case 103:     /* string catenation */
  735.             for (i = leftint = 0; i < numargs; i++) {
  736.                 if (! is_string(args[i])) goto argterror;
  737.                 leftint += strlen(string_value(args[i]));
  738.                 }
  739.             errp = (char *) o_alloc((unsigned) (1 + leftint));
  740.             *errp = '\0';
  741.             for (i = 0; i < numargs; i++)
  742.                 strcat(errp, string_value(args[i]));
  743.             resultobj = (object *) new_istr(errp);
  744.             goto return_obj;
  745.  
  746.         case 104:    /* string at: */
  747.             if (numargs != 2) goto argcerror;
  748.             leftint = leftp[i];
  749.             goto return_character;
  750.  
  751.         case 105:    /* string at: put: */
  752.             if (numargs != 3) goto argcerror;
  753.             if (! is_character(args[2])) goto argterror;
  754.             leftp[i] = int_value(args[2]);
  755.             goto return_nil;
  756.  
  757.         case 106:    /* copyFrom: length: */
  758.             if (numargs != 3) goto argcerror;
  759.             if (! is_integer(args[2])) goto argterror;
  760.             j = int_value(args[2]);
  761.             if (j < 0) goto indexerror;
  762.             for (rightp = strbuffer; j; j--, i++)
  763.                 *rightp++ = leftp[i];
  764.             *rightp = '\0';
  765.             goto return_string;
  766.  
  767.         case 107:    /* string copy */
  768.             resultobj = new_str(leftp);
  769.             goto return_obj;
  770.  
  771.         case 108:    /* string asSymbol */
  772.             resultobj = new_sym(leftp);
  773.             goto return_obj;
  774.  
  775.         case 109:    /* string printString */
  776.             sprintf(strbuffer,"\'%s\'", leftp);
  777.             goto return_string;
  778.  
  779.         case 110:    /* new untyped object */
  780.             if (numargs != 1) goto argcerror;
  781.             if (! is_integer(args[0])) goto argterror;
  782.             leftint = int_value(args[0]);
  783.             if (leftint < 0) goto numerror;
  784.             resultobj = new_obj((class *) 0, leftint, 1);
  785.             goto return_obj;
  786.  
  787.         case 111:    /* object at: */
  788.             if (numargs != 2) goto argcerror;
  789.             resultobj = args[0]->inst_var[ i - 1 ];
  790.             goto return_obj;
  791.  
  792.         case 112:    /* object at:put: */
  793.             if (numargs != 3) goto argcerror;
  794.             assign(args[0]->inst_var[i - 1], args[2]);
  795.             goto return_nil;
  796.  
  797.         case 113:    /*  object grow */
  798.             leftarg = args[0];
  799.             rightarg = args[1];
  800.             if (is_bltin(leftarg)) goto argterror;
  801.             resultobj = new_obj(leftarg->class,
  802.                 leftarg->size+1, 0);
  803.             if (leftarg->super_obj)
  804.                 sassign(resultobj->super_obj,
  805.                     leftarg->super_obj);
  806.             for (i = 0; i < leftarg->size; i++)
  807.                 sassign(resultobj->inst_var[i], leftarg->inst_var[i]);
  808.             sassign(resultobj->inst_var[i], rightarg);
  809.             goto return_obj;
  810.  
  811.  
  812.         case 114:    /* new array */
  813.             resultobj = new_array(i, 1);
  814.             goto return_obj;
  815.  
  816.         case 115:    /* new string */
  817.             for (j = 0; j < i; j++)
  818.                 strbuffer[j] = ' ';
  819.             strbuffer[j] = '\0';
  820.             goto return_string;
  821.  
  822.         case 116:    /* bytearray new */
  823.             /* initialize with random garbage */
  824.             resultobj = new_bytearray(strbuffer, i);
  825.             goto return_obj;
  826.  
  827.         case 117:    /* bytearray size */
  828.             if (numargs != 1) goto argcerror;
  829.             leftint = byarray->a_bsize;
  830.             goto return_integer;
  831.  
  832.         case 118:    /* bytearray at: */
  833.             if (numargs != 2) goto argcerror;
  834.             leftint = uctoi(byarray->a_bytes[i]);
  835.             goto return_integer;
  836.  
  837.         case 119:    /* bytearray at:put: */
  838.             if (numargs != 3) goto argcerror;
  839.             if (! int_value(args[2])) goto argterror;
  840.             byarray->a_bytes[i] = itouc(int_value(args[2]));
  841.             goto return_nil;
  842.  
  843.         case 120:    /* print, no return */
  844.             printf("%s", leftp);
  845. # ifdef FLUSHREQ
  846.             fflush(stdout);
  847. # endif
  848.             goto return_nil;
  849.  
  850.         case 121:    /* print, with return */
  851.             printf("%s\n", leftp);
  852. # ifdef FLUSHREQ
  853.             fflush(stdout);
  854. # endif
  855.             goto return_nil;
  856.  
  857.         case 122:    /* format for error printing */
  858.             aClass = (class *) fnd_class(args[1]);
  859.             sprintf(strbuffer,"%s: %s",
  860.                 symbol_value(aClass->class_name), leftp);
  861.             leftp = strbuffer;
  862.  
  863.         case 123:    /* print on error output */
  864.             fprintf(stderr,"%s\n", leftp);
  865. # ifdef FLUSHREQ
  866.             fflush(stderr);
  867. # endif
  868.             goto return_nil;
  869.  
  870.         case 125:    /* unix system call */
  871. # ifndef NOSYSTEM
  872.             leftint = system(leftp);
  873.             goto return_integer;
  874. # endif
  875. # ifdef NOSYSTEM
  876.             errp = "system()";
  877.             goto not_implemented;
  878. # endif
  879.  
  880.         case 126:    /* printAt: */
  881. # ifndef CURSES
  882.             errp = "curses graphics package not available";
  883.             goto return_error;
  884. # endif
  885. # ifdef CURSES
  886.             if (numargs != 3) goto argcerror;
  887.             if ((! is_string(args[0])) ||
  888.                 (! is_integer(args[1])) ||
  889.                 (! is_integer(args[2])) ) goto argterror;
  890.             move(int_value(args[1]), int_value(args[2]));
  891.             addstr(string_value(args[0]));
  892.             refresh();
  893.             move(0, LINES-1);
  894.             goto return_nil;
  895. # endif
  896.  
  897.         case 127:    /* block return */
  898.             errp = "block return without surrounding context";
  899.             goto return_error;
  900.  
  901.         case 128: /* reference count error */
  902.             if (numargs != 1) goto argcerror;
  903.             sprintf(strbuffer,"object %d reference count %d",
  904.                 args[0], args[0]->ref_count);
  905.             errp = strbuffer;
  906.             goto return_error;
  907.  
  908.         case 129: /* does not respond error */
  909.             if (numargs != 2) goto argcerror;
  910.             if (! is_symbol(args[1])) goto argterror;
  911.             fprintf(stderr,"respond error: %s\n",
  912.             symbol_value(args[1]));
  913.             aClass = (class *) fnd_class(args[0]);
  914.             if (! is_class(aClass)) goto argterror;
  915.             sprintf(strbuffer,"%s: does not respond to %s",
  916.                 symbol_value(aClass->class_name), 
  917.                 symbol_value(args[1]));
  918.             errp = strbuffer;
  919.             goto return_error;
  920.  
  921.         case 130:    /* file open */
  922. puts("130");
  923.             if (numargs != 3) goto argcerror;
  924.             if (! is_string(args[1])) goto argterror;
  925.             if (! is_string(args[2])) goto argterror;
  926.             file_open(phil, 
  927.                 string_value(args[1]), string_value(args[2]));
  928.             goto return_nil;
  929.  
  930.         case 131:    /* file read */
  931. puts("131");
  932.             if (numargs != 1) goto argcerror;
  933.             resultobj = file_read(phil);
  934.             goto return_obj;
  935.  
  936.         case 132:    /* file write */
  937.             if (numargs != 2) goto argcerror;
  938.             file_write(phil, args[1]);
  939.             goto return_nil;
  940.  
  941.         case 133:    /* set file mode */
  942.             if (numargs != 2) goto argcerror;
  943.             if (! is_integer(args[1])) goto argterror;
  944.             phil->file_mode = int_value(args[1]);
  945.             goto return_nil;
  946.  
  947.         case 134:    /* compute file size */
  948.             fseek(phil->fp, (long) 0, 2);
  949.             leftint = (int) ftell(phil->fp);
  950.             goto return_integer;
  951.  
  952.         case 135:    /* set file position */
  953.             if (numargs != 2) goto argcerror;
  954.             if (! is_integer(args[1])) goto argterror;
  955.             leftint = fseek(phil->fp, (long) int_value(args[1]), 0);
  956.             goto return_integer;
  957.  
  958.         case 136:    /* find current position */
  959.             if (numargs != 1) goto argcerror;
  960.             leftint = (int) ftell(phil->fp);
  961.             goto return_integer;
  962.  
  963.         case 140:
  964.             errp = "block execute should be trapped by interp";
  965.             goto return_error;
  966.  
  967.         case 141:    /* newProcess (withArguments:) */
  968.             if (numargs < 1) goto argcerror;
  969.             if (! is_block(args[0])) goto argterror;
  970.             if (numargs == 1)
  971.                 resultobj = (object *)
  972.                     block_execute((interpreter *) 0, 
  973.                     (block *) args[0], 0, args);
  974.             else if (numargs == 2)
  975.                 resultobj = (object *) 
  976.                     block_execute((interpreter *) 0, 
  977.                     (block *) args[0], args[1]->size,
  978.                     &(args[1]->inst_var[0]));
  979.             else goto argcerror;
  980.             if (((object *) 0) == resultobj) goto return_nil;
  981.             resultobj = (object *) cr_process(resultobj);
  982.             goto return_obj;
  983.  
  984.         case 142:    /* terminate a process */
  985.             if (numargs != 1) goto argcerror;
  986.             if (! is_process(args[0])) goto argterror;
  987.             terminate_process( (process *) args[0]);
  988.             goto return_nil;
  989.  
  990.         case 143:    /* perform:withArguments: */
  991.             errp = "perform should be trapped by interpreter";
  992.             goto return_error;
  993.  
  994.         case 145:    /* set the state of a process */
  995.             if (numargs != 2) goto argcerror;
  996.             if (! is_process(args[0])) goto argterror;
  997.             if (! is_integer(args[1])) goto argterror;
  998.             leftint = int_value(args[1]);
  999.             switch (leftint) {
  1000.                 case 0:    leftint = READY;
  1001.                     break;
  1002.                 case 1:    leftint = SUSPENDED;
  1003.                     break;
  1004.                 case 2:    leftint = BLOCKED;
  1005.                     break;
  1006.                 case 3:    leftint = UNBLOCKED;
  1007.                     break;
  1008.                 default:  errp = "invalid state for process";
  1009.                       goto return_error;
  1010.  
  1011.                 }
  1012.             set_state((process *) args[0], leftint);
  1013.             goto return_integer;
  1014.  
  1015.         case 146:    /* return the state of a process */
  1016.             if (numargs != 1) goto argcerror;
  1017.             if (! is_process(args[0])) goto argterror;
  1018.             leftint = set_state((process *) args[0], CUR_STATE);
  1019.             goto return_integer;
  1020.  
  1021.         case 148:    /* begin atomic action */
  1022.             if (numargs != 0) goto argcerror;
  1023.             atomcnt++;
  1024.             goto return_nil;
  1025.  
  1026.         case 149:    /* end atomic action */
  1027.             if (numargs != 0) goto argcerror;
  1028.             if (atomcnt == 0) {
  1029.                 errp = "end atomic attempted while not in atomic action";
  1030.                 goto return_error;
  1031.                 }
  1032.             atomcnt--;
  1033.             goto return_nil;
  1034.  
  1035.         case 150:    /* class edit */
  1036.             leftp = symbol_value(aClass->file_name);
  1037.             if (! writeable(leftp)) {
  1038.                 gettemp(tempname);
  1039.     sprintf(strbuffer,/*"cp %s %s"*/ "copy %s to %s", leftp, tempname);
  1040. # ifndef NOSYSTEM
  1041.                 system(strbuffer);
  1042. # endif
  1043.                 leftp = tempname;
  1044.                 }
  1045.             if (! lexedit(leftp)) lexinclude(leftp);
  1046.             goto return_nil;
  1047.  
  1048.         case 151:     /* superclass of a class */
  1049.             if (! aClass->super_class)
  1050.                 goto return_nil;
  1051.             resultobj = (object *) aClass->super_class;
  1052.             if (! is_symbol(resultobj)) goto return_nil;
  1053.             resultobj = lookup_class(symbol_value(resultobj));
  1054.             if (! resultobj) goto return_nil;
  1055.             goto return_obj;
  1056.  
  1057.         case 152: /* class name */
  1058.             resultobj = aClass->class_name;
  1059.             leftp = symbol_value(resultobj);
  1060.             resultobj = new_str(leftp);
  1061.             goto return_obj;
  1062.  
  1063.         case 153: /* new */
  1064.             if (numargs != 2) goto argcerror;
  1065.             if (args[1] == o_nil)
  1066.                 resultobj = new_inst(aClass);
  1067.             else
  1068.                 resultobj = new_sinst(aClass, args[1]);
  1069.             goto return_obj;
  1070.  
  1071.         case 154:    /* print message names list */
  1072.             prnt_messages(aClass);
  1073.             goto return_nil;
  1074.  
  1075.         case 155:     /* respondsTo: aMessage  */
  1076.             if (numargs != 2) goto argcerror;
  1077.             if (! is_symbol(args[1])) goto argterror;
  1078.             leftint = responds_to(symbol_value(args[1]), aClass);
  1079.             goto return_boolean;
  1080.  
  1081.         case 156:    /* class view */
  1082.             leftp = symbol_value(aClass->file_name);
  1083.             gettemp(tempname);
  1084. # ifndef NOSYSTEM
  1085.     sprintf(strbuffer,/*"cp %s %s"*/"copy %s to %s", leftp, tempname);
  1086.             system(strbuffer);
  1087. # endif
  1088.             leftp = tempname;
  1089.             lexedit(leftp);
  1090.             goto return_nil;
  1091.  
  1092.         case 157:    /* class list */
  1093.             class_list(aClass, 0);
  1094.             goto return_nil;
  1095.  
  1096.  
  1097.         case 158:    /* variables */
  1098.             resultobj = aClass->c_inst_vars;
  1099.             goto return_obj;
  1100.  
  1101.         case 160:    /* current time */
  1102.             time(&clock);
  1103.             strcpy(strbuffer, ctime(&clock));
  1104.             goto return_string;
  1105.  
  1106.         case 161:    /* time, measure in seconds */
  1107.             leftint = (int) time((long *) 0);
  1108.             goto return_integer;
  1109.  
  1110.         case 162:    /* clear screen */
  1111. # ifdef CURSES
  1112.             clear();
  1113.             move(0,0);
  1114.             refresh();
  1115. # endif
  1116. # ifdef PLOT3
  1117.             erase();
  1118. # endif
  1119.             goto return_nil;
  1120.  
  1121. # ifdef PLOT3
  1122. /**************************
  1123.     warning - the calls on the plot(3) routines are very device
  1124.     specific, and will probably require changes to work on any one
  1125.     particular new device
  1126. **********************************/
  1127.         case 170:    /* clear */
  1128.             erase();
  1129.             goto return_nil;
  1130.  
  1131.         case 171:    /* move(x,y) */
  1132.             move(leftint, rightint);
  1133.             goto return_nil;
  1134.  
  1135.         case 172:    /* cont(x,y) (draw line) */
  1136.             cont(leftint, rightint);
  1137.             goto return_nil;
  1138.  
  1139.         case 173:    /* point(x,y) (draw point) */
  1140.             point(leftint, rightint);
  1141.             goto return_nil;
  1142.  
  1143.         case 174:    /* circle(x, y, r) */
  1144.             if (numargs != 3) goto argcerror;
  1145.             for (i = 0; i < 3; i++)
  1146.                 if (! is_integer(args[i])) 
  1147.                     goto argterror;
  1148.             circle(int_value(args[0]), int_value(args[1]),
  1149.                 int_value(args[2]));
  1150.             goto return_nil;
  1151.  
  1152.         case 175:    /* arg(x, y, x0, y0, x1, y1) */
  1153.             if (numargs != 6) goto argcerror;
  1154.             for (i = 0; i < 6; i++)
  1155.                 if (! is_integer(args[i])) goto argterror;
  1156.             arc(int_value(args[0]), int_value(args[1]),
  1157.                 int_value(args[2]), int_value(args[3]),
  1158.                 int_value(args[4]), int_value(args[5]));
  1159.             goto return_nil;
  1160.  
  1161.         case 176:    /* space */
  1162.             space(leftint, rightint, i, j);
  1163.             goto return_nil;
  1164.  
  1165.         case 177:    /* line */
  1166.             line(leftint, rightint, i, j);
  1167.             goto return_nil;
  1168.  
  1169.         case 178:    /* label */
  1170.             label(leftp);
  1171.             goto return_nil;
  1172.  
  1173.         case 179:    /* linemod */
  1174.             linemod(leftp);
  1175.             goto return_nil;
  1176. # endif
  1177.  
  1178.         default: fprintf(stderr,"Primitive number %d not implemented\n",
  1179.                         primnumber);
  1180.             goto return_nil;
  1181.     }
  1182.  
  1183. /* return different types of objects */
  1184.  
  1185. return_obj:
  1186.  
  1187.     return(resultobj);
  1188.  
  1189. return_nil:
  1190.  
  1191.     return(o_nil);
  1192.  
  1193. return_integer:
  1194.  
  1195.     return(new_int(leftint));
  1196.  
  1197. return_character:
  1198.  
  1199.     return(new_char(leftint));
  1200.  
  1201. return_boolean:
  1202.  
  1203.     return(leftint ? o_true : o_false);
  1204.  
  1205. float_check:
  1206.  
  1207.     if (errno == ERANGE || errno == EDOM) goto numerror;
  1208.  
  1209. return_float:
  1210.  
  1211.     return(new_float(leftfloat));
  1212.  
  1213. return_string:
  1214.  
  1215.     return(new_str(strbuffer));
  1216.  
  1217. /* error conditions */
  1218.  
  1219. not_implemented:
  1220.     sprintf(strbuffer,"%s not implemented yet", errp);
  1221.     errp = strbuffer;
  1222.     goto return_error;
  1223.  
  1224. argcerror:
  1225.     sprintf(strbuffer,"%d is wrong number of arguments for primitive %d",
  1226.         numargs, primnumber);
  1227.     errp = strbuffer;
  1228.     goto return_error;
  1229.  
  1230. argterror:
  1231.     sprintf(strbuffer,"argument type not correct for primitive %d",
  1232.         primnumber);
  1233.     errp = strbuffer;
  1234.     goto return_error;
  1235.  
  1236. numerror:
  1237.     errp = "numerical error in primitive"; 
  1238.     goto return_error;
  1239.  
  1240. indexerror:
  1241.     errp = "primitive index error";
  1242.     goto return_error;
  1243.  
  1244. return_error:
  1245.     sassign(resultobj, new_str(errp));
  1246.     primitive(ERRPRINT, 1, &resultobj);
  1247.     obj_dec(resultobj);
  1248.     goto return_nil;
  1249. }
  1250.  
  1251. static prnt_radix(n, r, buffer)
  1252. int n, r;
  1253. char buffer[];
  1254. {  char *p, *q, buffer2[60];
  1255.    int i, s;
  1256.  
  1257.    if (n < 0) {n = - n; s = 1;}
  1258.    else s = 0;
  1259.    p = buffer2; *p++ = '\0';
  1260.    if (n == 0) *p++ = '0';
  1261.    while (n) {
  1262.       i = n % r;
  1263.       *p++ = i + ((i < 10) ?  '0' : ('A' - 10));
  1264.       n = n / r;
  1265.       }
  1266.    sprintf(buffer,"%dr", r);
  1267.    for (q = buffer; *q; q++);
  1268.    if (s) *q++ = '-';
  1269.    for (*p = '0' ; *p ; ) *q++ = *--p;
  1270.    *q = '\0';
  1271. }
  1272.  
  1273. static fprnt_radix(f, n, buffer)
  1274. double f;
  1275. int n;
  1276. char buffer[];
  1277. {    int sign, exp, i, j;
  1278.     char *p, *q, tempbuffer[60];
  1279.     double ip;
  1280.  
  1281.     if (f < 0) {
  1282.         sign = 1;
  1283.         f = - f;
  1284.         }
  1285.     else sign = 0;
  1286.     exp = 0;
  1287.     if (f != 0) {
  1288.         exp = (int) floor(log(f) / log((double) n));
  1289.         if (exp < -4 || 4 < exp) {
  1290.             f *= pow((double) n, (double) - exp);
  1291.             }
  1292.         else exp = 0;
  1293.         }
  1294.     f = modf(f, &ip);
  1295.     if (sign) ip = - ip;
  1296.     prnt_radix((int) ip, n, buffer);
  1297.     for (p = buffer; *p; p++) ;
  1298.     if (f != 0) {
  1299.         *p++ = '.';
  1300.         for (j = 0; (f != 0) && (j < 6); j++){
  1301.             i = (int) (f *= n);
  1302.             *p++ = (i < 10) ? '0' + i : 'A' + (i-10) ;
  1303.             f -= i;
  1304.             }
  1305.         }
  1306.     if (exp) {
  1307.         *p++ = 'e';
  1308.         sprintf(tempbuffer,"%d", exp);
  1309.         for (q = tempbuffer; *q; )
  1310.             *p++ = *q++;
  1311.         }
  1312.     *p = '\0';
  1313.     return;
  1314. }
  1315.  
  1316. /* generalit - numerical generality */
  1317. static int generality(aNumber)
  1318. object *aNumber;
  1319. {    int i;
  1320.  
  1321.     if (is_integer(aNumber)) i = 1;
  1322.     else if (is_float(aNumber)) i = 2;
  1323.     else i = 3;
  1324.     return(i);
  1325. }
  1326.  
  1327. /* cant_happen - report that an impossible condition has occured */
  1328. cant_happen(n) int n;
  1329. {   char *s;
  1330.  
  1331. # ifdef SMALLDATA
  1332.     s = "what a pain!";
  1333. # endif
  1334. # ifndef SMALLDATA
  1335.     switch(n) {
  1336.        case 1:  s = "out of memory allocation space"; break;
  1337.        case 2:  s = "array size less than zero"; break;
  1338.        case 3:  s = "block return from call should not occur"; break;
  1339.        case 4:  s = "attempt to make instance of non class"; break;
  1340.        case 5:  s = "case error in new integer or string"; break;
  1341.        case 6:  s = "decrement on unknown built in object"; break;
  1342.        case 7:  s = "cannot find class Object"; break;
  1343.        case 8:  s = "primitive free of object of wrong type"; break;
  1344.        case 9:  s = "internal interpreter error"; break;
  1345.        case 11: s = "block execute on non-block"; break;
  1346.        case 12: s = "out of symbol space"; break;
  1347.        case 14: s = "out of standard bytecode space"; break;
  1348.        case 15: s = "system deadlocked - all processes blocked"; break;
  1349.        case 16: s = "attempt to free symbol"; break;
  1350.        case 17: s = "invalid process state passed to set_state"; break;
  1351.        case 18: s = "internal buffer overflow"; break;
  1352.        case 20: s = "can't open prelude file"; break;
  1353.        case 22: s = "system file open error"; break;
  1354.        case 23: s = "fastsave error"; break;
  1355.        default: s = "unknown, but impossible nonetheless, condition"; break;
  1356.        }
  1357. # endif
  1358.    fprintf(stderr,"Can't happen number %d: %s .. So long!!!!\n", n, s);
  1359.    exit(1);
  1360. }
  1361.  
  1362. /* writeable - see if a file can be written to */
  1363. int writeable(name)
  1364. char *name;
  1365. {    char buffer[150];
  1366.  
  1367.     sprintf(buffer,"test -w %s", name);
  1368. # ifdef NOSYSTEM
  1369.     return(0);
  1370. # endif
  1371. # ifndef NOSYSTEM
  1372.     return(! system(buffer));
  1373. # endif
  1374. }
  1375.  
  1376. int seed = 1;
  1377.  
  1378. srand(x) {
  1379.     seed = x & 0x7fff;
  1380. }
  1381.  
  1382. int rand(x) { /* WMK - from blue book, p205 */
  1383.     static long a = 27181, c = 13849;
  1384.     seed = (a * (long)seed  + c) & 0x7fff;
  1385.     return(seed);
  1386. }
  1387.