⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cc1.c

📁 A simple C compiler source code.
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * 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 + -