?? cc1.c
字號:
/*
** Small-C Compiler -- Part 1 -- Top End.
** Copyright 1982, 1983, 1985, 1988 J. E. Hendrix
** All rights reserved.
*/
#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; {
fputs(VERSION, stderr);
fputs(CRIGHT1, stderr);
argcs = argc;
argvs = argv;
swnext = calloc(SWTABSZ, 1);
swend = swnext+(SWTABSZ-SWSIZ);
stage = calloc(STAGESIZE, 2*BPW);
wqptr =
wq = calloc(WQTABSZ, BPW);
litq = calloc(LITABSZ, 1);
macn = calloc(MACNSIZE, 1);
macq = calloc(MACQSIZE, 1);
pline = calloc(LINESIZE, 1);
mline = calloc(LINESIZE, 1);
slast = stage+(STAGESIZE*2*BPW);
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, BPW, 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;
public(ident);
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 = BPW);
}
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);
while(white()) gch();
while(putmac(gch()));
if(macptr >= MACMAX) {
error("macro string queue full");
abort(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 += BPW;
}
}
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+BPW; /* 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, 2);
putint(argtop-getint(ptr+OFFSET, 2), ptr+OFFSET, 2);
}
else error("not an argument");
}
argstk = argstk - BPW; /* cnt down */
if(endst()) return;
if(match(",") == 0) error("no comma");
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -