1
0
mirror of https://github.com/DoctorWkt/pdp7-unix.git synced 2026-02-09 01:41:09 +00:00

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.
This commit is contained in:
rswier
2016-03-16 01:46:35 -04:00
parent 3c3f946794
commit b3b868ed50
4 changed files with 1065 additions and 258 deletions

785
src/other/b.b Normal file
View File

@@ -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<symbuf+9) { *sp = c; sp = sp+1; }
c = read();
}
*sp = 0;
peekc = c;
csym = lookup();
if (csym[0]==1) {
cval = csym[1];
return(19); /* keyword */
}
return(20); /* name */
}
if (ct==127) { /* unknown */
error('sy');
c = read();
goto loop;
}
return(ctab[c]);
}
subseq(c,a,b) {
extrn peekc;
if (!peekc)
peekc = read();
if (peekc != c)
return(a);
peekc = 0;
return(b);
}
getcc() {
extrn cval;
auto c;
cval = 0;
if ((c = mapch('*'')) < 0) return;
cval = c;
if ((c = mapch('*'')) < 0) return;
cval = cval * 512 + c;
if ((c = mapch('*'')) >= 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;

View File

@@ -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

View File

@@ -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

445
tools/b.c
View File

@@ -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 <io.h>
@@ -21,66 +21,51 @@
#include <stdlib.h>
#include <memory.h>
#include <fcntl.h>
#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<symbuf+9) *sp++ = c;
c = xread();
if (sp<symbuf+9) { *sp = c; sp = sp+1; }
c = read();
}
*sp = 0;
peekc = c;
csym = lookup();
if (csym[0]==1) {
if (csym[0]==1) {
cval = csym[1];
return(19); /* keyword */
}
@@ -236,17 +217,17 @@ com1:
}
if (ct==127) { /* unknown */
error('sy');
c = xread();
c = read();
goto loop;
}
return(ctab[c]);
}
subseq(c,a,b) {
extern peekc; // extern xread, peekc;
extern peekc;
if (!peekc)
peekc = xread();
peekc = read();
if (peekc != c)
return(a);
peekc = 0;
@@ -267,10 +248,10 @@ getcc() {
}
mapch(c) {
extern peekc, line;
extern peekc;
auto a;
if((a=xread())==c)
if((a=read())==c)
return(-1);
if (a=='\n' | a==0 | a==4) {
@@ -280,10 +261,10 @@ mapch(c) {
}
if (a=='*') {
a=xread();
a=read();
if (a=='0')
return('\0');
return(0);
if (a=='e')
return(4);
@@ -306,40 +287,46 @@ mapch(c) {
return(a);
}
void expr(int lev) {
int o;
expr(lev) {
extern 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);
xwrite('\n');
write('\n');
goto loop;
}
if (o==20) { /* name */
if (*csym==0) { /* not seen */
if((peeksym=symbol())==6) { /* ( */
*csym = 6; /* extrn */
} else {
*csym = 2; /* internal */
csym[1] = ++isn;
isn = isn+1;
csym[1] = isn;
}
}
if(*csym==5) /* auto */
gen('a',csym[1]);
else {
xwrite('x ');
write('x ');
if (*csym==6) { /* extrn */
xwrite('.');
write('.');
name(csym+2);
} else { /* internal */
xwrite('l');
write('l');
number(csym[1]);
}
xwrite('\n');
}
write('\n');
}
goto loop;
}
@@ -408,22 +395,22 @@ loop:
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)
@@ -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() {
}
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;