pull/2/head
mortdeus 11 years ago
parent dbb93eacff
commit d2270d144b

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

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

@ -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);
}

@ -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);
}

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

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

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

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

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

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

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

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

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

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

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

@ -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);
}

@ -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);
}

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

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

@ -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;
}
Loading…
Cancel
Save