legacy-cc

The earliest versions of the very first c compiler known to exist in the wild written by the late legend himself dmr.
git clone http://git.hanabi.in/repos/legacy-cc.git
Log | Files | Refs | README

commit d2270d144bbf53d9d7a14f5065f0f2f75ee9cbe1
parent dbb93eacff2b9600b8601fc8a422d63a38070921
Author: mortdeus <mortdeus@gocos2d.org>
Date:   Fri,  1 Mar 2013 08:05:32 -0600

init

Diffstat:
MREADME.md | 8++++++--
Alast1120c/c00.c | 581+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Alast1120c/c01.c | 210+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Alast1120c/c02.c | 436+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Alast1120c/c03.c | 189+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Alast1120c/c0t.s | 264+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Alast1120c/c10.c | 469+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Alast1120c/c11.c | 251+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Alast1120c/c1t.s | 171+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Alast1120c/cctab.s | 118+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Alast1120c/cvopt.c | 357+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Alast1120c/efftab.s | 215+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Alast1120c/regtab.s | 696+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Alast1120c/sptab.s | 167+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aprestruct/c00.c | 776+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aprestruct/c01.c | 369+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aprestruct/c02.c | 505+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aprestruct/c03.c | 251+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aprestruct/c10.c | 588+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aprestruct/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; +} +