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

📄 cc3.c

📁 A simple C compiler source code.
💻 C
📖 第 1 页 / 共 2 页
字号:
/*** Small-C Compiler -- Part 3 -- Expression Analyzer.** Copyright 1982, 1983, 1985, 1988 J. E. Hendrix** Copyright 1998 H T Walheim** All rights reserved.*/#include <stdio.h>#include "cc.h"#define ST 0			/* is[ST] - symbol table address, else 0 */#define TI 1			/* is[TI] - type of indirect obj to fetch, else 0 */#define TA 2			/* is[TA] - type of address, else 0 */#define TC 3			/* is[TC] - type of constant (INT or UINT), else 0 */#define CV 4			/* is[CV] - value of constant (+ auxiliary uses) */#define OP 5			/* is[OP] - code of highest/last binary operator */#define SA 6			/* is[SA] - stage address of "op 0" code, else 0 */extern char*litq, *glbptr, *lptr, ssname[NAMESIZE], quote[2];extern int ch, csp, litlab, litptr, nch, op[16], op2[16], opindex, opsize, *snext;/***************** lead-in functions *******************/constexpr(val)int *val;{    int constant;    int *before, *start;    setstage(&before, &start);    expression(&constant, val);    clearstage(before, 0);	/* scratch generated code */    if (constant == 0)	error("must be constant expression");    return constant;}null_is(is)int is[7];{    int i;    for (i = 0; i < 7; ++i) {	is[i] = 0;		/* <-- */    }}expression(con, val)int *con, *val;{    int i;    int is[7];    null_is(is);    if (level1(is))	fetch(is);    *con = is[TC];    *val = is[CV];}test(label, parens)int label, parens;{    int is[7];    int *before, *start;    null_is(is);    if (parens)	need("(");    while (1) {	setstage(&before, &start);	if (level1(is))	    fetch(is);	if (match(","))	    clearstage(before, start);	else	    break;    }    if (parens)	need(")");    if (is[TC]) {		/* constant expression */	clearstage(before, 0);	if (is[CV])	    return;	gen(JMPm, label);	return;    }    if (is[SA]) {		/* stage address of "oper 0" code */	switch (is[OP]) {	/* operator code */	case EQ12:	case LE12u:	    zerojump(EQ10f, label, is);	    break;	case NE12:	case GT12u:	    zerojump(NE10f, label, is);	    break;	case GT12:	    zerojump(GT10f, label, is);	    break;	case GE12:	    zerojump(GE10f, label, is);	    break;	case GE12u:	    clearstage(is[SA], 0);	    break;	case LT12:	    zerojump(LT10f, label, is);	    break;	case LT12u:	    zerojump(JMPm, label, is);	    break;	case LE12:	    zerojump(LE10f, label, is);	    break;	default:	    gen(NE10f, label);	    break;	}    } else	gen(NE10f, label);    clearstage(before, start);}/*** test primary register against zero and jump if false*/zerojump(oper, label, is)int oper, label, is[];{    clearstage(is[SA], 0);	/* purge conventional code */    gen(oper, label);}/***************** precedence levels ******************/#ifdef __GNUC__level2();level3();level4();level5();level6();level7();level8();level9();level10();level11();level12();level13();#endiflevel1(is)int is[];{    int k, is2[7], is3[2], oper, oper2;    null_is(is2);    null_is(is3);    k = down1(level2, is);    if (is[TC]) {	gen(GETd1n, is[CV]);    }    if (match("|=")) {	oper = oper2 = OR12;    } else if (match("^=")) {	oper = oper2 = XOR12;    } else if (match("&=")) {	oper = oper2 = AND12;    } else if (match("+=")) {	oper = oper2 = ADD12;    } else if (match("-=")) {	oper = oper2 = SUB12;    } else if (match("*=")) {	oper = MUL12;	oper2 = MUL12u;    } else if (match("/=")) {	oper = DIV12;	oper2 = DIV12u;    } else if (match("%=")) {	oper = MOD12;	oper2 = MOD12u;    } else if (match(">>=")) {	oper = oper2 = ASR12;    } else if (match("<<=")) {	oper = oper2 = ASL12;    } else if (match("=")) {	oper = oper2 = 0;    } else	return k;    /* have an assignment operator */    if (k == 0) {	needlval();	return 0;    }    is3[ST] = is[ST];    is3[TI] = is[TI];    if (is[TI]) {		/* indirect target */	if (oper) {		/* ?= */	    gen(PUSH1, 0);	/* save address */	    fetch(is);		/* fetch left side */	}	down2(oper, oper2, level1, is, is2);	/* parse right side */	if (oper)	    gen(POP2, 0);	/* retrieve address */    } else {			/* direct target */	if (oper) {		/* ?= */	    fetch(is);		/* fetch left side */	    down2(oper, oper2, level1, is, is2);	/* parse right side */	} else {		/*  = */	    if (level1(is2))		fetch(is2);	/* parse right side */	}    }    store(is3);			/* store result */    return 0;}level2(is1)int is1[];{    int is2[7], is3[7], k, flab, endlab, *before, *after;    null_is(is2);    null_is(is3);    k = down1(level3, is1);	/* expression 1 */    if (match("?") == 0)	return k;    dropout(k, NE10f, flab = getlabel(), is1);    if (down1(level2, is2))	fetch(is2);		/* expression 2 */    else if (is2[TC]) {	gen(GETd1n, is2[CV]);    }    need(":");    gen(JMPm, endlab = getlabel());    gen(LABm, flab);    if (down1(level2, is3))	fetch(is3);		/* expression 3 */    else if (is3[TC]) {	gen(GETd1n, is3[CV]);    }    gen(LABm, endlab);    is1[TC] = is1[CV] = 0;    if (is2[TC] && is3[TC]) {	/* expr1 ? const2 : const3 */	is1[TA] = is1[TI] = is1[SA] = 0;    } else if (is3[TC]) {	/* expr1 ? var2 : const3 */	is1[TA] = is2[TA];	is1[TI] = is2[TI];	is1[SA] = is2[SA];    } else if ((is2[TC])	/* expr1 ? const2 : var3 */	       ||(is2[TA] == is3[TA])) {	/* expr1 ? same2 : same3 */	is1[TA] = is3[TA];	is1[TI] = is3[TI];	is1[SA] = is3[SA];    } else	error("mismatched expressions");    return 0;}level3(is)int is[];{    return skim("||", EQ10f, 1, 0, level4, is);}level4(is)int is[];{    return skim("&&", NE10f, 0, 1, level5, is);}level5(is)int is[];{    return down("|", 0, level6, is);}level6(is)int is[];{    return down("^", 1, level7, is);}level7(is)int is[];{    return down("&", 2, level8, is);}level8(is)int is[];{    return down("== !=", 3, level9, is);}level9(is)int is[];{    return down("<= >= < >", 5, level10, is);}level10(is)int is[];{    return down(">> <<", 9, level11, is);}level11(is)int is[];{    return down("+ -", 11, level12, is);}level12(is)int is[];{    return down("* / %", 13, level13, is);}level13(is)int is[];{    int k;    char *ptr;    if (match("++")) {		/* ++lval */	if (level13(is) == 0) {	    needlval();	    return 0;	}	step(rINC1, is, 0);	return 0;    } else if (match("--")) {	/* --lval */	if (level13(is) == 0) {	    needlval();	    return 0;	}	step(rDEC1, is, 0);	return 0;    } else if (match("~")) {	/* ~ */	if (level13(is))	    fetch(is);	gen(COM1, 0);	is[CV] = ~is[CV];	return (is[SA] = 0);    } else if (match("!")) {	/* ! */	if (level13(is))	    fetch(is);	gen(LNEG1, 0);	is[CV] = !is[CV];	return (is[SA] = 0);    } else if (match("-")) {	/* unary - */	if (level13(is))	    fetch(is);	gen(ANEG1, 0);	is[CV] = -is[CV];	return (is[SA] = 0);    } else if (match("*")) {	/* unary * */	if (level13(is))	    fetch(is);	if (ptr = is[ST])	    is[TI] = ptr[TYPE];	else	    is[TI] = INT;	is[SA] =		/* no (op 0) stage address */	    is[TA] =		/* not an address */	    is[TC] = 0;		/* not a constant */	is[CV] = 1;		/* omit fetch() on func call */	return 1;    } else if (amatch("sizeof", 6)) {	/* sizeof() */	int sz, p;	char *ptr, sname[NAMESIZE];	if (match("("))	    p = 1;	else	    p = 0;	sz = 0;	if (amatch("unsigned", 8))	    sz = INTSIZE;	if (amatch("int", 3))	    sz = INTSIZE;	else if (amatch("char", 4))	    sz = 1;	if (sz) {	    if (match("*"))		sz = PTRSIZE;	} else if (symname(sname)		   && ((ptr = findloc(sname)) || (ptr = findglb(sname)))		   && ptr[IDENT] != FUNCTION && ptr[IDENT] != LABEL)	    sz = getint(ptr + SIZE, INTSIZE);	else if (sz == 0)	    error("must be object or type");	if (p)	    need(")");	is[TC] = INT;	is[CV] = sz;	is[TA] = is[TI] = is[ST] = 0;	return 0;    } else if (match("&")) {	/* unary & */	if (level13(is) == 0) {	    error("illegal address");	    return 0;	}	ptr = is[ST];	is[TA] = ptr[TYPE];	if (is[TI])	    return 0;	gen(POINT1m, ptr);	is[TI] = ptr[TYPE];	return 0;    } else {	k = level14(is);	if (match("++")) {	/* lval++ */	    if (k == 0) {		needlval();		return 0;	    }	    step(rINC1, is, rDEC1);	    return 0;	} else if (match("--")) {	/* lval-- */	    if (k == 0) {		needlval();		return 0;	    }	    step(rDEC1, is, rINC1);	    return 0;	} else	    return k;    }}level14(is)int *is;{    int k, consta, val;    char *ptr, *before, *start;    k = primary(is);    ptr = is[ST];    blanks();    if (ch == '[' || ch == '(') {	int is2[7];		/* allocate only if needed */	null_is(is2);	while (1) {	    if (match("[")) {	/* [subscript] */		if (ptr == 0) {		    error("can't subscript");		    skip();		    need("]");		    return 0;		}		if (is[TA]) {		    if (k)			fetch(is);		} else {		    error("can't subscript");		    k = 0;		}		setstage(&before, &start);		is2[TC] = 0;		down2(0, 0, level1, is2, is2);		need("]");		if (is2[TC]) {		    clearstage(before, 0);		    if (is2[CV]) {	/* only add if non-zero */			if (ptr[TYPE] >> 2 == BPD) {			    gen(GETd2n, is2[CV] << LBPD);			} else if (ptr[TYPE] >> 2 == BPW) {			    gen(GETd2n, is2[CV] << LBPW);			} else {			    gen(GETd2n, is2[CV]);			}			gen(ADD12, 0);		    }		} else {		    if (ptr[TYPE] >> 2 == BPD) {			gen(DBL1, 0);			gen(DBL1, 0);		    } else if (ptr[TYPE] >> 2 == BPW) {			gen(DBL1, 0);		    }		    gen(ADD12, 0);		}		is[TA] = 0;		is[TI] = ptr[TYPE];		k = 1;	    } else if (match("(")) {	/* function(...) */		if (ptr == 0)		    callfunc(0);		else if (ptr[IDENT] != FUNCTION) {		    if (k && !is[CV])			fetch(is);		    callfunc(0);		} else		    callfunc(ptr);		k = is[ST] = is[TC] = is[CV] = 0;	    } else		return k;	}    }    if (ptr && ptr[IDENT] == FUNCTION) {	gen(POINT1m, ptr);	is[ST] = 0;	return 0;    }    return k;}primary(is)int *is;{    char *ptr, sname[NAMESIZE];    int k;    if (match("(")) {		/* (subexpression) */	do	    k = level1(is);	while (match(","));	need(")");	return k;    }    putint(0, is, 7 << LBPW);	/* clear "is" array */    if (symname(sname)) {	/* is legal symbol */	if (ptr = findloc(sname)) {	/* is local */	    if (ptr[IDENT] == LABEL) {		experr();		return 0;	    }	    gen(POINT1s, getint(ptr + OFFSET, INTSIZE));	    is[ST] = ptr;	    is[TI] = ptr[TYPE];	    if (ptr[IDENT] == ARRAY) {		is[TA] = ptr[TYPE];		return 0;	    }	    if (ptr[IDENT] == POINTER) {		is[TI] = UINT;		is[TA] = ptr[TYPE];	    }	    return 1;	}	if (ptr = findglb(sname)) {	/* is global */	    is[ST] = ptr;	    if (ptr[IDENT] != FUNCTION) {		if (ptr[IDENT] == ARRAY) {		    gen(POINT1m, ptr);		    is[TI] = is[TA] = ptr[TYPE];		    return 0;		}		if (ptr[IDENT] == POINTER)		    is[TA] = ptr[TYPE];		return 1;	    }	} else	    is[ST] = addsym(sname, FUNCTION, INT, 0, 0, &glbptr, AUTOEXT);	return 0;    }    if (constant(is) == 0)	experr();    return 0;}experr(){    error("invalid expression");

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -