📄 cc1.c
字号:
mod = *sz % ALIGN; if (mod) { *sz = *sz + (ALIGN - mod); } 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(DWORDn, *swptr++); /* case value */ } gen(DWORDn, 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, INTSIZE));}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) { zinline(); if (match("#endasm")) break; if (eof) break; fputs(line, output); } kill(); ccode = 1;}doexpr(use)int use;{ int constant, val; int *before, *start; usexpr = use; /* tell isfree() whether expr value is used */ while (1) { setstage(&before, &start); expression(&constant, &val); clearstage(before, start); if (ch != ',') break; bump(1); } usexpr = YES; /* return to normal value */}/******************** miscellaneous functions *******************//*** get run options*/ask(){ int i; int j; i = listfp = 0; nxtlab = 1; output = stdout;#ifdef LATER optimize = YES; // Not working for 32 bit int's yer#else optimize = NO;#endif 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' // List && isdigit(line[2]) && line[3] <= ' ') { listfp = line[2] - '0'; continue; } if (toupper(line[1]) == 'N' // No optimize && toupper(line[2]) == 'O' && line[3] <= ' ') { optimize = NO; continue; } if (toupper(line[1]) == 'D') { j = 0; ch = line[j + 2]; lptr = line + j + 2; dodefine(); 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: scc [file]... [-m] [-a] [-p] [-l#] [-no] [-d<id>]\n", stderr); fputs(" -m monitor\n", stderr); fputs(" -a alarm\n", stderr); fputs(" -p pause\n", stderr); fputs(" -l# list\n", stderr); fputs(" -no no optimize\n", stderr); fputs(" -d<id> pre-#define id\n", stderr); fputs(VERSION, stdout); fputs(CRIGHT1, stdout); fputs(CRIGHT2, stdout); exit(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) { 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); exit(ERRCODE);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -