home *** CD-ROM | disk | FTP | other *** search
/ Amiga Elysian Archive / AmigaElysianArchive.iso / prog / c / post17s.lha / postop2.c < prev    next >
Text File  |  1992-03-07  |  40KB  |  1,450 lines

  1. /* PostScript interpreter file "postop2.c" - operators (2)
  2.  * (C) Adrian Aylward 1989, 1992
  3.  * V1.6 First source release
  4.  * V1.7 Fix roll of zero items
  5.  */
  6.  
  7. # include "post.h"
  8.  
  9. /* index */
  10.     
  11. void opindex(void)
  12. {   struct object *token1;
  13.     int num;
  14.     if (opernest < 1) error(errstackunderflow);
  15.     token1 = &operstack[opernest - 1];
  16.     if (token1->type != typeint) error(errtypecheck);
  17.     num = token1->value.ival;
  18.     if (num < 0 || num > opernest - 2) error(errrangecheck);
  19.     *token1 = *(token1 - num - 1);
  20. }
  21.  
  22. /* known */
  23.  
  24. void opknown(void)
  25. {   struct object token, *token1, *token2;
  26.     int bool;
  27.     if (opernest < 2) error(errstackunderflow);
  28.     token2 = &operstack[opernest - 1];
  29.     token1 = token2 - 1;
  30.     if (token1->type != typedict) error(errtypecheck);
  31.     bool = dictget(token1->value.vref, token2, &token, flagrprot);
  32.     token.type = typebool;
  33.     token.flags = 0;
  34.     token.length = 0;
  35.     token.value.ival = bool;
  36.     *token1 = token;
  37.     opernest -= 1;
  38. }
  39.  
  40. /* le */
  41.  
  42. void ople(void)
  43. {   struct object token, *token1, *token2;
  44.     if (opernest < 2) error(errstackunderflow);
  45.     token2 = &operstack[opernest - 1];
  46.     token1 = token2 - 1;
  47.     token.type = typebool;
  48.     token.flags = 0;
  49.     token.length = 0;
  50.     token.value.ival = (compare(token1, token2) <= 0);
  51.     *token1 = token;
  52.     opernest--;
  53. }
  54.  
  55. /* length */
  56.  
  57. void oplength(void)
  58. {   struct object token, *token1;
  59.     struct dictionary *dict;
  60.     struct name *name;
  61.     int length;
  62.     if (opernest < 1) error(errstackunderflow);
  63.     token1 = &operstack[opernest - 1];
  64.     if      (token1->type == typearray || token1->type == typepacked ||
  65.              token1->type == typestring)
  66.     {   if (token1->flags & flagrprot) error(errinvalidaccess);
  67.         length = token1->length;
  68.     }
  69.     else if (token1->type == typedict)
  70.     {   dict = vmdptr(token1->value.vref);
  71.         if (dict->flags & flagrprot) error(errinvalidaccess);
  72.         length = dict->full;
  73.     }
  74.     else if (token1->type == typename)
  75.     {   name = vmnptr(token1->value.vref);
  76.         length = name->length;
  77.     }
  78.     else
  79.         error(errtypecheck);
  80.     token.type = typeint;
  81.     token.flags = 0;
  82.     token.length = 0;
  83.     token.value.ival = length;
  84.     *token1 = token;
  85. }
  86.  
  87. /* ln */
  88.  
  89. void opln(void)
  90. {   struct object token, *token1;
  91.     if (opernest < 1) error(errstackunderflow);
  92.     token1 = &operstack[opernest - 1];
  93.     token = *token1;
  94.     if (token.type == typeint)
  95.     {   token.type = typereal;
  96.         token.value.rval = token.value.ival;
  97.     }
  98.     if (token.type == typereal)
  99.         token.value.rval = (float) log((double) token.value.rval);
  100.     else
  101.         error(errtypecheck);
  102.     *token1 = token;
  103. }
  104.  
  105. /* load */
  106.  
  107. void opload(void)
  108. {   struct object *token;
  109.     if (opernest < 1) error(errstackunderflow);
  110.     token = &operstack[opernest - 1];
  111.     if (dictfind(token, token) == -1) error(errundefined);
  112. }
  113.  
  114. /* log */
  115.  
  116. void oplog(void)
  117. {   struct object token, *token1;
  118.     if (opernest < 1) error(errstackunderflow);
  119.     token1 = &operstack[opernest - 1];
  120.     token = *token1;
  121.     if (token.type == typeint)
  122.     {   token.type = typereal;
  123.         token.value.rval = token.value.ival;
  124.     }
  125.     if (token.type == typereal)
  126.         token.value.rval = (float) log10((double) token.value.rval);
  127.     else
  128.         error(errtypecheck);
  129.     *token1 = token;
  130. }
  131.  
  132. /* loop */
  133.  
  134. void oploop(void)
  135. {   struct object token, *token1, *tokenx;
  136.     if (currtoken->flags & flagctrl)
  137.     {   token1 = &execstack[execnest - 2];
  138.         token1[2] = *token1;
  139.         execnest++;
  140.     }
  141.     else
  142.     {   if (opernest < 1) error(errstackunderflow);
  143.         token1 = &operstack[opernest - 1];
  144.         if (token1->type != typearray && token1->type != typepacked)
  145.             error(errtypecheck);
  146.         if (execnest + 3 > execstacksize) error(errexecstackoverflow);
  147.         tokenx = &execstack[execnest];
  148.         *tokenx++ = *token1;
  149.         token = *currtoken;
  150.         token.flags &= ~flagexec;
  151.         token.flags |= flagctrl | flagloop;
  152.         token.length = 2;
  153.         *tokenx = token;
  154.         execnest += 2;
  155.         opernest -= 1;
  156.     }
  157. }
  158.  
  159. /* lt */
  160.  
  161. void oplt(void)
  162. {   struct object token, *token1, *token2;
  163.     if (opernest < 2) error(errstackunderflow);
  164.     token2 = &operstack[opernest - 1];
  165.     token1 = token2 - 1;
  166.     token.type = typebool;
  167.     token.flags = 0;
  168.     token.length = 0;
  169.     token.value.ival = (compare(token1, token2) < 0);
  170.     *token1 = token;
  171.     opernest--;
  172. }
  173.  
  174. /* maxlength */
  175.  
  176. void opmaxlength(void)
  177. {   struct object token, *token1;
  178.     struct dictionary *dict;
  179.     if (opernest < 1) error(errstackunderflow);
  180.     token1 = &operstack[opernest - 1];
  181.     if (token1->type != typedict) error(errtypecheck);
  182.     dict = vmdptr(token1->value.vref);
  183.     if (dict->flags & flagrprot) error(errinvalidaccess);
  184.     token.type = typeint;
  185.     token.flags = 0;
  186.     token.length = 0;
  187.     token.value.ival = dict->size;
  188.     *token1 = token;
  189. }
  190.  
  191. /* mod */
  192.  
  193. void opmod(void)
  194. {   struct object *token1, *token2;
  195.     int num1, num2;
  196.     if (opernest < 2) error(errstackunderflow);
  197.     token2 = &operstack[opernest - 1];
  198.     token1 = token2 - 1;
  199.     if (token1->type != typeint || token2->type != typeint)
  200.         error(errtypecheck);
  201.     num1 = token1->value.ival;
  202.     num2 = token2->value.ival;
  203.     if (num2 == 0) error(errundefinedresult);
  204.     token1->value.ival = num1 % num2;
  205.     opernest--;
  206. }
  207.  
  208. /* mul */
  209.  
  210. void opmul(void)
  211. {   struct object token, *token1, *token2;
  212.     int num1, num2, tmp1, tmp2;
  213.     unsigned int neg;
  214.     if (opernest < 2) error(errstackunderflow);
  215.     token2 = &operstack[opernest - 1];
  216.     token1 = token2 - 1;
  217.     if (token1->type == typeint && token2->type == typeint)
  218.     {   num1 = token1->value.ival;
  219.         num2 = token2->value.ival;
  220.         neg = 0x7fffffff;
  221.         if (num1 < 0)
  222.         {   neg = ~neg;
  223.             num1 = -num1;
  224.         }
  225.         if (num2 < 0)
  226.         {   neg = ~neg;
  227.             num2 = -num2;
  228.         }
  229.         tmp1 = (unsigned) num1 >> 16;
  230.         tmp2 = (unsigned) num2 >> 16;
  231.         num1 &= 0xffff;
  232.         num2 &= 0xffff;
  233.         if (tmp1 == 0)
  234.         {   if (tmp2 == 0)
  235.             {   num1 *= num2;
  236.                 if ((unsigned) num1 <= neg)
  237.                 {   token1->value.ival = (neg == 0x7fffffff) ? num1 : -num1;
  238.                     opernest--;
  239.                     return;
  240.                 }
  241.             }
  242.             else
  243.             {   tmp2 *= num1;
  244.                 num1 *= num2;
  245.                 tmp1 = tmp2 + ((unsigned) num1 >> 16);
  246.                 num1 += tmp2 << 16;
  247.                 if ((tmp1 & 0xffff0000) == 0 && (unsigned) num1 <= neg)
  248.                 {   token1->value.ival = (neg == 0x7fffffff) ? num1 : -num1;
  249.                     opernest--;
  250.                     return;
  251.                 }
  252.             }
  253.         }
  254.         else
  255.             if (tmp2 == 0)
  256.             {   tmp1 *= num2;
  257.                 num2 *= num1;
  258.                 tmp2 = tmp1 + ((unsigned) num2 >> 16);
  259.                 num2 += tmp1 << 16;
  260.                 if ((tmp2 & 0xffff0000) == 0 && (unsigned) num2 <= neg)
  261.                 {   token1->value.ival = (neg == 0x7fffffff) ? num2 : -num2;
  262.                     opernest--;
  263.                     return;
  264.                 }
  265.             }
  266.          
  267.     }
  268.     token = *token1;
  269.     if (token.type == typeint)
  270.     {   token.type = typereal;
  271.         token.value.rval = token.value.ival;
  272.     }
  273.     else
  274.         if (token.type != typereal) error(errtypecheck);
  275.     if (token2->type == typeint)
  276.         token.value.rval *= token2->value.ival;
  277.     else
  278.     {   if (token2->type != typereal) error(errtypecheck);
  279.         token.value.rval *= token2->value.rval;
  280.     }
  281.     *token1 = token;
  282.     opernest--;
  283. }
  284.  
  285. /* ne */
  286.  
  287. void opne(void)
  288. {   struct object token, *token1, *token2;
  289.     if (opernest < 2) error(errstackunderflow);
  290.     token2 = &operstack[opernest - 1];
  291.     token1 = token2 - 1;
  292.     token.type = typebool;
  293.     token.flags = 0;
  294.     token.length = 0;
  295.     token.value.ival = !equal(token1, token2);
  296.     *token1 = token;
  297.     opernest--;
  298. }
  299.  
  300. /* neg */
  301.  
  302. void opneg(void)
  303. {   struct object *token1;
  304.     int num1;
  305.     if (opernest < 1) error(errstackunderflow);
  306.     token1 = &operstack[opernest - 1];
  307.     if      (token1->type == typeint)
  308.     {   num1 = token1->value.ival;
  309.         if (num1 < 0)
  310.         {   num1 = -num1;
  311.             if (num1 < 0)
  312.             {   token1->type = typereal;
  313.                 token1->value.rval = -((float) num1);
  314.             }
  315.             else
  316.                 token1->value.ival = num1;
  317.         }
  318.         else
  319.             token1->value.ival = -num1;
  320.     }
  321.     else if (token1->type == typereal)
  322.         token1->value.rval = -token1->value.rval;
  323.     else
  324.         error(errtypecheck);
  325. }
  326.  
  327. /* noaccess */
  328.  
  329. void opnoaccess(void)
  330. {   struct object *token1;
  331.     int type;
  332.     if (opernest < 1) error(errstackunderflow);
  333.     token1 = &operstack[opernest - 1];
  334.     type = token1->type;
  335.     if      (type == typefile || type == typestring ||
  336.              type == typearray || type == typepacked)
  337.         token1->flags |= (flagwprot | flagrprot | flagxprot);
  338.     else if (type == typedict)
  339.         vmdptr(token1->value.vref)->flags |= (flagwprot | flagrprot);
  340.     else
  341.         error(errtypecheck);
  342. }
  343.  
  344. /* not */
  345.  
  346. void opnot(void)
  347. {   struct object *token1;
  348.     if (opernest < 1) error(errstackunderflow);
  349.     token1 = &operstack[opernest - 1];
  350.     if      (token1->type == typebool)
  351.         token1->value.ival = !token1->value.ival;
  352.     else if (token1->type == typeint)
  353.         token1->value.ival = ~token1->value.ival;
  354.     else
  355.         error(errtypecheck);
  356. }
  357.  
  358. /* null */
  359.  
  360. void opnull(void)
  361. {   struct object token;
  362.     if (opernest == operstacksize) error(errstackoverflow);
  363.     token.type = typenull;
  364.     token.flags = 0;
  365.     token.length = 0;
  366.     token.value.ival = 0;
  367.     operstack[opernest++] = token;
  368. }
  369.  
  370. /* or */
  371.  
  372. void opor(void)
  373. {   struct object *token1, *token2;
  374.     if (opernest < 2) error(errstackunderflow);
  375.     token2 = &operstack[opernest - 1];
  376.     token1 = token2 - 1;
  377.     if ((token1->type == typebool && token2->type == typebool) ||
  378.         (token1->type == typeint  && token2->type == typeint))
  379.         token1->value.ival |= token2->value.ival;
  380.     else
  381.         error(errtypecheck);
  382.     opernest--;
  383. }
  384.  
  385. /* packedarray */
  386.  
  387. void oppackedarray(void)
  388. {   struct object token, *token1, *aptr;
  389.     int length;
  390.     if (opernest < 1) error(errstackunderflow);
  391.     token1 = &operstack[opernest - 1];
  392.     if (token1->type != typeint) error(errtypecheck);
  393.     length = token1->value.ival;
  394.     if (length < 0) error(errrangecheck);
  395.     if (opernest < length + 1) error(errstackunderflow);
  396.     aptr = token1 - length;
  397.     token.type = typepacked;
  398.     token.flags = flagwprot;
  399.     token.length = length;
  400.     token.value.vref = arraypack(aptr, length);
  401.     *aptr = token;
  402.     opernest -= length;
  403. }
  404.  
  405. /* pop */
  406.  
  407. void oppop(void)
  408. {   if (opernest < 1) error(errstackunderflow);
  409.     opernest -= 1;
  410. }
  411.  
  412. /* print */
  413.  
  414. void opprint(void)
  415. {   struct object *token1;
  416.     if (opernest < 1) error(errstackunderflow);
  417.     token1 = &operstack[opernest - 1];
  418.     if (token1->type != typestring) error(errtypecheck);
  419.     if (token1->flags & flagrprot) error(errinvalidaccess);
  420.     if (sstdout)
  421.         putmem(sstdout, vmsptr(token1->value.vref), token1->length);
  422.     opernest--;
  423. }
  424.  
  425. /* prompts */
  426.  
  427. void opprompts(void)
  428. {   struct object *token1, *token2;
  429.     if (opernest < 2) error(errstackunderflow);
  430.     token2 = &operstack[opernest - 1];
  431.     token1 = token2 - 1;
  432.     if (token1->type != typestring) error(errtypecheck);
  433.     if (token1->flags & flagrprot) error(errinvalidaccess);
  434.     if (token1->length > promptsize) error(errrangecheck);
  435.     if (token2->type != typestring) error(errtypecheck);
  436.     if (token2->flags & flagrprot) error(errinvalidaccess);
  437.     if (token2->length > promptsize) error(errrangecheck);
  438.     memcpy(prompt1, vmsptr(token1->value.vref), token1->length);
  439.     prompt1[token1->length] = 0;
  440.     memcpy(prompt2, vmsptr(token2->value.vref), token2->length);
  441.     prompt2[token2->length] = 0;
  442.     opernest -= 2;
  443. }
  444.  
  445. /* pstack */
  446.  
  447. void oppstack(void)
  448. {   int nest = opernest;
  449.     if (sstdout)
  450.         while (nest)
  451.         {   printeqeq(sstdout, &operstack[--nest], 0, 0);
  452.             putch(sstdout, '\n');
  453.         }
  454. }
  455.  
  456. /* put */
  457.  
  458. void opput(void)
  459. {   struct object *token1, *token2, *token3;
  460.     int num;
  461.     if (opernest < 3) error(errstackunderflow);
  462.     token3 = &operstack[opernest - 1];
  463.     token2 = token3 - 1;
  464.     token1 = token2 - 1;
  465.     if (token1->type == typedict)
  466.         dictput(token1->value.vref, token2, token3);
  467.     else
  468.     {   if (token2->type != typeint) error(errtypecheck);
  469.         num = token2->value.ival;
  470.         if      (token1->type == typestring)
  471.         {   if (token3->type != typeint) error(errtypecheck);
  472.             if (token1->flags & flagwprot) error(errinvalidaccess);
  473.             if (num < 0 || num >= token1->length) error(errrangecheck);
  474.             vmsptr(token1->value.vref)[num] = token3->value.ival;
  475.         }
  476.         else if (token1->type == typearray)
  477.         {   if (token1->flags & flagwprot) error(errinvalidaccess);
  478.             if (num < 0 || num >= token1->length) error(errrangecheck);
  479.             arraysave(token1->value.vref, token1->length);
  480.             vmaptr(token1->value.vref)[num] = *token3;
  481.         }
  482.         else
  483.             error(errtypecheck);
  484.     }
  485.     opernest -= 3;
  486. }
  487.  
  488. /* putinterval */
  489.  
  490. void opputinterval(void)
  491. {   struct object *token1, *token2, *token3;
  492.     int num, len;
  493.     if (opernest < 3) error(errstackunderflow);
  494.     token3 = &operstack[opernest - 1];
  495.     token2 = token3 - 1;
  496.     token1 = token2 - 1;
  497.     if (token2->type != typeint) error(errtypecheck);
  498.     num = token2->value.ival;
  499.     if (token3->type != token1->type) error(errtypecheck);
  500.     len = token3->length;
  501.     if      (token1->type == typestring)
  502.     {   if (token1->flags & flagwprot) error(errinvalidaccess);
  503.         if (token3->flags & flagrprot) error(errinvalidaccess);
  504.         if (num < 0 || num > token1->length) error(errrangecheck);
  505.         if (len < 0 || num + len > token1->length) error(errrangecheck);
  506.         memcpy(vmsptr(token1->value.vref) + num,
  507.                vmsptr(token3->value.vref), len);
  508.     }
  509.     else if (token1->type == typearray)
  510.     {   if (token1->flags & flagwprot) error(errinvalidaccess);
  511.         if (token3->flags & flagrprot) error(errinvalidaccess);
  512.         if (num < 0 || num > token1->length) error(errrangecheck);
  513.         if (len < 0 || num + len > token1->length) error(errrangecheck);
  514.         arraysave(token1->value.vref, token1->length);
  515.         arraycopy(vmaptr(token1->value.vref) + num,
  516.                   vmaptr(token3->value.vref), len);
  517.     }
  518.     else
  519.         error(errtypecheck);
  520.     opernest -= 3;
  521. }
  522.  
  523. /* quit */
  524.  
  525. void opquit(void)
  526. {   execnest = 0;
  527.     errorjmp(0, 1);
  528. }
  529.  
  530. /* rand */
  531.  
  532. void oprand(void)
  533. {   struct object token;
  534.     if (opernest == operstacksize) error(errstackoverflow);
  535.     random *= 0x41c64e6d;
  536.     random += 0x3039;
  537.     token.type = typeint;
  538.     token.flags = 0;
  539.     token.length = 0;
  540.     token.value.ival = random >> 1;
  541.     operstack[opernest++] = token;
  542. }
  543.  
  544. /* rcheck */
  545.  
  546. void oprcheck(void)
  547. {   struct object token, *token1;
  548.     int type, bool;
  549.     if (opernest < 1) error(errstackunderflow);
  550.     token1 = &operstack[opernest - 1];
  551.     type = token1->type;
  552.     if      (type == typefile || type == typestring ||
  553.              type == typearray || type == typepacked)
  554.         bool = ((token1->flags & flagrprot) == 0);
  555.     else if (type == typedict)
  556.         bool = ((vmdptr(token1->value.vref)->flags & flagrprot) == 0);
  557.     else
  558.         error(errtypecheck);
  559.     token.type = typebool;
  560.     token.flags = 0;
  561.     token.length = 0;
  562.     token.value.ival = bool;
  563.     *token1 = token;
  564. }
  565.  
  566. /* read */
  567.  
  568. void opread(void)
  569. {   struct object token, *token1;
  570.     int ch;
  571.     if (opernest < 1) error(errstackunderflow);
  572.     if (opernest == operstacksize) error(errstackoverflow);
  573.     token1 = &operstack[opernest - 1];
  574.     if (token1->type != typefile) error(errtypecheck);
  575.     if (token1->flags & flagrprot) error(errinvalidaccess);
  576.     if (filecheck(token1, openread) == NULL) error(errioerror);
  577.     ch = readch(token1, -2);
  578.     token.flags = 0;
  579.     token.length = 0;
  580.     if (ch == EOF)
  581.     {   fileclose(token1);
  582.         token.value.ival = 0;
  583.     }
  584.     else
  585.     {   token.type = typeint;
  586.         token.value.ival = ch;
  587.         *token1++ = token;
  588.         token.value.ival = 1;
  589.         opernest++;
  590.     }
  591.     token.type = typebool;
  592.     *token1 = token;
  593. }
  594.  
  595. /* readhexstring */
  596.  
  597. void opreadhexstring(void)
  598. {   struct object token, *token1, *token2;
  599.     char *sptr;
  600.     int ch, length, num, dig, sw;
  601.     if (opernest < 2) error(errstackunderflow);
  602.     token2 = &operstack[opernest - 1];
  603.     token1 = token2 - 1;
  604.     if (token1->type != typefile) error(errtypecheck);
  605.     if (token1->flags & flagrprot) error(errinvalidaccess);
  606.     if (filecheck(token1, openread) == NULL) error(errioerror);
  607.     if (token2->type != typestring) error(errtypecheck);
  608.     if (token2->flags & flagwprot) error(errinvalidaccess);
  609.     length = 0;
  610.     sptr = vmsptr(token2->value.vref);
  611.     ch = 0;
  612.     sw = 1;
  613.     while (length < token2->length)
  614.     {   ch = readch(token1, -1);
  615.         if (ch == EOF) break;
  616.         dig = digitval(ch);
  617.         if (dig >= 16) continue;
  618.         if (sw)
  619.         {   sw = 0;
  620.             num = dig * 16;
  621.         }
  622.         else
  623.         {   sw = 1;
  624.             num += dig;
  625.             *sptr++ = num;
  626.             length++;
  627.         }
  628.     }
  629.     token = *token2;
  630.     token.length = length;
  631.     *token1 = token;
  632.     token.type = typebool;
  633.     token.flags = 0;
  634.     token.length = 0;
  635.     token.value.ival = (ch != EOF);
  636.     *token2 = token;
  637. }
  638.  
  639. /* readline */
  640.  
  641. void opreadline(void)
  642. {   struct object token, *token1, *token2;
  643.     char *sptr;
  644.     int ch, length;
  645.     if (opernest < 2) error(errstackunderflow);
  646.     token2 = &operstack[opernest - 1];
  647.     token1 = token2 - 1;
  648.     if (token1->type != typefile) error(errtypecheck);
  649.     if (token1->flags & flagrprot) error(errinvalidaccess);
  650.     if (filecheck(token1, openread) == NULL) error(errioerror);
  651.     if (token2->type != typestring) error(errtypecheck);
  652.     if (token2->flags & flagwprot) error(errinvalidaccess);
  653.     length = 0;
  654.     sptr = vmsptr(token2->value.vref);
  655.     ch = 0;
  656.     for (;;)
  657.     {   ch = readch(token1, -1);
  658.         if (ch == '\n' || ch == EOF) break;
  659.         if (length == token2->length) error(errrangecheck);
  660.         *sptr++ = ch;
  661.         length++;
  662.     }
  663.     token = *token2;
  664.     token.length = length;
  665.     *token1 = token;
  666.     token.type = typebool;
  667.     token.flags = 0;
  668.     token.length = 0;
  669.     token.value.ival = (ch != EOF);
  670.     *token2 = token;
  671. }
  672.  
  673. /* readonly */
  674.  
  675. void opreadonly(void)
  676. {   struct object *token1;
  677.     struct dictionary *dict;
  678.     int type;
  679.     if (opernest < 1) error(errstackunderflow);
  680.     token1 = &operstack[opernest - 1];
  681.     type = token1->type;
  682.     if      (type == typefile || type == typestring ||
  683.              type == typearray || type == typepacked)
  684.     {   if (token1->flags & flagrprot) error(errinvalidaccess);
  685.         token1->flags |= flagwprot;
  686.     }
  687.     else if (type == typedict)
  688.     {   dict = vmdptr(token1->value.vref);
  689.         if (dict->flags & flagrprot) error(errinvalidaccess);
  690.         dict->flags |= flagwprot;
  691.     }
  692.     else
  693.         error(errtypecheck);
  694. }
  695.  
  696. /* readstring */
  697.  
  698. void opreadstring(void)
  699. {   struct object token, *token1, *token2;
  700.     char *sptr;
  701.     int ch, length;
  702.     if (opernest < 2) error(errstackunderflow);
  703.     token2 = &operstack[opernest - 1];
  704.     token1 = token2 - 1;
  705.     if (token1->type != typefile) error(errtypecheck);
  706.     if (token1->flags & flagrprot) error(errinvalidaccess);
  707.     if (filecheck(token1, openread) == NULL) error(errioerror);
  708.     if (token2->type != typestring) error(errtypecheck);
  709.     if (token2->flags & flagwprot) error(errinvalidaccess);
  710.     length = 0;
  711.     sptr = vmsptr(token2->value.vref);
  712.     ch = 0;
  713.     while (length < token2->length)
  714.     {   ch = readch(token1, -2);
  715.         if (ch == EOF) break;
  716.         *sptr++ = ch;
  717.         length++;
  718.     }
  719.     token = *token2;
  720.     token.length = length;
  721.     *token1 = token;
  722.     token.type = typebool;
  723.     token.flags = 0;
  724.     token.length = 0;
  725.     token.value.ival = (ch != EOF);
  726.     *token2 = token;
  727. }
  728.  
  729. /* repeat */
  730.  
  731. void oprepeat(void)
  732. {   struct object token, *token1, *token2, *tokenx;
  733.     if (currtoken->flags & flagctrl)
  734.     {   token2 = &execstack[execnest - 2];
  735.         token1 = token2 - 1;
  736.         if (token1->value.ival <= 0)
  737.         {   execnest -= 3;
  738.             return;
  739.         }
  740.         token1->value.ival--;
  741.         token2[2] = *token2;
  742.         execnest++;
  743.     }
  744.     else
  745.     {   if (opernest < 2) error(errstackunderflow);
  746.         token2 = &operstack[opernest - 1];
  747.         token1 = token2 - 1;
  748.         if (token1->type != typeint) error(errtypecheck);
  749.         if (token2->type != typearray && token2->type != typepacked)
  750.             error(errtypecheck);
  751.         if (execnest + 4 > execstacksize) error(errexecstackoverflow);
  752.         tokenx = &execstack[execnest];
  753.         *tokenx++ = *token1;
  754.         *tokenx++ = *token2;
  755.         token = *currtoken;
  756.         token.flags &= ~flagexec;
  757.         token.flags |= flagctrl | flagloop;
  758.         token.length = 3;
  759.         *tokenx = token;
  760.         execnest += 3;
  761.         opernest -= 2;
  762.     }
  763. }
  764.  
  765. /* resetfile */
  766.  
  767. void opresetfile(void)
  768. {   struct object *token1;
  769.     if (opernest < 1) error(errstackunderflow);
  770.     token1 = &operstack[opernest - 1];
  771.     if (token1->type != typefile) error(errtypecheck);
  772.     if (filecheck(token1, openread | openwrite) == NULL) error(errioerror);
  773.     opernest--;
  774. }
  775.  
  776. /* restore */
  777.  
  778. void oprestore(void)
  779. {   struct object *token1;
  780.     if (opernest < 1) error(errstackunderflow);
  781.     token1 = &operstack[opernest - 1];
  782.     if (token1->type != typesave) error(errtypecheck);
  783.     vmrest(token1->length, token1->value.ival);
  784.     opernest--;
  785. }
  786.  
  787. /* roll */
  788.     
  789. void oproll(void)
  790. {   struct object *token1, *token2;
  791.     int num, dir, shf;
  792.     if (opernest < 2) error(errstackunderflow);
  793.     token2 = &operstack[opernest - 1];
  794.     token1 = token2 - 1;
  795.     if (token1->type != typeint) error(errtypecheck);
  796.     num = token1->value.ival;
  797.     if (token2->type != typeint) error(errtypecheck);
  798.     dir = token2->value.ival;
  799.     if (num < 0 || num > opernest - 2) error(errrangecheck);
  800.     if (num != 0)
  801.     {   dir = dir % num;
  802.         shf = num - dir;
  803.         if (opernest + shf - 2 > operstacksize) error(errstackoverflow);
  804.         arraycopy(token1, token1 - num, shf);
  805.         arraycopy(token1 - num, token1 - dir, num);
  806.     }
  807.     opernest -= 2;
  808. }
  809.  
  810. /* round */
  811.  
  812. void opround(void)
  813. {   struct object *token1;
  814.     if (opernest < 1) error(errstackunderflow);
  815.     token1 = &operstack[opernest - 1];
  816.     if (token1->type == typeint)
  817.         return;
  818.     else if (token1->type == typereal)
  819.         token1->value.rval = (float) floor((double) token1->value.rval + .5);
  820.     else
  821.         error(errtypecheck);
  822. }
  823.  
  824. /* rrand */
  825.  
  826. void oprrand(void)
  827. {   struct object token;
  828.     if (opernest == operstacksize) error(errstackoverflow);
  829.     token.type = typeint;
  830.     token.flags = 0;
  831.     token.length = 0;
  832.     token.value.ival = random;
  833.     operstack[opernest++] = token;
  834. }
  835.  
  836. /* run */
  837.  
  838. void oprun(void)
  839. {   struct object token, *token1, *tokenx;
  840.     if (currtoken->flags & flagctrl)
  841.         execnest -= 2;
  842.     else
  843.     {   if (opernest < 1) error(errstackunderflow);
  844.         token1 = &operstack[opernest - 1];
  845.         if (token1->type != typestring) error(errtypecheck);
  846.         if (token1->flags & flagrprot) error(errinvalidaccess);
  847.         if (execnest + 3 > execstacksize) error(errexecstackoverflow);
  848.         tokenx = &execstack[execnest];
  849.         fileopen(&token, openread, vmsptr(token1->value.vref),
  850.                          token1->length);
  851.         token.flags |= flagexec;
  852.         tokenx[0] = token;
  853.         tokenx[2] = token;
  854.         token = *currtoken;
  855.         token.flags &= ~flagexec;
  856.         token.flags |= flagctrl | flagrun;
  857.         token.length = 2;
  858.         tokenx[1] = token;
  859.         execnest += 3;
  860.         opernest--;
  861.     }
  862. }
  863.  
  864. /* save */
  865.  
  866. void opsave(void)
  867. {   struct object token;
  868.     if (opernest == operstacksize) error(errstackoverflow);
  869.     vmsave(&token);
  870.     operstack[opernest++] = token;
  871. }
  872.  
  873. /* search */
  874.  
  875. void opsearch(void)
  876. {   struct object *token1, *token2;
  877.     char *sptr1, *sptr2;
  878.     int len1, len2, offs, bool;
  879.     struct object token;
  880.     if (opernest < 2) error(errstackunderflow);
  881.     if (opernest + 2 > operstacksize) error(errstackoverflow);
  882.     token2 = &operstack[opernest - 1];
  883.     token1 = token2 - 1;
  884.     if (token1->type != typestring) error(errtypecheck);
  885.     if (token1->flags & flagrprot) error(errinvalidaccess);
  886.     len1 = token1->length;
  887.     sptr1 = vmsptr(token1->value.vref);
  888.     if (token2->type != typestring) error(errtypecheck);
  889.     if (token2->flags & flagrprot) error(errinvalidaccess);
  890.     len2 = token2->length;
  891.     sptr2 = vmsptr(token2->value.vref);
  892.     offs = 0;
  893.     bool = 0;
  894.     while (offs + len2 <= len1)
  895.     {   if (memcmp(sptr1 + offs, sptr2, len2) == 0)
  896.         {   bool = 1;
  897.             break;
  898.         }
  899.         offs++;
  900.     }
  901.     if (bool)
  902.     {   token = *token1;
  903.         token.length = offs;
  904.         *(token2 + 1) = token;
  905.         token.length = len2;
  906.         token.value.vref = token1->value.vref + offs;
  907.         *token2 = token;
  908.         token.length = len1 - offs - len2;
  909.         token.value.vref = token1->value.vref + offs + len2;
  910.         *token1 = token;
  911.         token2 += 2;
  912.         opernest += 2;
  913.     }
  914.     token.type = typebool;
  915.     token.flags = 0;
  916.     token.length = 0;
  917.     token.value.ival = bool;
  918.     *token2 = token;
  919. }
  920.  
  921. /* setpacking */
  922.  
  923. void opsetpacking(void)
  924. {   struct object *token1;
  925.     if (opernest < 1) error(errstackunderflow);
  926.     token1 = &operstack[opernest - 1];
  927.     if (token1->type != typebool) error(errtypecheck);
  928.     packing = token1->value.ival;
  929.     opernest--;
  930. }
  931.  
  932. /* sin */
  933.  
  934. void opsin(void)
  935. {   struct object token, *token1;
  936.     if (opernest < 1) error(errstackunderflow);
  937.     token1 = &operstack[opernest - 1];
  938.     token = *token1;
  939.     if (token.type == typeint)
  940.     {   token.type = typereal;
  941.         token.value.rval = token.value.ival;
  942.     }
  943.     if (token.type == typereal)
  944.         token.value.rval = (float) sin((double) token.value.rval * degtorad);
  945.     else
  946.         error(errtypecheck);
  947.     *token1 = token;
  948. }
  949.  
  950. /* sqrt */
  951.  
  952. void opsqrt(void)
  953. {   struct object token, *token1;
  954.     if (opernest < 1) error(errstackunderflow);
  955.     token1 = &operstack[opernest - 1];
  956.     token = *token1;
  957.     if (token.type == typeint)
  958.     {   token.type = typereal;
  959.         token.value.rval = token.value.ival;
  960.     }
  961.     if (token.type == typereal)
  962.     {   if (token.value.rval < 0.0) error(errrangecheck);
  963.         token.value.rval = (float) sqrt((double) token.value.rval);
  964.     }
  965.     else
  966.         error(errtypecheck);
  967.     *token1 = token;
  968. }
  969.  
  970. /* srand */
  971.  
  972. void opsrand(void)
  973. {   struct object *token1;
  974.     if (opernest < 1) error(errstackunderflow);
  975.     token1 = &operstack[opernest - 1];
  976.     if (token1->type != typeint) error(errrangecheck);
  977.     random = token1->value.ival;
  978.     opernest--;
  979. }
  980.  
  981. /* stack */
  982.  
  983. void opstack(void)
  984. {   int nest = opernest;
  985.     if (sstdout)
  986.         while (nest)
  987.         {   printequals(sstdout, &operstack[--nest]);
  988.             putch(sstdout, '\n');
  989.         }
  990. }
  991.  
  992. /* status */
  993.  
  994. void opstatus(void)
  995. {   struct object token, *token1;
  996.     if (opernest < 1) error(errstackunderflow);
  997.     token1 = &operstack[opernest - 1];
  998.     if (token1->type != typefile) error(errtypecheck);
  999.     token.type = typebool;
  1000.     token.flags = 0;
  1001.     token.length = 0;
  1002.     token.value.ival =
  1003.         (filecheck(token1, openread | openwrite) != NULL);
  1004.     *token1 = token;
  1005. }
  1006.  
  1007. /* stop */
  1008.  
  1009. void opstop(void)
  1010. {   stop();
  1011.     error(errinvalidstop);
  1012. }
  1013.  
  1014. /* stopped */
  1015.  
  1016. void opstopped(void)
  1017. {   struct object token, *token1, *tokenx;
  1018.     if (opernest == operstacksize) error(errstackoverflow);
  1019.     if (currtoken->flags & flagctrl)
  1020.     {   if (opernest == operstacksize) error(errstackoverflow);
  1021.         token.type = typebool;
  1022.         token.flags = 0;
  1023.         token.length = 0;
  1024.         token.value.ival = 0;
  1025.         operstack[opernest++] = token;
  1026.         execnest -= 2;
  1027.     }
  1028.     else
  1029.     {   if (opernest < 1) error(errstackunderflow);
  1030.         token1 = &operstack[opernest - 1];
  1031.         if (execnest + 3 > execstacksize) error(errexecstackoverflow);
  1032.         tokenx = &execstack[execnest];
  1033.         tokenx[0] = *token1;
  1034.         token = *currtoken;
  1035.         token.flags &= ~flagexec;
  1036.         token.flags |= flagctrl | flagstop;
  1037.         token.length = inest;
  1038.         tokenx[1] = token;
  1039.         tokenx[2] = *token1;
  1040.         execnest += 3;
  1041.         opernest--;
  1042.     }
  1043. }
  1044.  
  1045. /* store */
  1046.  
  1047. void opstore(void)
  1048. {   struct object token, *token1, *token2;
  1049.     int nest;
  1050.     if (opernest < 2) error(errstackunderflow);
  1051.     token2 = &operstack[opernest - 1];
  1052.     token1 = token2 - 1;
  1053.     nest = dictfind(token1, &token);
  1054.     if (nest == -1) nest = dictnest - 1;
  1055.     dictput(dictstack[nest].value.vref, token1, token2);
  1056.     opernest -= 2;
  1057. }
  1058.  
  1059. /* string */
  1060.  
  1061. void opstring(void)
  1062. {   struct object token, *token1;
  1063.     int length;
  1064.     if (opernest < 1) error(errstackunderflow);
  1065.     token1 = &operstack[opernest - 1];
  1066.     if (token1->type != typeint) error(errtypecheck);
  1067.     length = token1->value.ival;
  1068.     if (length < 0 || length > 65535) error(errrangecheck);
  1069.     token.type = typestring;
  1070.     token.flags = 0;
  1071.     token.length = token1->value.ival;
  1072.     token.value.vref = vmalloc(length);
  1073.     *token1 = token;
  1074. }
  1075.  
  1076. /* sub */
  1077.  
  1078. void opsub(void)
  1079. {   struct object token, *token1, *token2;
  1080.     int num1, num2;
  1081.     if (opernest < 2) error(errstackunderflow);
  1082.     token2 = &operstack[opernest - 1];
  1083.     token1 = token2 - 1;
  1084.     if (token1->type == typeint && token2->type == typeint)
  1085.     {   num1 = token1->value.ival;
  1086.         num2 = token2->value.ival;
  1087.         if      (num1 > 0 && num2 < 0)
  1088.         {   num1 -= num2;
  1089.             if (num1 > 0)
  1090.             {   token1->value.ival = num1;
  1091.                 opernest--;
  1092.                 return;
  1093.             }
  1094.         }
  1095.         else if (num1 < 0 && num2 > 0)
  1096.         {   num1 -= num2;
  1097.             if (num1 < 0)
  1098.             {   token1->value.ival = num1;
  1099.                 opernest--;
  1100.                 return;
  1101.             }
  1102.         }
  1103.         else
  1104.         {   num1 -= num2;
  1105.             token1->value.ival = num1;
  1106.             opernest--;
  1107.             return;
  1108.         }
  1109.     }
  1110.     token = *token1;
  1111.     if (token.type == typeint)
  1112.     {   token.type = typereal;
  1113.         token.value.rval = token.value.ival;
  1114.     }
  1115.     else
  1116.         if (token.type != typereal) error(errtypecheck);
  1117.     if (token2->type == typeint)
  1118.         token.value.rval -= token2->value.ival;
  1119.     else
  1120.     {   if (token2->type != typereal) error(errtypecheck);
  1121.         token.value.rval -= token2->value.rval;
  1122.     }
  1123.     *token1 = token;
  1124.     opernest--;
  1125. }
  1126.  
  1127. /* token */
  1128.  
  1129. void optoken(void)
  1130. {   struct object token, *token1;
  1131.     int bool;
  1132.     if (opernest < 1) error(errstackunderflow);
  1133.     token1 = &operstack[opernest - 1];
  1134.     if     (token1->type == typefile)
  1135.     {    if (opernest + 1 > operstacksize) error(errstackoverflow);
  1136.          bool = scantoken(&token, token1, -1);
  1137.          if (bool)
  1138.          {   *token1++ = token;
  1139.              opernest++;
  1140.          }
  1141.          else
  1142.              fileclose(token1);
  1143.     }
  1144.     else if (token1->type == typestring)
  1145.     {    if (opernest + 2 > operstacksize) error(errstackoverflow);
  1146.          bool = scantoken(&token, token1, -1);
  1147.          if (bool)
  1148.          {   token1++;
  1149.              *token1++ = token;
  1150.              opernest += 2;
  1151.          }
  1152.     }
  1153.     else
  1154.         error(errtypecheck);
  1155.     token.type = typebool;
  1156.     token.flags = 0;
  1157.     token.length = 0;
  1158.     token.value.ival = bool;
  1159.     *token1 = token;
  1160. }
  1161.  
  1162. /* truncate */
  1163.  
  1164. void optruncate(void)
  1165. {   struct object *token1;
  1166.     if (opernest < 1) error(errstackunderflow);
  1167.     token1 = &operstack[opernest - 1];
  1168.     if (token1->type == typeint)
  1169.         return;
  1170.     else if (token1->type == typereal)
  1171.         if (token1->value.rval > 0.0)
  1172.             token1->value.rval = (float) floor((double) token1->value.rval);
  1173.         else
  1174.             token1->value.rval = (float) ceil((double) token1->value.rval);
  1175.     else
  1176.         error(errtypecheck);
  1177. }
  1178.  
  1179. /* type */
  1180.  
  1181. void optype(void)
  1182. {   struct object token, *token1;
  1183.     char *sptr;
  1184.     if (opernest < 1) error(errstackunderflow);
  1185.     token1 = &operstack[opernest - 1];
  1186.     sptr = typetable[token1->type];
  1187.     nametoken(&token, sptr, -1, flagexec);
  1188.     *token1 = token;
  1189. }
  1190.  
  1191. /* usertime */
  1192.  
  1193. void opusertime(void)
  1194. {   struct object token;
  1195.     if (opernest == operstacksize) error(errstackoverflow);
  1196.     token.type = typeint;
  1197.     token.flags = 0;
  1198.     token.length = 0;
  1199.     token.value.ival = usertime();
  1200.     operstack[opernest++] = token;
  1201. }
  1202.  
  1203. /* vmhwm */
  1204.  
  1205. void opvmhwm(void)
  1206. {   struct object token, *token1;
  1207.     if (opernest + 2 > operstacksize) error(errstackoverflow);
  1208.     token1 = &operstack[opernest];
  1209.     token.type = typeint;
  1210.     token.flags = 0;
  1211.     token.length = 0;
  1212.     token.value.ival = vmhwm;
  1213.     token1[0] = token;
  1214.     token.value.ival = vmmax;
  1215.     token1[1] = token;
  1216.     opernest += 2;
  1217.     vmhwm = vmused;
  1218. }
  1219.  
  1220. /* vmstatus */
  1221.  
  1222. void opvmstatus(void)
  1223. {   struct object token, *token1;
  1224.     if (opernest + 3 > operstacksize) error(errstackoverflow);
  1225.     token1 = &operstack[opernest];
  1226.     token.type = typeint;
  1227.     token.flags = 0;
  1228.     token.length = 0;
  1229.     token.value.ival = vmnest;
  1230.     token1[0] = token;
  1231.     token.value.ival = vmused;
  1232.     token1[1] = token;
  1233.     token.value.ival = vmmax;
  1234.     token1[2] = token;
  1235.     opernest += 3;
  1236. }
  1237.  
  1238. /* wcheck */
  1239.  
  1240. void opwcheck(void)
  1241. {   struct object token, *token1;
  1242.     int type, bool;
  1243.     if (opernest < 1) error(errstackunderflow);
  1244.     token1 = &operstack[opernest - 1];
  1245.     type = token1->type;
  1246.     if      (type == typefile || type == typestring ||
  1247.              type == typearray || type == typepacked)
  1248.         bool = ((token1->flags & flagwprot) == 0);
  1249.     else if (type == typedict)
  1250.         bool = ((vmdptr(token1->value.vref)->flags & flagwprot) == 0);
  1251.     else
  1252.         error(errtypecheck);
  1253.     token.type = typebool;
  1254.     token.flags = 0;
  1255.     token.length = 0;
  1256.     token.value.ival = bool;
  1257.     *token1 = token;
  1258. }
  1259.  
  1260. /* where */
  1261.  
  1262. void opwhere(void)
  1263. {   struct object token, *token1;
  1264.     int nest;
  1265.     if (opernest < 1) error(errstackunderflow);
  1266.     if (opernest + 2 > operstacksize) error(errstackoverflow);
  1267.     token1 = &operstack[opernest - 1];
  1268.     nest = dictfind(token1, &token);
  1269.     token.type = typebool;
  1270.     token.flags = 0;
  1271.     token.length = 0;
  1272.     token.value.ival = 0;
  1273.     if (nest != -1)
  1274.     {   *token1++ = dictstack[nest];
  1275.         opernest++;
  1276.         token.value.ival = 1;
  1277.     }
  1278.     *token1 = token;
  1279. }
  1280.  
  1281. /* write */
  1282.  
  1283. void opwrite(void)
  1284. {   struct object *token1, *token2;
  1285.     struct file *file;
  1286.     if (opernest < 2) error(errstackunderflow);
  1287.     token2 = &operstack[opernest - 1];
  1288.     token1 = token2 - 1;
  1289.     if (token1->type != typefile) error(errtypecheck);
  1290.     if (token1->flags & flagwprot) error(errinvalidaccess);
  1291.     file = filecheck(token1, openwrite);
  1292.     if (file == NULL) error(errioerror);
  1293.     if (token2->type != typeint) error(errtypecheck);
  1294.     if (putc(token2->value.ival, file->fptr) == EOF) error(errioerror);
  1295.     opernest -= 2;
  1296. }
  1297.  
  1298. /* writehexstring */
  1299.  
  1300. void opwritehexstring(void)
  1301. {   struct object *token1, *token2;
  1302.     struct file *file;
  1303.     FILE *fptr;
  1304.     char *sptr;
  1305.     int length, ch, num;
  1306.     if (opernest < 2) error(errstackunderflow);
  1307.     token2 = &operstack[opernest - 1];
  1308.     token1 = token2 - 1;
  1309.     if (token1->type != typefile) error(errtypecheck);
  1310.     if (token1->flags & flagwprot) error(errinvalidaccess);
  1311.     file = filecheck(token1, openwrite);
  1312.     if (file == NULL) error(errioerror);
  1313.     fptr = file->fptr;
  1314.     if (token2->type != typestring) error(errtypecheck);
  1315.     if (token2->flags & flagrprot) error(errinvalidaccess);
  1316.     length = token2->length;
  1317.     sptr = vmsptr(token2->value.vref);
  1318.     while (length--)
  1319.     {   num = *(unsigned char *)(sptr++);
  1320.         ch = num >> 4;
  1321.         ch += (ch < 10) ? '0' : 'a' - 10;
  1322.         if (putc(ch, fptr) == EOF) error(errioerror);
  1323.         ch = num & 15;
  1324.         ch += (ch < 10) ? '0' : 'a' - 10;
  1325.         if (putc(ch, fptr) == EOF) error(errioerror);
  1326.     }
  1327.     opernest -= 2;
  1328. }
  1329.  
  1330. /* writestring */
  1331.  
  1332. void opwritestring(void)
  1333. {   struct object *token1, *token2;
  1334.     struct file *file;
  1335.     if (opernest < 2) error(errstackunderflow);
  1336.     token2 = &operstack[opernest - 1];
  1337.     token1 = token2 - 1;
  1338.     if (token1->type != typefile) error(errtypecheck);
  1339.     if (token1->flags & flagwprot) error(errinvalidaccess);
  1340.     file = filecheck(token1, openwrite);
  1341.     if (file == NULL) error(errioerror);
  1342.     if (token2->type != typestring) error(errtypecheck);
  1343.     if (token2->flags & flagrprot) error(errinvalidaccess);
  1344.     putmem(file->fptr, vmsptr(token2->value.vref), token2->length);
  1345.     opernest -= 2;
  1346. }
  1347.  
  1348. /* xcheck */
  1349.  
  1350. void opxcheck(void)
  1351. {   struct object token, *token1;
  1352.     int bool;
  1353.     if (opernest < 1) error(errstackunderflow);
  1354.     token1 = &operstack[opernest - 1];
  1355.     bool = ((token1->flags & flagexec) != 0);
  1356.     token.type = typebool;
  1357.     token.flags = 0;
  1358.     token.length = 0;
  1359.     token.value.ival = bool;
  1360.     *token1 = token;
  1361. }
  1362.  
  1363. /* xor */
  1364.  
  1365. void opxor(void)
  1366. {   struct object *token1, *token2;
  1367.     if (opernest < 2) error(errstackunderflow);
  1368.     token2 = &operstack[opernest - 1];
  1369.     token1 = token2 - 1;
  1370.     if ((token1->type == typebool && token2->type == typebool) ||
  1371.         (token1->type == typeint  && token2->type == typeint))
  1372.         token1->value.ival ^= token2->value.ival;
  1373.     else
  1374.         error(errtypecheck);
  1375.     opernest--;
  1376. }
  1377.  
  1378. /* Initialise the operators (2) */
  1379.  
  1380. void initop2(void)
  1381. {   systemop(opindex,            "index");
  1382.     systemop(opknown,            "known");
  1383.     systemop(ople,               "le");
  1384.     systemop(oplength,           "length");
  1385.     systemop(opln,               "ln");
  1386.     systemop(opload,             "load");
  1387.     systemop(oplog,              "log");
  1388.     systemop(oploop,             "loop");
  1389.     systemop(oplt,               "lt");
  1390.     systemop(opmaxlength,        "maxlength");
  1391.     systemop(opmod,              "mod");
  1392.     systemop(opmul,              "mul");
  1393.     systemop(opne,               "ne");
  1394.     systemop(opneg,              "neg");
  1395.     systemop(opnoaccess,         "noaccess");
  1396.     systemop(opnot,              "not");
  1397.     systemop(opnull,             "null");
  1398.     systemop(opor,               "or");
  1399.     systemop(oppackedarray,      "packedarray");
  1400.     systemop(oppop,              "pop");
  1401.     systemop(opprint,            "print");
  1402.     systemop(opprompts,          "prompts");
  1403.     systemop(oppstack,           "pstack");
  1404.     systemop(opput,              "put");
  1405.     systemop(opputinterval,      "putinterval");
  1406.     systemop(opquit,             "quit");
  1407.     systemop(oprcheck,           "rcheck");
  1408.     systemop(oprand,             "rand");
  1409.     systemop(opread,             "read");
  1410.     systemop(opreadhexstring,    "readhexstring");
  1411.     systemop(opreadline,         "readline");
  1412.     systemop(opreadonly,         "readonly");
  1413.     systemop(opreadstring,       "readstring");
  1414.     systemop(oprepeat,           "repeat");
  1415.     systemop(opresetfile,        "resetfile");
  1416.     systemop(oprestore,          "restore");
  1417.     systemop(oproll,             "roll");
  1418.     systemop(opround,            "round");
  1419.     systemop(oprrand,            "rrand");
  1420.     systemop(oprun,              "run");
  1421.     systemop(opsave,             "save");
  1422.     systemop(opsearch,           "search");
  1423.     systemop(opsetpacking,       "setpacking");
  1424.     systemop(opsin,              "sin");
  1425.     systemop(opsqrt,             "sqrt");
  1426.     systemop(opsrand,            "srand");
  1427.     systemop(opstack,            "stack");
  1428.     systemop(opstatus,           "status");
  1429.     systemop(opstop,             "stop");
  1430.     systemop(opstopped,          "stopped");
  1431.     systemop(opstore,            "store");
  1432.     systemop(opstring,           "string");
  1433.     systemop(opsub,              "sub");
  1434.     systemop(optoken,            "token");
  1435.     systemop(optruncate,         "truncate");
  1436.     systemop(optype,             "type");
  1437.     systemop(opusertime,         "usertime");
  1438.     systemop(opvmhwm,            "vmhwm");
  1439.     systemop(opvmstatus,         "vmstatus");
  1440.     systemop(opwcheck,           "wcheck");
  1441.     systemop(opwhere,            "where");
  1442.     systemop(opwrite,            "write");
  1443.     systemop(opwritehexstring,   "writehexstring");
  1444.     systemop(opwritestring,      "writestring");
  1445.     systemop(opxcheck,           "xcheck");
  1446.     systemop(opxor,              "xor");
  1447. }
  1448.  
  1449. /* End of file "postop2.c" */
  1450.