From b3b868ed50eccc8ff7318286aa7bcbfa162b1d14 Mon Sep 17 00:00:00 2001 From: rswier Date: Wed, 16 Mar 2016 01:46:35 -0400 Subject: [PATCH] Ported B compiler b.c to b.b. Ported B compiler b.c to b.b. It is able to compile itself. Hints are in the comment block. --- src/other/b.b | 785 ++++++++++++++++++++++++++++++++++++++++++++++ src/other/hello.s | 85 ++--- tools/a7out | 8 +- tools/b.c | 445 +++++++++++++------------- 4 files changed, 1065 insertions(+), 258 deletions(-) create mode 100644 src/other/b.b diff --git a/src/other/b.b b/src/other/b.b new file mode 100644 index 0000000..57a7a27 --- /dev/null +++ b/src/other/b.b @@ -0,0 +1,785 @@ +/* b.b - B compiler for PDP-7 Unix + + Coding style and organization based on lastc1120c.c + + (C) 2016 Robert Swierczek, GPL3 + + To compile the compiler with b.c: + gcc -Wno-multichar b.c -o b + ./b b.b b.s + perl as7 --out b.out bl.s b.s bi.s + + To compile hello.b: + perl a7out b.out hello.b hello.s + perl as7 --out h.out bl.s hello.s bi.s + perl a7out h.out + + To compile the compiler with itself: + perl a7out b.out b.b b2.s + perl as7 --out b2.out bl.s b2.s bi.s +*/ + +main() { + extrn symtab, eof, ns, nerror; + + while (!eof) { + ns = symtab + 51; + extdef(); + blkend(); + } +} + +lookup() { + extrn symtab, symbuf, eof, ns, nerror; + auto np, sp, rp; + + rp = symtab; + while (rp < ns) { + np = rp + 2; + sp = symbuf; + while (*np==*sp) { + if (!*np) + return(rp); + np = np+1; + sp = sp+1; + } + while (*np) + np = np+1; + rp = np+1; + } + sp = symbuf; + if (ns >= symtab + 290) { + error('sf'); + eof = 1; + return(rp); + } + *ns = 0; + ns[1] = 0; + ns = ns+2; + while (*ns = *sp) { + ns = ns+1; + sp = sp+1; + } + ns = ns+1; + return(rp); +} + +symbol() { + extrn symbuf, ctab, peeksym, peekc, eof, line, csym, cval; + auto b, c, ct, sp; + + if (peeksym>=0) { + c = peeksym; + peeksym = -1; + return(c); + } + if (peekc) { + c = peekc; + peekc = 0; + } else { + if (eof) + return(0); + else + c = read(); + } +loop: + ct = ctab[c]; + + if (ct==0) { /* eof */ + eof = 1; + return(0); + } + + if (ct==126) { /* white space */ + if (c=='*n') + line = line+1; + c = read(); + goto loop; + } + + if (c=='=') { + return(subseq('=',80,60)); + } + if (c=='<') { + return(subseq('=',63,62)); + } + if (c=='>') { + return(subseq('=',65,64)); + } + if (c=='!') { + return(subseq('=',34,61)); + } + if (c=='$') { + if (subseq('(',0,1)) + return(2); + if (subseq(')',0,1)) + return(3); + } + if (c=='/') { + if (subseq('**',1,0)) + return(43); +com: + c = read(); +com1: + if (c==4) { + eof = 1; + error('**/'); /* eof */ + return(0); + } + if (c=='*n') + line = line+1; + if (c!='**') + goto com; + c = read(); + if (c!='/') + goto com1; + c = read(); + goto loop; + } + if (ct==124) { /* number */ + cval = 0; + if (c=='0') + b = 8; + else + b = 10; + while(c >= '0' & c <= '9') { + cval = cval*b + c -'0'; + c = read(); + } + peekc = c; + return(21); + } + if (c=='*'') { /* ' */ + getcc(); + return(21); + } + if (ct==123) { /* letter */ + sp = symbuf; + while(ctab[c]==123 | ctab[c]==124) { + if (sp= 0) + error('cc'); +} + +mapch(c) { + extrn peekc; + auto a; + + if((a=read())==c) + return(-1); + + if (a=='*n' | a==0 | a==4) { + error('cc'); + peekc = a; + return(-1); + } + + if (a=='**') { + a=read(); + + if (a=='0') + return(0); + + if (a=='e') + return(4); + + if (a=='(') + return('{'); + + if (a==')') + return('}'); + + if (a=='t') + return('*t'); + + if (a=='r') + return('*r'); + + if (a=='n') + return('*n'); + } + return(a); +} + +expr(lev) { + extrn peeksym, csym, cval, isn; + auto o; + + o = symbol(); + + if (o==21) { /* number */ +case21: + if ((cval & 017777)==cval) { + gen('c',cval); /* consop */ + goto loop; + } + gen('n',5); /* litrl */ + number(cval); + write('*n'); + goto loop; + } + + if (o==20) { /* name */ + if (*csym==0) { /* not seen */ + if((peeksym=symbol())==6) { /* ( */ + *csym = 6; /* extrn */ + } else { + *csym = 2; /* internal */ + isn = isn+1; + csym[1] = isn; + } + } + if(*csym==5) /* auto */ + gen('a',csym[1]); + else { + write('x '); + if (*csym==6) { /* extrn */ + write('.'); + name(csym+2); + } else { /* internal */ + write('l'); + number(csym[1]); + } + write('*n'); + } + goto loop; + } + + if (o==34) { /* ! */ + expr(1); + gen('u',4); /* unot */ + goto loop; + } + + if (o==41) { /* - */ + peeksym = symbol(); + if (peeksym==21) { /* number */ + peeksym = -1; + cval = -cval; + goto case21; + } + expr(1); + gen('u',2); /* umin */ + goto loop; + } + + if (o==47) { /* & */ + expr(1); + gen('u',1); /* uadr */ + goto loop; + } + + if (o==42) { /* * */ + expr(1); + gen('u',3); /* uind */ + goto loop; + } + + if (o==6) { /* ( */ + peeksym = o; + pexpr(); + goto loop; + } + error('ex'); + +loop: + o = symbol(); + + if (lev>=14 & o==80) { /* = */ + expr(14); + gen('b',1); /* asg */ + goto loop; + } + if (lev>=10 & o==48) { /* | ^ */ + expr(9); + gen('b',2); /* bor */ + goto loop; + } + if (lev>=8 & o==47) { /* & */ + expr(7); + gen('b',3); /* band */ + goto loop; + } + if (lev>=7 & o>=60 & o<=61) { /* == != */ + expr(6); + gen('b',o-56); /* beq bne */ + goto loop; + } + if (lev>=6 & o>=62 & o<=65) { /* <= < >= > */ + expr(5); + gen('b',o-56); /* ble blt bge bgt */ + goto loop; + } + if (lev>=4 & o>=40 & o<=41) { /* + - */ + expr(3); + gen('b',o-28); /* badd bmin */ + goto loop; + } + if (lev>=3 & o>=42 & o<=43) { /* * / */ + expr(2); + gen('b',o-27); /* bmul bdiv */ + goto loop; + } + if (lev>=3 & o==44) { /* % */ + expr(2); + gen('b',14); /* bmod */ + goto loop; + } + if (o==4) { /* [ */ + expr(15); + if (symbol() != 5) + error('[]'); + gen('b',12); /* badd */ + gen('u',3); /* uind */ + goto loop; + } + if (o==6) { /* ( */ + o = symbol(); + if (o==7) /* ) */ + gen('n',1); /* mcall */ + else { + gen('n',2); /* mark */ + peeksym = o; + while (o!=7) { + expr(15); + o = symbol(); + if (o!=7 & o!=9) { /* ) , */ + error('ex'); + return; + } + } + gen('n',3); /* call */ + } + goto loop; + } + + peeksym = o; +} + +pexpr() +{ + auto o, t; + + if ((o=symbol())==6) { /* ( */ + expr(15); + if ((o=symbol())==7) /* ) */ + return; + } + error('()'); +} + +declare(kw) { + extrn csym, cval, nauto; + auto o; + + while((o=symbol())==20) { /* name */ + if (kw==6) { /* extrn */ + *csym = 6; + o = symbol(); + } else { /* auto/param */ + *csym = 5; /* auto */ + csym[1] = nauto; + o = symbol(); + if (kw==5 & o==21) { /* auto & number */ + gen('y',nauto); /* aryop */ + nauto = nauto + cval; + o = symbol(); + } + nauto = nauto+1; + } + if (o!=9) /* , */ + goto done; + } +done: + if(o==1 & kw!=8 | o==7 & kw==8) /* auto/extrn ; param ')' */ + return; +syntax: + error('[]'); /* declaration syntax */ +} + +extdef() { + extrn peeksym, csym, cval, nauto; + auto o, c; + + o = symbol(); + if(o==0 | o==1) /* eof ; */ + return; + + if(o!=20) /* name */ + goto syntax; + + csym[0] = 6; /* extrn */ + write('.'); + name(csym + 2); + write(':'); + o=symbol(); + + if (o==2 | o==6) { /* $( ( */ + write('.+'); + write('1*n'); + nauto = 2; + if (o==6) { /* ( */ + declare(8); /* param */ + if ((o=symbol())!=2) /* $( */ + goto syntax; + } + while((o=symbol())==19 & cval<10) /* auto extrn */ + declare(cval); + peeksym = o; + gen('s',nauto); /* setop */ + stmtlist(); + gen('n',7); /* retrn */ + return; + } + + if (o==41) { /* - */ + if (symbol()!=21) /* number */ + goto syntax; + number(-cval); + write('*n'); + return; + } + + if (o==21) { /* number */ + number(cval); + write('*n'); + return; + } + + if (o==1) { /* ; */ + write('0*n'); + return; + } + + if (o==4) { /* [ */ + c = 0; + if ((o=symbol())==21) { /* number */ + c = cval; + o = symbol(); + } + if (o!=5) /* ] */ + goto syntax; + write('.+'); + write('1*n'); + if ((o=symbol())==1) /* ; */ + goto done; + while (o==21 | o==41) { /* number - */ + if (o==41) { /* - */ + if (symbol()!=21) + goto syntax; + cval = -cval; + } + number(cval); + write('*n'); + c = c-1; + if ((o=symbol())==1) /* ; */ + goto done; + if (o!=9) /* , */ + goto syntax; + else + o = symbol(); + } + goto syntax; +done: + if (c>0) { + write('.='); + write('.+'); + number(c); + write('*n'); + } + return; + } + + if (o==0) /* eof */ + return; + +syntax: + error('xx'); + stmt(); +} + +stmtlist() { + extrn peeksym, eof; + auto o; + + while (!eof) { + if ((o = symbol())==3) /* $) */ + return; + peeksym = o; + stmt(); + } + error('$)'); /* missing $) */ +} + +stmt() { + extrn peeksym, peekc, csym, cval, isn, nauto; + auto o, o1, o2; + +next: + o = symbol(); + + if (o==0) /* eof */ + { + error('fe'); /* Unexpected eof */ + return; + } + + if (o==1 | o==3) /* ; $) */ + return; + + if (o==2) { /* $( */ + stmtlist(); + return; + } + + if (o==19) { /* keyword */ + + if (cval==10) { /* goto */ + expr(15); + gen('n',6); /* goto */ + goto semi; + } + + if (cval==11) { /* return */ + if((peeksym=symbol())==6) /* ( */ + pexpr(); + gen('n',7); /* retrn */ + goto semi; + } + + if (cval==12) { /* if */ + pexpr(); + isn = isn+1; + o1 = isn; + jumpc(o1); + stmt(); + o = symbol(); + if (o==19 & cval==14) { /* else */ + isn = isn+1; + o2 = isn; + jump(o2); + label(o1); + stmt(); + label(o2); + return; + } + peeksym = o; + label(o1); + return; + } + + if (cval==13) { /* while */ + isn = isn+1; + o1 = isn; + label(o1); + pexpr(); + isn = isn+1; + o2 = isn; + jumpc(o2); + stmt(); + jump(o1); + label(o2); + return; + } + + error('sx'); + goto syntax; + } + + if (o==20 & peekc==':') { /* name : */ + peekc = 0; + if (!*csym) { + *csym = 2; /* param */ + isn = isn+1; + csym[1] = isn; + } else if (*csym != 2) { + error('rd'); + goto next; + } + label(csym[1]); + goto next; + } + + peeksym = o; + expr(15); + gen('s',nauto); /* setop */ + +semi: + o = symbol(); + if (o==1) /* ; */ + return; + +syntax: + error('sz'); + goto next; +} + +blkend() { + extrn isn, nisn; + + while (nisn < isn) { + nisn = nisn+1; + write('l'); + number(nisn); + write(':'); + write('ll'); + number(nisn); + write('*n'); + } +} + +gen(o,n) { + write(o); + write(' '); + number(n); + write('*n'); +} + +jumpc(n) { + write('f '); /* ifop */ + write('l'); + number(n); + write('*n'); +} + +jump(n) { + write('t '); /* traop */ + write('ll'); + number(n); + write('*n'); +} + +label(n) { + write('ll'); + number(n); + write(':'); +} + +printn(n) { + if (n > 9) { + printn(n / 10); + n = n % 10; + } + write(n + '0'); +} + +number(x) { + if (x < 0) { + write('-'); + x = -x; + } + printn(x); +} + +name(s) { + while (*s) { + write(*s); + s = s+1; + } +} + +error(code) +{ + extrn line, eof, csym, nerror, fout; + auto f; + + if (eof | nerror==20) { + eof = 1; + return; + } + nerror = nerror+1; + flush(); + f = fout; + fout = 1; + write(code); + write(' '); + if (code=='rd' | code=='un') { + name(csym + 2); + write(' '); + } + printn(line); + write('*n'); + flush(); + fout = f; +} + +/* storage */ + +symtab[300] /* class value name */ + 1, 5,'a','u','t','o', 0 , + 1, 6,'e','x','t','r','n', 0 , + 1,10,'g','o','t','o', 0 , + 1,11,'r','e','t','u','r','n', 0 , + 1,12,'i','f', 0 , + 1,13,'w','h','i','l','e', 0 , + 1,14,'e','l','s','e', 0 ; + +ctab[] + 0,127,127,127, 0,127,127,127, /* NUL SOH STX ETX EOT ENQ ACK BEL */ + 127,126,126,127,127,127,127,127, /* BS TAB LF VT FF CR SO SI */ + 127,127,127,127,127,127,127,127, /* DLE DC1 DC2 DC3 DC4 NAK SYN ETB */ + 127,127,127,127,127,127,127,127, /* CAN EM SUB ESC FS GS RS US */ + 126, 34,122,127,127, 44, 47,121, /* SPC ! " # $ % & ' */ + 6, 7, 42, 40, 9, 41,127, 43, /* ( ) * + , - . / */ + 124,124,124,124,124,124,124,124, /* 0 1 2 3 4 5 6 7 */ + 124,124, 8, 1, 63, 80, 65, 90, /* 8 9 : ; < = > ? */ + 127,123,123,123,123,123,123,123, /* @ A B C D E F G */ + 123,123,123,123,123,123,123,123, /* H I J K L M N O */ + 123,123,123,123,123,123,123,123, /* P Q R S T U V W */ + 123,123,123, 4,127, 5, 48,127, /* X Y Z [ \ ] ^ _ */ + 127,123,123,123,123,123,123,123, /* ` a b c d e f g */ + 123,123,123,123,123,123,123,123, /* h i j k l m n o */ + 123,123,123,123,123,123,123,123, /* p q r s t u v w */ + 123,123,123, 2, 48, 3,127,127; /* x y z { | } ~ DEL */ + +symbuf[10]; +peeksym -1; +peekc; +eof; +line 1; +csym; +ns; +cval; +isn; +nisn; +nerror; +nauto; diff --git a/src/other/hello.s b/src/other/hello.s index e552760..0a417e1 100644 --- a/src/other/hello.s +++ b/src/other/hello.s @@ -1,40 +1,45 @@ -.main: .+1 - s 2 - x .write - n 2 " etcop mark - n 5 " etcop litrl - 36965 - n 3 " etcop call - x .write - n 2 " etcop mark - n 5 " etcop litrl - 55404 - n 3 " etcop call - x .write - n 2 " etcop mark - n 5 " etcop litrl - 56876 - n 3 " etcop call - x .write - n 2 " etcop mark - n 5 " etcop litrl - 16471 - n 3 " etcop call - x .write - n 2 " etcop mark - n 5 " etcop litrl - 56946 - n 3 " etcop call - x .write - n 2 " etcop mark - n 5 " etcop litrl - 55396 - n 3 " etcop call - x .write - n 2 " etcop mark - n 5 " etcop litrl - 16906 - n 3 " etcop call - x .flush - n 1 " etcop mcall - n 7 " etcop retrn +.main:.+1 +s 2 +x .write +n 2 +n 5 +36965 +n 3 +s 2 +x .write +n 2 +n 5 +55404 +n 3 +s 2 +x .write +n 2 +n 5 +56876 +n 3 +s 2 +x .write +n 2 +n 5 +16471 +n 3 +s 2 +x .write +n 2 +n 5 +56946 +n 3 +s 2 +x .write +n 2 +n 5 +55396 +n 3 +s 2 +x .write +n 2 +n 5 +16906 +n 3 +s 2 +n 7 diff --git a/tools/a7out b/tools/a7out index 0e33615..eeb81c7 100755 --- a/tools/a7out +++ b/tools/a7out @@ -545,7 +545,8 @@ sub eae { # Save the AC's sign into LINK my $newlink = ( $AC << 1 ) & LINKMASK; - $AC = ( ( $LINK | $AC ) >> $step ) & MAXINT; +# $AC = ( ( $LINK | $AC ) >> $step ) & MAXINT; + $AC = ( ( ($newlink * -1) | $AC ) >> $step ) & MAXINT; # XXX Not sure if this is correct!?!?! $LINK = $newlink; $PC++; return; @@ -1301,8 +1302,8 @@ sub word2ascii { my $c1 = ( $word >> 9 ) & 0177; my $c2 = $word & 0177; my $result = ""; - $result .= (($c1 >= 32) && ($c1 <= 126)) ? chr($c1) : ' '; - $result .= (($c2 >= 32) && ($c2 <= 126)) ? chr($c2) : ' '; + if (($c1 >= 1) && ($c1 <= 126)) { $result .= chr($c1); } + if (($c2 >= 1) && ($c2 <= 126)) { $result .= chr($c2); } return ($result); } @@ -1313,6 +1314,7 @@ sub mem2arg { my $addr = shift; my $result = ""; + $addr &= MAXADDR; foreach ( 1 .. 4 ) { # Stop if the address leave the 8K word address space diff --git a/tools/b.c b/tools/b.c index bebc123..bc340b4 100644 --- a/tools/b.c +++ b/tools/b.c @@ -1,16 +1,16 @@ -// b.c - B compiler for PDP-7 Unix -// -// Implemented in a subset of the C language compatible with B. -// Coding style and organization based on lastc1120c.c -// -// (C) 2016 Robert Swierczek, GPL3 -// +/* b.c - B compiler for PDP-7 Unix -// Just enough working to compile hello.b: -// gcc -m32 -Wno-multichar b.c -o b -// ./b hello.b hello.s -// perl as7 --out a.out bl.s hello.s bi.s -// perl a7out a.out + Implemented in a subset of the C language compatible with B. + Coding style and organization based on lastc1120c.c + + (C) 2016 Robert Swierczek, GPL3 + + To compile hello.b: + gcc -Wno-multichar b.c -o b + ./b hello.b hello.s + perl as7 --out a.out bl.s hello.s bi.s + perl a7out a.out +*/ #ifdef _WIN32 #include @@ -21,66 +21,51 @@ #include #include #include -#define eof xeof -int fin = 0; +/* runtime */ +int fin; int fout = 1; -int symtab[500] = { /* class value name */ - 1, 5,'a','u','t','o', 0 , - 1, 6,'e','x','t','r','n', 0 , - 1,10,'g','o','t','o', 0 , - 1,11,'r','e','t','u','r','n', 0 , - 1,12,'i','f', 0 , - 1,13,'w','h','i','l','e', 0 , - 1,14,'e','l','s','e', 0 , -}; +xread() { + char buf[1]; + if (read(fin, buf, 1) <= 0) + return 4; + return buf[0]; +} -int ctab[] = { - 0,127,127,127, 0,127,127,127, /* NUL SOH STX ETX EOT ENQ ACK BEL */ - 127,126,126,127,127,127,127,127, /* BS TAB LF VT FF CR SO SI */ - 127,127,127,127,127,127,127,127, /* DLE DC1 DC2 DC3 DC4 NAK SYN ETB */ - 127,127,127,127,127,127,127,127, /* CAN EM SUB ESC FS GS RS US */ - 126, 34,122,127,127, 44, 47,121, /* SPC ! " # $ % & ' */ - 6, 7, 42, 40, 9, 41,127, 43, /* ( ) * + , - . / */ - 124,124,124,124,124,124,124,124, /* 0 1 2 3 4 5 6 7 */ - 124,124, 8, 1, 63, 80, 65, 90, /* 8 9 : ; < = > ? */ - 127,123,123,123,123,123,123,123, /* @ A B C D E F G */ - 123,123,123,123,123,123,123,123, /* H I J K L M N O */ - 123,123,123,123,123,123,123,123, /* P Q R S T U V W */ - 123,123,123, 4,127, 5, 48,127, /* X Y Z [ \ ] ^ _ */ - 127,123,123,123,123,123,123,123, /* ` a b c d e f g */ - 123,123,123,123,123,123,123,123, /* h i j k l m n o */ - 123,123,123,123,123,123,123,123, /* p q r s t u v w */ - 123,123,123, 2, 48, 3,127,127, /* x y z { | } ~ DEL */ -}; +xwrite(c) { + char buf[2]; + if (c & 0xff00) { + buf[0] = (c >> 8) & 0xff; + buf[1] = c & 0xff; + write(fout, buf, 2); + } else { + buf[0] = c & 0xff; + write(fout, buf, 1); + } +} -/* storage */ +xflush() { +} +#define eof xeof +#define read xread +#define write xwrite +#define flush xflush -int symbuf[10]; -int peeksym = -1; -int peekc = 0; -int eof = 0; -int line = 1; -int *csym = 0; -int *ns; -int cval = 0; -int isn = 0; -int nisn = 0; -int nerror = 0; -int nauto = 0; +main(int argc, char **argv) { + extern symtab[], eof, *ns, nerror; + extern fin, fout; -int main(int argc, char **argv) { if (argc > 1) { if (argc > 2) { if ((fout = creat(argv[2], 0777))<0) { error('fo'); - exit(1); + return; } } if ((fin = open(argv[1],0))<0) { error('fi'); - exit(1); + return; } } @@ -89,50 +74,46 @@ int main(int argc, char **argv) { extdef(); blkend(); } - xflush(); - - exit(nerror); } int *lookup() { - int *np, *sp, *rp; + extern symtab[], symbuf[], eof, *ns, nerror; + auto *np, *sp, *rp; + rp = symtab; while (rp < ns) { np = rp + 2; sp = symbuf; while (*np==*sp) { if (!*np) - return rp; - np = np + 1; - sp = sp + 1; + return(rp); + np = np+1; + sp = sp+1; } while (*np) - np = np + 1; - rp = np + 1; + np = np+1; + rp = np+1; } sp = symbuf; - if (ns >= symtab + 490) { - error("sf"); - exit(1); + if (ns >= symtab + 290) { + error('sf'); + eof = 1; + return(rp); } *ns = 0; ns[1] = 0; - ns = ns + 2; + ns = ns+2; while (*ns = *sp) { - ns = ns + 1; - sp = sp + 1; + ns = ns+1; + sp = sp+1; } - ns = ns + 1; - return rp; + ns = ns+1; + return(rp); } symbol() { -// extern peeksym, peekc, eof, xread, subseq, error, line; -// extern *csym, symbuf[], namsiz, lookup[], ctab, cval; -// auto b, c, ct; -// char symbuf[], sp[], ctab[]; - int b, c, ct; - int *sp; + extern symbuf[], ctab[], peeksym, peekc, eof, line, *csym, cval; + auto b, c, ct, *sp; if (peeksym>=0) { c = peeksym; @@ -146,20 +127,20 @@ symbol() { if (eof) return(0); else - c = xread(); + c = read(); } loop: ct = ctab[c]; if (ct==0) { /* eof */ - eof++; + eof = 1; return(0); } if (ct==126) { /* white space */ if (c=='\n') - line = line + 1; - c = xread(); + line = line+1; + c = read(); goto loop; } @@ -185,21 +166,21 @@ loop: if (subseq('*',1,0)) return(43); com: - c = xread(); + c = read(); com1: if (c==4) { - eof++; + eof = 1; error('*/'); /* eof */ return(0); } if (c=='\n') - line++; + line = line+1; if (c!='*') goto com; - c = xread(); + c = read(); if (c!='/') goto com1; - c = xread(); + c = read(); goto loop; } if (ct==124) { /* number */ @@ -208,9 +189,9 @@ com1: b = 8; else b = 10; - while(c >= '0' && c <= '9') { + while(c >= '0' & c <= '9') { cval = cval*b + c -'0'; - c = xread(); + c = read(); } peekc = c; return(21); @@ -222,13 +203,13 @@ com1: if (ct==123) { /* letter */ sp = symbuf; while(ctab[c]==123 | ctab[c]==124) { - if (sp=4 & o>=40 & o<=41) { /* + - */ expr(3); gen('b',o-28); /* badd bmin */ goto loop; - } + } if (lev>=3 & o>=42 & o<=43) { /* * / */ expr(2); gen('b',o-27); /* bmul bdiv */ goto loop; - } + } if (lev>=3 & o==44) { /* % */ expr(2); gen('b',14); /* bmod */ goto loop; - } + } if (o==4) { /* [ */ expr(15); if (symbol() != 5) @@ -442,7 +429,7 @@ loop: while (o!=7) { expr(15); o = symbol(); - if (o!=7 && o!=9) { /* ) , */ + if (o!=7 & o!=9) { /* ) , */ error('ex'); return; } @@ -468,40 +455,36 @@ pexpr() } declare(kw) { -// extern csym[], symbol, paraml[], parame[]; -// extern error, cval, peeksym, exit; -// int t[], n, o; - int o; + extern *csym, cval, nauto; + auto o; while((o=symbol())==20) { /* name */ if (kw==6) { /* extrn */ *csym = 6; - o = symbol(); + o = symbol(); } else { /* auto/param */ *csym = 5; /* auto */ csym[1] = nauto; - o = symbol(); + o = symbol(); if (kw==5 & o==21) { /* auto & number */ gen('y',nauto); /* aryop */ nauto = nauto + cval; o = symbol(); } - nauto++; + nauto = nauto+1; } if (o!=9) /* , */ goto done; } done: - if(o==1 & kw!=8 | o==7 & kw==8) /* auto/extrn ; param ')' */ + if(o==1 & kw!=8 | o==7 & kw==8) /* auto/extrn ; param ')' */ return; syntax: error('[]'); /* declaration syntax */ } extdef() { -// extern eof, cval; -// extern symbol, block, printf, pname, csym[]; -// extern error; + extern peeksym, *csym, cval, nauto; auto o, c; o = symbol(); @@ -512,40 +495,48 @@ extdef() { goto syntax; csym[0] = 6; /* extrn */ - xwrite('.'); + write('.'); name(csym + 2); - xwrite(': '); + write(':'); o=symbol(); if (o==2 | o==6) { /* $( ( */ - xwrite('.+'); - xwrite('1\n'); + write('.+'); + write('1\n'); nauto = 2; if (o==6) { /* ( */ declare(8); /* param */ if ((o=symbol())!=2) /* $( */ goto syntax; } - while((o=symbol())==19 && cval<10) /* auto extrn */ + while((o=symbol())==19 & cval<10) /* auto extrn */ declare(cval); peeksym = o; gen('s',nauto); /* setop */ - stmtlist(); - gen('n',7); /* retrn */ + stmtlist(); + gen('n',7); /* retrn */ + return; + } + + if (o==41) { /* - */ + if (symbol()!=21) /* number */ + goto syntax; + number(-cval); + write('\n'); return; } if (o==21) { /* number */ number(cval); - xwrite('\n'); + write('\n'); return; } - + if (o==1) { /* ; */ - xwrite('0\n'); + write('0\n'); return; } - + if (o==4) { /* [ */ c = 0; if ((o=symbol())==21) { /* number */ @@ -554,14 +545,19 @@ extdef() { } if (o!=5) /* ] */ goto syntax; - xwrite('.+'); - xwrite('1\n'); + write('.+'); + write('1\n'); if ((o=symbol())==1) /* ; */ goto done; - while (o==21) { /* number */ + while (o==21 | o==41) { /* number - */ + if (o==41) { /* - */ + if (symbol()!=21) + goto syntax; + cval = -cval; + } number(cval); - xwrite('\n'); - c--; + write('\n'); + c = c-1; if ((o=symbol())==1) /* ; */ goto done; if (o!=9) /* , */ @@ -572,13 +568,13 @@ extdef() { goto syntax; done: if (c>0) { - xwrite('.='); - xwrite('.+'); + write('.='); + write('.+'); number(c); - xwrite('\n'); + write('\n'); } return; - } + } if (o==0) /* eof */ return; @@ -589,7 +585,9 @@ syntax: } stmtlist() { - int o; + extern peeksym, eof; + auto o; + while (!eof) { if ((o = symbol())==3) /* $) */ return; @@ -600,14 +598,8 @@ stmtlist() { } stmt() { -// extern symbol, error, blkhed, eof, peeksym; -// extern blkend, csym[], rcexpr, block[], tree[], regtab[]; -// extern jumpc, jump, label, contlab, brklab, cval; -// extern swp[], isn, pswitch, peekc, slabel; -// extern efftab[], declare, deflab, swtab[], swsiz, branch; - -// int o, o1, o2, np[]; - int o, o1, o2; + extern peeksym, peekc, *csym, cval, isn, nauto; + auto o, o1, o2; next: o = symbol(); @@ -618,7 +610,7 @@ next: return; } - if (o==1 || o==3) /* ; $) */ + if (o==1 | o==3) /* ; $) */ return; if (o==2) { /* $( */ @@ -633,23 +625,23 @@ next: gen('n',6); /* goto */ goto semi; } - + if (cval==11) { /* return */ if((peeksym=symbol())==6) /* ( */ pexpr(); gen('n',7); /* retrn */ goto semi; } - + if (cval==12) { /* if */ pexpr(); - isn++; + isn = isn+1; o1 = isn; jumpc(o1); stmt(); o = symbol(); if (o==19 & cval==14) { /* else */ - isn++; + isn = isn+1; o2 = isn; jump(o2); label(o1); @@ -663,11 +655,11 @@ next: } if (cval==13) { /* while */ - isn++; + isn = isn+1; o1 = isn; label(o1); pexpr(); - isn++; + isn = isn+1; o2 = isn; jumpc(o2); stmt(); @@ -684,7 +676,7 @@ next: peekc = 0; if (!*csym) { *csym = 2; /* param */ - ++isn; + isn = isn+1; csym[1] = isn; } else if (*csym != 2) { error('rd'); @@ -709,42 +701,44 @@ syntax: } blkend() { + extern isn, nisn; + while (nisn < isn) { - ++nisn; - xwrite('l'); + nisn = nisn+1; + write('l'); number(nisn); - xwrite(': '); - xwrite('ll'); + write(':'); + write('ll'); number(nisn); - xwrite('\n'); + write('\n'); } } gen(o,n) { - xwrite(o); - xwrite(' '); + write(o); + write(' '); number(n); - xwrite('\n'); + write('\n'); } jumpc(n) { - xwrite('f '); /* ifop */ - xwrite('l'); + write('f '); /* ifop */ + write('l'); number(n); - xwrite('\n'); + write('\n'); } jump(n) { - xwrite('t '); /* traop */ - xwrite('ll'); + write('t '); /* traop */ + write('ll'); number(n); - xwrite('\n'); + write('\n'); } label(n) { - xwrite('ll'); + write('ll'); number(n); - xwrite(':\n'); + write(':'); } printn(n) { @@ -752,12 +746,12 @@ printn(n) { printn(n / 10); n = n % 10; } - xwrite(n + '0'); + write(n + '0'); } number(x) { if (x < 0) { - xwrite('-'); + write('-'); x = -x; } printn(x); @@ -765,53 +759,74 @@ number(x) { name(int *s) { while (*s) { - xwrite(*s); - s = s + 1; + write(*s); + s = s+1; } } error(code) { - extern line; - int f; + extern line, eof, *csym, nerror, fout; + auto f; - nerror++; - xflush(); + if (eof | nerror==20) { + eof = 1; + return; + } + nerror = nerror+1; + flush(); f = fout; fout = 1; - xwrite(code); - xwrite(' '); + write(code); + write(' '); if (code=='rd' | code=='un') { name(csym + 2); - xwrite(' '); + write(' '); } printn(line); - xwrite('\n'); - if (nerror==20) - exit(20); + write('\n'); + flush(); fout = f; } -// runtime: +/* storage */ -xread() { - char buf[1]; - if (read(fin, buf, 1) <= 0) - return 4; - return buf[0]; -} +int symtab[300] = { /* class value name */ + 1, 5,'a','u','t','o', 0 , + 1, 6,'e','x','t','r','n', 0 , + 1,10,'g','o','t','o', 0 , + 1,11,'r','e','t','u','r','n', 0 , + 1,12,'i','f', 0 , + 1,13,'w','h','i','l','e', 0 , + 1,14,'e','l','s','e', 0 }; -xwrite(int c) { - char buf[2]; - if (c & 0xff00) { - buf[0] = (c >> 8) & 0xff; - buf[1] = c & 0xff; - write(fout, buf, 2); - } else { - buf[0] = c & 0xff; - write(fout, buf, 1); - } -} +int ctab[] = { + 0,127,127,127, 0,127,127,127, /* NUL SOH STX ETX EOT ENQ ACK BEL */ + 127,126,126,127,127,127,127,127, /* BS TAB LF VT FF CR SO SI */ + 127,127,127,127,127,127,127,127, /* DLE DC1 DC2 DC3 DC4 NAK SYN ETB */ + 127,127,127,127,127,127,127,127, /* CAN EM SUB ESC FS GS RS US */ + 126, 34,122,127,127, 44, 47,121, /* SPC ! " # $ % & ' */ + 6, 7, 42, 40, 9, 41,127, 43, /* ( ) * + , - . / */ + 124,124,124,124,124,124,124,124, /* 0 1 2 3 4 5 6 7 */ + 124,124, 8, 1, 63, 80, 65, 90, /* 8 9 : ; < = > ? */ + 127,123,123,123,123,123,123,123, /* @ A B C D E F G */ + 123,123,123,123,123,123,123,123, /* H I J K L M N O */ + 123,123,123,123,123,123,123,123, /* P Q R S T U V W */ + 123,123,123, 4,127, 5, 48,127, /* X Y Z [ \ ] ^ _ */ + 127,123,123,123,123,123,123,123, /* ` a b c d e f g */ + 123,123,123,123,123,123,123,123, /* h i j k l m n o */ + 123,123,123,123,123,123,123,123, /* p q r s t u v w */ + 123,123,123, 2, 48, 3,127,127}; /* x y z { | } ~ DEL */ -xflush() { -} \ No newline at end of file +int symbuf[10]; +int peeksym = -1; +int peekc; +int eof; +int line = 1; +int *csym; +int *ns; +int cval; +int isn; +int nisn; +int nerror; +int nauto;