📄 cc1.c
字号:
/* * Simple C Compiler * Based on Small C/386 * * Copyright (c) 2003 Charles Childers * Copyright (c) 1998 H. T. Walheim * Copyright (c) 1982, 1983, 1985, 1988 J. E. Hendrix*/#include <stdio.h>#include "notice.h"#include "cc.h"/*** miscellaneous storage*/int nogo, /* disable goto statements? */ noloc, /* disable block locals? */ opindex, /* index to matched operator */ opsize, /* size of operator in characters */ swactive, /* inside a switch? */ swdefault, /* default label #, else 0 */*swnext, /* address of next entry */*swend, /* address of last entry */*stage, /* staging buffer address */*wq, /* while queue */ argcs, /* static argc */*argvs, /* static argv */*wqptr, /* ptr to next entry */ litptr, /* ptr to next entry */ macptr, /* macro buffer index */ pptr, /* ptr to parsing buffer */ ch, /* current character of input line */ nch, /* next character of input line */ declared, /* # of local bytes to declare, -1 when declared */ iflevel, /* #if... nest level */ skiplevel, /* level at which #if... skipping started */ nxtlab, /* next avail label # */ litlab, /* label # assigned to literal pool */ csp, /* compiler relative stk ptr */ argstk, /* function arg sp */ argtop, /* highest formal argument offset */ ncmp, /* # open compound statements */ errflag, /* true after 1st error in statement */ eof, /* true on final input eof */ output, /* fd for output file */ files, /* true if file list specified on cmd line */ filearg, /* cur file arg index */ input = EOF, /* fd for input file */ input2 = EOF, /* fd for "#include" file */ usexpr = YES, /* true if value of expression is used */ ccode = YES, /* true while parsing C code */*snext, /* next addr in stage */*stail, /* last addr of data in stage */*slast, /* last addr in stage */ listfp, /* file pointer to list device */ lastst, /* last parsed statement type */ oldseg; /* current segment (0, DATASEG, CODESEG) */char optimize, /* optimize output of staging buffer? */ alarm, /* audible alarm on errors? */ monitor, /* monitor function headers? */ pause, /* pause for operator on errors? */*symtab, /* symbol table */*litq, /* literal pool */*macn, /* macro name buffer */*macq, /* macro string buffer */*pline, /* parsing buffer */*mline, /* macro buffer */*line, /* ptr to pline or mline */*lptr, /* ptr to current character in "line" */*glbptr, /* global symbol table */*locptr, /* next local symbol table entry */ quote[2] = { '"' }, /* literal string for '"' */*cptr, /* work ptrs to any char buffer */*cptr2, *cptr3, msname[NAMESIZE], /* macro symbol name */ ssname[NAMESIZE]; /* static symbol name */int op[16] = { /* p-codes of signed binary operators */ OR12, /* level5 */ XOR12, /* level6 */ AND12, /* level7 */ EQ12, NE12, /* level8 */ LE12, GE12, LT12, GT12, /* level9 */ ASR12, ASL12, /* level10 */ ADD12, SUB12, /* level11 */ MUL12, DIV12, MOD12 /* level12 */};int op2[16] = { /* p-codes of unsigned binary operators */ OR12, /* level5 */ XOR12, /* level6 */ AND12, /* level7 */ EQ12, NE12, /* level8 */ LE12u, GE12u, LT12u, GT12u, /* level9 */ ASR12, ASL12, /* level10 */ ADD12, SUB12, /* level11 */ MUL12u, DIV12u, MOD12u /* level12 */};/*** execution begins here*/main(argc, argv)int argc, *argv;{ argcs = argc; argvs = argv; swnext = calloc(SWTABSZ, 1); swend = swnext + (SWTABSZ - SWSIZ); stage = calloc(STAGESIZE, 2 * INTSIZE); wqptr = wq = calloc(WQTABSZ, INTSIZE); litq = calloc(LITABSZ, 1); macn = calloc(MACNSIZE, 1); macq = calloc(MACQSIZE, 1); pline = calloc(LINESIZE, 1); mline = calloc(LINESIZE, 1); slast = stage + (STAGESIZE * 2 * INTSIZE); symtab = calloc((NUMLOCS * SYMAVG + NUMGLBS * SYMMAX), 1); locptr = STARTLOC; glbptr = STARTGLB; ask(); /* get user options */ openfile(); /* and initial input file */ preprocess(); /* fetch first line */ header(); /* intro code */ setcodes(); /* initialize code pointer array */ parse(); /* process ALL input */ trailer(); /* follow-up code */ fclose(output); /* explicitly close output */}/******************** high level parsing *******************//*** process all input text**** At this level, only static declarations,** defines, includes and function** definitions are legal...*/parse(){ while (eof == 0) { if (amatch("extern", 6)) dodeclare(EXTERNAL); else if (dodeclare(STATIC)); else if (match("#asm")) doasm(); else if (match("#include")) doinclude(); else if (match("#define")) dodefine(); else dofunction(); blanks(); /* force eof if pending */ }}/*** test for global declarations*/dodeclare(class)int class;{ if (amatch("char", 4)) declglb(CHR, class); else if (amatch("unsigned", 8)) { if (amatch("char", 4)) declglb(UCHR, class); else { amatch("int", 3); declglb(UINT, class); } } else if (amatch("int", 3) || class == EXTERNAL) declglb(INT, class); else return 0; ns(); return 1;}/*** declare a static variable*/declglb(type, class)int type, class;{ int id, dim; while (1) { if (endst()) return; /* do line */ if (match("*")) { id = POINTER; dim = 0; } else { id = VARIABLE; dim = 1; } if (symname(ssname) == 0) illname(); if (findglb(ssname)) multidef(ssname); if (id == VARIABLE) { if (match("(")) { id = FUNCTION; need(")"); } else if (match("[")) { id = ARRAY; dim = needsub(); } } if (class == EXTERNAL) external(ssname, type >> 2, id); else if (id != FUNCTION) initials(type >> 2, id, dim); if (id == POINTER) addsym(ssname, id, type, PTRSIZE, 0, &glbptr, class); else addsym(ssname, id, type, dim * (type >> 2), 0, &glbptr, class); if (match(",") == 0) return; }}/*** initialize global objects*/initials(size, ident, dim)int size, ident, dim;{ int savedim; litptr = 0; if (dim == 0) dim = -1; /* *... or ...[] */ savedim = dim; if (match("=")) { if (match("{")) { while (dim) { init(size, ident, &dim); if (match(",") == 0) break; } need("}"); } else init(size, ident, &dim); } if (savedim == -1 && dim == -1) { if (ident == ARRAY) error("need array size"); stowlit(0, size = PTRSIZE); } public(ident); dumplits(size); dumpzero(size, dim); /* only if dim > 0 */}/*** evaluate one initializer*/init(size, ident, dim)int size, ident, *dim;{ int value; if (string(&value)) { if (ident == VARIABLE || size != 1) error("must assign to char pointer or char array"); *dim -= (litptr - value); if (ident == POINTER) point(); } else if (constexpr(&value)) { if (ident == POINTER) error("cannot assign to pointer"); stowlit(value, size); *dim -= 1; }}/*** get required array size*/needsub(){ int val; if (match("]")) return 0; /* null size */ if (constexpr(&val) == 0) val = 1; if (val < 0) { error("negative size illegal"); val = -val; } need("]"); /* force single dimension */ return val; /* and return size */}/*** open an include file*/doinclude(){ int i; char str[30]; blanks(); /* skip over to name */ if (*lptr == '"' || *lptr == '<') ++lptr; i = 0; while (lptr[i] && lptr[i] != '"' && lptr[i] != '>' && lptr[i] != '\n') { str[i] = lptr[i]; ++i; } str[i] = NULL; if ((input2 = fopen(str, "r")) == NULL) { input2 = EOF; error("open failure on include file"); } kill(); /* make next read come from new file (if open) */}/*** define a macro symbol*/dodefine(){ int k; if (symname(msname) == 0) { illname(); kill(); return; } k = 0; if (search(msname, macn, NAMESIZE + 2, MACNEND, MACNBR, 0) == 0) { if (cptr2 = cptr) while (*cptr2++ = msname[k++]); else { error("macro name table full"); return; } } putint(macptr, cptr + NAMESIZE, 2 /*INTSIZE*/); while (white()) gch(); while (putmac(gch())); if (macptr >= MACMAX) { error("macro string queue full"); exit(ERRCODE); }}putmac(c)char c;{ macq[macptr] = c; if (macptr < MACMAX) ++macptr; return c;}/*** begin a function**** called from "parse" and tries to make a function** out of the following text*/dofunction(){ char *ptr; nogo = /* enable goto statements */ noloc = /* enable block-local declarations */ lastst = /* no statement yet */ litptr = 0; /* clear lit pool */ litlab = getlabel(); /* label next lit pool */ locptr = STARTLOC; /* clear local variables */ if (match("void")) blanks(); /* skip "void" & locate header */ if (monitor) lout(line, stderr); if (symname(ssname) == 0) { error("illegal function or declaration"); errflag = 0; kill(); /* invalidate line */ return; } if (ptr = findglb(ssname)) { /* already in symbol table? */ if (ptr[CLASS] == AUTOEXT) ptr[CLASS] = STATIC; else multidef(ssname); } else addsym(ssname, FUNCTION, INT, 0, 0, &glbptr, STATIC); public(FUNCTION); argstk = 0; /* init arg count */ if (match("(") == 0) error("no open paren"); while (match(")") == 0) { /* then count args */ if (symname(ssname)) { if (findloc(ssname)) multidef(ssname); else { addsym(ssname, 0, 0, 0, argstk, &locptr, AUTOMATIC); argstk += INTSIZE; } } else { error("illegal argument name"); skip(); } blanks(); if (streq(lptr, ")") == 0 && match(",") == 0) error("no comma"); if (endst()) break; } csp = 0; /* preset stack ptr */ argtop = argstk + INTSIZE; /* account for the pushed BP */ while (argstk) { if (amatch("char", 4)) { doargs(CHR); ns(); } else if (amatch("int", 3)) { doargs(INT); ns(); } else if (amatch("unsigned", 8)) { if (amatch("char", 4)) { doargs(UCHR); ns(); } else { amatch("int", 3); doargs(UINT); ns(); } } else { error("wrong number of arguments"); break; } } gen(ENTER, 0); statement(); if (lastst != STRETURN && lastst != STGOTO) gen(RETURN, 0); if (litptr) { toseg(DATASEG); gen(REFm, litlab); dumplits(1); /* dump literals */ }}/*** declare argument types*/doargs(type)int type;{ int id, sz; char c, *ptr; while (1) { if (argstk == 0) return; /* no arguments */ if (decl(type, POINTER, &id, &sz)) { if (ptr = findloc(ssname)) { ptr[IDENT] = id; ptr[TYPE] = type; putint(sz, ptr + SIZE, INTSIZE); putint(argtop - getint(ptr + OFFSET, INTSIZE), ptr + OFFSET, INTSIZE); } else error("not an argument"); } argstk = argstk - INTSIZE; /* cnt down */ if (endst()) return; if (match(",") == 0) error("no comma"); }}/*** parse next local or argument declaration*/decl(type, aid, id, sz)int type, aid, *id, *sz;{ int n, p; int mod; if (match("(")) p = 1; else p = 0; if (match("*")) { *id = POINTER; *sz = PTRSIZE; } 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 = PTRSIZE; /* size of pointer argument */ } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -