Research V6 development
authorBrian W. Kernighan <bwk@research.uucp>
Wed, 14 May 1975 00:43:47 +0000 (19:43 -0500)
committerBrian W. Kernighan <bwk@research.uucp>
Wed, 14 May 1975 00:43:47 +0000 (19:43 -0500)
Work on file usr/source/rat/r.h
Work on file usr/source/rat/r2.c
Work on file usr/source/rat/r.g
Work on file usr/source/rat/r1.c
Work on file usr/source/rat/lex.c

Synthesized-from: v6

usr/source/rat/lex.c [new file with mode: 0644]
usr/source/rat/r.g [new file with mode: 0644]
usr/source/rat/r.h [new file with mode: 0644]
usr/source/rat/r1.c [new file with mode: 0644]
usr/source/rat/r2.c [new file with mode: 0644]

diff --git a/usr/source/rat/lex.c b/usr/source/rat/lex.c
new file mode 100644 (file)
index 0000000..4da5ece
--- /dev/null
@@ -0,0 +1,281 @@
+# include "r.h"
+
+char *keyword []{
+       "do", "DO",     /* have to be first */
+       "if", "IF",
+       "else", "ELSE",
+       "for", "FOR",
+       "repeat", "REPEAT",
+       "until", "UNTIL",
+       "while", "WHILE",
+       "break", "BREAK",
+       "next", "NEXT",
+       "define", "DEFINE",
+       "include", "INCLUDE",
+       0};
+
+#include "y.tab.c"
+
+int keytran[]{
+       0, 0,
+       XIF, XIF,
+       XELSE, XELSE,
+       XFOR, XFOR,
+       REPEAT, REPEAT,
+       UNTIL, UNTIL,
+       XWHILE, XWHILE,
+       XBREAK, XBREAK,
+       NEXT, NEXT,
+       XDEFINE, XDEFINE,
+       XINCLUDE, XINCLUDE,
+       0};
+
+int    svargc;
+char   **svargv;
+int    infile  0;
+int    fd      0;
+int    ninclude        0;
+int    filestack[10];
+int    linect[10];
+
+main(argc,argv) int argc; char **argv; {
+       contfld = errorflag = 0;
+       if(argc>1 && argv[1][0]=='-'){
+               if(argv[1][1]=='6')
+                       contfld=6;
+               argc--;
+               argv++;
+       }
+       svargc = argc;
+       svargv = argv;
+       filestack[0] = infile = fd = ninclude = linect[0] = 0;
+       if(--svargc>0)
+               if( (fd = filestack[0] = copen(svargv[++infile],'r')) < 0 ) {
+                       error("can't open %s", svargv[infile]);
+                       cexit(1);
+               }
+       yyparse();
+       cexit(errorflag);
+}
+
+int    peek    -1;
+int    nextchar        '\n';
+
+getc(){
+       nextchar = (peek<0) ? gchar(): peek;
+       peek = -1;
+       return(nextchar);
+}
+
+int    gcp     0;
+char   gcbuf[300];
+int    apos    -1;
+
+gchar(){
+       extern int linect[], nnames;
+       extern char *names[], *nameptr[];
+       int c,i,atype,t;
+       if( c=gcbuf[gcp++] )
+               return(c);
+   loop:
+       for(gcp=0; (c=gcbuf[gcp]=cgetc(fd))!='\0' ; gcp++ ){
+               if( gcbuf[0]== '%' ){
+                       while(putchar(cgetc(fd))!='\n');
+                       gcp = -1;
+                       ++linect[ninclude];
+                       continue;
+               }
+               if( (atype=alphanum(c)) && apos < 0 ){
+                       apos = gcp;
+                       continue;
+               }
+               if( !atype )
+                       if( apos >= 0 ){
+                               gcbuf[gcp] = '\0';
+                               if( nnames>0 && (t=lookup(&gcbuf[apos],names))>=0){
+                                       for(i=0;gcbuf[apos++]=nameptr[t][i];i++);
+                                       gcp = apos-1;
+                               }
+                               apos = -1;
+                               gcbuf[gcp] = c;
+                       }
+               if( c < ' ' && (c!='\n' && c!='\t') )   /* strip crap */
+                       c = gcbuf[gcp] = ' ';
+               if( c=='#' ){
+                       gcbuf[gcp] = '\n';
+                       while( (c=cgetc(fd))!='\n' && c!='\0');
+               }
+               if( c=='"' || c=='\'' ){
+                       while( (gcbuf[++gcp]=t=cgetc(fd)) != c )
+                               if( t=='\n' ) {
+                                       error("unbalanced quote");
+                                       gcbuf[gcp] = c;
+                                       gcbuf[++gcp] = c = '\n';
+                                       goto newline;
+                               }
+                       continue;
+               }
+       newline:
+               if( c=='\n' ){
+                       gcbuf[gcp+1] = '\0';
+                       gcp = 1;
+                       ++linect[ninclude];
+                       return(gcbuf[0]);
+               }
+       }
+       if(ninclude){
+               cclose(filestack[ninclude--]);
+               fd = filestack[ninclude];
+               goto loop;
+       }
+       cclose(filestack[ninclude]);
+       if(--svargc>0){
+               if( (fd = filestack[ninclude] = copen(svargv[++infile],'r')) < 0) {
+                       error("can't open %s", svargv[infile]);
+                       cexit(1);
+               }
+               linect[0] = 0;
+               goto loop;
+       }
+       return(0);
+}
+
+inclstat(){
+       int i,c;
+       char fname[100];
+       while( (c=getc())==' ' || c=='\t' );
+       peek = c;
+       for(i=0; (fname[i]=c=getc())!='\n' && c!=';' && c!=' ' && c!='\t'; i++);
+       fname[i] = '\0';
+       if( (fd = copen(fname,'r')) < 0 ) {
+               error("can't open %s", fname);
+               cexit(1);
+       }
+       else {
+               filestack[++ninclude] = fd;
+               linect[ninclude] = 0;
+       }
+}
+
+lookup(string,tbl) char *string; char *tbl[]; {
+       register i,j, r;
+       for(i=0; tbl[i]!=0; i++){ 
+               for( j=0; (r=tbl[i][j])==string[j] && r!='\0'; j++);
+               if( r == string[j] )
+                       return(i);
+       }
+       return( -1 );
+}
+
+char   str[200];
+int    strp;
+int    nstr;
+
+yylex(){
+       int c, type;
+  top:
+       while( (c=getc())==' ' || c=='\n' || c=='\t' );
+       yylval = c;
+       switch(c){
+
+       case '\0':
+               return('\0');
+       case ';':
+               return(SCOL);
+       case'{':
+               return(LCURL);
+       case '}':
+               return(RCURL);
+       }
+       peek = c;
+       nstr = getstr(str);
+       yylval = &str[0];
+       if( alldigits(str) )
+               return(DIGITS);
+       type = lookup(str,keyword);
+       if( keytran[type]==XDEFINE ) {
+               defstat();
+               goto top;
+       } else if( keytran[type]==XINCLUDE ) {
+               inclstat();
+               goto top;
+       } else if( type > 1 )
+               return(keytran[type]);
+       else if( type < 0 )
+               return(XGOK);
+       while( (c=getc())==' ' || c=='\t' || c=='\n' );
+       peek = c;
+       if( c>='a' && c<='z' || c>='A' && c<='Z' )
+               return(NEWDO);
+       else
+               return(OLDDO);
+}
+
+getstr(s) char *s; {
+       int  c, sp;
+       for (sp=0; (c=s[sp++]=getc())!=' ' && c!='\t' && c!='\n' && c!='{' && c!='}'
+               && c!=';' && c!='(' && c!=')' ; )
+                       if( c=='\'' || c=='"' )
+                               while( (s[sp++]=getc())!=c );
+       peek = c;
+       s[--sp]='\0';
+       return(sp);
+}
+
+alldigits(s) char *s; {
+       int c;
+       if( *s == '\0' )
+               return(0);
+       while( (c = *s++) != '\0' )
+               if( c<'0' || c>'9' )
+                       return(0);
+       return(1);
+}
+
+int    dbg     0;
+
+yyerror(){;}
+
+alphanum(c) int c; {
+       if(c>='0' && c<='9') return(1);
+       if(c>='a' && c<='z') return(1);
+       if(c>='A' && c<='Z') return(1);
+       return(0);
+}
+
+#define        MAXNAMES        100
+
+char   *names[MAXNAMES];
+char   *nameptr[MAXNAMES];
+int    nnames  0;
+
+defstat(){
+       int c,i,index;
+       extern int peek,nstr;
+       extern char str[];
+       char *getvec();
+       while( (c=getc())==' ' || c=='\t' );
+       peek = c;
+       for(nstr=0; c=getc(); nstr++ ){
+               if(c==' ' || c=='\t' || c=='\n') break;
+               str[nstr] = c;
+       }
+       peek = c;
+       str[nstr] = '\0';
+       if( (index=lookup(str,names)) >= 0 )
+               nameptr[index] = 0;
+       else if( (index = nnames++)>=MAXNAMES-1 ){
+               error("too many defined names");
+               cexit(1);
+       }
+       names[index] = getvec(nstr+1);
+       for( i=0; names[index][i]=str[i]; i++ );
+       while( (c=getc())==' ' || c=='\t' );
+       peek = c;
+       for( i=0; (c=getc())!='\n' && c!='\0'; i++ )
+               str[i] = c;
+       str[i] = '\0';
+       nameptr[index] = getvec(i+1);
+       for( i=0; nameptr[index][i]=str[i]; i++ );
+}
+
diff --git a/usr/source/rat/r.g b/usr/source/rat/r.g
new file mode 100644 (file)
index 0000000..e6142f4
--- /dev/null
@@ -0,0 +1,40 @@
+%term  LCURL RCURL LPAR RPAR SCOL DIGITS
+%term  XIF XELSE XFOR XWHILE XBREAK NEXT 
+%term  OLDDO NEWDO
+%term  XGOK XDEFINE XINCLUDE
+%term  REPEAT UNTIL
+%%
+
+statl  : statl  stat
+       |
+       ;
+stat   : if stat       ={ outcont($1); }
+       | ifelse stat   ={ outcont($1+1); }
+       | while stat    ={ whilestat($1); }
+       | for stat      ={ forstat($1); }
+       | repeat stat UNTIL     ={ untils($1); }
+       | XBREAK        ={ breakcode($1); }
+       | NEXT          ={ nextcode($1); }
+       | newdo stat    ={ dostat($1); }
+       | OLDDO         ={ docode(0,$1); }
+       | XGOK          ={ gokcode($1); }
+       | SCOL
+       | LCURL statl RCURL
+       | label stat
+       | error         ={ errcode($1); yyclearin; }
+       ;
+label  : DIGITS        ={ outcode($1); outcode("\t"); }
+       ;
+if     : XIF           ={ ifcode($1); }
+       ;
+ifelse : if stat XELSE ={ outgoto($1+1); outcont($1); }
+       ;
+while  : XWHILE        ={ whilecode($1); }
+       ;
+for    : XFOR          ={ forcode($1); }
+       ;
+repeat : REPEAT        ={ repcode($1); }
+       ;
+newdo  : NEWDO         ={ docode(1,$1); }
+       ;
+%%
diff --git a/usr/source/rat/r.h b/usr/source/rat/r.h
new file mode 100644 (file)
index 0000000..388914c
--- /dev/null
@@ -0,0 +1,8 @@
+#
+extern int     contfld;
+extern int     dbg;
+extern int     yyval;
+extern int     *yypv;
+extern int     yylval;
+extern int     peek;
+extern int     errorflag;
diff --git a/usr/source/rat/r1.c b/usr/source/rat/r1.c
new file mode 100644 (file)
index 0000000..b5abb00
--- /dev/null
@@ -0,0 +1,259 @@
+#include "r.h"
+
+char   scrat[500];
+
+int    brkptr  -1;
+int    brkstk[10];
+int    forptr  0;
+int    forstk[10];
+
+repcode() {
+       outcont(0);
+       yyval = genlab();
+       outcont(yyval);
+       brkstk[++brkptr] = yyval+1;
+       genlab();
+       genlab();
+}
+
+untils(p1) int p1; {
+       outnum(p1+1);
+       outcode("\tif(.not.");
+       balpar(scrat);
+       outcode(scrat);
+       outcode(")");
+       outgoto(p1);
+       outcont(p1+2);
+       brkptr--;
+}
+
+ifcode(p1) int p1; {
+       outcode("\tif(.not.");
+       balpar(scrat);
+       outcode(scrat);
+       outcode(")");
+       outgoto(yyval=genlab()); genlab();
+}
+
+whilecode(p1) int p1; {
+       outcont(0);
+       brkstk[++brkptr] = yyval = genlab(); genlab();
+       outnum(yyval);
+       outcode("\tif(.not.");
+       balpar(scrat);
+       outcode(scrat);
+       outcode(")");
+       outgoto(yyval+1);
+}
+
+whilestat(p1) int p1; {
+       outgoto(p1);
+       outcont(p1+1);
+       brkptr--;
+}
+
+balpar(bp) char *bp; {
+       int  i, c, lpar;
+       extern int peek;
+       while( (c=getc()) == ' ' || c == '\t' || c=='\n' );
+       peek = c;
+       if( c != '(' ){
+               error("missing left paren");
+               bp[0] = '\0';
+               return(bp);
+       }
+       for( lpar=i=0; (bp[i++]=c=getc())!='\0'; ){
+               if( c=='\'' || c=='"' )
+                       while( (bp[i++]=getc()) != c );
+               if( i>=499 || c=='{' || c=='}' ){
+                       error("missing right parenthesis at %.20s", bp);
+                       break;
+               }
+               if( c=='(' )
+                       lpar++;
+               else if( c==')' )
+                       lpar--;
+               if( lpar == 0 )
+                       break;
+       }
+       bp[i] = '\0';
+       return(bp);
+}
+
+int    labval  23000;
+
+genlab(){
+       return(++labval);
+}
+
+gokcode(p1) char *p1; {
+       outcode("\t");
+       outcode(p1);
+       eatup(p1,scrat);
+       outcode(scrat);
+       outcode(0);
+}
+
+eatup(p1,bp) char *p1, *bp; {
+       extern int peek;
+       int i,c,lnb,lpar;
+       lnb = '\n';
+       while( c = *p1++ )
+               if( c!=' ' )
+                       lnb = c;
+       i = lpar = 0;
+  more:
+       for( ; (bp[i++]=c=getc())!=';' && c!='{' && c!='\n' && c!='}'; ){
+               if( i>=499 ){
+                       error("statement too long at %.20s", bp);
+                       break;
+               }
+               if( c != ' ' && c != '\t' )
+                       lnb = c;
+               if( c=='\'' || c=='"' )
+                       while( (bp[i++]=getc()) != c );
+               if( c=='(' )
+                       lpar++;
+               else if( c==')' ) {
+                       lpar--;
+                       if( lpar < 0 )
+                               error("missing left paren at %.20s",bp);
+               }
+       }
+       if( c == '\n' ){
+               if( lnb=='\n' || lnb=='+' || lnb=='-' || lnb=='*' || lnb=='('
+                       || lnb=='/' || lnb==',' || lnb=='&'  || lnb=='|'
+                       || lnb=='=' )
+                               goto more;
+               c = ';';
+       }
+       if( c!=';' )
+               peek = c;
+       bp[i-1] = '\0';
+       if( lpar > 0 )
+               error("missing right paren at %.20s",bp);
+       return(bp);
+}
+
+forcode(){
+       extern int peek;
+       int i,j,c;
+       char *bp, *getvec();
+       outcont(0);
+       balpar(scrat);
+       yyval = genlab(); genlab(); genlab();
+       brkstk[++brkptr] = yyval+1;
+       if( scrat[0] == '\0' ){
+               forstk[forptr++] = bp = getvec(1);
+               *bp = '\0';
+               return;
+       }
+       scrat[0] = '\t';
+       for( i=1; (c=scrat[i++])!=';' && c!='\0' ; )
+               if( c=='\'' || c=='"' )
+                       while( scrat[i++] != c );
+       scrat[i-1] = '\0';
+       if( nonblank(scrat) ){
+               outcode(scrat);
+               outcode(0);
+       }
+       for( j=i; (c=scrat[i++])!=';' && c!='\0' ; )
+               if( c=='\'' || c=='"' )
+                       while( scrat[i++] != c );
+       scrat[i-1] = '\0';
+       if( nonblank(&scrat[j]) ){
+               outnum(yyval);
+               outcode("\tif(.not.(");
+               outcode(&scrat[j]);
+               outcode("))");
+               outgoto(yyval+2);
+       }
+       else
+               outcont(yyval);
+       for( j=0; scrat[i+1]!='\0'; )
+               scrat[j++] = scrat[i++];
+       scrat[j] = '\0';
+       forstk[forptr++] = bp = getvec(j+1);
+       for(i=0; *bp++ = scrat[i++]; );
+}
+
+forstat(p1) int p1; {
+       char *bp, *q;
+       int i;
+       bp = forstk[--forptr];
+       outnum(p1+1);
+       if( nonblank(bp) ){
+               outcode("\t");
+               outcode(bp);
+               outcode(0);
+       }
+       outgoto(p1);
+       outcont(p1+2);
+       for( q=bp; *q++; );
+       relvec(bp, q-bp);
+       brkptr--;
+}
+
+docode(new,p1) int new; char *p1; {
+       outcode("\t");
+       outcode(p1);
+       eatup(p1,scrat);
+       yyval = 0;
+       if(new){
+               yyval = genlab(); genlab();
+               brkstk[++brkptr] = yyval;
+               outnum(yyval);
+       }
+       outcode(scrat);
+       outcode(0);
+}
+
+dostat(p1) int p1; {
+       if( p1==0 )
+               return;
+       outcont(p1);
+       outcont(p1+1);
+       brkptr--;
+}
+
+breakcode(p1) int p1; {
+       if(brkptr<0){
+               error("illegal BREAK");
+               return;
+       }
+       outgoto(brkstk[brkptr]+1);
+}
+
+nextcode(p1) int p1; {
+       if(brkptr<0){
+               error("illegal NEXT");
+               return;
+       }
+       outgoto(brkstk[brkptr]);
+}
+
+nonblank(s) char *s; {
+       int c;
+       while( c = *s++ )
+               if( c!=' ' && c!='\t' && c!='\n' )
+                       return(1);
+       return(0);
+}
+
+error(s1, s2) char *s1, *s2; {
+       extern int linect[],ninclude,infile;
+       printf( 2, "error at line %d, file %d: ",linect[ninclude],infile);
+       printf( 2, s1,s2);
+       printf( 2, "\n");
+       errorflag = 1;
+}
+
+errcode(p1) char *p1; {
+       int c;
+       extern int yychar;
+       extern int linect[],ninclude,infile;
+       printf( 2, "\nsyntax error, line %d, file %d\n", linect[ninclude],infile);
+       while( (c=getc()) != ';' && c != '}' && c != '\n' && c != '\0' );
+       yychar = -1;
+       errorflag = 1;
+}
diff --git a/usr/source/rat/r2.c b/usr/source/rat/r2.c
new file mode 100644 (file)
index 0000000..8b8030a
--- /dev/null
@@ -0,0 +1,124 @@
+#include "r.h"
+
+char   outbuf[80];
+int    outp    0;
+int    cont    0;
+
+outcode(p) char *p; {
+       int i,j,c,c1;
+       char *q;
+       if( p == 0 ){
+               outbuf[outp] = '\0';
+               printf("%s\n", outbuf);
+               outp = cont = 0;
+               return;
+       }
+       while( (c = *p++) ){
+               c1 = *p;
+               switch(c){
+
+               case '"':
+               case '\'':
+                       for( q=p; *q != c; q++ );
+                       outnum(q-p);
+                       ptc('h');
+                       while( p != q )
+                               ptc(*p++);
+                       p++;
+                       break;
+               case '>':
+                       if( c1=='=' ){
+                               pts(".ge."); p++;
+                       } else
+                               pts(".gt.");
+                       break;
+               case '<':
+                       if( c1=='=' ){
+                               pts(".le."); p++;
+                       } else if( c1=='>' ){
+                               pts(".ne."); p++;
+                       } else
+                               pts(".lt.");
+                       break;
+               case '=':
+                       if( c1=='=' ){
+                               pts(".eq."); p++;
+                       } else
+                               ptc('=');
+                       break;
+               case '!':
+                       if( c1=='=' ){
+                               pts(".ne."); p++;
+                       } else
+                               pts(".not.");
+                       break;
+               case '&':
+                       if( c1=='&' )
+                               p++;
+                       pts(".and.");
+                       break;
+               case '|':
+                       if( c1=='|' )
+                               p++;
+                       pts(".or.");
+                       break;
+               case '\t':
+                       tabs();
+                       break;
+               case '\n':
+                       ptc(' ');
+                       break;
+               default:
+                       ptc(c);
+                       break;
+               }
+       }
+}
+
+ptc(c) char c; {
+       if( outp > 71 )
+               contcard();
+       outbuf[outp++] = c;
+}
+
+pts(s) char *s; {
+       while(*s)
+               ptc(*s++);
+}
+
+int    contfld 0;
+
+contcard(){
+       outbuf[outp] = '\0';
+       printf("%s\n", outbuf);
+       for( outp=0; outp<contfld-1; outbuf[outp++] = ' ' );
+       outbuf[outp++] = '&';
+}
+
+tabs(){
+       ptc(' ');
+       while( outp<7 )
+               ptc(' ');
+       while( outp%3 != 1)
+               ptc(' ');
+}
+
+outnum(n) int n; {
+       int a;
+       if( a = n/10 )
+               outnum(a);
+       ptc(n%10 + '0');
+}
+
+outcont(n) int n; {
+       if( n > 0 )
+               outnum(n);
+       outcode("\tcontinue");
+       outcode(0);
+}
+
+outgoto(n) int n; {
+       outcode("\tgoto ");
+       outnum(n);
+       outcode(0);
+}