?? cc1.c
字號(hào):
}
}
/*
** parse next local or argument declaration
*/
decl(type, aid, id, sz) int type, aid, *id, *sz; {
int n, p;
if(match("(")) p = 1;
else p = 0;
if(match("*")) {*id = POINTER; *sz = BPW;}
else {*id = VARIABLE; *sz = type >> 2;}
if((n = symname(ssname)) == 0) illname();
if(p && match(")")) ;
if(match("(")) {
if(!p || *id != POINTER) error("try (*...)()");
need(")");
}
else if(*id == VARIABLE && match("[")) {
*id = aid;
if((*sz *= needsub()) == 0) {
if(aid == ARRAY) error("need array size");
*sz = BPW; /* size of pointer argument */
}
}
return n;
}
/******************** start 2nd level parsing *******************/
/*
** statement parser
*/
statement() {
if(ch == 0 && eof) return;
else if(amatch("char", 4)) {declloc(CHR); ns();}
else if(amatch("int", 3)) {declloc(INT); ns();}
else if(amatch("unsigned", 8)) {
if (amatch("char", 4)) {declloc(UCHR); ns();}
else {amatch("int", 3); declloc(UINT); ns();}
}
else {
if(declared >= 0) {
if(ncmp > 1) nogo = declared; /* disable goto */
gen(ADDSP, csp - declared);
declared = -1;
}
if(match("{")) compound();
else if(amatch("if", 2)) {doif(); lastst = STIF;}
else if(amatch("while", 5)) {dowhile(); lastst = STWHILE;}
else if(amatch("do", 2)) {dodo(); lastst = STDO;}
else if(amatch("for", 3)) {dofor(); lastst = STFOR;}
else if(amatch("switch", 6)) {doswitch(); lastst = STSWITCH;}
else if(amatch("case", 4)) {docase(); lastst = STCASE;}
else if(amatch("default", 7)) {dodefault(); lastst = STDEF;}
else if(amatch("goto", 4)) {dogoto(); lastst = STGOTO;}
else if(dolabel()) lastst = STLABEL;
else if(amatch("return", 6)) {doreturn(); ns(); lastst = STRETURN;}
else if(amatch("break", 5)) {dobreak(); ns(); lastst = STBREAK;}
else if(amatch("continue", 8)) {docont(); ns(); lastst = STCONT;}
else if(match(";")) errflag = 0;
else if(match("#asm")) {doasm(); lastst = STASM;}
else {doexpr(NO); ns(); lastst = STEXPR;}
}
return lastst;
}
/*
** declare local variables
*/
declloc(type) int type; {
int id, sz;
if(swactive) error("not allowed in switch");
if(noloc) error("not allowed with goto");
if(declared < 0) error("must declare first in block");
while(1) {
if(endst()) return;
decl(type, ARRAY, &id, &sz);
declared += sz;
addsym(ssname, id, type, sz, csp - declared, &locptr, AUTOMATIC);
if(match(",") == 0) return;
}
}
compound() {
int savcsp;
char *savloc;
savcsp = csp;
savloc = locptr;
declared = 0; /* may now declare local variables */
++ncmp; /* new level open */
while (match("}") == 0)
if(eof) {
error("no final }");
break;
}
else statement(); /* do one */
if(--ncmp /* close current level */
&& lastst != STRETURN
&& lastst != STGOTO)
gen(ADDSP, savcsp); /* delete local variable space */
cptr = savloc; /* retain labels */
while(cptr < locptr) {
cptr2 = nextsym(cptr);
if(cptr[IDENT] == LABEL) {
while(cptr < cptr2) *savloc++ = *cptr++;
}
else cptr = cptr2;
}
locptr = savloc; /* delete local symbols */
declared = -1; /* may not declare variables */
}
doif() {
int flab1, flab2;
test(flab1 = getlabel(), YES); /* get expr, and branch false */
statement(); /* if true, do a statement */
if(amatch("else", 4) == 0) { /* if...else ? */
/* simple "if"...print false label */
gen(LABm, flab1);
return; /* and exit */
}
flab2 = getlabel();
if(lastst != STRETURN && lastst != STGOTO)
gen(JMPm, flab2);
gen(LABm, flab1); /* print false label */
statement(); /* and do "else" clause */
gen(LABm, flab2); /* print true label */
}
dowhile() {
int wq[4]; /* allocate local queue */
addwhile(wq); /* add entry to queue for "break" */
gen(LABm, wq[WQLOOP]); /* loop label */
test(wq[WQEXIT], YES); /* see if true */
statement(); /* if so, do a statement */
gen(JMPm, wq[WQLOOP]); /* loop to label */
gen(LABm, wq[WQEXIT]); /* exit label */
delwhile(); /* delete queue entry */
}
dodo() {
int wq[4];
addwhile(wq);
gen(LABm, wq[WQLOOP]);
statement();
need("while");
test(wq[WQEXIT], YES);
gen(JMPm, wq[WQLOOP]);
gen(LABm, wq[WQEXIT]);
delwhile();
ns();
}
dofor() {
int wq[4], lab1, lab2;
addwhile(wq);
lab1 = getlabel();
lab2 = getlabel();
need("(");
if(match(";") == 0) {
doexpr(NO); /* expr 1 */
ns();
}
gen(LABm, lab1);
if(match(";") == 0) {
test(wq[WQEXIT], NO); /* expr 2 */
ns();
}
gen(JMPm, lab2);
gen(LABm, wq[WQLOOP]);
if(match(")") == 0) {
doexpr(NO); /* expr 3 */
need(")");
}
gen(JMPm, lab1);
gen(LABm, lab2);
statement();
gen(JMPm, wq[WQLOOP]);
gen(LABm, wq[WQEXIT]);
delwhile();
}
doswitch() {
int wq[4], endlab, swact, swdef, *swnex, *swptr;
swact = swactive;
swdef = swdefault;
swnex = swptr = swnext;
addwhile(wq);
*(wqptr + WQLOOP - WQSIZ) = 0;
need("(");
doexpr(YES); /* evaluate switch expression */
need(")");
swdefault = 0;
swactive = 1;
gen(JMPm, endlab = getlabel());
statement(); /* cases, etc. */
gen(JMPm, wq[WQEXIT]);
gen(LABm, endlab);
gen(SWITCH, 0); /* match cases */
while(swptr < swnext) {
gen(NEARm, *swptr++);
gen(WORDn, *swptr++); /* case value */
}
gen(WORDn, 0);
if(swdefault) gen(JMPm, swdefault);
gen(LABm, wq[WQEXIT]);
delwhile();
swnext = swnex;
swdefault = swdef;
swactive = swact;
}
docase() {
if(swactive == 0) error("not in switch");
if(swnext > swend) {
error("too many cases");
return;
}
gen(LABm, *swnext++ = getlabel());
constexpr(swnext++);
need(":");
}
dodefault() {
if(swactive) {
if(swdefault) error("multiple defaults");
}
else error("not in switch");
need(":");
gen(LABm, swdefault = getlabel());
}
dogoto() {
if(nogo > 0) error("not allowed with block-locals");
else noloc = 1;
if(symname(ssname)) gen(JMPm, addlabel(NO));
else error("bad label");
ns();
}
dolabel() {
char *savelptr;
blanks();
savelptr = lptr;
if(symname(ssname)) {
if(gch() == ':') {
gen(LABm, addlabel(YES));
return 1;
}
else bump(savelptr-lptr);
}
return 0;
}
addlabel(def) int def; {
if(cptr = findloc(ssname)) {
if(cptr[IDENT] != LABEL) error("not a label");
else if(def) {
if(cptr[TYPE]) error("duplicate label");
else cptr[TYPE] = YES;
}
}
else cptr = addsym(ssname, LABEL, def, 0, getlabel(), &locptr, LABEL);
return (getint(cptr+OFFSET, 2));
}
doreturn() {
int savcsp;
if(endst() == 0) doexpr(YES);
savcsp = csp;
gen(RETURN, 0);
csp = savcsp;
}
dobreak() {
int *ptr;
if((ptr = readwhile(wqptr)) == 0) return;
gen(ADDSP, ptr[WQSP]);
gen(JMPm, ptr[WQEXIT]);
}
docont() {
int *ptr;
ptr = wqptr;
while (1) {
if((ptr = readwhile(ptr)) == 0) return;
if(ptr[WQLOOP]) break;
}
gen(ADDSP, ptr[WQSP]);
gen(JMPm, ptr[WQLOOP]);
}
doasm() {
ccode = 0; /* mark mode as "asm" */
while (1) {
inline();
if(match("#endasm")) break;
if(eof)break;
fputs(line, output);
}
kill();
ccode = 1;
}
doexpr(use) int use; {
int const, val;
int *before, *start;
usexpr = use; /* tell isfree() whether expr value is used */
while(1) {
setstage(&before, &start);
expression(&const, &val);
clearstage(before, start);
if(ch != ',') break;
bump(1);
}
usexpr = YES; /* return to normal value */
}
/******************** miscellaneous functions *******************/
/*
** get run options
*/
ask() {
int i;
i = listfp = nxtlab = 0;
output = stdout;
optimize = YES;
alarm = monitor = pause = NO;
line = mline;
while(getarg(++i, line, LINESIZE, argcs, argvs) != EOF) {
if(line[0] != '-' && line[0] != '/') continue;
if(toupper(line[1]) == 'L'
&& isdigit(line[2])
&& line[3] <= ' ') {
listfp = line[2]-'0';
continue;
}
if(toupper(line[1]) == 'N'
&& toupper(line[2]) == 'O'
&& line[3] <= ' ') {
optimize = NO;
continue;
}
if(line[2] <= ' ') {
if(toupper(line[1]) == 'A') {alarm = YES; continue;}
if(toupper(line[1]) == 'M') {monitor = YES; continue;}
if(toupper(line[1]) == 'P') {pause = YES; continue;}
}
fputs("usage: cc [file]... [-m] [-a] [-p] [-l#] [-no]\n", stderr);
abort(ERRCODE);
}
}
/*
** input and output file opens
*/
openfile() { /* entire function revised */
char outfn[15];
int i, j, ext;
input = EOF;
while(getarg(++filearg, pline, LINESIZE, argcs, argvs) != EOF) {
if(pline[0] == '-' || pline[0] == '/') continue;
ext = NO;
i = -1;
j = 0;
while(pline[++i]) {
if(pline[i] == '.') {
ext = YES;
break;
}
if(j < 10) outfn[j++] = pline[i];
}
if(!ext) strcpy(pline + i, ".C");
input = mustopen(pline, "r");
if(!files && iscons(stdout)) {
strcpy(outfn + j, ".ASM");
output = mustopen(outfn, "w");
}
files = YES;
kill();
return;
}
if(files++) eof = YES;
else input = stdin;
kill();
}
/*
** open a file with error checking
*/
mustopen(fn, mode) char *fn, *mode; {
int fd;
if(fd = fopen(fn, mode)) return fd;
fputs("open error on ", stderr);
lout(fn, stderr);
abort(ERRCODE);
}
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -