home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume2 / basic / part1 / newbs / bsint.c < prev    next >
Encoding:
C/C++ Source or Header  |  1986-11-30  |  5.3 KB  |  257 lines

  1. /* bsint.c -- main part of interpretor.
  2.  */
  3.  
  4. #include "bsdefs.h"
  5.  
  6. int (*_null[])() = { 0,0 };
  7.  
  8. struct line llist[NUMLINES] = {
  9.     0, _null, "",
  10.     MAXLN, _null, ""
  11. };
  12.  
  13. struct line *lastline = &llist[1];
  14. struct line *Thisline = &llist[0];
  15. int Thisp = 0;
  16.  
  17. struct dictnode vlist[VLSIZ];
  18.  
  19.  
  20.  
  21. /* gtok() -- read a token using input().  Tokens are delimited by whitespace.
  22.  *    When '\n' is found, "\n" is returned.
  23.  *    For EOF or control characters (not '\n' or '\t') 0 is returned.
  24.  */
  25. char *gtok()
  26. {
  27.     static char token[20];
  28.     register char *s,c;
  29.  
  30.     s = &token[0];
  31. loop: c=input();
  32.     if(c==' ' || c=='\t') goto loop;
  33.     else if(c == '\n') return("\n");
  34.     else if(c==EOF || iscntrl(c)) return(0);
  35.     else {
  36.     *s++ = c;
  37.     for(c=input(); c>' ' && c<='~'; c=input())
  38.         *s++ = c;
  39.     unput(c);
  40.     *s++ = '\0';
  41.     return(token);
  42.     }
  43. }
  44.  
  45. /* insline(num) -- insert num into llist with insertion sort style.
  46.  *    Replaces old lines if already in list.
  47.  */
  48. struct line *insline(num)
  49. int num;
  50. {
  51.     struct line *p,*p2,*p3;
  52.     struct dictnode *vp;
  53.     struct dictnode *gvadr();
  54.     char s[12];
  55.  
  56.     if(lastline == LASTLINE) return(0);
  57.     for(p=lastline; p->num > num; p--)
  58.     /* null */ ;
  59.     if(p->num == num) {
  60.     if(p->code != 0) { free(p->code); p->code = 0; }
  61.     if(p->text != 0) { free(p->text); p->text = 0; }
  62.     }
  63.     else { /* p->num < num */
  64.     ++p;
  65.     p2=lastline;
  66.     p3= ++lastline;
  67.     while(p2 >= p) {
  68.         p3->num = p2->num;
  69.         p3->code = p2->code;
  70.         p3->text = p2->text;
  71.         p2--;
  72.         p3--;
  73.     }
  74.     p->num = num;
  75.     p->text = p->code = 0;
  76.     }
  77.     sprintf(s,"LN%d",num);
  78.     vp = gvadr(s,T_LBL);
  79.     vp->val.lval.codelist = p;
  80.     vp->val.lval.place = 0;
  81.     return(p);
  82. }
  83.  
  84.  
  85.  
  86. /* gladr() -- get address of llist entry, given the line number.
  87.  */
  88. struct line *gladr(lnum)
  89. unsigned lnum;
  90. {
  91.     register struct line *q;
  92.     register int num;
  93.  
  94.     num = lnum;
  95.     for(q= &llist[0]; q->num!=num && q->num!=MAXLN ; q++)
  96.         ;
  97.     if(q->num == MAXLN) return(0);
  98.     /* else */
  99.     if(q->code==0 && q->text==0) return(0); /* fake line */
  100.     /* else */
  101.     return(q); /* found place */
  102. }
  103.  
  104. /* gllentry() -- Given an address for a code list, return llist entry which
  105.  *    has matching code list address.
  106.  */
  107. struct line *gllentry(l)
  108. int **l;
  109. {
  110.     register int llp;
  111.  
  112.     for(llp=0; llist[llp].num != MAXLN; llp++)
  113.     if(llist[llp].code == l)
  114.         return(&llist[llp]);
  115.  
  116.     return(0);    /* such an entry not found */
  117. }
  118.  
  119. /* glist() -- read rest of line as a code list, return the corresponding
  120.  *    code list.
  121.  */
  122. int **glist()
  123. {
  124.     register char *s;
  125.     int (*codestring[100])();
  126.     int lp,(**l)();
  127.     register int i;
  128.  
  129.     lp=0;
  130.     for(s=gtok(); s!=0 && strcmp(s,"\n")!=0; s=gtok()) {
  131.     for(i=0; wlist[i].name!=0; i++)
  132.         if(strcmp(wlist[i].name,s)==0)
  133.         break;
  134.     if(wlist[i].name == 0) {
  135.         fprintf(stderr,"unknown name %s\n",s);
  136.         exit(1);
  137.     }
  138.     if(wlist[i].funct == 0) {
  139.         fprintf(stderr,"glist: no function for %s at %o\n",s,&wlist[i]);
  140.         exit(1);
  141.     }
  142.     codestring[lp++] = wlist[i].funct;
  143.     lp = (*wlist[i].funct)(codestring,lp);
  144.     }
  145.     codestring[lp++] = 0;
  146.     l = myalloc(lp*2+1);
  147.     blcpy(l,codestring,lp*2);
  148.     return(l);
  149. }
  150.  
  151. /* rprg -- read in a bunch of lines, put them in program buffer.
  152.  */
  153. rprg()
  154. {
  155.     char *s;
  156.     int ln;
  157.     struct line *pl;
  158.  
  159.     for(s=gtok(); s!=0; s=gtok()) {
  160.     if(strcmp(s,"line") == 0) {
  161.         s=gtok();
  162.         ln=atoi(s);
  163.         pl=insline(ln);
  164.         if(pl == 0) {
  165.         fprintf(stderr,"out of room for program\n");
  166.         exit(1);
  167.         }
  168.         s=myalloc(strlen(ibuf)+1);
  169.         strcpy(s,ibuf);
  170.         pl->text = s;
  171.         pl->code = glist();
  172.     }
  173.     else { 
  174.         fprintf(stderr,"syntax error, no line number: %s\n",ibuf);
  175.         exit(1);
  176.     }
  177.     }
  178. }
  179.  
  180.  
  181. interp(l,start)
  182. int (*l[])(),start;
  183. {
  184.     int lp;
  185.     for(lp=start+1; l[lp-1]!=0; lp++)
  186.     lp = (*l[lp-1])(l,lp);
  187.     return(lp);
  188. }
  189.  
  190. /* runit() -- run the program in llist.  arg- address of place to start at.
  191.  *
  192.  * to do a goto type action, set Thisline to llist entry PREVIOUS to 
  193.  * desired place.  Set Thisp to desired index.  To cause it to happen,
  194.  * place a 0 in the code list where interp() will see it at the right
  195.  * time.
  196.  *
  197.  * All this will cause runit() to run correctly, and automatically take
  198.  * care of updating the line number pointers (Thisline and Thisp).
  199.  */
  200. runit()
  201. {
  202.     int ourthisp;
  203.  
  204.     ourthisp = Thisp;
  205.     Thisp = 0;
  206.     while(Thisline < lastline) {
  207.     interp((Thisline->code),ourthisp);
  208.     ++Thisline;
  209.     ourthisp = Thisp;
  210.     Thisp = 0;
  211.     }
  212. }
  213.  
  214. int dbg = 0;    /* debugging flag. */
  215. main(argc,argv)
  216. int argc;
  217. char **argv;
  218. {
  219.     int i,j;
  220.     int (**l)();
  221.  
  222.     if(argc >= 2) {
  223.     if((bsin=fopen(argv[1],"r")) == NULL) {
  224.         fprintf(stderr,"main: could not open input file %s\n",argv[1]);
  225.         exit(1);
  226.     }
  227.     }
  228.     if(argc > 2)
  229.     dbg = 1;    /* "int file <anything>" sets debugging */
  230.  
  231.     /* Read the program (on file bsin) and compile it to the executable code. */
  232.     rdlin(bsin);
  233.     status = M_COMPILE;
  234.     rprg();
  235.     if(bsin != stdin) 
  236.     fclose(bsin);
  237.     bsin = stdin;    /* make sure it is stdin for execution */
  238.     iptr = 0;
  239.     ibuf[iptr] = 0;    /* make the input buffer empty. */
  240.  
  241.     /* Scan through the compiled code, make sure things point to where
  242.      * they are supposed be pointing to, etc.
  243.      */
  244.     status = M_FIXUP;
  245.     Thisline = &llist[0];
  246.     while(Thisline < lastline) {
  247.     interp((Thisline->code),0);
  248.     ++Thisline;
  249.     }
  250.  
  251.     status = M_EXECUTE;
  252.     dlp = 0;    /* set it back to beginning of list */
  253.     Thisline = &llist[0];
  254.     Thisp = 0;
  255.     runit();
  256. }
  257.