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

📄 cc3.c

📁 A simple C compiler source code.
💻 C
📖 第 1 页 / 共 2 页
字号:
    gen(GETd1n, 0);    skip();}/* attempt at right to left - do it later */#ifdef LATERpushargs(ptr, nargs)char *ptr;int nargs;{    if (streq(lptr, ")") != 0)	return;    if (endst())	return;    if (ptr) {	expression(&consta, &val);	gen(PUSH1, 0);    } else {	gen(PUSH1, 0);	expression(&consta, &val);	gen(SWAP1s, 0);		/* don't push addr */    }    nargs = nargs + INTSIZE;	/* count args*BPW */    if (match(",") == 0)	break;}#endifcallfunc(ptr)char *ptr;			/* symbol table entry or 0 */{    int nargs, consta, val;    nargs = 0;    blanks();			/* already saw open paren */    while (streq(lptr, ")") == 0) {	if (endst())	    break;	if (ptr) {	    expression(&consta, &val);	    gen(PUSH1, 0);	} else {	    gen(PUSH1, 0);	    expression(&consta, &val);	    gen(SWAP1s, 0);	/* don't push addr */	}	nargs = nargs + INTSIZE;	/* count args*BPW */	if (match(",") == 0)	    break;    }    need(")");    if (ptr && (streq(ptr + NAME, "CCARGC") == 0))	/* accessing ... like va_args */	gen(ARGCNTn, nargs >> LBPD);	/* to get start of frame */    if (ptr)	gen(CALLm, ptr);    else	gen(CALL1, 0);    gen(ADDSP, csp + nargs);}/*** true if is2's operand should be doubled*/fdouble(oper, is1, is2)int oper, is1[], is2[];{    //////////////////////////////////////////////////////    // This is a 'magic' function, its usage and function    // are not so obvious    //    // Purpose:  when indexing an address we must know    // what we are pointing at so that the indexsize is    // proper, e,g,    // charptr++,  should multiply index by a 1    // shortptr++, should multiply index by a 2    // intptr++,   should multiply index by a 4    //    // Algorithm:    // IF    // operation is ADD12 or SUB12    // AND    // is1 is an address (pointer, array or via & operator    // AND    // is2 is NOT an address (pointer, array or via & operator    // THEN     // return the multiplication factor based on s1 (or true)    // ELSE    // return 0 (or false)    //    // Usage: The return value is used as a 'boolean'    // for nonconstant values, indicating that runtime code    // is necessary to do the necessary multiplication    // For contant value the return value is used to do a compile-time    // multiplication (shift actually)    //    if ((oper == ADD12 || oper == SUB12)	&& (is2[TA] == 0)) {	switch (is1[TA] >> 2) {	default:	case 1:		// char	    return (0);	case 2:		// short	    return (1);	case 4:		// int	    return (2);	}    }    return (0);}step(oper, is, oper2)int oper, is[], oper2;{    fetch(is);    gen(oper, is[TA] ? (is[TA] >> 2) : 1);    store(is);    if (oper2)	gen(oper2, is[TA] ? (is[TA] >> 2) : 1);}store(is)int is[];{    char *ptr;    if (is[TI]) {		/* putstk */	if (is[TI] >> 2 == 1) {	    gen(PUTbp1, 0);	} else if (is[TI] >> 2 == 2) {	    gen(PUTwp1, 0);	} else {	    gen(PUTdp1, 0);	}    } else {			/* putmem */	ptr = is[ST];	if (ptr[IDENT] == POINTER) {	    gen(PUTdm1, ptr);	} else if (ptr[TYPE] >> 2 == 1) {	    gen(PUTbm1, ptr);	} else if (ptr[TYPE] >> 2 == BPW) {	    gen(PUTwm1, ptr);	} else {	    gen(PUTdm1, ptr);	}    }}fetch(is)int is[];{    char *ptr;    ptr = is[ST];    if (is[TI]) {		/* indirect */	if (is[TI] >> 2 == BPD) {	/* pointer to DWORD */	    gen(GETd1p, 0);	} else if (is[TI] >> 2 == BPW) {	/* pointer to WORD */	    gen(GETw1p, 0);	} else {	    if (ptr[TYPE] & UNSIGNED)		gen(GETb1pu, 0);	    else		gen(GETb1p, 0);	}    } else {			/* direct */	if (ptr[IDENT] == POINTER) {	    gen(GETd1m, ptr);	} else if (ptr[TYPE] >> 2 == BPD) {	    gen(GETd1m, ptr);	} else if (ptr[TYPE] >> 2 == BPW) {	    gen(GETw1m, ptr);	} else {	    if (ptr[TYPE] & UNSIGNED)		gen(GETb1mu, ptr);	    else		gen(GETb1m, ptr);	}    }}constant(is)int is[];{    int offset;    if (is[TC] = number(is + CV)) {	gen(GETd1n, is[CV]);    } else if (is[TC] = chrcon(is + CV)) {	gen(GETd1n, is[CV]);    } else if (string(&offset)) {	gen(POINT1l, offset);    } else {	return 0;    }    return 1;}number(value)int *value;{    int k, minus;    k = minus = 0;    while (1) {	if (match("+"));	else if (match("-"))	    minus = 1;	else	    break;    }    if (isdigit(ch) == 0)	return 0;    if (ch == '0') {	while (ch == '0')	    inbyte();	if (toupper(ch) == 'X') {	    inbyte();	    while (isxdigit(ch)) {		if (isdigit(ch))		    k = k * 16 + (inbyte() - '0');		else		    k = k * 16 + 10 + (toupper(inbyte()) - 'A');	    }	} else	    while (ch >= '0' && ch <= '7')		k = k * 8 + (inbyte() - '0');    } else	while (isdigit(ch))	    k = k * 10 + (inbyte() - '0');    if (minus) {	*value = -k;	return (INT);    }    if ((*value = k) < 0)	return (UINT);    else	return (INT);}chrcon(value)int *value;{    int k;    k = 0;    if (match("'") == 0)	return 0;    while (ch != '\'')	k = (k << 8) + (litchar() & 255);    gch();    *value = k;    return (INT);}string(offset)int *offset;{    char c;    if (match(quote) == 0)	return 0;    *offset = litptr;    while (ch != '"') {	if (ch == 0)	    break;	stowlit(litchar(), 1);    }    gch();    litq[litptr++] = 0;    return 1;}stowlit(value, size)int value, size;{    if ((litptr + size) >= LITMAX) {	error("literal queue overflow");	exit(ERRCODE);    }    putint(value, litq + litptr, size);    litptr += size;}litchar(){    int i, oct;    if (ch != '\\' || nch == 0)	return gch();    gch();    switch (ch) {    case 'n':	gch();	return NEWLINE;    case 't':	gch();	return 9;		/* HT */    case 'b':	gch();	return 8;		/* BS */    case 'f':	gch();	return 12;		/* FF */    }    i = 3;    oct = 0;    while ((i--) > 0 && ch >= '0' && ch <= '7')	oct = (oct << 3) + gch() - '0';    if (i == 2)	return gch();    else	return oct;}/***************** pipeline functions ******************//*** skim over terms adjoining || and && operators*/skim(opstr, tcode, dropval, endval, level, is)char *opstr;int tcode, dropval, endval, (*level) (), is[];{    int k, droplab, endlab;    droplab = 0;    while (1) {	k = down1(level, is);	if (nextop(opstr)) {	    bump(opsize);	    if (droplab == 0)		droplab = getlabel();	    dropout(k, tcode, droplab, is);	} else if (droplab) {	    dropout(k, tcode, droplab, is);	    gen(GETd1n, endval);	    gen(JMPm, endlab = getlabel());	    gen(LABm, droplab);	    gen(GETd1n, dropval);	    gen(LABm, endlab);	    is[TI] = is[TA] = is[TC] = is[CV] = is[SA] = 0;	    return 0;	} else	    return k;    }}/*** test for early dropout from || or && sequences*/dropout(k, tcode, exit1, is)int k, tcode, exit1, is[];{    if (k)	fetch(is);    else if (is[TC]) {	gen(GETd1n, is[CV]);    }    gen(tcode, exit1);		/* jumps on false */}/*** drop to a lower level*/down(opstr, opoff, level, is)char *opstr;int opoff, (*level) (), is[];{    int k;    k = down1(level, is);    if (nextop(opstr) == 0)	return k;    if (k)	fetch(is);    while (1) {	if (nextop(opstr)) {	    int is2[7];		/* allocate only if needed */	    null_is(is2);	    bump(opsize);	    opindex += opoff;	    down2(op[opindex], op2[opindex], level, is, is2);	} else	    return 0;    }}/*** unary drop to a lower level*/down1(level, is)int (*level) (), is[];{    int k, *before, *start;    setstage(&before, &start);    k = (*level) (is);    if (is[TC])	clearstage(before, 0);	/* load constant later */    return k;}/*** binary drop to a lower level*/down2(oper, oper2, level, is, is2)int oper, oper2, (*level) (), is[], is2[];{    int *before, *start;    char *ptr;    int value;    setstage(&before, &start);    is[SA] = 0;			/* not "... op 0" syntax */    if (is[TC]) {		/* consant op unknown */	if (down1(level, is2))	    fetch(is2);	if (is[CV] == 0)	    is[SA] = snext;	gen(GETw2n, is[CV] << fdouble(oper, is2, is));    } else {			/* variable op unknown */	gen(PUSH1, 0);		/* at start in the buffer */	if (down1(level, is2))	    fetch(is2);	if (is2[TC]) {		/* variable op constant */	    if (is2[CV] == 0)		is[SA] = start;	    csp += BPD;		/* adjust stack and */	    clearstage(before, 0);	/* discard the PUSH */	    if (oper == ADD12) {	/* commutative */		gen(GETd2n, is2[CV] << fdouble(oper, is, is2));	    } else {		/* non-commutative */		gen(MOVE21, 0);		gen(GETd1n, is2[CV] << fdouble(oper, is, is2));	    }	} else {		/* variable op variable */	    gen(POP2, 0);	    if (value = fdouble(oper, is, is2)) {		gen(DBL1, 0);	// index size 2		if (value > 1)		    gen(DBL1, 0);	// .. or even 4	    }	    if (value = fdouble(oper, is2, is)) {		gen(DBL2, 0);		if (value > 1)		    gen(DBL2, 0);	    }	}    }    if (oper) {	if (nosign(is) || nosign(is2))	    oper = oper2;	if (is[TC] = is[TC] & is2[TC]) {	/* constant result */	    is[CV] = calc(is[CV], oper, is2[CV]);	    clearstage(before, 0);	    if (is2[TC] == UINT)		is[TC] = UINT;	} else {		/* variable result */	    gen(oper, 0);	    if (oper == SUB12 && is[TA] >> 2 == BPW && is2[TA] >> 2 == BPW) {	/* difference of two word addresses */		gen(SWAP12, 0);		gen(GETw1n, 1);		gen(ASR12, 0);	/* div by 2 */	    }	    is[OP] = oper;	/* identify the operator */	}	if (oper == SUB12 || oper == ADD12) {	    if (is[TA] && is2[TA])	/*  addr +/- addr */		is[TA] = 0;	    else if (is2[TA]) {	/* value +/- addr */		is[ST] = is2[ST];		is[TI] = is2[TI];		is[TA] = is2[TA];	    }	}	if (is[ST] == 0 || ((ptr = is2[ST]) && (ptr[TYPE] & UNSIGNED)))	    is[ST] = is2[ST];    }}/*** unsigned operand?*/nosign(is)int is[];{    char *ptr;    if (is[TA]	|| is[TC] == UINT || ((ptr = is[ST]) && (ptr[TYPE] & UNSIGNED))	)	return 1;    return 0;}/*** calcualte signed constant result*/calc(left, oper, right)int left, oper, right;{    switch (oper) {    case ADD12:	return (left + right);    case SUB12:	return (left - right);    case MUL12:	return (left * right);    case DIV12:	return (left / right);    case MOD12:	return (left % right);    case EQ12:	return (left == right);    case NE12:	return (left != right);    case LE12:	return (left <= right);    case GE12:	return (left >= right);    case LT12:	return (left < right);    case GT12:	return (left > right);    case AND12:	return (left & right);    case OR12:	return (left | right);    case XOR12:	return (left ^ right);    case ASR12:	return (left >> right);    case ASL12:	return (left << right);    }    return (calc2(left, oper, right));}/*** calcualte unsigned constant result*/calc2(left, oper, right)unsigned left, right;int oper;{    switch (oper) {    case MUL12u:	return (left * right);    case DIV12u:	return (left / right);    case MOD12u:	return (left % right);    case LE12u:	return (left <= right);    case GE12u:	return (left >= right);    case LT12u:	return (left < right);    case GT12u:	return (left > right);    }    return (0);}

⌨️ 快捷键说明

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