Add original unix v6
This commit is contained in:
+849
@@ -0,0 +1,849 @@
|
||||
#
|
||||
/*
|
||||
* C compiler
|
||||
*/
|
||||
|
||||
#include "c1h.c"
|
||||
|
||||
max(a, b)
|
||||
{
|
||||
if (a>b)
|
||||
return(a);
|
||||
return(b);
|
||||
}
|
||||
|
||||
degree(at)
|
||||
struct tnode *at;
|
||||
{
|
||||
register struct tnode *t, *t1;
|
||||
|
||||
if ((t=at)==0 || t->op==0)
|
||||
return(0);
|
||||
if (t->op == CON)
|
||||
return(-3);
|
||||
if (t->op == AMPER)
|
||||
return(-2);
|
||||
if (t->op==ITOL && (t1 = isconstant(t)) && t1->value>= 0)
|
||||
return(-2);
|
||||
if ((opdope[t->op] & LEAF) != 0) {
|
||||
if (t->type==CHAR || t->type==FLOAT)
|
||||
return(1);
|
||||
return(0);
|
||||
}
|
||||
return(t->degree);
|
||||
}
|
||||
|
||||
pname(ap, flag)
|
||||
struct tnode *ap;
|
||||
{
|
||||
register i;
|
||||
register struct tnode *p;
|
||||
|
||||
p = ap;
|
||||
loop:
|
||||
switch(p->op) {
|
||||
|
||||
case SFCON:
|
||||
case CON:
|
||||
printf("$");
|
||||
psoct(p->value);
|
||||
return;
|
||||
|
||||
case FCON:
|
||||
printf("L%d", p->value);
|
||||
return;
|
||||
|
||||
case NAME:
|
||||
i = p->offset;
|
||||
if (flag==2)
|
||||
i =+ 2;
|
||||
if (i) {
|
||||
psoct(i);
|
||||
if (p->class!=OFFS)
|
||||
putchar('+');
|
||||
if (p->class==REG)
|
||||
regerr();
|
||||
}
|
||||
switch(p->class) {
|
||||
|
||||
case SOFFS:
|
||||
case XOFFS:
|
||||
pbase(p);
|
||||
|
||||
case OFFS:
|
||||
printf("(r%d)", p->regno);
|
||||
return;
|
||||
|
||||
case EXTERN:
|
||||
case STATIC:
|
||||
pbase(p);
|
||||
return;
|
||||
|
||||
case REG:
|
||||
printf("r%d", p->nloc);
|
||||
return;
|
||||
|
||||
}
|
||||
error("Compiler error: pname");
|
||||
return;
|
||||
|
||||
case AMPER:
|
||||
putchar('$');
|
||||
p = p->tr1;
|
||||
if (p->op==NAME && p->class==REG)
|
||||
regerr();
|
||||
goto loop;
|
||||
|
||||
case AUTOI:
|
||||
printf("(r%d)%c", p->nloc, flag==1?0:'+');
|
||||
return;
|
||||
|
||||
case AUTOD:
|
||||
printf("%c(r%d)", flag==1?0:'-', p->nloc);
|
||||
return;
|
||||
|
||||
case STAR:
|
||||
p = p->tr1;
|
||||
putchar('*');
|
||||
goto loop;
|
||||
|
||||
}
|
||||
error("pname called illegally");
|
||||
}
|
||||
|
||||
regerr()
|
||||
{
|
||||
error("Illegal use of register");
|
||||
}
|
||||
|
||||
pbase(ap)
|
||||
struct tnode *ap;
|
||||
{
|
||||
register struct tnode *p;
|
||||
|
||||
p = ap;
|
||||
if (p->class==SOFFS || p->class==STATIC)
|
||||
printf("L%d", p->nloc);
|
||||
else
|
||||
printf("_%.8s", &(p->nloc));
|
||||
}
|
||||
|
||||
xdcalc(ap, nrleft)
|
||||
struct tnode *ap;
|
||||
{
|
||||
register struct tnode *p;
|
||||
register d;
|
||||
|
||||
p = ap;
|
||||
d = dcalc(p, nrleft);
|
||||
if (d<20 && p->type==CHAR) {
|
||||
if (nrleft>=1)
|
||||
d = 20;
|
||||
else
|
||||
d = 24;
|
||||
}
|
||||
return(d);
|
||||
}
|
||||
|
||||
dcalc(ap, nrleft)
|
||||
struct tnode *ap;
|
||||
{
|
||||
register struct tnode *p, *p1;
|
||||
|
||||
if ((p=ap)==0)
|
||||
return(0);
|
||||
switch (p->op) {
|
||||
|
||||
case NAME:
|
||||
if (p->class==REG)
|
||||
return(9);
|
||||
|
||||
case AMPER:
|
||||
case FCON:
|
||||
case AUTOI:
|
||||
case AUTOD:
|
||||
return(12);
|
||||
|
||||
case CON:
|
||||
case SFCON:
|
||||
if (p->value==0)
|
||||
return(4);
|
||||
if (p->value==1)
|
||||
return(5);
|
||||
if (p->value > 0)
|
||||
return(8);
|
||||
return(12);
|
||||
|
||||
case STAR:
|
||||
p1 = p->tr1;
|
||||
if (p1->op==NAME||p1->op==CON||p1->op==AUTOI||p1->op==AUTOD)
|
||||
if (p->type!=LONG)
|
||||
return(12);
|
||||
}
|
||||
if (p->type==LONG)
|
||||
nrleft--;
|
||||
return(p->degree <= nrleft? 20: 24);
|
||||
}
|
||||
|
||||
notcompat(ap, ast, op)
|
||||
struct tnode *ap;
|
||||
{
|
||||
register at, st;
|
||||
register struct tnode *p;
|
||||
|
||||
p = ap;
|
||||
at = p->type;
|
||||
st = ast;
|
||||
if (st==0) /* word, byte */
|
||||
return(at>CHAR && at<PTR);
|
||||
if (st==1) /* word */
|
||||
return(at>INT && at<PTR);
|
||||
st =- 2;
|
||||
if ((at&(~(TYPE+XTYPE))) != 0)
|
||||
at = 020;
|
||||
if ((at&(~TYPE)) != 0)
|
||||
at = at&TYPE | 020;
|
||||
if (st==FLOAT && at==DOUBLE)
|
||||
at = FLOAT;
|
||||
if (p->op==NAME && p->class==REG && op==ASSIGN && st==CHAR)
|
||||
return(0);
|
||||
return(st != at);
|
||||
}
|
||||
|
||||
prins(op, c, itable)
|
||||
struct instab *itable;
|
||||
{
|
||||
register struct instab *insp;
|
||||
register char *ip;
|
||||
|
||||
for (insp=itable; insp->op != 0; insp++) {
|
||||
if (insp->op == op) {
|
||||
ip = c? insp->str2: insp->str1;
|
||||
if (ip==0)
|
||||
break;
|
||||
printf("%s", ip);
|
||||
return;
|
||||
}
|
||||
}
|
||||
error("No match' for op %d", op);
|
||||
}
|
||||
|
||||
collcon(ap)
|
||||
struct tnode *ap;
|
||||
{
|
||||
register op;
|
||||
register struct tnode *p;
|
||||
|
||||
p = ap;
|
||||
if (p->op==STAR)
|
||||
p = p->tr1;
|
||||
if (p->op==PLUS) {
|
||||
op = p->tr2->op;
|
||||
if (op==CON || op==AMPER)
|
||||
return(1);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
isfloat(at)
|
||||
struct tnode *at;
|
||||
{
|
||||
register struct tnode *t;
|
||||
|
||||
t = at;
|
||||
if ((opdope[t->op]&RELAT)!=0)
|
||||
t = t->tr1;
|
||||
if (t->type==FLOAT || t->type==DOUBLE) {
|
||||
nfloat = 1;
|
||||
return('f');
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
oddreg(t, areg)
|
||||
struct tnode *t;
|
||||
{
|
||||
register reg;
|
||||
|
||||
reg = areg;
|
||||
if (!isfloat(t))
|
||||
switch(t->op) {
|
||||
case DIVIDE:
|
||||
case MOD:
|
||||
case ASDIV:
|
||||
case ASMOD:
|
||||
reg++;
|
||||
|
||||
case TIMES:
|
||||
case ASTIMES:
|
||||
return(reg|1);
|
||||
}
|
||||
return(reg);
|
||||
}
|
||||
|
||||
arlength(t)
|
||||
{
|
||||
if (t>=PTR)
|
||||
return(2);
|
||||
switch(t) {
|
||||
|
||||
case INT:
|
||||
case CHAR:
|
||||
return(2);
|
||||
|
||||
case LONG:
|
||||
return(4);
|
||||
|
||||
case FLOAT:
|
||||
case DOUBLE:
|
||||
return(8);
|
||||
}
|
||||
return(1024);
|
||||
}
|
||||
|
||||
/*
|
||||
* Strings for switch code.
|
||||
*/
|
||||
|
||||
char dirsw[] {"\
|
||||
cmp r0,$%o\n\
|
||||
jhi L%d\n\
|
||||
asl r0\n\
|
||||
jmp *L%d(r0)\n\
|
||||
.data\n\
|
||||
L%d:\
|
||||
" };
|
||||
|
||||
char simpsw[] {"\
|
||||
mov $L%d,r1\n\
|
||||
mov r0,L%d\n\
|
||||
L%d:cmp r0,(r1)+\n\
|
||||
jne L%d\n\
|
||||
jmp *L%d-L%d(r1)\n\
|
||||
.data\n\
|
||||
L%d:\
|
||||
"};
|
||||
|
||||
char hashsw[] {"\
|
||||
mov r0,r1\n\
|
||||
clr r0\n\
|
||||
div $%o,r0\n\
|
||||
asl r1\n\
|
||||
add $L%d,r1\n\
|
||||
mov r0,*(r1)+\n\
|
||||
mov (r1)+,r1\n\
|
||||
L%d:cmp r0,-(r1)\n\
|
||||
jne L%d\n\
|
||||
jmp *L%d-L%d(r1)\n\
|
||||
.data\n\
|
||||
L%d:\
|
||||
"};
|
||||
|
||||
pswitch(afp, alp, deflab)
|
||||
struct swtab *afp, *alp;
|
||||
{
|
||||
int tlab, ncase, i, j, tabs, worst, best, range;
|
||||
register struct swtab *swp, *fp, *lp;
|
||||
int poctab[swsiz];
|
||||
|
||||
fp = afp;
|
||||
lp = alp;
|
||||
if (fp==lp) {
|
||||
printf("jbr L%d\n", deflab);
|
||||
return;
|
||||
}
|
||||
tlab = isn++;
|
||||
if (sort(fp, lp))
|
||||
return;
|
||||
ncase = lp-fp;
|
||||
lp--;
|
||||
range = lp->swval - fp->swval;
|
||||
/* direct switch */
|
||||
if (range>0 && range <= 3*ncase) {
|
||||
if (fp->swval)
|
||||
printf("sub $%o,r0\n", fp->swval);
|
||||
printf(dirsw, range, deflab, isn, isn);
|
||||
isn++;
|
||||
for (i=fp->swval; i<=lp->swval; i++) {
|
||||
if (i==fp->swval) {
|
||||
printf("L%d\n", fp->swlab);
|
||||
fp++;
|
||||
} else
|
||||
printf("L%d\n", deflab);
|
||||
}
|
||||
goto esw;
|
||||
}
|
||||
/* simple switch */
|
||||
if (ncase<8) {
|
||||
i = isn++;
|
||||
j = isn++;
|
||||
printf(simpsw, i, j, isn, isn, j, i, i);
|
||||
isn++;
|
||||
for (; fp<=lp; fp++)
|
||||
printf("%o\n", fp->swval);
|
||||
printf("L%d:..\n", j);
|
||||
for (fp = afp; fp<=lp; fp++)
|
||||
printf("L%d\n", fp->swlab);
|
||||
printf("L%d\n", deflab);
|
||||
goto esw;
|
||||
}
|
||||
/* hash switch */
|
||||
best = 077777;
|
||||
for (i=ncase/4; i<=ncase/2; i++) {
|
||||
for (j=0; j<i; j++)
|
||||
poctab[j] = 0;
|
||||
for (swp=fp; swp<=lp; swp++)
|
||||
poctab[lrem(0, swp->swval, i)]++;
|
||||
worst = 0;
|
||||
for (j=0; j<i; j++)
|
||||
if (poctab[j]>worst)
|
||||
worst = poctab[j];
|
||||
if (i*worst < best) {
|
||||
tabs = i;
|
||||
best = i*worst;
|
||||
}
|
||||
}
|
||||
i = isn++;
|
||||
printf(hashsw, tabs, isn, i, i, isn+tabs+1, isn+1, isn);
|
||||
isn++;
|
||||
for (i=0; i<=tabs; i++)
|
||||
printf("L%d\n", isn+i);
|
||||
for (i=0; i<tabs; i++) {
|
||||
printf("L%d:..\n", isn++);
|
||||
for (swp=fp; swp<=lp; swp++)
|
||||
if (lrem(0, swp->swval, tabs) == i)
|
||||
printf("%o\n", ldiv(0, swp->swval, tabs));
|
||||
}
|
||||
printf("L%d:", isn++);
|
||||
for (i=0; i<tabs; i++) {
|
||||
printf("L%d\n", deflab);
|
||||
for (swp=fp; swp<=lp; swp++)
|
||||
if (lrem(0, swp->swval, tabs) == i)
|
||||
printf("L%d\n", swp->swlab);
|
||||
}
|
||||
esw:
|
||||
printf(".text\n");
|
||||
}
|
||||
|
||||
sort(afp, alp)
|
||||
struct swtab *afp, *alp;
|
||||
{
|
||||
register struct swtab *cp, *fp, *lp;
|
||||
int intch, t;
|
||||
|
||||
fp = afp;
|
||||
lp = alp;
|
||||
while (fp < --lp) {
|
||||
intch = 0;
|
||||
for (cp=fp; cp<lp; cp++) {
|
||||
if (cp->swval == cp[1].swval) {
|
||||
error("Duplicate case (%d)", cp->swval);
|
||||
return(1);
|
||||
}
|
||||
if (cp->swval > cp[1].swval) {
|
||||
intch++;
|
||||
t = cp->swval;
|
||||
cp->swval = cp[1].swval;
|
||||
cp[1].swval = t;
|
||||
t = cp->swlab;
|
||||
cp->swlab = cp[1].swlab;
|
||||
cp[1].swlab = t;
|
||||
}
|
||||
}
|
||||
if (intch==0)
|
||||
break;
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
ispow2(atree)
|
||||
{
|
||||
register int d;
|
||||
register struct tnode *tree;
|
||||
|
||||
tree = atree;
|
||||
if (!isfloat(tree) && tree->tr2->op==CON) {
|
||||
d = tree->tr2->value;
|
||||
if (d>1 && (d&(d-1))==0)
|
||||
return(d);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
pow2(atree)
|
||||
struct tnode *atree;
|
||||
{
|
||||
register int d, i;
|
||||
register struct tnode *tree;
|
||||
|
||||
tree = atree;
|
||||
if (d = ispow2(tree)) {
|
||||
for (i=0; (d=>>1)!=0; i++);
|
||||
tree->tr2->value = i;
|
||||
d = tree->op;
|
||||
tree->op = d==TIMES? LSHIFT:
|
||||
(d==DIVIDE? RSHIFT:
|
||||
(d==ASTIMES? ASLSH: ASRSH));
|
||||
tree = optim(tree);
|
||||
}
|
||||
return(tree);
|
||||
}
|
||||
|
||||
cbranch(atree, albl, cond, areg)
|
||||
struct tnode *atree;
|
||||
{
|
||||
int l1, op;
|
||||
register lbl, reg;
|
||||
register struct tnode *tree;
|
||||
|
||||
lbl = albl;
|
||||
reg = areg;
|
||||
if ((tree=atree)==0)
|
||||
return;
|
||||
switch(tree->op) {
|
||||
|
||||
case LOGAND:
|
||||
if (cond) {
|
||||
cbranch(tree->tr1, l1=isn++, 0, reg);
|
||||
cbranch(tree->tr2, lbl, 1, reg);
|
||||
label(l1);
|
||||
} else {
|
||||
cbranch(tree->tr1, lbl, 0, reg);
|
||||
cbranch(tree->tr2, lbl, 0, reg);
|
||||
}
|
||||
return;
|
||||
|
||||
case LOGOR:
|
||||
if (cond) {
|
||||
cbranch(tree->tr1, lbl, 1, reg);
|
||||
cbranch(tree->tr2, lbl, 1, reg);
|
||||
} else {
|
||||
cbranch(tree->tr1, l1=isn++, 1, reg);
|
||||
cbranch(tree->tr2, lbl, 0, reg);
|
||||
label(l1);
|
||||
}
|
||||
return;
|
||||
|
||||
case EXCLA:
|
||||
cbranch(tree->tr1, lbl, !cond, reg);
|
||||
return;
|
||||
|
||||
case COMMA:
|
||||
rcexpr(tree->tr1, efftab, reg);
|
||||
tree = tree->tr2;
|
||||
break;
|
||||
}
|
||||
op = tree->op;
|
||||
if (tree->type==LONG || opdope[op]&RELAT&&tree->tr1->type==LONG) {
|
||||
if (tree->type!=LONG) {
|
||||
tree->op = MINUS;
|
||||
tree->type = LONG;
|
||||
tree = optim(tree);
|
||||
} else
|
||||
op = NEQUAL;
|
||||
rcexpr(tree, regtab, 0);
|
||||
printf("ashc $0,r0\n");
|
||||
branch(lbl, op, !cond);
|
||||
return;
|
||||
}
|
||||
rcexpr(tree, cctab, reg);
|
||||
op = tree->op;
|
||||
if ((opdope[op]&RELAT)==0)
|
||||
op = NEQUAL;
|
||||
else {
|
||||
l1 = tree->tr2->op;
|
||||
if ((l1==CON || l1==SFCON) && tree->tr2->value==0)
|
||||
op =+ 200; /* special for ptr tests */
|
||||
else
|
||||
op = maprel[op-EQUAL];
|
||||
}
|
||||
if (isfloat(tree))
|
||||
printf("cfcc\n");
|
||||
branch(lbl, op, !cond);
|
||||
}
|
||||
|
||||
branch(lbl, aop, c)
|
||||
{
|
||||
register op;
|
||||
|
||||
if(op=aop)
|
||||
prins(op, c, branchtab);
|
||||
else
|
||||
printf("jbr");
|
||||
printf("\tL%d\n", lbl);
|
||||
}
|
||||
|
||||
label(l)
|
||||
{
|
||||
printf("L%d:", l);
|
||||
}
|
||||
|
||||
popstk(a)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
error(s, p1, p2, p3, p4, p5, p6)
|
||||
{
|
||||
register f;
|
||||
extern fout;
|
||||
|
||||
nerror++;
|
||||
flush();
|
||||
f = fout;
|
||||
fout = 1;
|
||||
printf("%d: ", line);
|
||||
printf(s, p1, p2, p3, p4, p5, p6);
|
||||
putchar('\n');
|
||||
flush();
|
||||
fout = f;
|
||||
}
|
||||
|
||||
psoct(an)
|
||||
{
|
||||
register int n, sign;
|
||||
|
||||
sign = 0;
|
||||
if ((n = an) < 0) {
|
||||
n = -n;
|
||||
sign = '-';
|
||||
}
|
||||
printf("%c%o", sign, n);
|
||||
}
|
||||
|
||||
/*
|
||||
* Read in an intermediate file.
|
||||
*/
|
||||
getree()
|
||||
{
|
||||
struct tnode *expstack[20];
|
||||
register struct tnode **sp;
|
||||
register t, op;
|
||||
static char s[9];
|
||||
struct swtab *swp;
|
||||
|
||||
spacep = treespace;
|
||||
sp = expstack;
|
||||
for (;;) {
|
||||
if (sp >= &expstack[20])
|
||||
error("Stack botch");
|
||||
op = getw(ascbuf);
|
||||
if ((op&0177400) != 0177000) {
|
||||
error("Intermediate file error");
|
||||
exit(1);
|
||||
}
|
||||
switch(op =& 0377) {
|
||||
|
||||
case EOF:
|
||||
return;
|
||||
|
||||
case BDATA:
|
||||
printf(".byte ");
|
||||
seq(',');
|
||||
break;
|
||||
|
||||
case WDATA:
|
||||
seq(';');
|
||||
break;
|
||||
|
||||
case PROG:
|
||||
printf(".text\n");
|
||||
break;
|
||||
|
||||
case DATA:
|
||||
printf(".data\n");
|
||||
break;
|
||||
|
||||
case BSS:
|
||||
printf(".bss\n");
|
||||
break;
|
||||
|
||||
case SYMDEF:
|
||||
printf(".globl _%s\n", outname(s));
|
||||
break;
|
||||
|
||||
case RETRN:
|
||||
printf("jmp cret\n");
|
||||
break;
|
||||
|
||||
case CSPACE:
|
||||
t = outname(s);
|
||||
printf(".comm _%s,%o\n", t, getw(ascbuf));
|
||||
break;
|
||||
|
||||
case SSPACE:
|
||||
printf(".=.+%o\n", getw(ascbuf));
|
||||
break;
|
||||
|
||||
case EVEN:
|
||||
printf(".even\n");
|
||||
break;
|
||||
|
||||
case SAVE:
|
||||
printf("jsr r5,csv\n");
|
||||
t = getw(ascbuf)-6;
|
||||
if (t==2)
|
||||
printf("tst -(sp)\n");
|
||||
else if (t > 2)
|
||||
printf("sub $%o,sp\n", t);
|
||||
break;
|
||||
|
||||
case PROFIL:
|
||||
t = getw(ascbuf);
|
||||
printf("mov $L%d,r0\njsr pc,mcount\n", t);
|
||||
printf(".bss\nL%d:.=.+2\n.text\n", t);
|
||||
break;
|
||||
|
||||
case SNAME:
|
||||
t = outname(s);
|
||||
printf("~%s=L%d\n", t, getw(ascbuf));
|
||||
break;
|
||||
|
||||
case ANAME:
|
||||
t = outname(s);
|
||||
printf("~%s=%o\n", t, getw(ascbuf));
|
||||
break;
|
||||
|
||||
case RNAME:
|
||||
t = outname(s);
|
||||
printf("~%s=r%d\n", t, getw(ascbuf));
|
||||
break;
|
||||
|
||||
case SWIT:
|
||||
t = getw(ascbuf);
|
||||
line = getw(ascbuf);
|
||||
swp = treespace;
|
||||
while (swp->swlab = getw(ascbuf)) {
|
||||
swp->swval = getw(ascbuf);
|
||||
swp++;
|
||||
}
|
||||
pswitch(treespace, swp, t);
|
||||
break;
|
||||
|
||||
case EXPR:
|
||||
line = getw(ascbuf);
|
||||
if (sp != &expstack[1]) {
|
||||
error("Expression input botch\n");
|
||||
exit(1);
|
||||
}
|
||||
nstack = 0;
|
||||
rcexpr(optim(*--sp), efftab, 0);
|
||||
spacep = treespace;
|
||||
break;
|
||||
|
||||
case NAME:
|
||||
t = getw(ascbuf);
|
||||
if (t==EXTERN) {
|
||||
t = getw(ascbuf);
|
||||
*sp = block(6, NAME, t, 0, EXTERN, 0, 0,0,0,0);
|
||||
outname(&(*sp)->nloc);
|
||||
sp++;
|
||||
break;
|
||||
}
|
||||
*sp = block(3, NAME, 0, 0, t, 0, 0);
|
||||
(*sp)->type = getw(ascbuf);
|
||||
(*sp)->nloc = getw(ascbuf);
|
||||
sp++;
|
||||
break;
|
||||
|
||||
case CON:
|
||||
case SFCON:
|
||||
case FCON:
|
||||
t = getw(ascbuf);
|
||||
*sp++ = block(1, op, t, 0, getw(ascbuf));
|
||||
break;
|
||||
|
||||
case FSEL:
|
||||
t = getw(ascbuf);
|
||||
sp[-1] = block(2, op, t, 0, sp[-1], getw(ascbuf));
|
||||
break;
|
||||
|
||||
case NULL:
|
||||
*sp++ = block(0, 0, 0, 0);
|
||||
break;
|
||||
|
||||
case CBRANCH:
|
||||
t = getw(ascbuf);
|
||||
sp[-1] = block(1, CBRANCH, sp[-1], t, getw(ascbuf));
|
||||
break;
|
||||
|
||||
case LABEL:
|
||||
label(getw(ascbuf));
|
||||
break;
|
||||
|
||||
case NLABEL:
|
||||
printf("_%s:\n", outname(s));
|
||||
break;
|
||||
|
||||
case RLABEL:
|
||||
t = outname(s);
|
||||
printf("_%s:\n~~%s:\n", t, t);
|
||||
break;
|
||||
|
||||
case BRANCH:
|
||||
branch(getw(ascbuf), 0);
|
||||
break;
|
||||
|
||||
case SETREG:
|
||||
nreg = getw(ascbuf)-1;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (opdope[op]&BINARY) {
|
||||
if (sp < &expstack[1]) {
|
||||
error("Binary expression botch");
|
||||
exit(1);
|
||||
}
|
||||
t = *--sp;
|
||||
*sp++ = block(2, op, getw(ascbuf), 0, *--sp, t);
|
||||
} else {
|
||||
sp[-1] = block(1, op, getw(ascbuf), 0, sp[-1]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
outname(s)
|
||||
{
|
||||
register char *p, c;
|
||||
register n;
|
||||
|
||||
p = s;
|
||||
n = 0;
|
||||
while (c = getc(ascbuf)) {
|
||||
*p++ = c;
|
||||
n++;
|
||||
}
|
||||
while (n++ < 8)
|
||||
*p++ = 0;
|
||||
return(s);
|
||||
}
|
||||
|
||||
seq(c)
|
||||
{
|
||||
register o;
|
||||
|
||||
if (getw(ascbuf) == 0)
|
||||
return;
|
||||
for (;;) {
|
||||
printf("%o", getw(ascbuf));
|
||||
if ((o = getw(ascbuf)) != 1)
|
||||
break;
|
||||
printf("%c", c);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
Reference in New Issue
Block a user