📄 cc3.c
字号:
/*** 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 + -