📄 c04.c
字号:
#/* * C compiler * * */#include "c0h.c"/* * Reduce the degree-of-reference by one. * e.g. turn "ptr-to-int" into "int". */decref(at){ register t; t = at; if ((t & ~TYPE) == 0) { error("Illegal indirection"); return(t); } return((t>>TYLEN) & ~TYPE | t&TYPE);}/* * Increase the degree of reference by * one; e.g. turn "int" to "ptr-to-int". */incref(t){ return(((t&~TYPE)<<TYLEN) | (t&TYPE) | PTR);}/* * Make a tree that causes a branch to lbl * if the tree's value is non-zero together with the cond. */cbranch(tree, lbl, cond)struct tnode *tree;{ rcexpr(block(1,CBRANCH,tree,lbl,cond));}/* * Write out a tree. */rcexpr(tree)struct tnode *tree;{ treeout(tree); outcode("BN", EXPR, line);}treeout(atree)struct tnode *atree;{ register struct tnode *tree; if ((tree = atree) == 0) return; switch(tree->op) { case 0: outcode("B", NULL); return; case NAME: outcode("BNN", NAME, tree->class, tree->type); if (tree->class==EXTERN) outcode("S", tree->nname); else outcode("N", tree->nloc); return; case CON: case FCON: case SFCON: outcode("BNN", tree->op, tree->type, tree->value); return; case FSEL: treeout(tree->tr1); outcode("BNN", tree->op, tree->type, tree->tr2); return; case CBRANCH: treeout(tree->btree); outcode("BNN", tree->op, tree->lbl, tree->cond); return; default: treeout(tree->tr1); if (opdope[tree->op]&BINARY) treeout(tree->tr2); outcode("BN", tree->op, tree->type); return; }}/* * Generate a branch */branch(lab) { outcode("BN", BRANCH, lab);}/* * Generate a label */label(l) { outcode("BN", LABEL, l);}/* * ap is a tree node whose type * is some kind of pointer; return the size of the object * to which the pointer points. */plength(ap)struct tname *ap;{ register t, l; register struct tname *p; p = ap; if (p==0 || ((t=p->type)&~TYPE) == 0) /* not a reference */ return(1); p->type = decref(t); l = length(p); p->type = t; return(l);}/* * return the number of bytes in the object * whose tree node is acs. */length(acs)struct tnode *acs;{ register t, n; register struct tnode *cs; cs = acs; t = cs->type; n = 1; while ((t&XTYPE) == ARRAY) { t = decref(t); n = dimtab[cs->ssp&0377]; } if ((t&~TYPE)==FUNC) return(0); if (t>=PTR) return(2*n); switch(t&TYPE) { case INT: return(2*n); case CHAR: return(n); case FLOAT: case LONG: return(4*n); case DOUBLE: return(8*n); case STRUCT: return(n * dimtab[cs->lenp&0377]); case RSTRUCT: error("Bad structure"); return(0); } error("Compiler error (length)");}/* * The number of bytes in an object, rounded up to a word. */rlength(cs)struct tnode *cs;{ return((length(cs)+ALIGN) & ~ALIGN);}/* * After an "if (...) goto", look to see if the transfer * is to a simple label. */simplegoto(){ register struct hshtab *csp; if ((peeksym=symbol())==NAME && nextchar()==';') { csp = csym; if (csp->hclass==0 && csp->htype==0) { csp->htype = ARRAY; if (csp->hoffset==0) csp->hoffset = isn++; } if ((csp->hclass==0||csp->hclass==STATIC) && csp->htype==ARRAY) { peeksym = -1; return(csp->hoffset); } } return(0);}/* * Return the next non-white-space character */nextchar(){ while (spnextchar()==' ') peekc = 0; return(peekc);}/* * Return the next character, translating all white space * to blank and handling line-ends. */spnextchar(){ register c; if ((c = peekc)==0) c = getchar(); if (c=='\t') c = ' '; else if (c=='\n') { c = ' '; if (inhdr==0) line++; inhdr = 0; } else if (c=='\001') { /* SOH, insert marker */ inhdr++; c = ' '; } peekc = c; return(c);}/* * is a break or continue legal? */chconbrk(l){ if (l==0) error("Break/continue error");}/* * The goto statement. */dogoto(){ register struct tnode *np; *cp++ = tree(); build(STAR); chkw(np = *--cp, -1); rcexpr(block(1,JUMP,0,0,np));}/* * The return statement, which has to convert * the returned object to the function's type. */doret(){ register struct tnode *t; if (nextchar() != ';') { t = tree(); *cp++ = &funcblk; *cp++ = t; build(ASSIGN); cp[-1] = cp[-1]->tr2; build(RFORCE); rcexpr(*--cp); } branch(retlab);}/* * write out a character to the usual output * or to the string file */putchar(c){ write(1, &c, 1);}outcode(s, a)char *s;{ register char *sp; register *ap, *bufp; int n; char *np; bufp = obuf; if (strflg) bufp = sbuf; ap = &a; for (;;) switch(*s++) { case 'B': putw(*ap++ | (0376<<8), bufp); continue; case 'N': putw(*ap++, bufp); continue; case 'S': np = *ap++; n = ncps; while (n-- && *np) { putc(*np++, bufp); } putc(0, bufp); continue; case '1': putw(1, bufp); continue; case '0': putw(0, bufp); continue; case '\0': return; } error("Botch in outcode");}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -