commit d2270d144bbf53d9d7a14f5065f0f2f75ee9cbe1
parent dbb93eacff2b9600b8601fc8a422d63a38070921
Author: mortdeus <mortdeus@gocos2d.org>
Date: Fri, 1 Mar 2013 08:05:32 -0600
init
Diffstat:
M | README.md | | | 8 | ++++++-- |
A | last1120c/c00.c | | | 581 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | last1120c/c01.c | | | 210 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | last1120c/c02.c | | | 436 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | last1120c/c03.c | | | 189 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | last1120c/c0t.s | | | 264 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | last1120c/c10.c | | | 469 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | last1120c/c11.c | | | 251 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | last1120c/c1t.s | | | 171 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | last1120c/cctab.s | | | 118 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | last1120c/cvopt.c | | | 357 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | last1120c/efftab.s | | | 215 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | last1120c/regtab.s | | | 696 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | last1120c/sptab.s | | | 167 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | prestruct/c00.c | | | 776 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | prestruct/c01.c | | | 369 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | prestruct/c02.c | | | 505 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | prestruct/c03.c | | | 251 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | prestruct/c10.c | | | 588 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | prestruct/c11.c | | | 261 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
20 files changed, 6880 insertions(+), 2 deletions(-)
diff --git a/README.md b/README.md
@@ -1,4 +1,9 @@
legacy-cc
=========
-The earliest versions of the very first c compiler known to exist in the wild written by the late legend himself dmr.
-\ No newline at end of file
+The earliest versions of the very first c compiler known to exist in the wild written by the late legend himself dmr.
+
+These are not capable of being compiled today with modern c compilers like gcc. I am only posting these here for the enjoyment and reminiscing of the spark that ignited a soon to be trillion dollar industry. Enjoy. :)
+
+
+Source: [http://cm.bell-labs.com/cm/cs/who/dmr/primevalC.html]
diff --git a/last1120c/c00.c b/last1120c/c00.c
@@ -0,0 +1,581 @@
+/* C compiler
+
+Copyright 1972 Bell Telephone Laboratories, Inc.
+
+*/
+
+ossiz 250;
+ospace() {} /* fake */
+
+init(s, t)
+char s[]; {
+ extern lookup, symbuf, namsiz;
+ char symbuf[], sp[];
+ int np[], i;
+
+ i = namsiz;
+ sp = symbuf;
+ while(i--)
+ if ((*sp++ = *s++)=='\0') --s;
+ np = lookup();
+ *np++ = 1;
+ *np = t;
+}
+
+main(argc, argv)
+int argv[]; {
+ extern init, flush;
+ extern extdef, eof, open, creat;
+ extern fout, fin, error, exit, nerror, tmpfil;
+
+ if(argc<4) {
+ error("Arg count");
+ exit(1);
+ }
+ if((fin=open(argv[1],0))<0) {
+ error("Can't find %s", argv[1]);
+ exit(1);
+ }
+ if((fout=creat(argv[2], 017))<0) {
+ error("Can't create %s", argv[2]);
+ exit(1);
+ }
+ tmpfil = argv[3];
+ init("int", 0);
+ init("char", 1);
+ init("float", 2);
+ init("double", 3);
+/* init("long", 4); */
+ init("auto", 5);
+ init("extern", 6);
+ init("static", 7);
+ init("goto", 10);
+ init("return", 11);
+ init("if", 12);
+ init("while", 13);
+ init("else", 14);
+ init("switch", 15);
+ init("case", 16);
+ init("break", 17);
+ init("continue", 18);
+ init("do", 19);
+ init("default", 20);
+ while(!eof) {
+ extdef();
+ blkend();
+ }
+ flush();
+ flshw();
+ exit(nerror!=0);
+}
+
+lookup() {
+ extern hshtab[], hshsiz, pssiz, symbuf[];
+ extern hshlen, hshused, exit, error, nwps;
+ auto i, j, np[], sp[], rp[];
+
+ i = 0;
+ sp = symbuf;
+ j = nwps;
+ while(j--)
+ i =+ *sp++;
+ if (i<0) i = -i;
+ i =% hshsiz;
+ i =* pssiz;
+ while(*(np = &hshtab[i+4])) {
+ sp = symbuf;
+ j = nwps;
+ while(j--)
+ if (*np++ != *sp++) goto no;
+ return(&hshtab[i]);
+no: if ((i =+ pssiz) >= hshlen) i = 0;
+ }
+ if(hshused++ > hshsiz) {
+ error("Symbol table overflow");
+ exit(1);
+ }
+ rp = np = &hshtab[i];
+ sp = symbuf;
+ j = 4;
+ while(j--)
+ *np++ = 0;
+ j = nwps;
+ while(j--)
+ *np++ = *sp++;
+ return(rp);
+}
+
+symbol() {
+ extern peeksym, peekc, eof, getchar, subseq, error, line;
+ extern csym[], getstr, symbuf, namsiz, lookup[], ctab, cval;
+ auto b, c;
+ char symbuf[], sp[], ctab[];
+
+ if (peeksym>=0) {
+ c = peeksym;
+ peeksym = -1;
+ return(c);
+ }
+ if (peekc) {
+ c = peekc;
+ peekc = 0;
+ } else
+ if (eof)
+ return(0); else
+ c = getchar();
+loop:
+ switch(ctab[c]) {
+
+ case 125: /* newline */
+ line++;
+
+ case 126: /* white space */
+ c = getchar();
+ goto loop;
+
+ case 0: /* EOF */
+ eof++;
+ return(0);
+
+ case 40: /* + */
+ return(subseq(c,40,30));
+
+ case 41: /* - */
+ return(subseq(c,41,31));
+
+ case 80: /* = */
+ if (subseq(' ',0,1)) return(80);
+ c = symbol();
+ if (c>=40 & c<=49)
+ return(c+30);
+ if (c==80)
+ return(60);
+ peeksym = c;
+ return(80);
+
+ case 63: /* < */
+ if (subseq(c,0,1)) return(46);
+ return(subseq('=',63,62));
+
+ case 65: /* > */
+ if (subseq(c,0,1)) return(45);
+ return(subseq('=',65,64));
+
+ case 34: /* ! */
+ return(subseq('=',34,61));
+
+ case 43: /* / */
+ if (subseq('*',1,0))
+ return(43);
+com:
+ c = getchar();
+com1:
+ if (c=='\0') {
+ eof++;
+ error("Nonterminated comment");
+ return(0);
+ }
+ if (c=='\n')
+ line++;
+ if (c!='*')
+ goto com;
+ c = getchar();
+ if (c!='/')
+ goto com1;
+ c = getchar();
+ goto loop;
+
+ case 124: /* number */
+ cval = 0;
+ if (c=='0')
+ b = 8; else
+ b = 10;
+ while(ctab[c]==124) {
+ cval = cval*b + c -'0';
+ c = getchar();
+ }
+ peekc = c;
+ return(21);
+
+ case 122: /* " */
+ return(getstr());
+
+ case 121: /* ' */
+ return(getcc());
+
+ case 123: /* letter */
+ sp = symbuf;
+ while(ctab[c]==123 | ctab[c]==124) {
+ if (sp<symbuf+namsiz) *sp++ = c;
+ c = getchar();
+ }
+ while(sp<symbuf+namsiz)
+ *sp++ = '\0';
+ peekc = c;
+ csym = lookup();
+ if (csym[0]==1) { /* keyword */
+ cval = csym[1];
+ return(19);
+ }
+ return(20);
+
+ case 127: /* unknown */
+ error("Unknown character");
+ c = getchar();
+ goto loop;
+
+ }
+ return(ctab[c]);
+}
+
+subseq(c,a,b) {
+ extern getchar, peekc;
+
+ if (!peekc)
+ peekc = getchar();
+ if (peekc != c)
+ return(a);
+ peekc = 0;
+ return(b);
+}
+getstr() {
+ extern isn, cval;
+ auto c;
+
+ printf(".data;L%d:.byte ", cval=isn++);
+ while((c=mapch('"')) >= 0)
+ printf("%o,", c);
+ printf("0;.even;.text\n");
+ return(22);
+}
+
+getcc()
+{
+ extern cval, ncpw;
+ auto c, cc;
+ char cp[];
+
+ cval = 0;
+ cp = &cval;
+ cc = 0;
+ while((c=mapch('\'')) >= 0)
+ if(cc++ < ncpw)
+ *cp++ = c;
+ if(cc>ncpw)
+ error("Long character constant");
+ return(21);
+}
+
+mapch(c)
+{
+ extern peekc, line;
+ auto a;
+
+ if((a=getchar())==c)
+ return(-1);
+ switch(a) {
+
+ case '\n':
+ case 0:
+ error("Nonterminated string");
+ peekc = a;
+ return(-1);
+
+ case '\\':
+ switch (a=getchar()) {
+
+ case 't':
+ return('\t');
+
+ case 'n':
+ return('\n');
+
+ case '0':
+ return('\0');
+
+ case 'r':
+ return('\r');
+
+ case '\n':
+ line++;
+ return('\n');
+ }
+
+ }
+ return(a);
+}
+
+tree() {
+ extern symbol, block, csym[], ctyp, isn,
+ peeksym, opdope[], build, error, cp[], cmst[],
+ space, ospace, cval, ossiz, exit, errflush, cmsiz;
+
+ auto op[], opst[20], pp[], prst[20], andflg, o,
+ p, ps, os;
+
+ space = ospace;
+ op = opst;
+ pp = prst;
+ cp = cmst;
+ *op = 200; /* stack EOF */
+ *pp = 06;
+ andflg = 0;
+
+advanc:
+ switch (o=symbol()) {
+
+ /* name */
+ case 20:
+ 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 */
+ *cp++ = block(5,20,csym[1],0,*csym,
+ csym[4],csym[5],csym[6],csym[7]);
+ else
+ *cp++ = block(2,20,csym[1],0,*csym,csym[2]);
+ goto tand;
+
+ /* short constant */
+ case 21:
+ case21:
+ *cp++ = block(1,21,ctyp,0,cval);
+ goto tand;
+
+ /* string constant */
+ case 22:
+ *cp++ = block(1,22,17,0,cval);
+
+tand:
+ if(cp>=cmst+cmsiz) {
+ error("Expression overflow");
+ exit(1);
+ }
+ if (andflg)
+ goto syntax;
+ andflg = 1;
+ goto advanc;
+
+ /* ++, -- */
+ case 30:
+ case 31:
+ if (andflg)
+ o =+ 2;
+ goto oponst;
+
+ /* ! */
+ case 34:
+ if (andflg)
+ goto syntax;
+ goto oponst;
+
+ /* - */
+ case 41:
+ if (!andflg) {
+ peeksym = symbol();
+ if (peeksym==21) {
+ peeksym = -1;
+ cval = -cval;
+ goto case21;
+ }
+ o = 37;
+ }
+ andflg = 0;
+ goto oponst;
+
+ /* & */
+ /* * */
+ case 47:
+ case 42:
+ if (andflg)
+ andflg = 0; else
+ if(o==47)
+ o = 35;
+ else
+ o = 36;
+ goto oponst;
+
+ /* ( */
+ case 6:
+ if (andflg) {
+ o = symbol();
+ if (o==7)
+ o = 101; else {
+ peeksym = o;
+ o = 100;
+ andflg = 0;
+ }
+ }
+ goto oponst;
+
+ /* ) */
+ /* ] */
+ case 5:
+ case 7:
+ if (!andflg)
+ goto syntax;
+ goto oponst;
+ }
+
+ /* binaries */
+ if (!andflg)
+ goto syntax;
+ andflg = 0;
+
+oponst:
+ p = (opdope[o]>>9) & 077;
+opon1:
+ ps = *pp;
+ if (p>ps | p==ps & (opdope[o]&0200)!=0) { /* right-assoc */
+putin:
+ switch (o) {
+
+ case 6: /* ( */
+ case 4: /* [ */
+ case 100: /* call */
+ p = 04;
+ }
+ if(op>=opst+20) { /* opstack size */
+ error("expression overflow");
+ exit(1);
+ }
+ *++op = o;
+ *++pp = p;
+ goto advanc;
+ }
+ --pp;
+ switch (os = *op--) {
+
+ /* EOF */
+ case 200:
+ peeksym = o;
+ return(*--cp);
+
+ /* call */
+ case 100:
+ if (o!=7)
+ goto syntax;
+ build(os);
+ goto advanc;
+
+ /* mcall */
+ case 101:
+ *cp++ = 0; /* 0 arg call */
+ os = 100;
+ goto fbuild;
+
+ /* ( */
+ case 6:
+ if (o!=7)
+ goto syntax;
+ goto advanc;
+
+ /* [ */
+ case 4:
+ if (o!=5)
+ goto syntax;
+ build(4);
+ goto advanc;
+ }
+fbuild:
+ build(os);
+ goto opon1;
+
+syntax:
+ error("Expression syntax");
+ errflush(o);
+ return(0);
+}
+
+declare(kw) {
+ extern csym[], symbol, paraml[], parame[];
+ extern error, cval, errflush, peeksym, exit;
+ int t[], n, o;
+
+ while((o=symbol())==20) { /* name */
+ if(kw>=5) { /* type or sort? */
+ if(*csym>0)
+ error("%p redeclared", csym[4]);
+ *csym = kw;
+ } else {
+ if ((csym[1]&017)!=0)
+ 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("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("Declaration syntax");
+ errflush(o);
+}
+
+/* storage */
+
+regtab 0;
+efftab 1;
+cctab 2;
+sptab 3;
+symbuf[4];
+pssiz 8;
+namsiz 8;
+nwps 4;
+hshused 0;
+hshsiz 100;
+hshlen 800; /* 8*hshsiz */
+hshtab[800];
+space 0;
+cp 0;
+cmsiz 40;
+cmst[40];
+ctyp 0;
+isn 1;
+swsiz 120;
+swtab[120];
+swp 0;
+contlab 0;
+brklab 0;
+deflab 0;
+nreg 4;
+maprel[] 60,61,64,65,62,63,68,69,66,67;
+nauto 0;
+stack 0;
+peeksym 0177777;
+peekc 0;
+eof 0;
+line 1;
+csym 0;
+cval 0;
+ncpw 2;
+nerror 0;
+paraml;
+parame;
+tmpfil;
+
diff --git a/last1120c/c01.c b/last1120c/c01.c
@@ -0,0 +1,210 @@
+build(op) {
+ extern cp[], error, block, opdope[], maprel[], chklval;
+ extern chkw, cvtab, lintyp, dcalc;
+ auto p1[], t1, d1, p2[], t2, d2, p3[], t3, d3, t;
+ auto d, dope, lr, cvn;
+ char cvtab[];
+
+ if (op==4) { /* [] */
+ build(40); /* + */
+ op = 36;
+ }
+ dope = opdope[op];
+ if ((dope&01)!=0) {
+ p2 = *--cp;
+ t2 = p2[1];
+ d2 = p2[2];
+ }
+ p1 = *--cp;
+ t1 = p1[1];
+ d1 = p1[2];
+ switch (op) {
+
+ /* , */
+ case 9:
+ *cp++ = block(2, 9, 0, 0, p1, p2);
+ return;
+
+ /* ? */
+ case 90:
+ if (*p2!=8)
+ error("Illegal conditional");
+ goto goon;
+
+ /* call */
+ case 100:
+ *cp++ = block(2,100,t1,24,p1,p2);
+ return;
+
+ /* * */
+ case 36:
+ if ((t1 =- 16)<0) {
+ error("Illegal indirection");
+ t1 =+ 16;
+ }
+ if (*p1!=20 & d1==0)
+ d1 = 1;
+ *cp++ = block(1,36,t1,d1,p1);
+ return;
+
+ /* & unary */
+ case 35:
+ if (*p1 == 36) { /* * */
+ *cp++ = p1[3];
+ return;
+ }
+ if (*p1 == 20) {
+ *cp++ = block(1,p1[3]==5?29:35,t1+16,1,p1);
+ return;
+ }
+ error("Illegal lvalue");
+ }
+goon:
+ if ((dope&02)!=0) /* lvalue needed on left? */
+ chklval(p1);
+ if ((dope&020)!=0) /* word operand on left? */
+ chkw(p1);
+ if ((dope&040)!=0) /* word operand on right? */
+ chkw(p2);
+ if ((dope&01)!=0) { /* binary op? */
+ cvn = cvtab[9*lintyp(t1)+lintyp(t2)];
+ if ((dope&010)!=0) { /* assignment? */
+ t = t1;
+ lr = 1;
+ cvn =& 07;
+ } else {
+ t = (cvn&0100)!=0? t2:t1;
+ lr = cvn&0200;
+ cvn = (cvn>>3)&07;
+ }
+ if (cvn) {
+ if (cvn==07) {
+ error("Illegal conversion");
+ goto nocv;
+ }
+ cvn =+ (dope&010)!=0? 83:93;
+ if (lr) {
+ t2 = t;
+ d2 = (p2=convert(p2, t, d2, cvn))[2];
+ } else {
+ t1 = t;
+ d1 = (p1=convert(p1, t, d1, cvn))[2];
+ }
+nocv:; }
+ if (d2>d1 & (dope&0100)!=0) { /* flip commutative? */
+ if ((dope&04)!=0) /* relational? */
+ op = maprel[op-60];
+ d = d1;
+ d1 = d2;
+ d2 = d;
+ d = p1;
+ p1 = p2;
+ p2 = d;
+ d = t1;
+ t1 = t2;
+ t2 = d;
+ }
+ if (d1==d2)
+ d = d1+1; else
+ d = max(d1,d2);
+ if ((dope&04)!=0)
+ t = 0; /* relational is integer */
+ *cp++ = block(2,op,t,d,p1,p2);
+ return;
+ }
+ *cp++ = block(1,op,t1,d1==0?1:d1,p1);
+}
+
+convert(p, t, d, cvn)
+int p[];
+{
+ auto c;
+ if (*p==21) { /* constant */
+ c = p[3];
+ switch(cvn) {
+
+ case 99: /* c18 */
+ c =<< 1;
+
+ case 98: /* c14 */
+ c =<< 1;
+
+ case 97: /* c12 */
+ c =<< 1;
+
+ p[3] = c;
+ return(p);
+ }
+ }
+ return(block(1, cvn, t, max(1,d), p));
+}
+
+chkw(p)
+int p[]; {
+ extern error;
+ auto t;
+
+ if ((t=p[1])>1 & t<16)
+ error("Integer operand required");
+ return;
+}
+
+lintyp(t) {
+ return(t<16? t:(t<32? t-12: 8));
+}
+
+error(s, p1, p2) {
+ extern printf, line, fout, flush, putchar, nerror;
+ int f;
+
+ nerror++;
+ flush();
+ f = fout;
+ fout = 1;
+ printf("%d: ", line);
+ printf(s, p1, p2);
+ putchar('\n');
+ fout = f;
+}
+
+block(n, op, t, d, p1,p2,p3)
+int p1[],p2[],p3[]; {
+ extern space[], error, exit, ossiz, ospace[];
+ auto p[], ap[];
+
+ p = space;
+ ap = &op;
+ n =+ 3;
+ if(space+n >= ospace+ossiz) {
+ error("Expression overflow");
+ exit(1);
+ }
+ while(n--)
+ *space++ = *ap++;
+ return(p);
+}
+
+chklval(p)
+int p[]; {
+ extern error;
+ if (*p!=20)
+ if (*p!=36)
+ error("Lvalue required");
+}
+
+notcompat(at, st) {
+
+ if (st==0) /* word, byte */
+ return(at>1 & at<16);
+ if (st==1) /* word */
+ return(at>0 & at<16);
+ return((st-2) != at);
+}
+
+max(a, b)
+{
+ if (a>b)
+ return(a);
+ return(b);
+}
+
diff --git a/last1120c/c02.c b/last1120c/c02.c
@@ -0,0 +1,436 @@
+function() {
+ extern declare, blkhed, blkend;
+ extern printf, statement, peeksym, cval, symbol, retseq;
+ extern paraml;
+ auto o;
+
+ printf(".text; 1:mov r5,-(sp); mov sp,r5\n");
+ declare(8);
+ declist();
+ statement(1);
+ retseq();
+}
+
+extdef() {
+ extern eof, function, cval;
+ extern symbol, block, printf, pname, errflush, csym[];
+ extern error;
+ auto o, c, cs[];
+ char s[];
+
+ if(((o=symbol())==0) | o==1) /* EOF */
+ return;
+ if(o!=20)
+ goto syntax;
+ csym[0] = 6;
+ cs = &csym[4];
+ printf(".globl %p\n", cs);
+ s = ".data; %p:1f\n";
+ switch(o=symbol()) {
+
+ case 6: /* ( */
+ printf(s, cs);
+ function();
+ return;
+
+ case 21: /* const */
+ printf(".data; %p: %o\n", cs, cval);
+ if((o=symbol())!=1) /* ; */
+ goto syntax;
+ return;
+
+ case 1: /* ; */
+ printf(".bss; %p: .=.+2\n", cs);
+ return;
+
+ case 4: /* [ */
+ c = 0;
+ if((o=symbol())==21) { /* const */
+ c = cval<<1;
+ o = symbol();
+ }
+ if(o!=5) /* ] */
+ goto syntax;
+ printf(s, cs);
+ 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;
+
+ case 0: /* EOF */
+ return;
+ }
+
+syntax:
+ error("External definition syntax");
+ errflush(o);
+ statement(0);
+}
+
+statement(d) {
+ extern symbol, error, blkhed, eof, peeksym;
+ extern blkend, csym[], rcexpr, block[], tree[], regtab[];
+ extern retseq, jumpc, jump, label, contlab, brklab, cval;
+ extern swp[], isn, pswitch, peekc, slabel;
+ extern efftab[], declare, deflab, errflush, swtab[], swsiz, branch;
+
+ int o, o1, o2, o3, np[];
+
+stmt:
+ switch(o=symbol()) {
+
+ /* EOF */
+ case 0:
+ error("Unexpected EOF");
+ /* ; */
+ case 1:
+ /* } */
+ case 3:
+ return;
+
+ /* { */
+ case 2: {
+ if(d)
+ blkhed();
+ while (!eof) {
+ if ((o=symbol())==3) /* } */
+ goto bend;
+ peeksym = o;
+ statement(0);
+ }
+ error("Missing '}'");
+ bend:
+ return;
+ }
+
+ /* keyword */
+ case 19:
+ switch(cval) {
+
+ /* goto */
+ case 10:
+ o1 = block(1,102,0,0,tree());
+ rcexpr(o1, regtab);
+ goto semi;
+
+ /* return */
+ case 11:
+ if((peeksym=symbol())==6) /* ( */
+ rcexpr(pexpr(), regtab);
+ retseq();
+ goto semi;
+
+ /* if */
+ case 12:
+ jumpc(pexpr(), o1=isn++, 0);
+ statement(0);
+ if ((o=symbol())==19 & cval==14) { /* else */
+ o2 = isn++;
+ (easystmt()?branch:jump)(o2);
+ label(o1);
+ statement(0);
+ label(o2);
+ return;
+ }
+ peeksym = o;
+ label(o1);
+ return;
+
+ /* while */
+ case 13:
+ o1 = contlab;
+ o2 = brklab;
+ label(contlab = isn++);
+ jumpc(pexpr(), brklab=isn++, 0);
+ o3 = easystmt();
+ statement(0);
+ (o3?branch:jump)(contlab);
+ label(brklab);
+ contlab = o1;
+ brklab = o2;
+ return;
+
+ /* break */
+ case 17:
+ if(brklab==0)
+ error("Nothing to break from");
+ jump(brklab);
+ goto semi;
+
+ /* continue */
+ case 18:
+ if(contlab==0)
+ error("Nothing to continue");
+ jump(contlab);
+ goto semi;
+
+ /* do */
+ case 19:
+ o1 = contlab;
+ o2 = brklab;
+ contlab = isn++;
+ brklab = isn++;
+ label(o3 = isn++);
+ statement(0);
+ label(contlab);
+ contlab = o1;
+ if ((o=symbol())==19 & cval==13) { /* while */
+ jumpc(tree(), o3, 1);
+ label(brklab);
+ brklab = o2;
+ goto semi;
+ }
+ goto syntax;
+
+ /* case */
+ case 16:
+ if ((o=symbol())!=21) /* constant */
+ goto syntax;
+ if ((o=symbol())!=8) /* : */
+ goto syntax;
+ if (swp==0) {
+ error("Case not in switch");
+ goto stmt;
+ }
+ if(swp>=swtab+swsiz) {
+ error("Switch table overflow");
+ } else {
+ *swp++ = isn;
+ *swp++ = cval;
+ label(isn++);
+ }
+ goto stmt;
+
+ /* switch */
+ case 15:
+ o1 = brklab;
+ brklab = isn++;
+ np = pexpr();
+ if (np[1]>1 & np[1]<16)
+ error("Integer required");
+ rcexpr(np, regtab);
+ pswitch();
+ brklab = o1;
+ return;
+
+ /* default */
+ case 20:
+ if (swp==0)
+ error("Default not in switch");
+ if ((o=symbol())!=8) /* : */
+ goto syntax;
+ deflab = isn++;
+ label(deflab);
+ goto stmt;
+ }
+
+ error("Unknown keyword");
+ goto syntax;
+
+ /* name */
+ case 20:
+ if (peekc==':') {
+ peekc = 0;
+ if (csym[0]>0) {
+ error("Redefinition");
+ goto stmt;
+ }
+ csym[0] = 2;
+ csym[1] = 020; /* int[] */
+ if (csym[2]==0)
+ csym[2] = isn++;
+ slabel();
+ goto stmt;
+ }
+ }
+
+ peeksym = o;
+ rcexpr(tree(), efftab);
+ goto semi;
+
+semi:
+ if ((o=symbol())!=1) /* ; */
+ goto syntax;
+ return;
+
+syntax:
+ error("Statement syntax");
+ errflush(o);
+ goto stmt;
+}
+
+pexpr()
+{
+ auto o, t;
+
+ if ((o=symbol())!=6) /* ( */
+ goto syntax;
+ t = tree();
+ if ((o=symbol())!=7) /* ) */
+ goto syntax;
+ return(t);
+syntax:
+ error("Statement syntax");
+ errflush(o);
+ return(0);
+}
+
+pswitch() {
+ extern swp[], isn, swtab[], printf, deflab, statement, brklab;
+ extern label;
+ int sswp[], dl, cv, swlab;
+
+ sswp = swp;
+ if (swp==0)
+ swp = swtab;
+ swlab = isn++;
+ printf("jsr pc,bswitch; l%d\n", swlab);
+ dl = deflab;
+ deflab = 0;
+ statement(0);
+ if (!deflab) {
+ deflab = isn++;
+ label(deflab);
+ }
+ printf("L%d:.data;L%d:", brklab, swlab);
+ while(swp>sswp & swp>swtab) {
+ cv = *--swp;
+ printf("%o; l%d\n", cv, *--swp);
+ }
+ printf("L%d; 0\n.text\n", deflab);
+ deflab = dl;
+ swp = sswp;
+}
+
+blkhed()
+{
+ 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);
+}
+
+blkend() {
+ extern hshtab[], hshsiz, pssiz, hshused;
+ auto i, hl;
+
+ i = 0;
+ hl = hshsiz;
+ while(hl--) {
+ if(hshtab[i+4])
+ if (hshtab[i]==0)
+ error("%p undefined", &hshtab[i+4]);
+ if(hshtab[i]!=1) { /* not keyword */
+ hshused--;
+ hshtab[i+4] = 0;
+ }
+ i =+ pssiz;
+ }
+}
+
+errflush(o) {
+ extern symbol, peeksym, eof;
+
+ while(o>3) /* ; { } */
+ o = symbol();
+ peeksym = o;
+}
+
+declist()
+{
+ extern peeksym, peekc, csym[], cval;
+ auto o;
+
+ while((o=symbol())==19 & cval<10)
+ declare(cval);
+ peeksym = o;
+}
+
+easystmt()
+{
+ extern peeksym, peekc, cval;
+
+ if((peeksym=symbol())==20) /* name */
+ return(peekc!=':'); /* not label */
+ if (peeksym==19) { /* keyword */
+ switch(cval)
+
+ case 10: /* goto */
+ case 11: /* return */
+ case 17: /* break */
+ case 18: /* continue */
+ return(1);
+ return(0);
+ }
+ return(peeksym!=2); /* { */
+}
+
+branch(lab)
+{
+ printf("br L%d\n", lab);
+}
+
diff --git a/last1120c/c03.c b/last1120c/c03.c
@@ -0,0 +1,189 @@
+jumpc(tree, lbl, cond)
+int tree[];
+{
+ extern cctab, block, rcexpr;
+
+ rcexpr(block(1,easystmt()+103,tree,lbl,cond),cctab);
+}
+
+rcexpr(tree, table)
+int tree[], table;
+{
+ extern space, ospace, putwrd, putchar, line;
+ int c, sp[];
+
+ putchar('#');
+ c = space-ospace;
+ c =/ 2; /* # addresses per word */
+ sp = ospace;
+
+ putwrd(c);
+ putwrd(tree);
+ putwrd(table);
+ putwrd(line);
+ while(c--)
+ putwrd(*sp++);
+}
+
+jump(lab) {
+ extern printf;
+
+ printf("jmp\tl%d\n", lab);
+}
+
+label(l) {
+ extern printf;
+
+ printf("l%d:", l);
+}
+
+retseq() {
+ extern printf;
+
+ printf("jmp\tretrn\n");
+}
+
+slabel() {
+ extern csym[], printf;
+
+ printf(".data; l%d: 1f; .text; 1:\n", csym[2]);
+}
+
+setstk(a) {
+ extern printf, stack;
+ auto ts;
+
+ ts = a-stack;
+ stack = a;
+ switch(ts) {
+
+ case 0:
+ return;
+
+ case 0177776: /* -2 */
+ printf("tst -(sp)\n");
+ return;
+
+ case 0177774: /* -4 */
+ printf("cmp -(sp),-(sp)\n");
+ return;
+ }
+ printf("add $%o,sp\n", ts);
+}
+
+defvec() {
+ extern printf, stack;
+
+ printf("mov\tsp,r0\nmov\tr0,-(sp)\n");
+ stack =- 2;
+}
+
+defstat(s)
+int s[]; {
+ extern printf, length;
+ int len;
+
+ len = length(s[1]);
+ if (s[3])
+ printf(".data; l%d:1f; .bss; 1:.=.+%o; .even; .text\n", s[2],
+ s[3]*len);
+ else
+ printf(".bss; l%d:.=.+%o; .even; .text\n", s[2], len);
+}
+
+length(t) {
+
+ if (t<0)
+ t =+ 020;
+ if (t>=020)
+ return(2);
+ switch(t) {
+
+ case 0:
+ return(2);
+
+ case 1:
+ return(1);
+
+ case 2:
+ return(4);
+
+ case 3:
+ return(8);
+
+ case 4:
+ return(4);
+
+ }
+ return(1024);
+}
+
+rlength(c) {
+ extern length;
+ auto l;
+
+ return((l=length(c))==1? 2: l);
+}
+
+printn(n,b) {
+ extern putchar;
+ auto a;
+
+ if(a=n/b) /* assignment, not test for equality */
+ printn(a, b); /* recursive */
+ putchar(n%b + '0');
+}
+
+printf(fmt,x1,x2,x3,x4,x5,x6,x7,x8,x9)
+char fmt[]; {
+ extern printn, putchar, namsiz, ncpw;
+ char s[];
+ auto adx[], x, c, i[];
+
+ adx = &x1; /* argument pointer */
+loop:
+ while((c = *fmt++) != '%') {
+ if(c == '\0')
+ return;
+ putchar(c);
+ }
+ x = *adx++;
+ switch (c = *fmt++) {
+
+ case 'd': /* decimal */
+ case 'o': /* octal */
+ if(x < 0) {
+ x = -x;
+ if(x<0) { /* - infinity */
+ if(c=='o')
+ printf("100000");
+ else
+ printf("-32767");
+ goto loop;
+ }
+ putchar('-');
+ }
+ printn(x, c=='o'?8:10);
+ goto loop;
+
+ case 's': /* string */
+ s = x;
+ while(c = *s++)
+ putchar(c);
+ goto loop;
+
+ case 'p':
+ s = x;
+ putchar('_');
+ c = namsiz;
+ while(c--)
+ if(*s)
+ putchar(*s++);
+ goto loop;
+ }
+ putchar('%');
+ fmt--;
+ adx--;
+ goto loop;
+}
+
diff --git a/last1120c/c0t.s b/last1120c/c0t.s
@@ -0,0 +1,264 @@
+/ word I/O
+
+.globl _putwrd
+
+.globl _tmpfil
+.globl putw
+.globl fcreat
+.globl flush
+
+.data
+_putwrd: 1f
+.text
+1:
+ tst buf
+ bne 1f
+ mov _tmpfil,r0
+ jsr r5,fcreat; buf
+ bec 1f
+ mov $1,r0
+ sys write; botch; ebotch-botch
+ sys exit
+1:
+ mov 2(sp),r0
+ jsr r5,putw; buf
+ rts pc
+.globl _flshw
+.data
+_flshw: 1f
+.text
+1:
+ jsr r5,flush; buf
+ rts pc
+
+botch: <Temp file?\n\0>; ebotch:
+.even
+
+.bss
+buf: .=.+518.
+.text
+
+/ C operator and conversion tables
+
+.globl _opdope
+.globl _cvtab
+
+_opdope:.+2
+ 00000 / EOF
+ 00000 / ;
+ 00000 / {
+ 00000 / }
+ 36000 / [
+ 02000 / ]
+ 36000 / (
+ 02000 / )
+ 14201 / :
+ 07001 / ,
+ 00000 / 10
+ 00000 / 11
+ 00000 / 12
+ 00000 / 13
+ 00000 / 14
+ 00000 / 15
+ 00000 / 16
+ 00000 / 17
+ 00000 / 18
+ 00000 / 19
+ 00000 / name
+ 00000 / short constant
+ 00000 / string
+ 00000 / float
+ 00000 / double
+ 00000 / 25
+ 00000 / 26
+ 00000 / 27
+ 00000 / 28
+ 00000 / 29
+ 34202 / ++pre
+ 34202 / --pre
+ 34202 / ++post
+ 34202 / --post
+ 34220 / !un
+ 34202 / &un
+ 34220 / *un
+ 34200 / -un
+ 34220 / ~un
+ 00000 / 39
+ 30101 / +
+ 30001 / -
+ 32101 / *
+ 32001 / /
+ 32001 / %
+ 26061 / >>
+ 26061 / <<
+ 20161 / &
+ 16161 / |
+ 16161 / ^
+ 00000 / 50
+ 00000 / 51
+ 00000 / 52
+ 00000 / 53
+ 00000 / 54
+ 00000 / 55
+ 00000 / 56
+ 00000 / 57
+ 00000 / 58
+ 00000 / 59
+ 22105 / ==
+ 22105 / !=
+ 24105 / <=
+ 24105 / <
+ 24105 / >=
+ 24105 / >
+ 24105 / <p
+ 24105 / <=p
+ 24105 / >p
+ 24105 / >=p
+ 12213 / =+
+ 12213 / =-
+ 12213 / =*
+ 12213 / =/
+ 12213 / =%
+ 12253 / =>>
+ 12253 / =<<
+ 12253 / =&
+ 12253 / =|
+ 12253 / =^
+ 12213 / =
+ 00000 / 81
+ 00000 / 82
+ 00000 / 83
+ 00000 / int -> float
+ 00000 / int -> double
+ 00000 / float -> int
+ 00000 / float -> double
+ 00000 / double -> int
+ 00000 / double -> float
+ 14201 / ?
+ 00000 / 91
+ 00000 / 92
+ 00000 / 93
+ 00000 / int -> float
+ 00000 / int -> double
+ 00000 / float -> double
+ 00000 / int -> int[]
+ 00000 / int -> float[]
+ 00000 / int -> double[]
+ 36001 / call
+ 36001 / mcall
+
+_cvtab: .+2
+ .byte 000 / i:i
+ .byte 000 / i:c
+ .byte 113 / i:f
+ .byte 125 / i:d
+ .byte 140 / i:i[]
+ .byte 100 / i:c[]
+ .byte 150 / i:f[]
+ .byte 160 / i:d[]
+ .byte 140 / i:[][]
+
+ .byte 100 / c:i
+ .byte 100 / c:c
+ .byte 113 / c:f
+ .byte 125 / c:d
+ .byte 140 / c:i[]
+ .byte 100 / c:c[]
+ .byte 150 / c:f[]
+ .byte 160 / c:d[]
+ .byte 140 / c[][]
+
+ .byte 211 / f:i
+ .byte 211 / f:c
+ .byte 000 / f:f
+ .byte 136 / f:d
+ .byte 211 / f:i[]
+ .byte 211 / f:c[]
+ .byte 211 / f:f[]
+ .byte 211 / f:d[]
+ .byte 211 / f:[][]
+
+ .byte 222 / d:i
+ .byte 222 / d:c
+ .byte 234 / d:f
+ .byte 000 / d:d
+ .byte 222 / d:i[]
+ .byte 222 / d:c[]
+ .byte 222 / d:f[]
+ .byte 222 / d:d[]
+ .byte 222 / d:[][]
+
+ .byte 240 / i[]:i
+ .byte 240 / i[]:c
+ .byte 113 / i[]:f
+ .byte 125 / i[]:d
+ .byte 000 / i[]:i[]
+ .byte 000 / i[]:c[]
+ .byte 100 / i[]:f[]
+ .byte 100 / i[]:d[]
+ .byte 100 / i[]:[][]
+
+ .byte 000 / c[]:i
+ .byte 000 / c[]:c
+ .byte 113 / c[]:f
+ .byte 125 / c[]:d
+ .byte 200 / c[]:i[]
+ .byte 000 / c[]:c[]
+ .byte 200 / c[]:f[]
+ .byte 200 / c[]:d[]
+ .byte 200 / c[]:[][]
+
+ .byte 250 / f[]:i
+ .byte 250 / f[]:c
+ .byte 113 / f[]:f
+ .byte 125 / f[]:d
+ .byte 000 / f[]:i[]
+ .byte 000 / f[]:c[]
+ .byte 000 / f[]:f[]
+ .byte 100 / f[]:d[]
+ .byte 000 / f[]:[][]
+
+ .byte 260 / d[]:i
+ .byte 260 / d[]:c
+ .byte 113 / d[]:f
+ .byte 125 / d[]:d
+ .byte 000 / d[]:i[]
+ .byte 000 / d[]:c[]
+ .byte 000 / d[]:f[]
+ .byte 000 / d[]:d[]
+ .byte 000 / d[]:[][]
+
+ .byte 240 / [][]:i
+ .byte 240 / [][]:c
+ .byte 113 / [][]:f
+ .byte 125 / [][]:d
+ .byte 000 / [][]:i[]
+ .byte 000 / [][]:c[]
+ .byte 100 / [][]:f[]
+ .byte 100 / [][]:d[]
+ .byte 000 / [][]:[][]
+
+.even
+
+/ character type table
+
+.globl _ctab
+
+_ctab: .+2
+ .byte 000.,127.,127.,127.,127.,127.,127.,127.
+ .byte 127.,126.,125.,127.,127.,127.,127.,127.
+ .byte 127.,127.,127.,127.,127.,127.,127.,127.
+ .byte 127.,127.,127.,127.,127.,127.,127.,127.
+ .byte 126.,034.,122.,127.,127.,044.,047.,121.
+ .byte 006.,007.,042.,040.,009.,041.,127.,043.
+ .byte 124.,124.,124.,124.,124.,124.,124.,124.
+ .byte 124.,124.,008.,001.,063.,080.,065.,090.
+ .byte 127.,123.,123.,123.,123.,123.,123.,123.
+ .byte 123.,123.,123.,123.,123.,123.,123.,123.
+ .byte 123.,123.,123.,123.,123.,123.,123.,123.
+ .byte 123.,123.,123.,004.,127.,005.,049.,127.
+ .byte 127.,123.,123.,123.,123.,123.,123.,123.
+ .byte 123.,123.,123.,123.,123.,123.,123.,123.
+ .byte 123.,123.,123.,123.,123.,123.,123.,123.
+ .byte 123.,123.,123.,002.,048.,003.,127.,127.
+
diff --git a/last1120c/c10.c b/last1120c/c10.c
@@ -0,0 +1,469 @@
+/*
+
+ C compiler, part 2
+
+ Copyright 1972 Bell Telephone Laboratories, Inc.
+
+*/
+
+ospace() {} /* fake */
+
+waste() /* waste space */
+{
+ waste(waste(waste),waste(waste),waste(waste));
+ waste(waste(waste),waste(waste),waste(waste));
+ waste(waste(waste),waste(waste),waste(waste));
+ waste(waste(waste),waste(waste),waste(waste));
+ waste(waste(waste),waste(waste),waste(waste));
+ waste(waste(waste),waste(waste),waste(waste));
+ waste(waste(waste),waste(waste),waste(waste));
+ waste(waste(waste),waste(waste),waste(waste));
+}
+main(argc, argv)
+char argv[][];
+{
+ extern fout, fin, nerror, line;
+ extern getwrd, rcexpr, ospace, tmpfil;
+ extern cctab[], regtab[], efftab[], sptab[];
+ int sp[], c, table[], tabtab[3][], tree;
+
+ if (argc<4) {
+ error("Arg count");
+ exit(1);
+ }
+ if((fin=open(argv[1],0))<0) {
+ error("Cant't find %s", argv[1]);
+ exit(1);
+ }
+ if((fout=creat(argv[3],017))<0) {
+ error("Can't create %s", argv[3]);
+ exit(1);
+ }
+ tmpfil = argv[2];
+
+ tabtab[0] = regtab;
+ tabtab[1] = efftab;
+ tabtab[2] = cctab;
+ tabtab[3] = sptab;
+ while(c=getchar()) {
+ if(c=='#') {
+ sp = ospace;
+ c = getwrd();
+ tree = getwrd();
+ table = tabtab[getwrd()];
+ line = getwrd();
+ while(c--)
+ *sp++ = getwrd();
+ rcexpr(tree, table, 0);
+ } else
+ putchar(c);
+ }
+ flush();
+ exit(nerror!=0);
+}
+
+match(tree, table, nreg)
+int tree[], table[]; {
+ extern opdope[], dcalc, notcompat;
+ int op, d1, d2, t1, t2, p1[], p2[];
+ char mp[];
+
+ if (tree==0)
+ return(0);
+ op = *tree;
+ if (op>=29) /* if not leaf */
+ p1 = tree[3];
+ else
+ p1 = tree;
+ t1 = p1[1];
+ d1 = dcalc(p1, nreg);
+ if ((opdope[op]&01)!=0) { /* binary? */
+ p2 = tree[4];
+ t2 = p2[1];
+ d2 = dcalc(p2, nreg);
+ }
+ while(*table) {
+ if (*table++ == op) goto foundop;
+ table++;
+ }
+ return(0);
+foundop:
+ table = *table;
+nxtry:
+ mp = table;
+ if (*mp == 0)
+ return(0);
+ if (d1 > (*mp&077) | (*mp>=0100)&(*p1!=36))
+ goto notyet;
+ if (notcompat(t1, mp[1]))
+ goto notyet;
+ if ((opdope[op]&01)!=0 & p2!=0) {
+ if (d2 > (mp[2]&077) | (mp[2]>=0100)&(*p2!=36))
+ goto notyet;
+ if (notcompat(t2,mp[3]))
+ goto notyet;
+ }
+now:
+ return(table[2]);
+notyet:
+ table = table+3;
+ goto nxtry;
+}
+
+rcexpr(tree, table, reg)
+int tree[]; {
+ extern cexpr, regtab, cctab, sptab, printf, error;
+ extern jumpc, cbranch;
+
+ if(tree==0)
+ return;
+ if(*tree >= 103) {
+ (*tree==103?jumpc:cbranch)(tree[1],tree[2],tree[3],0);
+ return;
+ }
+ if (cexpr(tree, table, reg))
+ return;
+ if (table!=regtab)
+ if(cexpr(tree, regtab, reg)) {
+ if (table==sptab)
+ printf("mov r%d,-(sp)\n", reg);
+ if (table==cctab)
+ printf("tst r%d\n", reg);
+ return;
+ }
+ error("No match for op %d", *tree);
+}
+
+cexpr(tree, table, reg)
+int tree[][], table[]; {
+ extern match, nreg, printf, pname, putchar, regtab;
+ extern sptab, cctab, rcexpr, prins, rlength, popstk;
+ extern collcon, isn, label, branch, cbranch, fltmod;
+ int p1[], p2[], c, r, p[], otable[], ctable[], regtab[], cctab[];
+ char string[], match[];
+
+ if ((c = *tree)==100) { /* call */
+ p1 = tree[3];
+ p2 = tree[4];
+ r = 0;
+ if(p2) {
+ while (*p2==9) { /* comma */
+ rcexpr(p2[4], sptab, 0);
+ r =+ rlength((p=p2[4])[1]);
+ p2 = p2[3];
+ }
+ rcexpr(p2, sptab, 0);
+ r =+ rlength(p2[1]);
+ }
+ *tree = 101;
+ tree[2] = r; /* save arg length */
+ }
+ if(c==90) { /* ? */
+ cbranch(tree[3], c=isn++, 0, reg);
+ rcexpr(tree[4][3], table, reg);
+ branch(r=isn++, 0);
+ label(c);
+ rcexpr(tree[4][4], table, reg);
+ label(r);
+ return(1);
+ }
+ if ((string=match(tree, table, nreg-reg))==0)
+ return(0);
+ p1 = tree[3];
+ p2 = tree[4];
+loop:
+ switch(c = *string++) {
+
+ case '\0':
+ p = tree;
+ if (*p==101 & p[2]>0) {
+ popstk(p[2]);
+ }
+ return(1);
+
+ /* A1 */
+ case 'A':
+ p = tree[3];
+ goto adr;
+
+ /* A2 */
+ case 'B':
+ p = tree[4];
+ goto adr;
+
+ /* A */
+ case 'O':
+ p = tree;
+ adr:
+ pname(p);
+ goto loop;
+
+ /* I */
+ case 'M':
+ if ((c = *string)=='\'')
+ string++; else
+ c = 0;
+ prins(*tree, c);
+ goto loop;
+
+ /* B1 */
+ case 'C':
+ p = tree[3];
+ goto pbyte;
+
+ /* BF */
+ case 'P':
+ p = tree;
+ goto pb1;
+
+ /* B2 */
+ case 'D':
+ p = tree[4];
+ pbyte:
+ if (p[1]==1) /* char type? */
+ putchar('b');
+pb1:
+ if (isfloat(p))
+ putchar('f');
+ goto loop;
+
+ /* BE */
+ case 'L':
+ if (tree[3][1]==1 | tree[4][1]==1)
+ putchar('b');
+ goto loop;
+
+ /* C1 */
+ case 'E':
+ p = p1[3];
+ goto const;
+
+ /* C2 */
+ case 'F':
+ p = p2[3];
+ const:
+ printf("%o", p);
+ goto loop;
+
+ /* F */
+ case 'G':
+ p = p1;
+ goto subtre;
+
+ /* S */
+ case 'K':
+ p = p2;
+ goto subtre;
+
+ /* H */
+ case 'H':
+ p = tree;
+
+ subtre:
+ ctable = regtab;
+ r = reg;
+ c = *string++ - 'A';
+ if ((c&02)!=0)
+ ctable = sptab;
+ if ((c&04)!=0)
+ ctable = cctab;
+ if((c&010)!=0)
+ r = reg+1;
+ if((c&01)!=0)
+ if(*p==36) {
+ p = p[3];
+ if(collcon(p) & ctable!=sptab)
+ p = p[3];
+ }
+ rcexpr(p, ctable, r);
+ goto loop;
+
+ /* R */
+ case 'I':
+ r = reg;
+ goto preg;
+
+ /* R1 */
+ case 'J':
+ r = reg+1;
+ preg:
+ printf("r%d", r);
+ goto loop;
+
+ case '#':
+ p = p1[3];
+ goto nmbr;
+
+ case '"':
+ p = p2[3];
+ goto nmbr;
+ case '~':
+ p = tree[3];
+
+ nmbr:
+ if(collcon(p)) {
+ c = *p;
+ if(r = (p=p[4])[3])
+ printf("%o", c==40?r:-r);
+ }
+ goto loop;
+
+ /* M */
+ case 'N':
+ if ((c=isfloat(tree, &string))==fltmod)
+ goto loop;
+ printf((fltmod=c)==2?"setf\n":"setd\n");
+ goto loop;
+
+ /* Z */
+ case 'Z':
+ printf("$%o", p1[4]);
+ goto loop;
+ }
+ putchar(c);
+ goto loop;
+}
+
+pname(p)
+int p[][][]; {
+ extern putchar, printf, error;
+ char np[];
+ int i;
+
+loop:
+ switch(*p) {
+
+ case 21: /* const */
+ printf("$%o", p[3]);
+ return;
+
+ case 22: /* string */
+ printf("$l%d", p[3]);
+ return;
+
+ case 20: /* name */
+ switch(p[3]) {
+
+ case 5: /* auto, param */
+ printf("%o(r5)", p[4]);
+ return;
+
+ /* extern */
+ case 6:
+ printf("%p", &p[4]);
+ return;
+
+ }
+ printf("L%d", p[4]);
+ return;
+
+ case 35: /* & */
+ putchar('$');
+ p = p[3];
+ goto loop;
+
+ case 36: /* * */
+ putchar('*');
+ p = p[3];
+ goto loop;
+ }
+ error("pname called illegally");
+}
+
+dcalc(p, nreg)
+int p[]; {
+ int op, t;
+
+ if (p==0)
+ return(0);
+ op = *p;
+ switch (op) {
+
+ case 20: /* name */
+ case 22: /* string */
+ case 23: /* float */
+ case 24: /* double */
+ return(12);
+
+ case 21: /* short constant */
+ return(p[3]==0? 4:8);
+
+ case 35: /* & */
+ return(12);
+
+ case 36: /* * */
+ if ((op=dcalc(p[3], nreg))<16)
+ return(16);
+ }
+
+def:
+ return(p[2]<=nreg? 20: 24);
+}
+
+notcompat(at, st) {
+
+ if (st==0) /* word, byte */
+ return(at>1 & at<16);
+ if (st==1) /* word */
+ return(at>0 & at<16);
+ st =- 2;
+ if (st==2 & at==3)
+ at = 2;
+ return(st != at);
+}
+
+prins(op, c) {
+ extern instab[], printf;
+ int insp[];
+
+ insp = instab;
+ while(*insp) {
+ if (*insp++ == op) {
+ if ((c = insp[c!=0])==0)
+ goto err;
+ printf("%s", c);
+ return;
+ } else
+ insp = insp + 2;
+ }
+err:
+ error("No match' for op %d", op);
+}
+
+collcon(p)
+int p[]; {
+ int p1[];
+
+ if(*p==40 | *p==41)
+ if(*(p1=p[4])==21)
+ return(1);
+ return(0);
+}
+
+isfloat(t, s)
+int t[];
+char s[][];
+{
+ extern opdope[];
+ int rt;
+
+ rt = **s - '0';
+ if (rt==2 | rt==4) {
+ (*s)++;
+ return(rt>2?3:2);
+ }
+ if ((opdope[t[0]]&010)!=0) /* relational */
+ t = t[3];
+ if ((rt=t[1])>=2 & rt<=3)
+ return(rt);
+ return(0);
+}
+
+nreg 4;
+isn 10000;
+namsiz 8;
+line;
+tmpfil;
+nerror;
+fltmod;
+
diff --git a/last1120c/c11.c b/last1120c/c11.c
@@ -0,0 +1,251 @@
+jumpc(tree, lbl, cond)
+int tree[]; {
+ extern jump, cctab[], rcexpr, isn, label, branch, cbranch;
+ int l1, l2;
+
+ if (tree==0)
+ return;
+ switch(*tree) {
+
+ /* & */
+ case 47:
+ if (cond) {
+ cbranch(tree[3], l1=isn++, 0, 0);
+ cbranch(tree[4], l1, 0, 0);
+ jump(lbl);
+ label(l1);
+ } else {
+ cbranch(tree[3], l1=isn++, 0, 0);
+ cbranch(tree[4], l2=isn++, 1, 0);
+ label(l1);
+ jump(lbl);
+ label(l2);
+ }
+ return;
+
+ /* | */
+ case 48:
+ if (cond) {
+ cbranch(tree[3], l1=isn++, 1, 0);
+ cbranch(tree[4], l2=isn++, 0, 0);
+ label(l1);
+ jump(lbl);
+ label(l2);
+ } else {
+ cbranch(tree[3], l1=isn++, 1, 0);
+ cbranch(tree[4], l1, 1, 0);
+ jump(lbl);
+ label(l1);
+ }
+ return;
+
+ /* ! */
+ case 34:
+ jumpc(tree[3], lbl, !cond);
+ return;
+ }
+ rcexpr(tree, cctab, 0);
+ branch(l1=isn++, *tree, cond);
+ jump(lbl);
+ label(l1);
+ return;
+}
+
+cbranch(tree, lbl, cond, reg)
+int tree[]; {
+ extern branch, cctab[], rcexpr, isn, label;
+ int l1;
+
+ if (tree==0)
+ return;
+ switch(*tree) {
+
+ /* & */
+ case 47:
+ if (cond) {
+ cbranch(tree[3], l1=isn++, 0, reg);
+ cbranch(tree[4], lbl, 1, reg);
+ label(l1);
+ } else {
+ cbranch(tree[3], lbl, 0, reg);
+ cbranch(tree[4], lbl, 0, reg);
+ }
+ return;
+
+ /* | */
+ case 48:
+ if (cond) {
+ cbranch(tree[3], lbl, 1, reg);
+ cbranch(tree[4], lbl, 1, reg);
+ } else {
+ cbranch(tree[3], l1=isn++, 1, reg);
+ cbranch(tree[4], lbl, 0, reg);
+ label(l1);
+ }
+ return;
+
+ /* ! */
+ case 34:
+ cbranch(tree[3], lbl, !cond, reg);
+ return;
+ }
+ rcexpr(tree, cctab, reg);
+ branch(lbl, *tree, !cond);
+ return;
+}
+
+
+branch(lbl, op, c) {
+ extern printf, prins, opdope[];
+
+ if(op) {
+ if((opdope[op]&04)==0)
+ op = 61;
+ prins(op,c);
+ } else
+ printf("br");
+ printf("\tl%d\n", lbl);
+}
+
+jump(lab) {
+ extern printf;
+
+ printf("jmp\tl%d\n", lab);
+}
+
+label(l) {
+ extern printf;
+
+ printf("l%d:", l);
+}
+
+
+popstk(a) {
+ extern printf;
+
+ switch(a) {
+
+ case 0:
+ return;
+
+ case 2:
+ printf("tst (sp)+\n");
+ return;
+
+ case 4:
+ printf("cmp (sp)+,(sp)+\n");
+ return;
+ }
+ printf("add $%o,sp\n", a);
+}
+
+length(t) {
+
+ if (t<0)
+ t =+ 020;
+ if (t>=020)
+ return(2);
+ switch(t) {
+
+ case 0:
+ return(2);
+
+ case 1:
+ return(1);
+
+ case 2:
+ return(4);
+
+ case 3:
+ return(8);
+
+ case 4:
+ return(4);
+
+ }
+ return(1024);
+}
+
+rlength(c) {
+ extern length;
+ auto l;
+
+ return((l=length(c))==1? 2: l);
+}
+
+printn(n,b) {
+ extern putchar;
+ auto a;
+
+ if(a=n/b) /* assignment, not test for equality */
+ printn(a, b); /* recursive */
+ putchar(n%b + '0');
+}
+
+printf(fmt,x1,x2,x3,x4,x5,x6,x7,x8,x9)
+char fmt[]; {
+ extern printn, putchar, namsiz, ncpw;
+ char s[];
+ auto adx[], x, c, i[];
+
+ adx = &x1; /* argument pointer */
+loop:
+ while((c = *fmt++) != '%') {
+ if(c == '\0')
+ return;
+ putchar(c);
+ }
+ x = *adx++;
+ switch (c = *fmt++) {
+
+ case 'd': /* decimal */
+ case 'o': /* octal */
+ if(x < 0) {
+ x = -x;
+ if(x<0) { /* - infinity */
+ if(c=='o')
+ printf("100000");
+ else
+ printf("-32767");
+ goto loop;
+ }
+ putchar('-');
+ }
+ printn(x, c=='o'?8:10);
+ goto loop;
+
+ case 's': /* string */
+ s = x;
+ while(c = *s++)
+ putchar(c);
+ goto loop;
+
+ case 'p':
+ s = x;
+ putchar('_');
+ c = namsiz;
+ while(c--)
+ if(*s)
+ putchar(*s++);
+ goto loop;
+ }
+ putchar('%');
+ fmt--;
+ adx--;
+ goto loop;
+}
+
+error(s, p1, p2) {
+ extern printf, line, fout, flush, putchar, nerror;
+ int f;
+
+ nerror++;
+ flush();
+ f = fout;
+ fout = 1;
+ printf("%d: ", line);
+ printf(s, p1, p2);
+ putchar('\n');
+ fout = f;
+}
+
diff --git a/last1120c/c1t.s b/last1120c/c1t.s
@@ -0,0 +1,171 @@
+/ C operator tables
+
+.globl _getwrd
+
+.globl getw
+.globl fopen
+.globl _tmpfil
+
+.data
+_getwrd: 1f
+.text
+1:
+ tst buf
+ bne 1f
+ mov _tmpfil,r0
+ jsr r5,fopen; buf
+ bes botchp
+1:
+ jsr r5,getw; buf
+ bes botchp
+ rts pc
+botchp:
+ mov $1,r0
+ sys write; botch; ebotch-botch
+ sys exit
+botch:
+ <Temp file botch.\n>; ebotch:
+.even
+.bss
+buf: .=.+518.
+.text
+.globl _opdope
+.globl _instab
+
+_instab:.+2
+ 40.; 1f; 1f; .data; 1:<add\0>; .text
+ 70.; 1b; 1b
+ 41.; 2f; 2f; .data; 2:<sub\0>; .text
+ 71.; 2b; 2b
+ 30.; 3f; 1b; .data; 3:<inc\0>; .text
+ 31.; 4f; 2b; .data; 4:<dec\0>; .text
+ 32.; 3b; 1b
+ 33.; 4b; 2b
+
+ 45.; 2b; 5f; .data; 5:<ac\0>; .text
+ 46.; 6f; 7f; .data; 6:<mov\0>; 7:<(r4)\0>; .text
+ 75.; 2b; 5b
+ 76.; 6b; 7b
+ 43.; 7b; 1f; .data; 1:<divf\0>; .text
+ 44.; 5b; 0
+ 73.; 7b; 1b
+ 74.; 5b; 0
+
+ 60.; 0f; 1f; .data; 0:<beq\0>; 1:<bne\0>; .text
+ 61.; 1b; 0b
+ 62.; 2f; 5f; .data; 2:<ble\0>; 5:<bgt\0>; .text
+ 63.; 3f; 4f; .data; 3:<blt\0>; 4:<bge\0>; .text
+ 64.; 4b; 3b
+ 65.; 5b; 2b
+ 66.; 6f; 9f; .data; 6:<blos\0>; 9:<bhi\0>; .text
+ 67.; 7f; 8f; .data; 7:<blo\0>; 8:<bhis\0>; .text
+ 68.; 8b; 7b
+ 69.; 9b; 6b
+ 0
+ .data
+ .even
+ .text
+
+_opdope:.+2
+ 00000 / EOF
+ 00000 / ;
+ 00000 / {
+ 00000 / }
+ 36000 / [
+ 02000 / ]
+ 36000 / (
+ 02000 / )
+ 02000 / :
+ 07001 / ,
+ 00000 / 10
+ 00000 / 11
+ 00000 / 12
+ 00000 / 13
+ 00000 / 14
+ 00000 / 15
+ 00000 / 16
+ 00000 / 17
+ 00000 / 18
+ 00000 / 19
+ 00000 / name
+ 00000 / short constant
+ 00000 / string
+ 00000 / float
+ 00000 / double
+ 00000 / 25
+ 00000 / 26
+ 00000 / 27
+ 00000 / 28
+ 00000 / 29
+ 34002 / ++pre
+ 34002 / --pre
+ 34002 / ++post
+ 34002 / --post
+ 34020 / !un
+ 34002 / &un
+ 34020 / *un
+ 34000 / -un
+ 34020 / ~un
+ 00000 / 39
+ 30101 / +
+ 30001 / -
+ 32101 / *
+ 32001 / /
+ 32001 / %
+ 26061 / >>
+ 26061 / <<
+ 20161 / &
+ 16161 / |
+ 16161 / ^
+ 00000 / 50
+ 00000 / 51
+ 00000 / 52
+ 00000 / 53
+ 00000 / 54
+ 00000 / 55
+ 00000 / 56
+ 00000 / 57
+ 00000 / 58
+ 00000 / 59
+ 22105 / ==
+ 22105 / !=
+ 24105 / <=
+ 24105 / <
+ 24105 / >=
+ 24105 / >
+ 24105 / <p
+ 24105 / <=p
+ 24105 / >p
+ 24105 / >=p
+ 12013 / =+
+ 12013 / =-
+ 12013 / =*
+ 12013 / =/
+ 12013 / =%
+ 12053 / =>>
+ 12053 / =<<
+ 12053 / =&
+ 12053 / =|
+ 12053 / =^
+ 12013 / =
+ 00000 / 81
+ 00000 / 82
+ 00000 / 83
+ 00000 / int -> float
+ 00000 / int -> double
+ 00000 / float -> int
+ 00000 / float -> double
+ 00000 / double -> int
+ 00000 / double -> float
+ 14001 / ?
+ 00000 / 91
+ 00000 / 92
+ 00000 / 93
+ 00000 / int -> float
+ 00000 / int -> double
+ 00000 / float -> double
+ 00000 / int -> int[]
+ 00000 / int -> float[]
+ 00000 / int -> double[]
+ 36001 / call
+ 36001 / mcall
diff --git a/last1120c/cctab.s b/last1120c/cctab.s
@@ -0,0 +1,118 @@
+/ c code tables-- set condition codes
+
+.globl _cctab
+
+_cctab=.;.+2
+ 20.; rest
+ 21.; rest
+ 22.; rest
+ 30.; rest
+ 31.; rest
+ 34.; rest
+ 35.; rest
+ 36.; rest
+ 37.; rest
+ 40.; rest
+ 41.; rest
+ 42.; rest
+ 43.; rest
+ 44.; rest
+ 45.; rest
+ 46.; rest
+ 47.; rest
+ 48.; rest
+ 60.; cc60
+ 61.; cc60
+ 62.; cc60
+ 63.; cc60
+ 64.; cc60
+ 65.; cc60
+ 66.; cc60
+ 67.; cc60
+ 68.; cc60
+ 69.; cc60
+ 70.; rest
+ 71.; rest
+ 72.; rest
+ 73.; rest
+ 74.; rest
+ 75.; rest
+ 76.; rest
+ 77.; rest
+ 78.; rest
+ 79.; rest
+ 80.; rest
+
+/ relationals
+cc60:
+%a,z
+ tstB1 A1
+
+%n*,z
+ F*
+ tstB1 #1(R)
+
+%n,z
+ F
+ tst R
+
+%a,a
+ cmpBE A1,A2
+
+%n*,a
+ F*
+ cmpBE #1(R),A2
+
+%n,a
+ F
+ cmpB2 R,A2
+
+%n*,e*
+ F*
+ S1*
+ cmpBE #1(R),#2(R1)
+
+%n*,e
+ F*
+ S1
+ cmpB1 #1(R),R1
+
+%n,e*
+ F
+ S1*
+ cmpB2 R,#2(R1)
+
+%n,e
+ F
+ S1
+ cmp R,R1
+
+%n*,n*
+ FS*
+ S*
+ cmpBE (sp)+,#2(R)
+
+%n*,n
+ FS*
+ S
+ cmpB1 *(sp)+,R
+
+%n,n*
+ FS
+ S*
+ cmpB2 (sp)+,#2(R)
+
+%n,n
+ FS
+ S
+ cmp (sp)+,R
+
+/ set codes right
+rest:
+%n,n
+ H
+
+.data
+.even
+.text
+
diff --git a/last1120c/cvopt.c b/last1120c/cvopt.c
@@ -0,0 +1,357 @@
+main() {
+/*
+ A1 -> A
+ A2 B
+ A O
+ B1 C
+ B2 D
+ BE L
+ BF P
+ C1 E
+ C2 F
+ F G
+ H H
+ R I
+ R1 J
+ S K
+ I M
+ M N
+
+ * +1
+ S +2
+ C +4
+ 1 +8
+
+ z -> 4
+ c 10
+ a 14
+ e 20
+ n 63
+ * +0100
+*/
+
+ extern putchar,getc,peekc,printf,flag,flush;
+
+ auto c,snlflg,nlflg,t,smode,m,ssmode;
+
+ smode = nlflg = snlflg = ssmode = 0;
+loop:
+ c = getc();
+ if (c!='\n' & c!='\t') nlflg = 0;
+ if (ssmode!=0 & c!='%') {
+ ssmode = 0;
+ printf(".data\n1:<");
+ }
+ switch(c) {
+
+ case '\0':
+ printf(".text; 0\n");
+ flush();
+ return;
+
+ case ':':
+ if (!smode)
+ printf("=.+2; 0"); else
+ putchar(':');
+ goto loop;
+
+ case 'A':
+ if ((c=getc())=='1' | c=='2') {
+ putchar(c+'A'-'1');
+ goto loop;
+ }
+ putchar('O');
+ peekc = c;
+ goto loop;
+
+ case 'B':
+ switch (getc()) {
+
+ case '1':
+ putchar('C');
+ goto loop;
+
+ case '2':
+ putchar('D');
+ goto loop;
+
+ case 'E':
+ putchar('L');
+ goto loop;
+
+ case 'F':
+ putchar('P');
+ goto loop;
+ }
+ putchar('?');
+ goto loop;
+
+ case 'C':
+ putchar(getc()+'E'-'1');
+ goto loop;
+
+ case 'F':
+ putchar('G');
+ goto subtre;
+
+ case 'R':
+ if ((c=getc()) == '1')
+ putchar('J'); else {
+ putchar('I');
+ peekc = c;
+ }
+ goto loop;
+
+ case 'H':
+ putchar('H');
+ goto subtre;
+
+ case 'I':
+ putchar('M');
+ goto loop;
+
+ case 'M':
+ putchar('N');
+ snlflg++;
+ goto loop;
+
+ case 'S':
+ putchar('K');
+subtre:
+ snlflg = 1;
+ t = 'A';
+l1:
+ switch (c=getc()) {
+
+ case '*':
+ t++;
+ goto l1;
+
+ case 'S':
+ t =+ 2;
+ goto l1;
+
+ case 'C':
+ t =+ 4;
+ goto l1;
+
+ case '1':
+ t =+ 8;
+ goto l1;
+ }
+ peekc = c;
+ putchar(t);
+ goto loop;
+
+ case '#':
+ if(getc()=='1')
+ putchar('#'); else
+ putchar('"');
+ goto loop;
+
+ case '%':
+ if (smode)
+ printf(".text;");
+loop1:
+ switch (c=getc()) {
+
+ case 'a':
+ m = 16;
+ t = flag();
+ goto pf;
+
+ case ',':
+ putchar(';');
+ goto loop1;
+
+ case 'i':
+ m = 12;
+ t = flag();
+ goto pf;
+ case 'z':
+ m = 4;
+ t = 0;
+ goto pf;
+
+ case 'c':
+ t = 0;
+ m = 8;
+ goto pf;
+
+ case 'e':
+ t = flag();
+ m = 20;
+ goto pf;
+
+ case 'n':
+ t = flag();
+ m = 63;
+pf:
+ if ((c=getc())=='*')
+ m =+ 0100; else
+ peekc = c;
+ printf(".byte %o,%o", m, t);
+ goto loop1;
+
+ case '\n':
+ printf(";1f\n");
+ ssmode = 1;
+ nlflg = 1;
+ smode = 1;
+ goto loop;
+ }
+ putchar(c);
+ goto loop1;
+
+ case '\t':
+ if (nlflg) {
+ nlflg = 0;
+ goto loop;
+ }
+ putchar('\t');
+ goto loop;
+
+ case '\n':
+ if (!smode) {
+ putchar('\n');
+ goto loop;
+ }
+ if (nlflg) {
+ nlflg = 0;
+ printf("\\0>\n.text\n");
+ smode = 0;
+ goto loop;
+ }
+ if (!snlflg)
+ printf("\\n");
+ snlflg = 0;
+ printf(">\n<");
+ nlflg = 1;
+ goto loop;
+ }
+ putchar(c);
+ goto loop;
+}
+
+getc() {
+ extern getchar, peekc, nofloat;
+ auto t, ifcnt;
+
+ ifcnt = 0;
+gc:
+ if (peekc) {
+ t = peekc;
+ peekc = 0;
+ } else
+ t = getchar();
+ if (t==0)
+ return(0);
+ if (t=='{') {
+ ifcnt++;
+ t = getchar();
+ }
+ if (t=='}') {
+ t = getc();
+ if (--ifcnt==0)
+ if (t=='\n')
+ t = getc();
+ }
+ if (ifcnt & nofloat)
+ goto gc;
+ return(t);
+}
+
+flag() {
+ extern getc, peekc;
+ auto c, f;
+
+ f = 0;
+l1:
+ switch(c=getc()) {
+
+ case 'w':
+ f = 1;
+ goto l1;
+
+ case 'i':
+ f = 2;
+ goto l1;
+
+ case 'b':
+ f = 3;
+ goto l1;
+
+ case 'f':
+ f = 4;
+ goto l1;
+
+ case 'd':
+ f = 5;
+ goto l1;
+
+ case 'p':
+ f =+ 16;
+ goto l1;
+ }
+ peekc = c;
+ return(f);
+}
+
+peekc 0;
+
+putchar(c) {
+ extern flush, oubuf, ouptr;
+ char ouptr[], oubuf[];
+ auto c1;
+
+ goto init;
+init:
+ ouptr = oubuf;
+ init = init1;
+init1:
+ if(c1 = c>>8) {
+ *ouptr++ = c1;
+ if(ouptr >= oubuf+512)
+ flush();
+ }
+ if(c =& 0377) {
+ *ouptr++ = c;
+ if(ouptr >= oubuf+512)
+ flush();
+ }
+}
+
+flush() {
+ extern ouptr, oubuf, fout, write;
+ char ouptr[], oubuf[];
+
+ write(fout, oubuf, ouptr-oubuf);
+ ouptr = oubuf;
+}
+
+getcha() {
+ extern read, incnt, fin, inbuf, inptr;
+ char inbuf[], inptr[];
+
+ goto init;
+init:
+ inptr = inbuf;
+ init = init1;
+init1:
+ if(inptr >= inbuf+incnt) {
+ inptr = inbuf;
+ incnt = read(fin, inbuf, 512);
+ if(!incnt)
+ return('\0');
+ }
+ return(*inptr++);
+}
+
+inbuf[256];
+oubuf[256];
+inptr 0;
+incnt 0;
+ouptr 0;
+fin 0;
+fout 1;
+nofloat 0;
diff --git a/last1120c/efftab.s b/last1120c/efftab.s
@@ -0,0 +1,215 @@
+/ c code tables
+
+.globl _efftab
+
+_efftab=.;.+2
+ 30.; ci30
+ 31.; ci30
+ 32.; ci30 / same as 30
+ 33.; ci30 / same as 31
+ 80.; ci80
+ 70.; ci70
+ 71.; ci70 / - like +
+ 77.; ci77
+ 78.; ci78
+ 0
+
+/ ++ prefix
+ci30:
+%ai,n
+%abp,n
+%ab,n
+ IB1 A1
+
+%aip,n
+ I' $2,A1
+
+%nbp*,n
+%ni*,n
+%nb*,n
+ F*
+ IB1 #1(R)
+
+%nip*,n
+ F*
+ I' $2,#1(R)
+
+/ =
+ci80:
+%a,z
+ clrB1 A1
+
+%n*,z
+ F*
+ clrB1 #1(R)
+
+%a,aw
+ movB1 A2,A1
+
+%a,nw*
+ S*
+ movB1 #2(R),A1
+
+%a,n
+ S
+ movB1 R,A1
+
+%n*,aw
+ F*
+ movB1 A2,#1(R)
+
+%n*,ew*
+ F*
+ S1*
+ movB1 #2(R1),#1(R)
+
+%n*,e
+ F*
+ S1
+ movB1 R1,#1(R)
+
+%e*,nw*
+ S*
+ F1*
+ movB1 #2(R),#1(R1)
+
+%e*,n
+ S
+ F1*
+ movB1 R,#1(R1)
+
+%n*,nw*
+ FS*
+ S*
+ movB1 #2(R),*(sp)+
+
+%n*,n
+ FS*
+ S
+ movB1 R,*(sp)+
+
+/ =| i
+ci78:
+%a,a
+ bisBE A2,A1
+
+%a,n
+ S
+ bisB1 R,A1
+
+%n*,a
+ F*
+ bisBE A2,#1(R)
+
+%e*,n*
+ S*
+ F1*
+ bisBE #2(R),#1(R1)
+
+%e*,n
+ S
+ F1*
+ bisBE R,#1(R1)
+
+%n*,e*
+ F*
+ S1*
+ bisBE #2(R1),#1(R)
+
+%n*,e
+ F*
+ S1
+ bisBE R1,#1(R)
+
+%n*,n*
+ FS*
+ S*
+ bisBE #2(R),*(sp)+
+
+%n*,n
+ FS*
+ S
+ bisBE R,*(sp)+
+
+/ =& i
+ci77:
+%a,c
+ bicB1 $!C2,A1
+
+%a,n
+ S
+ com R
+ bicB1 R,A1
+
+%e*,n
+ S
+ F1*
+ com R
+ bicB1 R,#1(R1)
+
+%n*,c
+ F*
+ bicB1 $!C2,#1(R)
+
+%n*,e
+ F*
+ S1
+ com R1
+ bicB1 R1,#1(R)
+
+%n*,n
+ FS*
+ S
+ com R
+ bicB1 R,*(sp)+
+
+/ =+
+ci70:
+%aw,aw
+ I A2,A1
+
+%aw,nw*
+ S*
+ I #2(R),A1
+
+%aw,n
+ S
+ I R,A1
+
+%ew*,nw*
+ S*
+ F1*
+ I #2(R),#1(R1)
+
+%a,nw*
+ S*
+ movB1 A1,R1
+ I #2(R),R1
+ movB1 R1,#2(R)
+
+%a,n
+ S
+ movB1 A1,R1
+ I R1,R
+ movB1 R,A1
+
+%ew*,n
+ S
+ F1*
+ I R,#1(R1)
+
+%nw*,n
+ SS
+ F*
+ I (sp)+,#1(R)
+
+%n*,n
+ SS
+ F*
+ movB1 #1(R),R1
+ I (sp)+,R1
+ movB1 R1,#1(R)
+
+.data
+.even
+
diff --git a/last1120c/regtab.s b/last1120c/regtab.s
@@ -0,0 +1,696 @@
+/ c code tables-- compile to register
+
+fp = 1 / enable floating-point
+
+.globl _regtab
+
+_regtab=.; .+2
+ 20.; cr20
+ 21.; cr20
+ 22.; cr20
+ 30.; cr30
+ 31.; cr30
+ 32.; cr32
+ 33.; cr32
+ 34.; cr34
+ 35.; cr35
+ 29.; cr29
+ 36.; cr36
+ 37.; cr37
+ 38.; cr38
+ 101.; cr100
+ 80.; cr80
+ 40.; cr40
+ 41.; cr40 / - like +
+ 42.; cr42
+ 43.; cr43
+ 44.; cr43
+ 45.; cr45
+ 46.; cr45
+ 47.; cr47
+ 48.; cr48
+ 60.; cr60
+ 61.; cr60
+ 62.; cr60
+ 63.; cr60
+ 64.; cr60
+ 65.; cr60
+ 66.; cr60
+ 67.; cr60
+ 68.; cr60
+ 69.; cr60
+ 70.; cr70
+ 71.; cr70
+ 72.; cr72
+ 73.; cr73
+ 74.; cr73
+ 75.; cr75
+ 76.; cr75
+ 77.; cr77
+ 78.; cr78
+ 102.; cr102
+ 97.; cr97
+ 0
+
+/ goto
+cr102:
+%i,n
+ jmp *A1
+
+%n*,n
+ F*
+ jmp *#1(R)
+
+%n,n
+ F
+ jmp (R)
+
+/ call
+cr100:
+%n*,n
+ F*
+ jsr pc,*#1(R)
+
+%a,n
+ jsr pc,*A1
+
+%n,n
+ F
+ jsr pc,(R)
+
+/ name, constant
+cr20:
+%z,n
+ clr R
+
+%aw,n
+ mov A,R
+
+%ab,n
+ movb A,R
+
+.if fp
+%af,n
+ M
+ movf A,R
+
+.endif
+
+/++,-- prefix
+cr30:
+%ai,n
+%abp,n
+%ab,n
+ IB1 A1
+ movB1 A1,R
+
+%a,n
+ I' $2,A1
+ mov A1,R
+
+%nbp*,n
+%ni*,n
+%nb*,n
+ F*
+ IB1 #1(R)
+ movB1 #1(R),R
+
+%n*,n
+ F*
+ I' $2,#1(R)
+ mov #1(R),R
+
+/ ++,-- postfix
+cr32:
+%ai,n
+%abp,n
+%ab,n
+ movB1 A1,R
+ IB1 A1
+
+%a,n
+ mov A1,R
+ I' $2,A1
+
+%nbp*,n
+%nb*,n
+%ni*,n
+ F*
+ movB1 #1(R),-(sp)
+ IB1 #1(R)
+ movB1 (sp)+,R
+
+%n*,n
+ F*
+ mov #1(R),-(sp)
+ I' $2,#1(R)
+ mov (sp)+,R
+
+/ !
+cr34:
+%n,n
+ FC
+ beq 1f
+ clr R
+ br 2f
+1: mov $1,R
+2:
+
+/ &unary
+cr35:
+%a,n
+ mov $A1,R
+
+/ & unary of auto
+cr29:
+%e,n
+ mov r5,R
+ add Z,R
+
+/ *unary
+cr36:
+%abp*,n
+ F
+ movb (R),R
+
+%a*,n
+ F
+ mov (R),R
+
+%abp,n
+ movb *A1,R
+
+%a,n
+ mov *A1,R
+
+%nbp*,n
+ F*
+ movb *#1(R),R
+
+%n*,n
+ F*
+ mov *#1(R),R
+
+%nbp,n
+ H*
+ movb ~(R),R
+
+%n,n
+ H*
+ mov ~(R),R
+
+/ - unary
+cr37:
+%n,n
+ F
+ neg R
+
+/ ~
+cr38:
+%n,n
+ F
+ com R
+
+/ =
+cr80:
+%a,n
+ S
+ movB1 R,A1
+
+%n*,a
+ F*
+ movB1 A2,#1(R)
+ movB1 #1(R),R
+
+%n*,e
+ F*
+ S1
+ movB1 R1,#1(R)
+ mov R1,R
+
+%n*,n
+ FS*
+ S
+ movB1 R,*(sp)+
+
+/ |
+cr48:
+%n,a
+ F
+ bisB2 A2,R
+
+%n,e*
+ F
+ S1*
+ bisB2 #2(R1),R
+
+%n,e
+ F
+ S1
+ bis R1,R
+
+%n,n
+ FS
+ S
+ bis (sp)+,R
+
+/ &
+cr47:
+%n,c
+ F
+ bic $!C2,R
+
+%n,e
+ F
+ S1
+ com R1
+ bic R1,R
+
+%n,n
+ FS
+ S
+ com (sp)
+ bic (sp)+,R
+
+/ relationals
+cr60:
+%n,n
+ HC
+ I 2f
+ clr R
+ br 1f
+2: mov $1,R
+1:
+
+/ >>, <<
+cr45:
+%a,aw
+ movB1 A1,I'
+ I A2,lsh
+ movB1 I',R
+
+%n*,aw
+ F*
+ movB1 #1(R),I'
+ I A2,lsh
+ movB1 I',R
+
+%n,aw
+ F
+ mov R,I'
+ I A2,lsh
+ mov I',R
+
+%a,nw*
+ S*
+ movB1 A1,(r4)
+ I #2(R),lsh
+ mov (r4),R
+
+%a,n
+ S
+ movB1 A1,I'
+ I R,lsh
+ mov I',R
+
+%n,n
+ FS
+ S
+ mov (sp)+,I'
+ I R,lsh
+ mov I',R
+
+/ +, -
+cr40:
+%n,aw
+ F
+ I A2,R
+
+%n,ew*
+ F
+ S1*
+ I #2(R1),R
+
+%n,e
+ F
+ S1
+ I R1,R
+
+%n,nw*
+ SS*
+ F
+ I *(sp)+,R
+
+%n,n
+ SS
+ F
+ I (sp)+,R
+
+/ *
+cr42:
+%aw,a
+ mov A1,(r4)+
+ movB2 A2,(r4)
+ mov -(r4),R
+
+%n,a
+ F
+ mov R,(r4)+
+ movB2 A2,(r4)
+ mov -(r4),R
+
+%n,e
+ F
+ S1
+ mov R,(r4)+
+ mov R1,(r4)
+ mov -(r4),R
+
+%n,n
+ FS
+ S
+ mov (sp)+,(r4)+
+ mov R,(r4)
+ mov -(r4),R
+
+/ /; mod
+cr43:
+%a,a
+ movB1 A1,(r4)
+ movB2 A2,div
+ mov I,R
+
+%a,n
+ S
+ movB1 A1,(r4)
+ mov R,div
+ mov I,R
+
+%n,a
+ F
+ mov R,(r4)
+ movB2 A2,div
+ mov I,R
+
+%n,e
+ F
+ S1
+ mov R,(r4)
+ mov R1,div
+ mov I,R
+
+%e,n
+ S
+ F1
+ mov R1,(r4)
+ mov R,div
+ mov I,R
+
+%n,n
+ FS
+ S
+ mov (sp)+,(r4)
+ mov R,div
+ mov I,R
+
+/ =*
+cr72:
+%a,a
+ movB1 A1,(r4)
+ movB2 A2,mul
+ movB1 (r4),A1
+ mov (r4),R
+
+%a,n
+ S
+ mov R,(r4)+
+ movB1 A1,(r4)
+ mov -(r4),R
+ movB1 R,A1
+
+%n*,a
+ F*
+ movB1 #1(R),(r4)
+ movB2 A2,mul
+ movB1 (r4),#1(R)
+ mov (r4),R
+
+%n*,e
+ F*
+ S1
+ movB1 #1(R),(r4)
+ mov R1,mul
+ movB1 (r4),#1(R)
+ mov (r4),R
+
+%e*,n
+ S
+ F1*
+ movB1 #1(R1),(r4)
+ mov R,mul
+ movB1 (r4),#1(R1)
+ mov (r4),R
+
+%n*,n
+ FS*
+ S
+ movB1 *(sp),(r4)
+ mov R,mul
+ movB1 (r4),*(sp)+
+ mov (r4),R
+
+/ =mod, =/
+cr73:
+%a,a
+ movB1 A1,(r4)
+ movB2 A2,div
+ movB1 I,A1
+ mov I,R
+
+%a,n
+ S
+ movB1 A1,(r4)
+ mov R,div
+ mov I,R
+ movB1 R,A1
+
+%n*,a
+ F*
+ movB1 #1(R),(r4)
+ movB2 A2,div
+ movB1 I,#1(R)
+ mov I,R
+
+%n*,e
+ F*
+ S1
+ movB1 #1(R),(r4)
+ mov R1,div
+ movB1 I,#1(R)
+ mov I,R
+
+%e*,n
+ S
+ F1*
+ movB1 #1(R1),(r4)
+ mov R,div
+ movB1 I,#1(R1)
+ mov I,R
+
+%n*,n
+ FS*
+ S
+ movB1 *(sp),(r4)
+ mov R,div
+ movB1 I,*(sp)+
+ mov I,R
+
+/ =|
+cr78:
+%a,a
+ bisBE A2,A1
+ movB1 A1,R
+
+%a,n
+ S
+ bisB1 R,A1
+ movB1 A1,R
+
+%n*,a
+ F*
+ bisBE A2,#1(R)
+ movB1 #1(R),R
+
+%e*,n*
+ S*
+ F1*
+ bisBE #1(R1),#2(R)
+ movB1 #2(R),R
+
+%e*,n
+ S
+ F1*
+ bisBE R,#1(R1)
+ movB1 #1(R1),R
+
+%n*,e*
+ F*
+ S1*
+ bisBE #2(R1),#1(R)
+ movB1 #1(R),R
+
+%n*,e
+ F*
+ S1
+ bisBE R1,#1(R)
+ movB2 #1(R),R
+
+%n*,n*
+ FS*
+ S*
+ bisBE #2(R),*(sp)
+ movB2 *(sp)+,R
+
+%n*,n
+ FS*
+ S
+ bisBE R,*(sp)
+ mov *(sp)+,R
+
+/ =&
+cr77:
+%a,c
+ bicB1 $!C2,A1
+ movB2 A1,R
+
+%a,n
+ S
+ com R
+ bicB1 R,A1
+ movB1 A1,R
+
+%e*,n
+ S
+ F1*
+ com R
+ bicB1 R,#1(R1)
+ movB1 #1(R1),R
+
+%n*,e
+ F*
+ S1
+ com R1
+ bicB1 R1,#1(R)
+ movB1 #1(R),R
+
+%n*,n
+ FS*
+ S
+ com R
+ bicB1 R,*(sp)
+ movB1 *(sp)+,R
+
+/ =>>, =<<
+cr75:
+%a,aw
+ movB1 A1,I'
+ I A2,lsh
+ movB1 I',A1
+ movB1 I',R
+
+%a,n
+ S
+ movB1 A1,I'
+ I R,lsh
+ movB1 I',A1
+ movB1 I',R
+
+%n*,e
+ F*
+ S1
+ movB1 #1(R),I'
+ I R1,lsh
+ movB1 I',#1(R)
+ movB1 I',R
+
+%e*,n
+ S
+ F1*
+ movB1 #1(R1),I'
+ I R,lsh
+ movB I',#1(R1)
+ movB1 I',R
+
+%n*,n
+ FS*
+ S
+ movB1 *(sp),I'
+ I R,lsh
+ movB1 I',*(sp)+
+ movB1 I',R
+
+/ =+
+cr70:
+%aw,aw
+ I A2,A1
+ mov A1,R
+
+%aw,nw*
+ S*
+ I #2(R),A1
+ mov A1,R
+
+%aw,n
+ S
+ I R,A1
+ mov A1,R
+
+%ew*,nw*
+ S*
+ F1*
+ I #2(R),#1(R1)
+ mov #1(R1),R
+
+%a,nw*
+ S*
+ movB1 A1,R1
+ I #2(R),R1
+ movB1 R1,#2(R)
+ mov R1,R
+
+%a,n
+ S
+ movB1 A1,R1
+ I R1,R
+ movB1 R,A1
+
+%ew*,n
+ S
+ F1*
+ I R,#1(R1)
+ mov #1(R1),R
+
+%nw*,n
+ SS
+ F*
+ I (sp)+,#1(R)
+ mov #1(R),R
+
+%n*,n
+ SS
+ F*
+ movB1 #1(R),R1
+ I (sp)+,R1
+ movB1 R1,#1(R)
+ mov R1,R
+
+/ int -> int[]
+cr97:
+%n,n
+ F
+ asl R
+
+.data
+.even
+.text
+
diff --git a/last1120c/sptab.s b/last1120c/sptab.s
@@ -0,0 +1,167 @@
+/ c code tables-- expression to -(sp)
+
+.globl _sptab
+
+_sptab=.;.+2
+ 20.; cs20
+ 21.; cs21
+ 22.; cs21
+ 30.; cs30
+ 31.; cs30
+ 32.; cs32
+ 33.; cs32
+ 35.; cs35
+ 36.; cs36
+ 40.; cs40
+ 41.; cs40
+ 42.; cs42
+ 47.; cs47
+ 48.; cs48
+ 0
+
+
+/ name
+cs20:
+%aw,n
+ mov A,-(sp)
+
+/ constant
+cs21:
+%z,n
+ clr -(sp)
+
+%a,n
+ mov A,-(sp)
+
+/ ++,-- prefix
+cs30:
+%ai,n
+%abp,n
+ I A1
+ mov A1,-(sp)
+
+%aw,n
+ I' $2,A1
+ mov A1,-(sp)
+
+%nbp*,n
+%ni*,n
+ F*
+ I #1(R)
+ mov #1(R),-(sp)
+
+%nip*,n
+ F*
+ mov #1(R),-(sp)
+ I' $2,#1(R)
+
+/ ++,-- postfix
+cs32:
+%ai,n
+%abp,n
+ mov A1,-(sp)
+ I A1
+
+%aip,n
+ mov A1,-(sp)
+ I' $2,A1
+
+%nbp*,n
+%ni*,n
+ F*
+ mov #1(R),-(sp)
+ I #1(R)
+
+%nip*,n
+ F*
+ mov #1(R),-(sp)
+ I' $2,#1(R)
+
+/ & unary
+cs35:
+%i,n
+ mov $A1,-(sp)
+
+/ * unary
+cs36:
+%aw,n
+ mov *A1,-(sp)
+
+%nw*,n
+ F*
+ mov #1(R),-(sp)
+
+/ +
+cs40:
+%n,aw
+ FS
+ I A2,(sp)
+
+%n,nw*
+ FS
+ S*
+ I #2(R),(sp)
+
+%n,n
+ FS
+ S
+ I R,(sp)
+
+/ *
+cs42:
+%aw,a
+ mov A1,(r4)+
+ movB2 A2,(r4)
+ mov -(r4),-(sp)
+
+%n,a
+ F
+ mov R,(r4)+
+ movB2 A2,(r4)
+ mov -(r4),-(sp)
+
+%n,nw*
+ FS
+ S*
+ mov (sp)+,(r4)+
+ mov #2(R),(r4)
+ mov -(r4),-(sp)
+
+%n,n
+ FS
+ S
+ mov (sp)+,(r4)+
+ mov R,(r4)
+ mov -(r4),-(sp)
+
+/ &
+cs47:
+%n,c
+ FS
+ bic $!C2,(sp)
+
+%n,n
+ FS
+ S
+ com R
+ bic R,(sp)
+
+/ |
+cs48:
+%n,a
+ FS
+ bisB2 A2,(sp)
+
+%n,n*
+ FS
+ S*
+ bisB2 #2(R),(sp)
+
+%n,n
+ FS
+ S
+ bis R,(sp)
+
+.data
+.even
+.text
diff --git a/prestruct/c00.c b/prestruct/c00.c
@@ -0,0 +1,776 @@
+/* C compiler
+
+Copyright 1972 Bell Telephone Laboratories, Inc.
+
+*/
+
+init(s, t)
+char s[]; {
+ extern symbuf, namsiz;
+ char symbuf[], sp[];
+ int np[], i;
+
+ i = namsiz;
+ sp = symbuf;
+ while(i--)
+ if ((*sp++ = *s++)=='\0') --s;
+ np = lookup();
+ *np++ = 1;
+ *np = t;
+}
+
+main(argc, argv)
+int argv[]; {
+ extern extdef, eof;
+ extern fout, fin, nerror, tmpfil, xdflg;
+
+ if(argc<4) {
+ error("Arg count");
+ exit(1);
+ }
+ if((fin=open(argv[1],0))<0) {
+ error("Can't find %s", argv[1]);
+ exit(1);
+ }
+ if((fout=creat(argv[2], 017))<0) {
+ error("Can't create %s", argv[2]);
+ exit(1);
+ }
+ tmpfil = argv[3];
+ xdflg++;
+ init("int", 0);
+ init("char", 1);
+ init("float", 2);
+ init("double", 3);
+ init("struct", 4);
+ init("auto", 5);
+ init("extern", 6);
+ init("static", 7);
+ init("goto", 10);
+ init("return", 11);
+ init("if", 12);
+ init("while", 13);
+ init("else", 14);
+ init("switch", 15);
+ init("case", 16);
+ init("break", 17);
+ init("continue", 18);
+ init("do", 19);
+ init("default", 20);
+ xdflg = 0;
+ while(!eof) {
+ extdef();
+ blkend();
+ }
+ flush();
+ flshw();
+ exit(nerror!=0);
+}
+
+lookup() {
+ extern hshtab, hshsiz, pssiz, symbuf, xdflg;
+ int hshtab[], symbuf[];
+ extern hshlen, hshused, nwps;
+ auto i, j, np[], sp[], rp[];
+
+ i = 0;
+ sp = symbuf;
+ j = nwps;
+ while(j--)
+ i =+ *sp++ & 077577;
+ if (i<0) i = -i;
+ i =% hshsiz;
+ i =* pssiz;
+ while(*(np = &hshtab[i+4])) {
+ sp = symbuf;
+ j = nwps;
+ while(j--)
+ if ((*np++&077577) != *sp++) goto no;
+ return(&hshtab[i]);
+no: if ((i =+ pssiz) >= hshlen) i = 0;
+ }
+ if(++hshused > hshsiz) {
+ error("Symbol table overflow");
+ exit(1);
+ }
+ rp = np = &hshtab[i];
+ sp = symbuf;
+ j = 4;
+ while(j--)
+ *np++ = 0;
+ j = nwps;
+ while(j--)
+ *np++ = *sp++;
+ *np = 0;
+ if (xdflg)
+ rp[4] =| 0200; /* mark non-deletable */
+ return(rp);
+}
+
+symbol() {
+ extern peeksym, peekc, eof, line;
+ extern csym, symbuf, namsiz, lookup, ctab, cval;
+ int csym[];
+ extern isn, mosflg, xdflg;
+ auto b, c;
+ char symbuf[], sp[], ctab[];
+
+ if (peeksym>=0) {
+ c = peeksym;
+ peeksym = -1;
+ if (c==20)
+ mosflg = 0;
+ return(c);
+ }
+ if (peekc) {
+ c = peekc;
+ peekc = 0;
+ } else
+ if (eof)
+ return(0); else
+ c = getchar();
+loop:
+ switch(ctab[c]) {
+
+ case 125: /* newline */
+ line++;
+
+ case 126: /* white space */
+ c = getchar();
+ goto loop;
+
+ case 0: /* EOF */
+ eof++;
+ return(0);
+
+ case 40: /* + */
+ return(subseq(c,40,30));
+
+ case 41: /* - */
+ return(subseq(c,subseq('>',41,50),31));
+
+ case 80: /* = */
+ if (subseq(' ',0,1)) return(80);
+ c = symbol();
+ if (c>=40 & c<=49)
+ return(c+30);
+ if (c==80)
+ return(60);
+ peeksym = c;
+ return(80);
+
+ case 63: /* < */
+ if (subseq(c,0,1)) return(46);
+ return(subseq('=',63,62));
+
+ case 65: /* > */
+ if (subseq(c,0,1)) return(45);
+ return(subseq('=',65,64));
+
+ case 34: /* ! */
+ return(subseq('=',34,61));
+
+ case 43: /* / */
+ if (subseq('*',1,0))
+ return(43);
+com:
+ c = getchar();
+com1:
+ if (c=='\0') {
+ eof++;
+ error("Nonterminated comment");
+ return(0);
+ }
+ if (c=='\n')
+ line++;
+ if (c!='*')
+ goto com;
+ c = getchar();
+ if (c!='/')
+ goto com1;
+ c = getchar();
+ goto loop;
+
+ case 120: /* . */
+ case 124: /* number */
+ peekc = c;
+ switch(c=getnum(c=='0'? 8:10)) {
+ case 25: /* float 0 */
+ c = 23;
+ break;
+
+ case 23: /* float non 0 */
+ cval = isn++;
+ }
+ return(c);
+
+ case 122: /* " */
+ return(getstr());
+
+ case 121: /* ' */
+ return(getcc());
+
+ case 123: /* letter */
+ sp = symbuf;
+ if (mosflg) {
+ *sp++ = '.';
+ mosflg = 0;
+ }
+ while(ctab[c]==123 | ctab[c]==124) {
+ if (sp<symbuf+namsiz) *sp++ = c;
+ c = getchar();
+ }
+ while(sp<symbuf+namsiz)
+ *sp++ = '\0';
+ peekc = c;
+ csym = lookup();
+ if (csym[0]==1) { /* keyword */
+ cval = csym[1];
+ return(19);
+ }
+ return(20);
+
+ case 127: /* unknown */
+ error("Unknown character");
+ c = getchar();
+ goto loop;
+
+ }
+ return(ctab[c]);
+}
+
+subseq(c,a,b) {
+ extern peekc;
+
+ if (!peekc)
+ peekc = getchar();
+ if (peekc != c)
+ return(a);
+ peekc = 0;
+ return(b);
+}
+getstr() {
+ extern isn, cval, strflg;
+ auto c;
+ char t[], d[];
+
+ t = ".text";
+ d = ".data";
+ printf("%s;L%d:.byte ", (strflg?t:d), cval=isn++);
+ while((c=mapch('"')) >= 0)
+ printf("%o,", c);
+ printf("0;.even;%s\n", (strflg?d:t));
+ return(22);
+}
+
+getcc()
+{
+ extern cval, ncpw;
+ auto c, cc;
+ char cp[];
+
+ cval = 0;
+ cp = &cval;
+ cc = 0;
+ while((c=mapch('\'')) >= 0)
+ if(cc++ < ncpw)
+ *cp++ = c;
+ if(cc>ncpw)
+ error("Long character constant");
+ return(21);
+}
+
+mapch(c)
+{
+ extern peekc, line;
+ auto a;
+
+ if((a=getchar())==c)
+ return(-1);
+ switch(a) {
+
+ case '\n':
+ case 0:
+ error("Nonterminated string");
+ peekc = a;
+ return(-1);
+
+ case '\\':
+ switch (a=getchar()) {
+
+ case 't':
+ return('\t');
+
+ case 'n':
+ return('\n');
+
+ case '0':
+ return('\0');
+
+ case 'r':
+ return('\r');
+
+ case '\n':
+ line++;
+ return('\n');
+ }
+
+ }
+ return(a);
+}
+
+tree() {
+ extern csym, ctyp, isn, fcval, peeksym, opdope, cp, cmst;
+ int csym[], opdope[], cp[], cmst[];
+ extern space, cval, ossiz, cmsiz, mosflg, osleft;
+ double fcval;
+ int space[];
+
+ int op[], opst[20], pp[], prst[20], andflg, o,
+ p, ps, os;
+
+ osleft = ossiz;
+ space = 0;
+ *space++ = 0;
+ op = opst;
+ pp = prst;
+ cp = cmst;
+ *op = 200; /* stack EOF */
+ *pp = 06;
+ andflg = 0;
+
+advanc:
+ switch (o=symbol()) {
+
+ /* name */
+ case 20:
+ if (*csym==0)
+ if((peeksym=symbol())==6) { /* ( */
+ *csym = 6; /* extern */
+ csym[1] = 020; /* int() */
+ } else {
+ csym[1] = 030; /* array */
+ if (csym[2]==0)
+ csym[2] = isn++;
+ }
+ *cp++ = block(2,20,csym[1],csym[3],*csym,0);
+ if (*csym==6) { /* external */
+ o = 3;
+ while(++o<8) {
+ pblock(csym[o]);
+ if ((csym[o]&077400) == 0)
+ break;
+ }
+ } else
+ pblock(csym[2]);
+ goto tand;
+
+ /* short constant */
+ case 21:
+ case21:
+ *cp++ = block(1,21,ctyp,0,cval);
+ goto tand;
+
+ /* floating constant */
+ case 23:
+ *cp++ = block(1,23,3,0,cval);
+ if (cval) /* non-0 */
+ printf(".data;L%d:%o;%o;%o;%o;.text\n",cval,fcval);
+ goto tand;
+
+ /* string constant: fake a static char array */
+ case 22:
+ *cp++ = block(3, 20, 031, 1, 7, 0, cval);
+
+tand:
+ if(cp>=cmst+cmsiz) {
+ error("Expression overflow");
+ exit(1);
+ }
+ if (andflg)
+ goto syntax;
+ andflg = 1;
+ goto advanc;
+
+ /* ++, -- */
+ case 30:
+ case 31:
+ if (andflg)
+ o =+ 2;
+ goto oponst;
+
+ /* ! */
+ case 34:
+ /* ~ */
+ case 38:
+ if (andflg)
+ goto syntax;
+ goto oponst;
+
+ /* - */
+ case 41:
+ if (!andflg) {
+ peeksym = symbol();
+ if (peeksym==21) {
+ peeksym = -1;
+ cval = -cval;
+ goto case21;
+ }
+ o = 37;
+ }
+ andflg = 0;
+ goto oponst;
+
+ /* & */
+ /* * */
+ case 47:
+ case 42:
+ if (andflg)
+ andflg = 0; else
+ if(o==47)
+ o = 35;
+ else
+ o = 36;
+ goto oponst;
+
+ /* ( */
+ case 6:
+ if (andflg) {
+ o = symbol();
+ if (o==7)
+ o = 101; else {
+ peeksym = o;
+ o = 100;
+ andflg = 0;
+ }
+ }
+ goto oponst;
+
+ /* ) */
+ /* ] */
+ case 5:
+ case 7:
+ if (!andflg)
+ goto syntax;
+ goto oponst;
+
+ case 39: /* . */
+ mosflg++;
+ break;
+
+ }
+ /* binaries */
+ if (!andflg)
+ goto syntax;
+ andflg = 0;
+
+oponst:
+ p = (opdope[o]>>9) & 077;
+opon1:
+ ps = *pp;
+ if (p>ps | p==ps & (opdope[o]&0200)!=0) { /* right-assoc */
+putin:
+ switch (o) {
+
+ case 6: /* ( */
+ case 4: /* [ */
+ case 100: /* call */
+ p = 04;
+ }
+ if(op>=opst+20) { /* opstack size */
+ error("expression overflow");
+ exit(1);
+ }
+ *++op = o;
+ *++pp = p;
+ goto advanc;
+ }
+ --pp;
+ switch (os = *op--) {
+
+ /* EOF */
+ case 200:
+ peeksym = o;
+ return(*--cp);
+
+ /* call */
+ case 100:
+ if (o!=7)
+ goto syntax;
+ build(os);
+ goto advanc;
+
+ /* mcall */
+ case 101:
+ *cp++ = block(0,0,0,0); /* 0 arg call */
+ os = 100;
+ goto fbuild;
+
+ /* ( */
+ case 6:
+ if (o!=7)
+ goto syntax;
+ goto advanc;
+
+ /* [ */
+ case 4:
+ if (o!=5)
+ goto syntax;
+ build(4);
+ goto advanc;
+ }
+fbuild:
+ build(os);
+ goto opon1;
+
+syntax:
+ error("Expression syntax");
+ errflush(o);
+ return(0);
+}
+
+scdeclare(kw)
+{
+ extern csym, paraml, parame, peeksym;
+ int csym[], paraml[], parame[];
+ int o;
+
+ while((o=symbol())==20) { /* name */
+ if(*csym>0 & *csym!=kw)
+ redec();
+ *csym = kw;
+ if(kw==8) { /* parameter */
+ *csym = -1;
+ if (paraml==0)
+ paraml = csym;
+ else
+ *parame = csym;
+ parame = csym;
+ }
+ if ((o=symbol())!=9) /* , */
+ break;
+ }
+ if(o==1 & kw!=8 | o==7 & kw==8)
+ return;
+syntax:
+ decsyn(o);
+}
+
+tdeclare(kw, offset, mos)
+{
+ int o, elsize, ds[];
+ extern xdflg, peeksym, mosflg, defsym, csym;
+ int csym[], ssym[];
+
+ if (kw == 4) { /* struct */
+ ssym = 0;
+ ds = defsym;
+ mosflg = mos;
+ if ((o=symbol())==20) { /* name */
+ ssym = csym;
+ o = symbol();
+ }
+ mosflg = mos;
+ if (o != 6) { /* ( */
+ if (ssym==0)
+ goto syntax;
+ if (*ssym!=8) /* class structname */
+ error("Bad structure name");
+ if (ssym[3]==0) { /* no size yet */
+ kw = 5; /* deferred MOS */
+ elsize = ssym;
+ } else
+ elsize = ssym[3];
+ peeksym = o;
+ } else {
+ if (ssym) {
+ if (*ssym)
+ redec();
+ *ssym = 8;
+ ssym[3] = 0;
+ }
+ elsize = declist(4);
+ if ((elsize&01) != 0)
+ elsize++;
+ defsym = ds;
+ if ((o = symbol()) != 7) /* ) */
+ goto syntax;
+ if (ssym)
+ ssym[3] = elsize;
+ }
+ }
+ mosflg = mos;
+ if ((peeksym=symbol()) == 1) { /* ; */
+ peeksym = -1;
+ mosflg = 0;
+ return(offset);
+ }
+ do {
+ offset =+ t1dec(kw, offset, mos, elsize);
+ if (xdflg & !mos)
+ return;
+ } while ((o=symbol()) == 9); /* , */
+ if (o==1)
+ return(offset);
+syntax:
+ decsyn(o);
+}
+
+t1dec(kw, offset, mos, elsize)
+{
+ int type, nel, defsym[], t1;
+ extern defsym, mosflg;
+
+ nel = 0;
+ mosflg = mos;
+ if ((t1=getype(&nel)) < 0)
+ goto syntax;
+ type = 0;
+ do
+ type = type<<2 | (t1 & 03);
+ while(t1 =>> 2);
+ t1 = type<<3 | kw;
+ if (defsym[1] & defsym[1]!=t1)
+ redec();
+ defsym[1] = t1;
+ defsym[3] = elsize;
+ elsize = length(defsym);
+ if (mos) {
+ if (*defsym)
+ redec();
+ else
+ *defsym = 4;
+ if ((offset&1)!=0 & elsize!=1)
+ offset++;
+ defsym[2] = offset;
+ } else
+ if (*defsym == 0)
+ *defsym = -2; /* default auto */
+ if (nel==0)
+ nel = 1;
+ defsym[8] = nel;
+syntax:
+ return(nel*elsize);
+}
+
+getype(pnel)
+int pnel[];
+{
+ int o, type;
+ extern cval, peeksym, xdflg, defsym, csym, pssiz;
+ int defsym[], csym[];
+
+ switch(o=symbol()) {
+
+ case 42: /* * */
+ return(getype(pnel)<<2 | 01);
+
+ case 6: /* ( */
+ type = getype(pnel);
+ if ((o=symbol()) != 7) /* ) */
+ goto syntax;
+ goto getf;
+
+ case 20: /* name */
+ defsym = csym;
+ type = 0;
+ getf:
+ switch(o=symbol()) {
+
+ case 6: /* ( */
+ if (xdflg) {
+ xdflg = 0;
+ o = defsym;
+ scdeclare(8);
+ defsym = o;
+ xdflg++;
+ } else
+ if ((o=symbol()) != 7) /* ) */
+ goto syntax;
+ type = type<<2 | 02;
+ goto getf;
+
+ case 4: /* [ */
+ if ((o=symbol()) != 5) { /* ] */
+ if (o!=21) /* const */
+ goto syntax;
+ *pnel = cval;
+ if ((o=symbol())!=5)
+ goto syntax;
+ }
+ type = type<<2 | 03;
+ goto getf;
+ }
+ peeksym = o;
+ return(type);
+ }
+syntax:
+ decsyn(o);
+ return(-1);
+}
+
+decsyn(o)
+{
+ error("Declaration syntax");
+ errflush(o);
+}
+
+redec()
+{
+ extern csym;
+ int csym[];
+
+ error("%p redeclared", &csym[4]);
+}
+
+/* storage */
+
+regtab 0;
+efftab 1;
+cctab 2;
+sptab 3;
+symbuf[4];
+pssiz 9;
+namsiz 8;
+nwps 4;
+hshused;
+hshsiz 100;
+hshlen 900; /* 9*hshsiz */
+hshtab[900];
+space;
+cp;
+cmsiz 40;
+cmst[40];
+ctyp;
+isn 1;
+swsiz 120;
+swtab[120];
+swp;
+contlab;
+brklab;
+deflab;
+nreg 4;
+nauto;
+stack;
+peeksym 0177777;
+peekc;
+eof;
+line 1;
+defsym;
+xdflg;
+csym;
+cval;
+fcval 0; /* a double number */
+fc1 0;
+fc2 0;
+fc3 0;
+ncpw 2;
+nerror;
+paraml;
+parame;
+tmpfil;
+strflg;
+ossiz 250;
+osleft;
+mosflg;
+debug 0;
diff --git a/prestruct/c01.c b/prestruct/c01.c
@@ -0,0 +1,369 @@
+build(op) {
+ extern cp[], cvtab, opdope[], maprel[];
+ auto p1[], t1, d1, p2[], t2, d2, p3[], t3, d3, t;
+ auto d, dope, leftc, cvn, pcvn;
+ char cvtab[];
+
+ if (op==4) { /* [] */
+ build(40); /* + */
+ op = 36; /* * */
+ }
+ dope = opdope[op];
+ if ((dope&01)!=0) { /* binary */
+ p2 = disarray(*--cp);
+ t2 = p2[1];
+ chkfun(p2);
+ d2 = p2[2];
+ if (*p2==20)
+ d2 = 0;
+ }
+ p1 = disarray(*--cp);
+ if (op!=100 & op!=35) /* call, * */
+ chkfun(p1);
+ t1 = p1[1];
+ d1 = p1[2];
+ if (*p1==20)
+ d1 = 0;
+ pcvn = 0;
+ switch (op) {
+
+ /* : */
+ case 8:
+ if (t1!=t2)
+ error("Type clash in conditional");
+ t = t1;
+ goto nocv;
+
+ /* , */
+ case 9:
+ *cp++ = block(2, 9, 0, 0, p1, p2);
+ return;
+
+ /* ? */
+ case 90:
+ if (*p2!=8)
+ error("Illegal conditional");
+ t = t2;
+ goto nocv;
+
+ /* call */
+ case 100:
+ if ((t1&030) != 020)
+ error("Call of non-function");
+ *cp++ = block(2,100,decref(t1),24,p1,p2);
+ return;
+
+ /* * */
+ case 36:
+ if (*p1==35 | *p1==29) { /* & unary */
+ *cp++ = p1[3];
+ return;
+ }
+ if (*p1!=20 & d1==0)
+ d1 = 1;
+ if ((t1&030) == 020) /* function */
+ error("Illegal indirection");
+ *cp++ = block(1,36,decref(t1),d1,p1);
+ return;
+
+ /* & unary */
+ case 35:
+ if (*p1==36) { /* * */
+ *cp++ = p1[3];
+ return;
+ }
+ if (*p1==20) {
+ *cp++ = block(1,p1[3]==5?29:35,incref(t1),1,p1);
+ return;
+ }
+ error("Illegal lvalue");
+ break;
+
+ case 43: /* / */
+ case 44: /* % */
+ case 73: /* =/ */
+ case 74: /* =% */
+ d1++;
+ d2++;
+
+ case 42: /* * */
+ case 72: /* =* */
+ d1++;
+ d2++;
+ break;
+
+ case 30: /* ++ -- pre and post */
+ case 31:
+ case 32:
+ case 33:
+ chklval(p1);
+ *cp++ = block(2,op,t1,max(d1,1),p1,plength(p1));
+ return;
+
+ case 39: /* . (structure ref) */
+ case 50: /* -> (indirect structure ref) */
+ if (p2[0]!=20 | p2[3]!=4) /* not mos */
+ error("Illegal structure ref");
+ *cp++ = p1;
+ t = t2;
+ if ((t&030) == 030) /* array */
+ t = decref(t);
+ setype(p1, t);
+ if (op==39) /* is "." */
+ build(35); /* unary & */
+ *cp++ = block(1,21,7,0,p2[5]);
+ build(40); /* + */
+ if ((t2&030) != 030) /* not array */
+ build(36); /* unary * */
+ return;
+ }
+ if ((dope&02)!=0) /* lvalue needed on left? */
+ chklval(p1);
+ if ((dope&020)!=0) /* word operand on left? */
+ chkw(p1);
+ if ((dope&040)!=0) /* word operand on right? */
+ chkw(p2);
+ if ((dope&01)==0) { /* unary op? */
+ *cp++ = block(1,op,t1,max(d1,1),p1);
+ return;
+ }
+ if (t2==7) {
+ t = t1;
+ p2[1] = 0; /* no int cv for struct */
+ t2 = 0;
+ goto nocv;
+ }
+ cvn = cvtab[11*lintyp(t1)+lintyp(t2)];
+ leftc = cvn&0100;
+ t = leftc? t2:t1;
+ if (op==80 & t1!=4 & t2!=4) { /* = */
+ t = t1;
+ if (leftc | cvn!=1)
+ goto nocv;
+ }
+ if (cvn =& 077) {
+ if (cvn==077) {
+ illcv:
+ error("Illegal conversion");
+ goto nocv;
+ }
+ if (cvn>4 & cvn<10) { /* ptr conv */
+ t = 0; /* integer result */
+ cvn = 0;
+ if ((dope&04)!=0) /* relational? */
+ goto nocv;
+ if (op!=41) /* - */
+ goto illcv;
+ pcvn = cvn;
+ goto nocv;
+ }
+ if (leftc) {
+ if ((dope&010) != 0) { /* =op */
+ if (cvn == 1) {
+ leftc = 0;
+ cvn = 8;
+ t = t1;
+ goto rcvt;
+ } else
+ goto illcv;
+ }
+ d1 = (p1=convert(p1, t, d1, cvn, plength(p2)))[2];
+ } else {
+ rcvt:
+ d2 = (p2=convert(p2, t, d2, cvn, plength(p1)))[2];
+ }
+nocv:; }
+ if (d1==d2)
+ d = d1+1; else
+ d = max(d1,d2);
+ if ((dope&04)!=0) { /* relational? */
+ if (op>61 & t>=010)
+ op =+ 4; /* ptr relation */
+ t = 0; /* relational is integer */
+ }
+ *cp++ = optim(block(2,op,t,d,p1,p2));
+ if (pcvn) {
+ p1 = *--cp;
+ *cp++ = block(1,50+pcvn,0,d,p1);
+ }
+ return;
+ *cp++ = block(1,op,t1,d1==0?1:d1,p1);
+}
+
+setype(p, t)
+int p[];
+{
+ int p1[];
+
+ if ((p[1]&07) != 4) /* not structure */
+ return;
+ p[1] = t;
+ switch(*p) {
+
+ case 29: /* & */
+ case 35:
+ setype(p[3], decref(t));
+ return;
+
+ case 36: /* * */
+ setype(p[3], incref(t));
+ return;
+
+ case 40: /* + */
+ setype(p[4], t);
+ }
+}
+
+chkfun(p)
+int p[];
+{
+ if ((p[1]&030)==020) /* func */
+ error("Illegal use of function");
+}
+
+optim(p)
+int p[];
+{
+ int p1[], p2[], t;
+
+ if (*p != 40) /* + */
+ return(p);
+ p1 = p[3];
+ p2 = p[4];
+ if (*p1==21) { /* const */
+ t = p1;
+ p1 = p2;
+ p2 = t;
+ }
+ if (*p2 != 21) /* const */
+ return(p);
+ if ((t=p2[3]) == 0) /* const 0 */
+ return(p1);
+ if (*p1!=35 & *p1!=29) /* not & */
+ return(p);
+ p2 = p1[3];
+ if (*p2!=20) { /* name? */
+ error("C error (optim)");
+ return(p);
+ }
+ p2[4] =+ t;
+ return(p1);
+}
+
+disarray(p)
+int p[];
+{
+ extern cp;
+ int t, cp[];
+
+ if (((t = p[1]) & 030)!=030 | p[0]==20&p[3]==4) /* array & not MOS */
+ return(p);
+ p[1] = decref(t);
+ *cp++ = p;
+ build(35); /* add & */
+ return(*--cp);
+}
+
+convert(p, t, d, cvn, len)
+int p[];
+{
+ int c, p1[];
+
+ if (*p==21) { /* constant */
+ c = p[3];
+ switch(cvn) {
+
+ case 4: /* int -> double[] */
+ c =<< 1;
+
+ case 3: /* int -> float[] */
+ c =<< 1;
+
+ case 2: /* int -> int[] */
+ c =<< 1;
+ p[3] = c;
+ return(p);
+
+ case 10: /* i -> s[] */
+ p[3] = c*len;
+ return(p);
+ }
+ }
+ if (cvn==10) /* i -> s[]; retrun i*len */
+ return(block(2,42,t,d+2,p,block(1,21,0,0,len)));
+ return(block(1, 50+cvn, t, max(1,d), p));
+}
+
+chkw(p)
+int p[]; {
+ extern error;
+ auto t;
+
+ if ((t=p[1])>1 & t<=07)
+ error("Integer operand required");
+ return;
+}
+
+lintyp(t)
+{
+ if (t<=07)
+ return(t);
+ if ((t&037)==t)
+ return((t&07)+5);
+ return(10);
+}
+
+error(s, p1, p2, p3, p4, p5, p6) {
+ extern line, fout, nerror;
+ int f;
+
+ nerror++;
+ flush();
+ f = fout;
+ fout = 1;
+ printf("%d: ", line);
+ printf(s, p1, p2, p3, p4, p5, p6);
+ putchar('\n');
+ fout = f;
+}
+
+block(n, op, t, d, p1,p2,p3)
+int p1[],p2[],p3[]; {
+ int p[], ap[], space[];
+ extern space;
+
+ ap = &op;
+ n =+ 3;
+ p = space;
+ while(n--)
+ pblock(*ap++);
+ return(p);
+}
+
+pblock(p)
+{
+ extern space, osleft;
+ int space[];
+
+ *space++ = p;
+ if (--osleft<=0) {
+ error("Expression overflow");
+ exit(1);
+ }
+}
+
+chklval(p)
+int p[]; {
+ extern error;
+
+ if (*p!=20 & *p !=36)
+ error("Lvalue required");
+}
+
+max(a, b)
+{
+ if (a>b)
+ return(a);
+ return(b);
+}
+
diff --git a/prestruct/c02.c b/prestruct/c02.c
@@ -0,0 +1,505 @@
+extdef() {
+ extern eof, cval, defsym;
+ extern csym, strflg, xdflg, peeksym, fcval;
+ int o, c, cs[], type, csym[], width, nel, ninit, defsym[];
+ char s[];
+ float sf;
+ double fcval;
+
+ if(((o=symbol())==0) | o==1) /* EOF */
+ return;
+ type = 0;
+ if (o==19) { /* keyword */
+ if ((type=cval)>4)
+ goto syntax; /* not type */
+ } else {
+ if (o==20)
+ csym[4] =| 0200; /* remember name */
+ peeksym = o;
+ }
+ defsym = 0;
+ xdflg++;
+ tdeclare(type, 0, 0);
+ if (defsym==0)
+ return;
+ *defsym = 6;
+ cs = &defsym[4];
+ printf(".globl %p\n", cs);
+ strflg = 1;
+ xdflg = 0;
+ type = defsym[1];
+ if ((type&030)==020) { /* a function */
+ printf(".text\n%p:\nmov r5,-(sp); mov sp,r5\n", cs);
+ declist(0);
+ strflg = 0;
+ c = 0;
+ if ((peeksym=symbol())!=2) { /* { */
+ blkhed();
+ c++;
+ }
+ statement(1);
+ retseq();
+ if (c)
+ blkend();
+ return;
+ }
+ width = length(defsym);
+ if ((type&030)==030) /* array */
+ width = plength(defsym);
+ nel = defsym[8];
+ ninit = 0;
+ if ((peeksym=symbol()) == 1) { /* ; */
+ printf(".comm %p,%o\n", &defsym[4], nel*width);
+ peeksym = -1;
+ return;
+ }
+ printf(".data\n%p:", &defsym[4]);
+loop: {
+ ninit++;
+ switch(o=symbol()) {
+
+ case 22: /* string */
+ if (width!=2)
+ bxdec();
+ printf("L%d\n", cval);
+ break;
+
+ case 41: /* - const */
+ if ((o=symbol())==23) { /* float */
+ fcval = -fcval;
+ goto case23;
+ }
+ if (o!=21)
+ goto syntax;
+ cval = -cval;
+
+ case 21: /* const */
+ if (width==1)
+ printf(".byte ");
+ if (width>2) {
+ fcval = cval;
+ goto case23;
+ }
+ printf("%o\n", cval);
+ break;
+
+ case 20: /* name */
+ if (width!=2)
+ bxdec();
+ printf("%p\n", &csym[4]);
+ break;
+
+ case 23:
+ case23:
+ if (width==4) {
+ sf = fcval;
+ printf("%o;%o\n", sf);
+ break;
+ }
+ if (width==8) {
+ printf("%o;%o;%o;%o\n", fcval);
+ break;
+ }
+ bxdec();
+ break;
+
+ default:
+ goto syntax;
+
+ }
+ } if ((o=symbol())==9) goto loop; /* , */
+ if (o==1) { /* ; */
+ done:
+ if (ninit<nel)
+ printf(".=.+%d.\n", (nel-ninit)*width);
+ return;
+ }
+syntax:
+ error("External definition syntax");
+ errflush(o);
+ statement(0);
+}
+
+bxdec()
+{
+ error("Inconsistent external initialization");
+}
+
+statement(d) {
+ extern symbol, error, blkhed, eof, peeksym;
+ extern blkend, csym[], rcexpr, block[], tree[], regtab[];
+ extern retseq, jumpc, jump, label, contlab, brklab, cval;
+ extern swp[], isn, pswitch, peekc;
+ extern efftab[], deflab, errflush, swtab[], swsiz, branch;
+
+ int o, o1, o2, o3, np[];
+
+stmt:
+ switch(o=symbol()) {
+
+ /* EOF */
+ case 0:
+ error("Unexpected EOF");
+ /* ; */
+ case 1:
+ /* } */
+ case 3:
+ return;
+
+ /* { */
+ case 2: {
+ if(d)
+ blkhed();
+ while (!eof) {
+ if ((o=symbol())==3) /* } */
+ goto bend;
+ peeksym = o;
+ statement(0);
+ }
+ error("Missing '}'");
+ bend:
+ return;
+ }
+
+ /* keyword */
+ case 19:
+ switch(cval) {
+
+ /* goto */
+ case 10:
+ np = tree();
+ if ((np[1]&030)!=030) /* not array */
+ np = block(1, 36, 1, np[2]+1, np);
+ rcexpr(block(1,102,0,0,np), regtab);
+ goto semi;
+
+ /* return */
+ case 11:
+ if((peeksym=symbol())==6) /* ( */
+ rcexpr(block(1,110,0,0,pexpr()), regtab);
+ retseq();
+ goto semi;
+
+ /* if */
+ case 12:
+ jumpc(pexpr(), o1=isn++, 0);
+ statement(0);
+ if ((o=symbol())==19 & cval==14) { /* else */
+ o2 = isn++;
+ (easystmt()?branch:jump)(o2);
+ label(o1);
+ statement(0);
+ label(o2);
+ return;
+ }
+ peeksym = o;
+ label(o1);
+ return;
+
+ /* while */
+ case 13:
+ o1 = contlab;
+ o2 = brklab;
+ label(contlab = isn++);
+ jumpc(pexpr(), brklab=isn++, 0);
+ o3 = easystmt();
+ statement(0);
+ (o3?branch:jump)(contlab);
+ label(brklab);
+ contlab = o1;
+ brklab = o2;
+ return;
+
+ /* break */
+ case 17:
+ if(brklab==0)
+ error("Nothing to break from");
+ jump(brklab);
+ goto semi;
+
+ /* continue */
+ case 18:
+ if(contlab==0)
+ error("Nothing to continue");
+ jump(contlab);
+ goto semi;
+
+ /* do */
+ case 19:
+ o1 = contlab;
+ o2 = brklab;
+ contlab = isn++;
+ brklab = isn++;
+ label(o3 = isn++);
+ statement(0);
+ label(contlab);
+ contlab = o1;
+ if ((o=symbol())==19 & cval==13) { /* while */
+ jumpc(tree(), o3, 1);
+ label(brklab);
+ brklab = o2;
+ goto semi;
+ }
+ goto syntax;
+
+ /* case */
+ case 16:
+ if ((o=symbol())!=21) { /* constant */
+ if (o!=41) /* - */
+ goto syntax;
+ if ((o=symbol())!=21)
+ goto syntax;
+ cval = - cval;
+ }
+ if ((o=symbol())!=8) /* : */
+ goto syntax;
+ if (swp==0) {
+ error("Case not in switch");
+ goto stmt;
+ }
+ if(swp>=swtab+swsiz) {
+ error("Switch table overflow");
+ } else {
+ *swp++ = isn;
+ *swp++ = cval;
+ label(isn++);
+ }
+ goto stmt;
+
+ /* switch */
+ case 15:
+ o1 = brklab;
+ brklab = isn++;
+ np = pexpr();
+ if (np[1]>1 & np[1]<07)
+ error("Integer required");
+ rcexpr(block(1,110,0,0,np), regtab);
+ pswitch();
+ brklab = o1;
+ return;
+
+ /* default */
+ case 20:
+ if (swp==0)
+ error("Default not in switch");
+ if ((o=symbol())!=8) /* : */
+ goto syntax;
+ deflab = isn++;
+ label(deflab);
+ goto stmt;
+ }
+
+ error("Unknown keyword");
+ goto syntax;
+
+ /* name */
+ case 20:
+ if (peekc==':') {
+ peekc = 0;
+ if (csym[0]>0) {
+ error("Redefinition");
+ goto stmt;
+ }
+ csym[0] = 7;
+ csym[1] = 030; /* int[] */
+ if (csym[2]==0)
+ csym[2] = isn++;
+ label(csym[2]);
+ goto stmt;
+ }
+ }
+
+ peeksym = o;
+ rcexpr(tree(), efftab);
+ goto semi;
+
+semi:
+ if ((o=symbol())!=1) /* ; */
+ goto syntax;
+ return;
+
+syntax:
+ error("Statement syntax");
+ errflush(o);
+ goto stmt;
+}
+
+pexpr()
+{
+ auto o, t;
+
+ if ((o=symbol())!=6) /* ( */
+ goto syntax;
+ t = tree();
+ if ((o=symbol())!=7) /* ) */
+ goto syntax;
+ return(t);
+syntax:
+ error("Statement syntax");
+ errflush(o);
+ return(0);
+}
+
+pswitch() {
+ extern swp[], isn, swtab[], printf, deflab, statement, brklab;
+ extern label;
+ int sswp[], dl, cv, swlab;
+
+ sswp = swp;
+ if (swp==0)
+ swp = swtab;
+ swlab = isn++;
+ printf("jsr pc,bswitch; l%d\n", swlab);
+ dl = deflab;
+ deflab = 0;
+ statement(0);
+ if (!deflab) {
+ deflab = isn++;
+ label(deflab);
+ }
+ printf("L%d:.data;L%d:", brklab, swlab);
+ while(swp>sswp & swp>swtab) {
+ cv = *--swp;
+ printf("%o; l%d\n", cv, *--swp);
+ }
+ printf("L%d; 0\n.text\n", deflab);
+ deflab = dl;
+ swp = sswp;
+}
+
+blkhed()
+{
+ extern symbol, cval, peeksym, paraml[], parame[];
+ extern error, rlength, setstk, defvec, isn, defstat;
+ extern stack, hshtab[], hshsiz, pssiz;
+ int al, pl, cs[], hl, t[];
+
+ declist(0);
+ stack = al = 0;
+ pl = 4;
+ while(paraml) {
+ *parame = 0;
+ paraml = *(cs = paraml);
+ if (cs[1]==2) /* float args -> double */
+ cs[1] = 3;
+ cs[2] = pl;
+ *cs = 10;
+ if ((cs[1]&030) == 030) /* array */
+ cs[1] =- 020; /* set ref */
+ pl =+ rlength(cs);
+ }
+ cs = hshtab;
+ hl = hshsiz;
+ while(hl--) {
+ if (cs[4]) {
+ if (cs[0]>1 & (cs[1]&07)==05) { /* referred structure */
+ t = cs[3];
+ cs[3] = t[3];
+ cs[1] = cs[1]&077770 | 04;
+ }
+ switch(cs[0]) {
+
+ /* sort unmentioned */
+ case -2:
+ cs[0] = 5; /* auto */
+
+ /* auto */
+ case 5:
+ al =- trlength(cs);
+ cs[2] = al;
+ break;
+
+ /* parameter */
+ case 10:
+ cs[0] = 5;
+ break;
+
+ /* static */
+ case 7:
+ cs[2] = isn;
+ printf(".bss; L%d: .=.+%o; .text\n",
+ isn++, trlength(cs));
+ break;
+
+ }
+ }
+ cs = cs+pssiz;
+ }
+ setstk(al);
+}
+
+blkend() {
+ extern hshtab[], hshsiz, pssiz, hshused, debug;
+ auto i, hl;
+
+ i = 0;
+ hl = hshsiz;
+ while(hl--) {
+ if(hshtab[i+4]) {
+if (debug)
+if (hshtab[i]!=1)
+error("%p %o %o %o %o %o",
+ &hshtab[i+4],
+ hshtab[i],
+ hshtab[i+1],
+ hshtab[i+2],
+ hshtab[i+3],
+ hshtab[i+8]);
+ if (hshtab[i]==0)
+ error("%p undefined", &hshtab[i+4]);
+ if((hshtab[i+4]&0200)==0) { /* not top-level */
+ hshtab[i+4] = 0;
+ hshused--;
+ }
+ }
+ i =+ pssiz;
+ }
+}
+
+errflush(o) {
+ extern symbol, peeksym, eof;
+
+ while(o>3) /* ; { } */
+ o = symbol();
+ peeksym = o;
+}
+
+declist(mosflg)
+{
+ extern peeksym, csym[], cval;
+ auto o, offset;
+
+ offset = 0;
+ while((o=symbol())==19 & cval<10)
+ if (cval<=4)
+ offset = tdeclare(cval, offset, mosflg);
+ else
+ scdeclare(cval);
+ peeksym = o;
+ return(offset);
+}
+
+easystmt()
+{
+ extern peeksym, peekc, cval;
+
+ if((peeksym=symbol())==20) /* name */
+ return(peekc!=':'); /* not label */
+ if (peeksym==19) { /* keyword */
+ switch(cval)
+
+ case 10: /* goto */
+ case 11: /* return */
+ case 17: /* break */
+ case 18: /* continue */
+ return(1);
+ return(0);
+ }
+ return(peeksym!=2); /* { */
+}
+
+branch(lab)
+{
+ printf("br L%d\n", lab);
+}
+
diff --git a/prestruct/c03.c b/prestruct/c03.c
@@ -0,0 +1,251 @@
+retseq()
+{
+ printf("jmp retrn\n");
+}
+
+decref(t)
+{
+
+ if ((t & 077770) == 0) {
+ error("Illegal indirection");
+ return(t);
+ }
+ return((t>>2) & 077770 | t&07);
+}
+
+incref(t)
+{
+ return((t<<2)&077740 | (t&07) | 010);
+}
+
+jumpc(tree, lbl, cond)
+int tree[];
+{
+ extern cctab, block, rcexpr;
+
+ rcexpr(block(1,easystmt()+103,tree,lbl,cond),cctab);
+}
+
+rcexpr(tree, table)
+int tree[], table;
+{
+ extern space, putwrd, putchar, line;
+ int c, sp[];
+
+ if (tree == 0)
+ return;
+ putchar('#');
+ c = space;
+ c =/ 2; /* # addresses per word */
+ sp = 0;
+ putwrd(c);
+ putwrd(tree);
+ putwrd(table);
+ putwrd(line);
+ while(c--)
+ putwrd(*sp++);
+}
+
+jump(lab) {
+ extern printf;
+
+ printf("jmp\tl%d\n", lab);
+}
+
+label(l) {
+ extern printf;
+
+ printf("L%d:", l);
+}
+
+setstk(a) {
+ extern printf, stack;
+ auto ts;
+
+ ts = a-stack;
+ stack = a;
+ switch(ts) {
+
+ case 0:
+ return;
+
+ case 0177776: /* -2 */
+ printf("tst -(sp)\n");
+ return;
+
+ case 0177774: /* -4 */
+ printf("cmp -(sp),-(sp)\n");
+ return;
+ }
+ printf("add $%o,sp\n", ts);
+}
+
+plength(p)
+int p[];
+{
+ int t, l;
+
+ if (((t=p[1])&077770) == 0) /* not a reference */
+ return(1);
+ p[1] = decref(t);
+ l = length(p);
+ p[1] = t;
+ return(l);
+}
+
+length(cs)
+int cs[];
+{
+ extern hshtab[];
+ int t;
+
+ t = cs[1];
+ if ((t&030) == 030) /* array */
+ t = decref(t);
+ if (t>=010)
+ return(2);
+ switch(t&07) {
+
+ case 0: /* int */
+ return(2);
+
+ case 1: /* char */
+ return(1);
+
+ case 2: /* float */
+ return(4);
+
+ case 3: /* double */
+ return(8);
+
+ case 4: /* structure */
+ if (cs>=hshtab) /* in namelist */
+ return(cs[3]);
+ return(getlen(cs));
+
+ case 5:
+ error("Bad structure");
+ return(0);
+ }
+ error("Compiler error (length)");
+}
+
+getlen(p)
+int p[];
+{
+ int p1[];
+
+ switch(*p) {
+
+ case 20: /* name */
+ return(p[2]);
+
+ case 35:
+ case 29: /* & */
+ case 36: /* * */
+ case 100: /* call */
+ case 41: /* - */
+ return(getlen(p[3]));
+
+ case 40: /* + */
+ p1 = p[4];
+ if ((p1[1]&07) == 04)
+ return(getlen(p1));
+ return(getlen(p[3]));
+ }
+ error("Unimplemented pointer conversion");
+ return(0);
+}
+
+rlength(cs)
+int cs[];
+{
+ auto l;
+
+ if (((l=length(cs))&01) != 0)
+ l++;
+ return(l);
+}
+
+tlength(cs)
+int cs[];
+{
+ int nel;
+
+ if ((nel = cs[8]) == 0)
+ nel = 1;
+ return(length(cs)*nel);
+}
+
+trlength(cs)
+int cs[];
+{
+ int l;
+
+ if (((l=tlength(cs))&01) != 0)
+ l++;
+ return(l);
+}
+
+printn(n,b) {
+ extern putchar;
+ auto a;
+
+ if(a=n/b) /* assignment, not test for equality */
+ printn(a, b); /* recursive */
+ putchar(n%b + '0');
+}
+
+printf(fmt,x1,x2,x3,x4,x5,x6,x7,x8,x9)
+char fmt[]; {
+ extern printn, putchar, namsiz, ncpw;
+ char s[];
+ auto adx[], x, c, i[];
+
+ adx = &x1; /* argument pointer */
+loop:
+ while((c = *fmt++) != '%') {
+ if(c == '\0')
+ return;
+ putchar(c);
+ }
+ x = *adx++;
+ switch (c = *fmt++) {
+
+ case 'd': /* decimal */
+ case 'o': /* octal */
+ if(x < 0) {
+ x = -x;
+ if(x<0) { /* - infinity */
+ if(c=='o')
+ printf("100000");
+ else
+ printf("-32767");
+ goto loop;
+ }
+ putchar('-');
+ }
+ printn(x, c=='o'?8:10);
+ goto loop;
+
+ case 's': /* string */
+ s = x;
+ while(c = *s++)
+ putchar(c);
+ goto loop;
+
+ case 'p':
+ s = x;
+ putchar('_');
+ c = namsiz;
+ while(c--)
+ if (*s)
+ putchar((*s++)&0177);
+ goto loop;
+ }
+ putchar('%');
+ fmt--;
+ adx--;
+ goto loop;
+}
+
diff --git a/prestruct/c10.c b/prestruct/c10.c
@@ -0,0 +1,588 @@
+/*
+
+ C compiler, part 2
+
+ Copyright 1972 Bell Telephone Laboratories, Inc.
+
+*/
+
+waste() /* waste space */
+{
+ waste(waste(waste),waste(waste),waste(waste));
+ waste(waste(waste),waste(waste),waste(waste));
+ waste(waste(waste),waste(waste),waste(waste));
+ waste(waste(waste),waste(waste),waste(waste));
+ waste(waste(waste),waste(waste),waste(waste));
+ waste(waste(waste),waste(waste),waste(waste));
+ waste(waste(waste),waste(waste),waste(waste));
+ waste(waste(waste),waste(waste),waste(waste));
+}
+main(argc, argv)
+char argv[][];
+{
+ extern fout, fin, nerror, line;
+ extern getwrd, rcexpr, tmpfil;
+ extern cctab[], regtab[], efftab[], sptab[];
+ int sp[], c, table[], tabtab[3][], tree;
+
+ if (argc<4) {
+ error("Arg count");
+ exit(1);
+ }
+ if((fin=open(argv[1],0))<0) {
+ error("Cant't find %s", argv[1]);
+ exit(1);
+ }
+ if((fout=creat(argv[3],017))<0) {
+ error("Can't create %s", argv[3]);
+ exit(1);
+ }
+ tmpfil = argv[2];
+
+ tabtab[0] = regtab;
+ tabtab[1] = efftab;
+ tabtab[2] = cctab;
+ tabtab[3] = sptab;
+ while(c=getchar()) {
+ if(c=='#') {
+ sp = 0;
+ c = getwrd();
+ tree = getwrd();
+ table = tabtab[getwrd()];
+ line = getwrd();
+ while(c--)
+ *sp++ = getwrd();
+ rcexpr(tree, table, 0);
+ } else
+ putchar(c);
+ }
+ flush();
+ exit(nerror!=0);
+}
+
+match(tree, table, nreg)
+int tree[], table[]; {
+ extern opdope[], cctab, maprel;
+ int op, d1, d2, t1, t2, p1[], p2[], dope, cctab[];
+ int maprel[];
+ char mp[];
+
+ if (tree==0)
+ return(0);
+ op = *tree;
+ if (op>=29) /* if not leaf */
+ p1 = tree[3];
+ else
+ p1 = tree;
+ t1 = p1[1];
+ d1 = dcalc(p1, nreg);
+ if (((dope=opdope[op])&01)!=0) { /* binary? */
+ p2 = tree[4];
+ t2 = p2[1];
+ d2 = dcalc(p2, nreg);
+ if (d2>d1 & (dope&0100)!=0) /* commute? */
+ if (table!=cctab | (op!=47&op!=48)) { /* commute? */
+ if ((dope&04)!=0) /* relation? */
+ *tree = op = maprel[op-60];
+ dope = t1;
+ t1 = t2;
+ t2 = dope;
+ dope = p1;
+ tree[3] = p1 = p2;
+ tree[4] = p2 = dope;
+ dope = d1;
+ d1 = d2;
+ d2 = dope;
+ dope = t1;
+ t1 = t2;
+ t2 = dope;
+ }
+ }
+ while(*table) {
+ if (*table++ == op) goto foundop;
+ table++;
+ }
+ return(0);
+foundop:
+ table = *table;
+nxtry:
+ mp = table;
+ if (*mp == 0)
+ return(0);
+ if (d1 > (*mp&077) | (*mp>=0100)&(*p1!=36))
+ goto notyet;
+ if (notcompat(t1, mp[1]))
+ goto notyet;
+ if ((opdope[op]&01)!=0 & p2!=0) {
+ if (d2 > (mp[2]&077) | (mp[2]>=0100)&(*p2!=36))
+ goto notyet;
+ if (notcompat(t2,mp[3]))
+ goto notyet;
+ }
+now:
+ return(table[2]);
+notyet:
+ table = table+3;
+ goto nxtry;
+}
+
+rcexpr(tree, table, reg)
+int tree[]; {
+ extern cexpr, regtab, cctab, sptab, printf, error;
+ extern jumpc, cbranch;
+ int r, modf;
+
+ if(tree==0)
+ return(0);
+ if(*tree == 103 | *tree==104) {
+ (*tree==103?jumpc:cbranch)(tree[1],tree[2],tree[3],0);
+ return(0);
+ }
+ modf = isfloat(tree)? 'f':0;
+ if (*tree == 110) { /* force r0 */
+ if((r=rcexpr(tree[3], table, reg)) != 0)
+ printf("mov%c r%d,r0\n", modf, r);
+ return(0);
+ }
+ if ((r=cexpr(tree, table, reg))>=0)
+ return(r);
+ if (table!=regtab)
+ if((r=cexpr(tree, regtab, reg))>=0) {
+ if (table==sptab)
+ printf("mov%c r%d,-(sp)\n", modf, r);
+ if (table==cctab) {
+ if (modf=='f')
+ printf("cfcc\n");
+ printf("tst%c r%d\n", modf, r);
+ }
+ return(0);
+ }
+ error("No match for op %d", *tree);
+}
+
+cexpr(tree, table, reg)
+int tree[][], table[]; {
+ extern match, nreg, printf, pname, putchar, regtab;
+ extern sptab, cctab, rcexpr, prins, rlength, popstk;
+ extern collcon, isn, label, branch, cbranch;
+ extern maprel[];
+ int p1[], p2[], c, r, p[], otable[], ctable[], regtab[], cctab[];
+ int sptab[];
+ char string[], match[];
+ int reg1, rreg;
+
+ if ((c = *tree)==100) { /* call */
+ p1 = tree[3];
+ p2 = tree[4];
+ r = 0;
+ if(*p2) {
+ while (*p2==9) { /* comma */
+ rcexpr(p2[4], sptab, 0);
+ r =+ arlength((p=p2[4])[1]);
+ p2 = p2[3];
+ }
+ rcexpr(p2, sptab, 0);
+ r =+ arlength(p2[1]);
+ }
+ *tree = 101;
+ tree[2] = r; /* save arg length */
+ }
+ if(c==90) { /* ? */
+ cbranch(tree[3], c=isn++, 0, reg);
+ rcexpr(tree[4][3], table, reg);
+ branch(r=isn++, 0);
+ label(c);
+ reg = rcexpr(tree[4][4], table, reg);
+ label(r);
+ goto retrn;
+ }
+ reg = oddreg(tree, reg);
+ reg1 = reg+1;
+ if ((string=match(tree, table, nreg-reg))==0)
+ return(-1);
+ p1 = tree[3];
+ p2 = tree[4];
+loop:
+ switch(c = *string++) {
+
+ case '\0':
+ p = tree;
+ if (*p==101) {
+ if (p[2]>0)
+ popstk(p[2]);
+ reg = 0;
+ }
+retrn:
+ c = isfloat(tree);
+ if (table==cctab & c)
+ printf("cfcc\n");
+ if (!c)
+ if ((c = *tree)==43 | c==73)
+ reg--;
+ return(reg);
+
+ /* A1 */
+ case 'A':
+ p = tree[3];
+ goto adr;
+
+ /* A2 */
+ case 'B':
+ p = tree[4];
+ goto adr;
+
+ /* A */
+ case 'O':
+ p = tree;
+ adr:
+ pname(p);
+ goto loop;
+
+ /* I */
+ case 'M':
+ if ((c = *string)=='\'')
+ string++; else
+ c = 0;
+ prins(*tree, c);
+ goto loop;
+
+ /* B1 */
+ case 'C':
+ if ((c = *tree)<28)
+ p = tree;
+ else
+ p = tree[3];
+ goto pbyte;
+
+ /* BF */
+ case 'P':
+ p = tree;
+ goto pb1;
+
+ /* B2 */
+ case 'D':
+ p = tree[4];
+ pbyte:
+ if (p[1]==1) /* char type? */
+ putchar('b');
+ pb1:
+ if (isfloat(p))
+ putchar('f');
+ goto loop;
+
+ /* BE */
+ case 'L':
+ if (tree[3][1]==1 | tree[4][1]==1)
+ putchar('b');
+ p = tree;
+ goto pb1;
+
+ /* C1 */
+ case 'E':
+ p = p1[3];
+ goto const;
+
+ /* C2 */
+ case 'F':
+ p = p2[3];
+ const:
+ printf("%o", p);
+ goto loop;
+
+ /* F */
+ case 'G':
+ p = p1;
+ goto subtre;
+
+ /* S */
+ case 'K':
+ p = p2;
+ goto subtre;
+
+ /* H */
+ case 'H':
+ p = tree;
+
+ subtre:
+ ctable = regtab;
+ r = reg;
+ c = *string++ - 'A';
+ if ((c&02)!=0)
+ ctable = sptab;
+ if ((c&04)!=0)
+ ctable = cctab;
+ if((c&010)!=0)
+ r = reg1;
+ if((c&01)!=0)
+ if(*p==36) {
+ p = p[3];
+ if(collcon(p) & ctable!=sptab)
+ p = p[3];
+ }
+ rreg = rcexpr(p, ctable, r);
+ if (rreg==r | ctable!=regtab)
+ goto loop;
+ if (string[-2]=='G') /* left operand */
+ if (oddreg(tree, 0)==1) {
+ printf("mov r%d,r%d\n", rreg, r);
+ goto loop;
+ }
+ if (r==reg) {
+ reg = rreg;
+ reg1 = rreg+1;
+ } else
+ reg1 = rreg;
+ goto loop;
+
+ /* R */
+ case 'I':
+ r = reg;
+ if (*string=='-') {
+ string++;
+ r--;
+ }
+ goto preg;
+
+ /* R1 */
+ case 'J':
+ r = reg1;
+ preg:
+ if (r>=5)
+ error("Register overflow: simplify expression");
+ printf("r%d", r);
+ goto loop;
+
+ case '#':
+ p = p1[3];
+ goto nmbr;
+
+ case '"':
+ p = p2[3];
+ goto nmbr;
+
+ case '~':
+ p = tree[3];
+
+ nmbr:
+ if(collcon(p)) {
+ if (*p==41) /* - */
+ putchar('-');
+ switch (*(p = p[4])) {
+
+ case 21: /* number */
+ if (p[3])
+ printf("%d.", p[3]);
+ break;
+
+ case 35: /* & name */
+ pname(p[3]);
+ break;
+
+ }
+ }
+ goto loop;
+
+ /* V */
+ case 'V':
+ tree[0] = maprel[(c=tree[0])-60];
+ goto loop;
+
+ /* Z */
+ case 'Z':
+ printf("$%o", p1[5]+p1[4]);
+ goto loop;
+
+ case '^': /* for ++ -- */
+ printf("%o", tree[4]);
+ goto loop;
+ }
+ putchar(c);
+ goto loop;
+}
+
+pname(p)
+int p[][]; {
+ char np[];
+ int i;
+
+loop:
+ switch(*p) {
+
+ case 21: /* const */
+ printf("$%o", p[3]);
+ return;
+
+ case 23: /* float const */
+ printf("L%d", p[3]);
+ return;
+
+ casename:
+ case 20: /* name */
+ if (i=p[4])
+ printf("%d.+", i);
+ switch(p[3]) {
+
+ case 5: /* auto, param */
+ printf("%d.(r5)", p[5]);
+ return;
+
+ /* extern */
+ case 6:
+ printf("%p", &p[5]);
+ return;
+
+ case 4:
+ error("Illegal structure reference");
+ printf("$0");
+ return;
+
+ }
+ printf("L%d", p[5]);
+ return;
+
+ case 35: /* & */
+ putchar('$');
+ p = p[3];
+ goto loop;
+
+ case 36: /* * */
+ putchar('*');
+ p = p[3];
+ goto loop;
+
+ }
+ error("pname called illegally");
+}
+
+dcalc(p, nreg)
+int p[]; {
+ int op, t, p1[], p2[];
+
+ if (p==0)
+ return(0);
+ op = *p;
+ switch (op) {
+
+ case 20: /* name */
+ case 35: /* & (non-automatic) */
+ return(12);
+
+ case 21: /* short constant */
+ return(p[3]==0? 4:8);
+
+ case 23: /* float const */
+ return(p[3]==0? 4:12);
+
+ case 36: /* * */
+ p1 = p[3];
+ if (*p1==20) /* name or offset name */
+ return(12);
+ }
+
+def:
+ return(p[2]<=nreg? 20: 24);
+}
+
+notcompat(at, st) {
+
+ if (st==0) /* word, byte */
+ return(at>1 & at<=07);
+ if (st==1) /* word */
+ return(at>0 & at<=07);
+ st =- 2;
+ if ((at&077740) != 0)
+ at = 020; /* *int for **stuff */
+ if ((at&077770) != 0)
+ at = at&07 | 020;
+ if (st==2 & at==3)
+ at = 2;
+ return(st != at);
+}
+
+prins(op, c) {
+ extern instab[], printf;
+ int insp[];
+
+ insp = instab;
+ while(*insp) {
+ if (*insp++ == op) {
+ if ((c = insp[c!=0])==0)
+ goto err;
+ printf("%s", c);
+ return;
+ } else
+ insp = insp + 2;
+ }
+err:
+ error("No match' for op %d", op);
+}
+
+collcon(p)
+int p[]; {
+ int p1[], t[];
+
+ if(*p==40 | *p==41) {
+ if(*(p1=p[4])==21) { /* number */
+ return(1);
+ }
+ if (*p1==35)
+ return(1);
+ if (*(p1=p[3])==35) {
+ p1 = p[3];
+ p[3] = p[4];
+ p[4] = p1;
+ return(1);
+ }
+ }
+ return(0);
+}
+
+isfloat(t)
+int t[];
+{
+ extern opdope[];
+ int rt;
+
+ if ((opdope[t[0]]&04)!=0) /* relational */
+ t = t[3];
+ if ((rt=t[1])>=2 & rt<=3)
+ return(rt);
+ return(0);
+}
+
+nreg 3;
+isn 10000;
+namsiz 8;
+line;
+tmpfil;
+nerror;
+
+oddreg(t, reg)
+int t[];
+{
+ if (!isfloat(t))
+ switch(*t) {
+ case 43: /* / */
+ case 44: /* % */
+ case 73: /* =/ */
+ case 74: /* =% */
+ reg++;
+
+ case 42: /* * */
+ case 72: /* =* */
+ return(reg|1);
+ }
+ return(reg);
+}
+
+arlength(t)
+{
+ int arl;
+
+ if ((arl=rlength(t)) == 4)
+ return(8);
+ return(arl);
+}
+
+maprel[] 60, 61, 64, 65, 62, 63, 68, 69, 66, 67;
+
diff --git a/prestruct/c11.c b/prestruct/c11.c
@@ -0,0 +1,261 @@
+jumpc(tree, lbl, cond)
+int tree[]; {
+ extern jump, cctab[], rcexpr, isn, label, branch, cbranch;
+ int l1, l2;
+
+ if (tree==0)
+ return;
+ switch(*tree) {
+
+ /* & */
+ case 47:
+ if (cond) {
+ cbranch(tree[3], l1=isn++, 0, 0);
+ cbranch(tree[4], l1, 0, 0);
+ jump(lbl);
+ label(l1);
+ } else {
+ cbranch(tree[3], l1=isn++, 0, 0);
+ cbranch(tree[4], l2=isn++, 1, 0);
+ label(l1);
+ jump(lbl);
+ label(l2);
+ }
+ return;
+
+ /* | */
+ case 48:
+ if (cond) {
+ cbranch(tree[3], l1=isn++, 1, 0);
+ cbranch(tree[4], l2=isn++, 0, 0);
+ label(l1);
+ jump(lbl);
+ label(l2);
+ } else {
+ cbranch(tree[3], l1=isn++, 1, 0);
+ cbranch(tree[4], l1, 1, 0);
+ jump(lbl);
+ label(l1);
+ }
+ return;
+
+ /* ! */
+ case 34:
+ jumpc(tree[3], lbl, !cond);
+ return;
+ }
+ rcexpr(tree, cctab, 0);
+ branch(l1=isn++, *tree, cond);
+ jump(lbl);
+ label(l1);
+ return;
+}
+
+cbranch(tree, lbl, cond, reg)
+int tree[]; {
+ extern branch, cctab[], rcexpr, isn, label;
+ int l1;
+
+ if (tree==0)
+ return;
+ switch(*tree) {
+
+ /* & */
+ case 47:
+ if (cond) {
+ cbranch(tree[3], l1=isn++, 0, reg);
+ cbranch(tree[4], lbl, 1, reg);
+ label(l1);
+ } else {
+ cbranch(tree[3], lbl, 0, reg);
+ cbranch(tree[4], lbl, 0, reg);
+ }
+ return;
+
+ /* | */
+ case 48:
+ if (cond) {
+ cbranch(tree[3], lbl, 1, reg);
+ cbranch(tree[4], lbl, 1, reg);
+ } else {
+ cbranch(tree[3], l1=isn++, 1, reg);
+ cbranch(tree[4], lbl, 0, reg);
+ label(l1);
+ }
+ return;
+
+ /* ! */
+ case 34:
+ cbranch(tree[3], lbl, !cond, reg);
+ return;
+ }
+ rcexpr(tree, cctab, reg);
+ branch(lbl, *tree, !cond);
+ return;
+}
+
+
+branch(lbl, op, c) {
+ extern printf, prins, opdope[];
+
+ if(op) {
+ if((opdope[op]&04)==0)
+ op = 61;
+ prins(op,c);
+ } else
+ printf("br");
+ printf("\tl%d\n", lbl);
+}
+
+jump(lab) {
+ extern printf;
+
+ printf("jmp\tl%d\n", lab);
+}
+
+label(l) {
+ extern printf;
+
+ printf("l%d:", l);
+}
+
+
+popstk(a) {
+ extern printf;
+
+ switch(a) {
+
+ case 0:
+ return;
+
+ case 2:
+ printf("tst (sp)+\n");
+ return;
+
+ case 4:
+ printf("cmp (sp)+,(sp)+\n");
+ return;
+ }
+ printf("add $%o,sp\n", a);
+}
+
+length(t) {
+
+ if (t>=010)
+ return(2);
+ switch(t) {
+
+ case 0:
+ return(2);
+
+ case 1:
+ return(1);
+
+ case 2:
+ return(4);
+
+ case 3:
+ return(8);
+
+ case 4:
+ return(4);
+
+ }
+ return(1024);
+}
+
+rlength(c) {
+ extern length;
+ auto l;
+
+ return((l=length(c))==1? 2: l);
+}
+
+printd(n) {
+ int a;
+
+ if(a=n/10)
+ printd(a);
+ putchar(n%10 + '0');
+}
+
+printo(n)
+{
+ int a;
+ if (a = (n>>3) & 017777)
+ printo(a);
+ putchar((n&07) + '0');
+}
+
+printf(fmt,x1,x2,x3,x4,x5,x6,x7,x8,x9)
+char fmt[]; {
+ extern namsiz, ncpw;
+ char s[];
+ auto adx[], x, c, i[];
+
+ adx = &x1; /* argument pointer */
+loop:
+ while((c = *fmt++) != '%') {
+ if(c == '\0')
+ return;
+ putchar(c);
+ }
+ x = *adx++;
+ switch (c = *fmt++) {
+
+ case 'o':
+ printo(x);
+ goto loop;
+
+ case 'd': /* decimal */
+ if(x < 0) {
+ x = -x;
+ if(x<0) { /* - infinity */
+ printf("-32768");
+ goto loop;
+ }
+ putchar('-');
+ }
+ printd(x);
+ goto loop;
+
+ case 'c':
+ if (x)
+ putchar(x);
+ goto loop;
+
+ case 's': /* string */
+ s = x;
+ while(c = *s++)
+ putchar(c);
+ goto loop;
+
+ case 'p':
+ s = x;
+ putchar('_');
+ c = namsiz;
+ while(c--)
+ if(*s)
+ putchar((*s++)&0177);
+ goto loop;
+ }
+ putchar('%');
+ fmt--;
+ adx--;
+ goto loop;
+}
+
+error(s, p1, p2) {
+ extern printf, line, fout, flush, putchar, nerror;
+ int f;
+
+ nerror++;
+ flush();
+ f = fout;
+ fout = 1;
+ printf("%d: ", line);
+ printf(s, p1, p2);
+ putchar('\n');
+ fout = f;
+}
+