/*********************************************************/
/*                                                       */
/* PISTOL-Portably Implemented Stack Oriented Language   */
/*                      Version 1.3                      */
/* (C) 1982 by  Ernest E. Bergmann                       */
/*              Physics, Building #16                    */
/*              Lehigh Univerisity                       */
/*              Bethlehem, Pa. 18015                     */
/*                                                       */
/* Permission is hereby granted for all reproduction and */
/* distribution of this material provided this notice is */
/* is included.                                          */
/*                                                       */
/*********************************************************/

/* second pistol module, February, 1982 */

#include "bdscio.h"
#include "pistol.h"

init()
{int psemcol(),wstore(),times(),plus(),subtract(),
       divmod(),pif(),wat(),abort(),sp(),
       load(),pelse(),wrd(),rp(),drop(),
       puser(),exec(),exitop(),lit(),rpop(),
       swap(),tyi(),tyo(),rpsh(),semicf(),
       rat(),compme(),comphere(),dollarc(),colon(),
       semcol(),ifop(),elseop(),thenop(),doop(),
       loopop(),beginop(),endop(),repet(),geoln(),pdollar(),
       pcolon(),casat(),pdo(),pploop(),plloop(),
       cat(),cstore(),ploop(),gt(),semidol(),
       kernq(),strange(),sat(),findop(),listfil(),
       lat(),ofcas(),ccolon(),semicc(),ndcas(),
       pofcas(),pccol(),psemicc(),getline(),intoken(),
       openr(),openw(),readl(),writl(),cordmp(),
       restor();

       farray[PSEMICOL]=psemcol;
       farray[WSTORE]=wstore;
       farray[TIMES]=times;
       farray[PLUS]=plus;
       farray[SUBTRACT]=subtract;
       farray[DIVMOD]=divmod;
       farray[PIF]=pif;
       farray[WAT]=wat;
       farray[ABRT]=abort;
       farray[SP]=sp;
       farray[LOAD]=load;
       farray[PELSE]=pelse;
       farray[WRD]=wrd;
       farray[RP]=rp;
       farray[DROPOP]=drop;
       farray[PUSER]=puser;
       farray[EXEC]=exec;
       farray[EXITOP]=exitop;
       farray[STRLIT]=farray[LIT]=lit;
       farray[RPOP]=rpop;
       farray[SWP]=swap;
       farray[TYI]=tyi;
       farray[TYO]=tyo;
       farray[RPSH]=rpsh;
       farray[SEMICF]=semicf;
       farray[RAT]=rat;
       farray[COMPME]=compme;
       farray[COMPHERE]=comphere;
       farray[DOLLARC]=dollarc;
       farray[COLON]=colon;
       farray[SEMICOLON]=semcol;
       farray[IFOP]=ifop;
       farray[ELSEOP]=elseop;
       farray[THENOP]=thenop;
       farray[DOOP]=doop;
       farray[LOOPOP]=loopop;
       farray[BEGINOP]=beginop;
       farray[ENDOP]=endop;
       farray[REPET]=repet;
       farray[PERCENT]=geoln;
       farray[PDOLLAR]=pdollar;
       farray[PCOLON]=pcolon;
       farray[CASAT]=casat;
       farray[PDOOP]=pdo;
       farray[PPLOOP]=pploop;
       farray[PLLOOP]=plloop;
       farray[CAT]=cat;
       farray[CSTORE]=cstore;
       farray[PLOOP]=ploop;
       farray[GT]=gt;
       farray[SEMIDOL]=semidol;
       farray[KRNQ]=kernq;
       farray[53]=farray[54]=strange;
       farray[SAT]=sat;
       farray[FINDOP]=findop;
       farray[LISTFIL]=listfil;
       farray[58]=strange;
       farray[LAT]=lat;
       farray[OFCAS]=ofcas;
       farray[CCOLON]=ccolon;
       farray[SEMICC]=semicc;
       farray[NDCAS]=ndcas;
       farray[POFCAS]=pofcas;
       farray[PCCOL]=pccol;
       farray[PSEMICC]=psemicc;
       farray[GTLIN]=getline;
       farray[WORD]=intoken();
       farray[OPENR]=openr;
       farray[OPENW]=openw;
       farray[READL]=readl;
       farray[WRITL]=writl;
       farray[CORDMP]=cordmp;
       farray[RESTOR]=restor;

       penter(2,"W!",WSTORE);
       penter(1,"*",TIMES);
       penter(1,"+",PLUS);
       penter(1,"-",SUBTRACT);
       penter(4,"/MOD",DIVMOD);
       penter(2,"W@",WAT);
       penter(5,"ABORT",ABRT);
       penter(2,"SP",SP);
       penter(4,"LOAD",LOAD);
       penter(1,"W",WRD);
       penter(2,"RP",RP);
       penter(4,"DROP",DROPOP);
       penter(4,"USER",PUSER);
       penter(4,"EXEC",EXEC);
       penter(4,"EXIT",EXITOP);
       penter(2,"R>",RPOP);
       penter(4,"SWAP",SWP);
       penter(3,"TYI",TYI);
       penter(3,"TYO",TYO);
       penter(2,"<R",RPSH);
       penter(2,";F",SEMICF);
       penter(2,"R@",RAT);
       penter(2,"$:",-DOLLARC);
       penter(1,":",-COLON);
       penter(1,";",-SEMICOLON);
       penter(2,"IF",-IFOP);
       penter(4,"ELSE",-ELSEOP);
       penter(4,"THEN",-THENOP);
       penter(2,"DO",-DOOP);
       penter(4,"LOOP",-LOOPOP);
       penter(5,"BEGIN",-BEGINOP);
       penter(3,"END",-ENDOP);
       penter(6,"REPEAT",-REPET);
       penter(1,"%",-PERCENT);
       penter(5,"CASE@",CASAT);
       penter(5,"+LOOP",-PLLOOP);
       penter(2,"C@",CAT);
       penter(2,"C!",CSTORE);
       penter(2,"GT",GT);
       penter(2,";$",-SEMIDOL);
       penter(7,"KERNEL?",KRNQ);
       penter(2,"S@",SAT);
       penter(4,"FIND",FINDOP);
       penter(8,"LISTFILE",LISTFIL);
       penter(2,"L@",LAT);
       penter(6,"OFCASE",-OFCAS);
       penter(2,"C:",-CCOLON);
       penter(2,";C",-SEMICC);
       penter(7,"ENDCASE",-NDCAS);
       penter(4,"(;C)",PSEMICC);
       penter(7,"GETLINE",GTLIN);
       penter(4,"WORD",WORD);
       penter(5,"OPENR",OPENR);
       penter(5,"OPENW",OPENW);
       penter(8,"READLINE",READL);
       penter(9,"WRITELINE",WRITL);
       penter(8,"COREDUMP",CORDMP);
       penter(7,"RESTORE",RESTOR);
}


tyi()   /* inputs a character from the keyboard,buffered line*/
{       if(*ram[-15].pc == NEWLINE) cinline();
       else nextch();
       push(*ram[-15].pc);
}

psemcol()
{ ip=rstack[rptr--];
}

wstore()
{       drop(); drop(); Pw=stack[2+stkptr];
                       *Pw=stack[1+stkptr];
}

times()
{       drop(); stack[stkptr] *= stack[1+stkptr];
}

plus()
{       drop(); stack[stkptr] += stack[1+stkptr];
}

subtract()
{       drop();stack[stkptr] -= stack[1+stkptr];
}

divmod()
{       if(stack[stkptr])
               {stack[1+stkptr]=
                       stack[stkptr-1]/stack[stkptr];
               stack[stkptr]=
                       stack[-1+stkptr]%stack[stkptr];
               stack[stkptr-1]=stack[stkptr+1];
               }
       else merr(divby0);
}

pif()
{       drop();
       if(stack[1+stkptr]) ip+=W;
       else{Pw=ip;ip+=*Pw;}
}

wat()
{ Pw=stack[stkptr]; stack[stkptr]=*Pw;
}

sp()
{ push(stkptr); }

load()
{       drop();
       ram[-11].in=stack[stkptr+1];
       if(ram[-11].in>MAXLINNO)
               {movmem(ram[-11].pc+1,infil1,
                               *ram[-11].pc);
               infil1[*ram[-11].pc]='\0';
               if(fopen(infil1,ldfil1) == ERROR)
                       {printf("can't open %s\n",
                               infil1);
                       abort();
                       }
               ram[-29].in=0;
               }
}

pelse()
{ Pw=ip; ip += *Pw;}

wrd()
{ push(W); }

rp()
{ push(rptr); }

puser()
{ push(ram); }

exec()
{       instr=stack[stkptr]; drop();
       if(instr<(RESTOR+1)) (*farray[instr])();
       else {rpush(ip);ip=instr;}
}

exitop()
{       if(lptr<3) abort();
       else lstack[lptr]=lstack[lptr-1];
}

lit()
{ Pw=ip; push(*Pw); ip +=W; }

rpop()
{ push(rstack[rptr]);rptr--; }

tyo()
{ drop(); chout(stack[stkptr+1]); }

rpsh()
{ rpush(stack[stkptr]);drop(); }

semicf()
{       if(ram[-24].in) carret();
       if((ram[-11].in<MAXLINNO)&&(ram[-11].in>0))
               {ram[-11].in--;
               printf("\n THROUGH LINE %d(DECIMAL) LOADED\n",
                       ram[-11].in);
               if(ram[-12].in)
               fprintf(list,
                       "\n THROUGH LINE %d(DECIMAL) LOADED\n",
                       ram[-11].in);
               }
       if(ram[-11].in>=MAXLINNO)
               {printf("%s LOADED\n",infil1);
               if(ram[-12].in)
                       fprintf(list,"%s LOADED\n",infil1);
               }
       ram[-11].in=0;
}

rat()
{       drop();
       if(rptr<stack[1+stkptr])merr(undflo);
       push(rstack[rptr-stack[stkptr+1]]);
}

compme()
{       Pw2=ip;Pw2 -= 4; j=*Pw2; Pw2=ip;
       while(Pw2<j)    {compile(*Pw2);Pw2++;}
       ip=rstack[rptr--];
}

comphere()
{       compile(ip);
       ip=rstack[rptr--];
}

dollarc()
{       pushck('$');compile(PDOLLAR);
       fwdref();
}

colon()
{       pushck(':'); compile(PCOLON);
       fwdref();
}

semcol()
{       if(strings[1+strings[1]]==':')
               {dropck();compile(PSEMICOLON);touchup();}
       else synterr();
}

ifop()
{ pushck('F');compile(PIF);fwdref(); }

elseop()
{       if(strings[1+strings[1]]=='F')
               {strings[1+strings[1]]='E';
               compile(PELSE);fwdref();
               swap();touchup();
               }
       else synterr();
}

thenop()
{       Pc= &strings[1]; Pc += *Pc;
       if((*Pc=='F')||(*Pc=='E'))
               {dropck();touchup();}
       else synterr();
}

doop()
{ pushck('D');compile(PDOOP);fwdref(); }

loopop()
{       if(strings[1+strings[1]]=='D')
               {dropck(); compile(PLOOP);
               compile(stack[stkptr]-ram[-2].in+W);
               touchup();
               }
       else synterr();
}