diff --git a/src/cmd/ed1.s b/src/cmd/ed1.s index 63d15ca..3210d09 100644 --- a/src/cmd/ed1.s +++ b/src/cmd/ed1.s @@ -26,7 +26,7 @@ dzm fbuf lac d1 dac dskadr - dac wrlfg + dac wrflg dzm diskin "o------------> [scan markup] jmp advanc @@ -272,7 +272,7 @@ cw: jms putsc; tal1 1: -1 - tad tufp + tad tbufp cma tad tal1 dac 1f @@ -283,7 +283,7 @@ cw: jms number jmp advanc -cn1: +cnl: lac adrflg sna jmp 1f @@ -346,7 +346,7 @@ addres: 0 ad1: jms getsc; tal ad2: - jms betwen; d47; d56 + jms betwen; d47; d58 skp jmp numb sad o40 "[o40 circled in scan] @@ -523,7 +523,7 @@ gline: 0 dac glint1 jms getdsk lac glint1 " [these 6 lines were surrounded by a box - adn o17777 " that was Xed out with an arrow pointing to it]: + and o17777 " that was Xed out with an arrow pointing to it]: tad dskbfp " -- dac ital "|\/| lac linep "|/\|<--- diff --git a/src/cmd/ed2.s b/src/cmd/ed2.s index 3345e98..458491a 100644 --- a/src/cmd/ed2.s +++ b/src/cmd/ed2.s @@ -3,7 +3,7 @@ " ed2 cs: - jsm getsc; tal + jms getsc; tal sad o40 jmp cs sad o12 @@ -67,7 +67,7 @@ cs: jmp 3b 3: -1 - tad lcrhno + tad lchrno rcr szl xor o400000 @@ -118,7 +118,7 @@ bsrch: jms compile jms srcsav lac dot - dad zerop + sad zerop lac eofp bloop: tad dm1 @@ -275,7 +275,7 @@ execute: 0 dac i trvect+1 jmp 1f -exchg: "??? +xchg: "??? lacq sad o12 jmp i execute @@ -310,7 +310,7 @@ matchar: 0 "??? skp jmp 1f lac matchar - adn o17777 + and o17777 tad jms1 dac i 8 "??? [unreadable page cutoff] "** 08-rest.pdf page 26 @@ -407,7 +407,7 @@ matclo: 0 "??? "??? the remainder of this scan had an unreadable first character "??? I did the best I could to recreate the characters appropriately -o1: 1 +d1: 1 o133: 0133 dm3: -3 o136: 0136 @@ -456,7 +456,7 @@ o54: 054 o17: 017 tname: - 0145056;0164155;0160040;040040 + 0145056;0164155;0160040;040040 " e.tmp tbufp: tbuf linep: line nlistp: nlist @@ -480,7 +480,7 @@ c1: .=.+1 ital: .=.+1 otal: .=.+1 diskin: .=.+1 -glint: .=.+1 +glint1: .=.+1 c2: .=.+1 num: .=.+1 zermp: .=.+1 @@ -502,7 +502,7 @@ bett1: .=.+1 bett2: .=.+1 wrflg: .=.+1 apt1: .=.+1 -"[page cuts off one label] +sfi: .=.+1 "[page cuts off one label] PLB: added "** 08-rest.pdf page 29 "[handwritten page number top right of scan - 22] sfo: .=.+1 @@ -513,7 +513,7 @@ fbuf: .=.+4 "not sure if this is fbuf, but tbuf: .=.+64 "there is a write; tbuf; 64 call line: .=.+64 nlist: .=.+50 -"??? ?list: .=.+50, unable to determine label +clist: .=.+50 " unable to determine label [PLB missing clist] compbuf: .=.+100 dskbuf: .=.+1 "[line crossed out - scan markup] lnodes: .=.+1000 diff --git a/tools/b.c b/tools/b.c new file mode 100644 index 0000000..4fc4556 --- /dev/null +++ b/tools/b.c @@ -0,0 +1,895 @@ +// 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 +// + +// 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 + +#ifdef _WIN32 +#include +#else +#include +#endif +#include +#include +#include +#include +#define eof xeof + +int fin = 0; +int fout = 1; + +int symtab[500] = { /* , type = 1, value = 1, name = 4 */ + 1, 5,0,0,'a','u','t','o',0, + 1, 6,0,0,'e','x','t','r','n',0, + 1,10,0,0,'g','o','t','o',0, + 1,11,0,0,'r','e','t','u','r','n',0, + 1,12,0,0,'i','f',0, + 1,13,0,0,'w','h','i','l','e',0, + 1,14,0,0,'e','l','s','e',0, + 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 */ +}; + +/* storage */ + +int symbuf[10]; +int peeksym = -1; +int peekc = 0; +int eof = 0; +int line = 1; +int *csym = 0; +int cval = 0; +int isn = 1; +int nerror = 0; + +int main(int argc, char **argv) { + if (argc > 1) { + if (argc > 2) { + if ((fout = creat(argv[2], 0777))<0) { + error('fo'); + exit(1); + } + } + if ((fin = open(argv[1],0))<0) { + error('fi'); + exit(1); + } + } + + while (!eof) { + extdef(); +// blkend(); + } + xflush(); + + exit(nerror); +} + +int *lookup() { + int *np, *sp, *rp; + + rp = symtab; + while (*rp) { + np = rp + 4; + 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; + np = rp + 4; + if (np >= symtab + 490) { + error("sf"); + exit(1); + } +loop: + *np = *sp; + np = np + 1; + sp = sp + 1; + if (*sp) + goto loop; + *np = 0; + 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; + + if (peeksym>=0) { + c = peeksym; + peeksym = -1; + return(c); + } + if (peekc) { + c = peekc; + peekc = 0; + } else { + if (eof) + return(0); + else + c = xread(); + } +loop: + ct = ctab[c]; + + if (ct==0) { /* EOT */ + eof++; + return(0); + } + + if (ct==126) { /* white space */ + if (c=='\n') /* newline */ + line = line + 1; + c = xread(); + 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 = xread(); +com1: + if (c==4) { + eof++; + error('*/'); /* end of text */ + return(0); + } + if (c=='\n') + line++; + if (c!='*') + goto com; + c = xread(); + if (c!='/') + goto com1; + c = xread(); + 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 = xread(); + } + 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) { + extern peekc, line; + auto a; + + if((a=xread())==c) + return(-1); + + if (a=='\n' | a==0 | a==4) { + error('cc'); + peekc = a; + return(-1); + } + + if (a=='*') { + a=xread(); + + 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); +} + +void expr(int lev) { + int o; + + o = symbol(); + + if (o==21) { /* constant */ +case21: + gen('n',5); /* litrl */ + xwrite(' '); + number(cval); + xwrite('\n'); + goto loop; + } + + if (o==20) { /* name */ + if (*csym==0) { + if((peeksym=symbol())==6) { /* ( */ + *csym = 6; /* extern */ + } + else { + if(csym[2]==0) /* unseen so far */ + csym[2] = isn++; + } + } + if(*csym==6) /* extern */ + gens('x',csym+4); + else + gen('a',csym+4); + goto loop; + } + + if (o==34) { /* ! */ + expr(1); + gen('u',4); /* unot */ + goto loop; + } + + if (o==41) { /* - */ + peeksym = symbol(); + if (peeksym==21) { /* constant */ + 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); + } + goto loop; + } + + peeksym = o; +} + +#if 0 + +decl(kw) { + extern csym[], symbol, paraml[], parame[]; + extern error, cval, peeksym, exit; + int t[], n, o; + + while((o=symbol())==20) { /* name */ + if(kw>=5) { /* type or sort? */ + if(*csym>0) + error('rd'); //error("%p redeclared", csym[4]); + *csym = kw; + } else { + if ((csym[1]&017)!=0) + error('rd'); //error("%p redeclared", &csym[4]); + csym[1] =| csym[1]&0760 | kw; + if (*csym==0) + *csym = -2; + } + while((o=symbol())==4) { /* [ */ + if((o=symbol())==21) { /* const */ + if(csym[1]>=020) + error('de'); //error("Bad vector"); + csym[3] = cval; + o = symbol(); + } + if (o!=5) /* ] */ + goto syntax; + csym[1] =+ 020; + } + if(kw==8) { /* parameter */ + *csym = -1; + if (paraml==0) + paraml = csym; + else + *parame = csym; + parame = csym; + } + if (o!=9) /* , */ + break; + } + if(o==1 & kw!=8 | o==7 & kw==8) + return; +syntax: + error('[]'); //error("Declaration syntax"); +} +#endif + +function() { +// extern declare, blkhed, blkend; +// extern printf, statement, peeksym, cval, symbol; +// extern paraml; +// auto o; + +// printf(".text; 1:mov r5,-(sp); mov sp,r5\n"); +// declare(8); +// declist(); + gen('s',2); /* ??? */ + statement(1); + gen('n',7); /* retrn */ +} + + +extdef() { +// extern eof, function, cval; +// extern symbol, block, printf, pname, csym[]; +// extern error; + auto o, c, *cs; +// char s; + + o = symbol(); + if(o==0 | o==1) /* EOF */ + return; + + if(o!=20) + goto syntax; + + csym[0] = 6; + cs = csym + 4; + xwrite('.'); + name(cs); + xwrite(': '); + xwrite('.+'); + xwrite('1\n'); +// s = ".data; %p:1f\n"; + o=symbol(); + + if (o==6) { /* ( */ + function(); + return; + } + + if (o==2) { /* $( */ + peeksym = o; + function(); + return; + } + + if (o==21) { /* const */ + printf(".data; %p: %o\n", cs, cval); + if((o=symbol())!=1) /* ; */ + goto syntax; + return; + } + + if (o==1) { /* ; */ + printf(".bss; %p: .=.+2\n", cs); + return; + } + + if (o==4) { /* [ */ + c = 0; + if((o=symbol())==21) { /* const */ + c = cval<<1; + o = symbol(); + } + if(o!=5) /* ] */ + goto syntax; + if((o=symbol())==1) { /* ; */ + printf(".bss; 1:.=.+%o\n", c); + return; + } + printf("1:"); + while(o==21) { /* const */ + printf("%o\n", cval); + c =- 2; + if((o=symbol())==1) /* ; */ + goto done; + if(o!=9) /* , */ + goto syntax; + else + o = symbol(); + } + goto syntax; +done: + if(c>0) + printf(".=.+%o\n", c); + return; + } + + if (o==0) /* EOF */ + return; + +syntax: + error('xx'); + statement(0); +} + +statement(d) { +// 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, n, *np; + +stmt: + o = symbol(); + + if (o==0) /* EOF */ + { + error('fe'); //"Unexpected EOF"); + return; + } + + if (o==1 || o==3) /* ; } */ + return; + + if (o==2) { /* { */ + if(d) + blkhed(); + while (!eof) { + o = symbol(); + if (o==3) /* } */ + return; + peeksym = o; + statement(0); + } + error('$)'); //error("Missing '}'"); + return; + } + + if (o==19) { /* keyword */ + +#if 0 + + if (cval==10) { /* goto */ + o1 = block(1,102,0,0,tree()); +// rcexpr(o1, regtab); + goto semi; + } +#endif + + if (cval==11) { /* return */ + if((peeksym=symbol())==6) /* ( */ + pexpr(); + gen('n',7); /* retrn */ + goto semi; + } + + if (cval==12) { /* if */ + pexpr(); + o1 = isn; + isn++; + jumpc(o1); + statement(0); + o = symbol(); + if (o==19 & cval==14) { /* else */ + o2 = isn; + isn++; + jump(o2); + label(o1); + statement(0); + label(o2); + return; + } + peeksym = o; + label(o1); + return; + } + + if (cval==13) { /* while */ + o1 = isn; + isn++; + label(o1); + pexpr(); + o2 = isn; + isn++; + jumpc(o2); + statement(0); + jump(o1); + label(o2); + return; + } + + error('sx'); + goto syntax; + } + + if (o==20) { /* name */ +#if 0 + if (peekc==':') { + peekc = 0; + if (csym[0]>0) { + error('rd'); + goto stmt; + } + csym[0] = 2; + csym[1] = 020; /* int[] */ +// if (csym[2]==0) +// csym[2] = isn++; + slabel(); + goto stmt; + } +#endif + } + + peeksym = o; + expr(15); + +semi: + o = symbol(); + if (o==1) /* ; */ + return; + +syntax: + error('sz'); + goto stmt; +} + +pexpr() +{ + auto o, t; + + if ((o=symbol())==6) { /* ( */ + expr(15); + if ((o=symbol())==7) /* ) */ + return; + } + error('()'); +} + +blkhed() +{ +#if 0 + extern symbol, cval, declare, peeksym, paraml[], parame[]; + extern error, length, rlength, setstk, defvec, isn, defstat; + extern stack, hshtab[], hshsiz, pssiz; + int o, al, pl, cs[], hl; + + declist(); + stack = al = -2; + pl = 4; + while(paraml) { + *parame = 0; + paraml = *(cs = paraml); + cs[2] = pl; + *cs = 10; + pl =+ rlength(cs[1]); + } + cs = hshtab; + hl = hshsiz; + while(hl--) { + if (cs[4]) + switch(cs[0]) { + + /* sort unmentioned */ + case 0177776: /* -2 */ + cs[0] = 5; /* auto */ + + /* auto */ + case 5: + if (cs[3]) { /* vector */ + al =- (cs[3]*length(cs[1]-020)+1) & 077776; + setstk(al); + defvec(al); + } + cs[2] = al; + al =- rlength(cs[1]); + goto loop; + + /* parameter */ + case 10: + cs[0] = 5; + goto loop; + + /* static */ + case 7: + cs[2] = isn++; + defstat(cs); + goto loop; + + loop:; + } + cs = cs+pssiz; + } + setstk(al); +#endif +} + +gens(o,n) { + xwrite(' '); + xwrite(o); + xwrite(' .'); + name(n); + xwrite('\n'); +} + +gen(o,n) { + xwrite(' '); + xwrite(o); + xwrite(' '); + number(n); + xwrite('\n'); +} + +jumpc(n) { + xwrite(' f'); /* ifop */ + xwrite(' .'); + number(n); + xwrite('\n'); +} + +jump(lbl) { + xwrite(' t'); /* traop */ + xwrite(' .'); + number(lbl); + xwrite('\n'); +} + +label(lbl) { + xwrite('.'); + number(lbl); + xwrite(': '); + xwrite('t '); + xwrite('.+'); + xwrite('1\n'); +} + +printn(n) { + if (n > 9) { + printn(n / 10); + n = n % 10; + } + xwrite(n + '0'); +} + +number(x) { + if (x < 0) { + xwrite('-'); + x = -x; + } + printn(x); +} + +name(int *s) { + while (*s) { + xwrite(*s); + s = s + 1; + } +} + +error(code) +{ + extern line; + int f; + + nerror++; + xflush(); + f = fout; + fout = 1; + xwrite(code); + xwrite(' '); + if (code=='rd' | code=='un') { + name(csym + 4); + xwrite(' '); + } + printn(line); + xwrite('\n'); + fout = f; +} + +// runtime: + +xread() { + char buf[1]; + if (read(fin, buf, 1) <= 0) + return 4; + return buf[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); + } +} + +xflush() { +} \ No newline at end of file