?? enode.c
字號:
/*enode.c:進行語義處理并建立抽象語法樹*/#include "cmm.h"static Tree addtree(int op, Tree l,Tree r);static Tree cmptree(int op, Tree l, Tree r);static int compatible(Type ty1, Type ty2);static int isnullptr(Tree e);static Tree subtree(int op, Tree l, Tree r);static Tree multree(int op, Tree l, Tree r);Tree (*optree[])(int op, Tree l, Tree r) = {/*二元表達式處理函數*/#define xx(a,b,c,d,e,f,g) f,#define yy(a,b,c,d,e,f,g) f,#include "token.h"};/*call:為函數調用生成調用樹。 *call用函數原型對實參進行類型檢查。 */Tree call(Tree f, Type fty, Coordinate *src){ int n = 0; Tree args = NULL; Type *proto, rty = freturn(fty); DEBUG(fprint(2,"function call begin\n")); proto = fty->proto; if (t != ')') for (;;) { Tree q = pointer(expr(0)); if (proto && *proto && *proto != voidtype) { Type aty; aty = assign(*proto,q); if (aty) q = cast(q, aty); else error("type error in argument %d to\ %s;found '%t'\expected '%t'\n", n+1,funcname(f),q->type,*proto); if (ischar(q->type)) /*將字符參數類型提升為整形*/ q = cast(q, promote(q->type)); proto++; } else { if (NULL == proto || NULL == *proto|| *proto == voidtype) error("too many arguments to %s\n",funcname(f)); } args = tree(ARG + ttob(q->type),q->type,q,args); n++; if(t != ',') break; t = gettoken(); } expect(')'); if (proto && *proto) error("insufficient number of arguments to %s\n", funcname(f)); DEBUG(fprint(2,"function call end\n")); return tree(CALL + ttob(rty), promote(rty),args,f);}/*addtree:為加運算生成樹*/static Tree addtree(int op, Tree l,Tree r){ Type ty = inttype; if (isarith(l->type) && isarith(r->type)) { ty = binary(l->type, r->type); l = cast(l,ty); r = cast(r,ty); }else if(isptr(l->type) && isarith(r->type)) return addtree(op, r, l); else if(isptr(r->type) && isarith(l->type) &&!isfunc(r->type->type)) { /*對于指針與算術類型的運算,總是使指針成為右操作數*/ int n; ty = r->type; n = ty->type->size; if(0 == n) error("unknown size for type '%t' \n",ty->type); l = cast(l, promote(l->type)); if(n > 1) /*計算偏移量*/ l = multree(MUL, consttree(n,inttype),l); return simplify(ADD+P, ty, l, r); }else typeerror(op, l,r); return simplify(op, ty, l, r); }/*consttree:生成類型為ty值為n的常量樹*/Tree consttree(int n, Type ty){ Tree p; if(isarray(ty)) ty = atop(ty); p = tree(CNST+ttob(ty),ty,NULL,NULL); p->u.v.i = n; return p;}/*cmptree:為比較運算生成樹*/static Tree cmptree(int op, Tree l, Tree r){ Type ty = inttype; if(isarith(l->type) && isarith(r->type)) { ty = binary(l->type, r->type); l = cast(l,ty); r = cast(r,ty); }else if(compatible(l->type,r->type)){ /*比較可以兼容的指針類型,并把它們轉換成無符號數的比較*/ ty = unsignedtype; l = cast(l, ty); r = cast(r,ty); }else typeerror(op,l,r); return simplify(op + ttob(ty),inttype,l,r); }static int compatible(Type ty1, Type ty2){ return (isptr(ty1) && !isfunc(ty1->type) && isptr(ty2) && !isfunc(ty2->type) && eqtype(ty1->type,ty2->type));}static int isnullptr(Tree e){ return (isint(e->type) && CNST == generic(e->op) && 0 == e->u.v.i) || (isvoidptype(e->type) && CNST+P == e->op &&NULL == e->u.v.p);}Tree eqtree(int op, Tree l, Tree r){ Type xty = l->type, yty = r->type; if((isptr(xty) && isnullptr(r)) || (isptr(xty) && !isfunc(xty->type) && isvoidptype(yty)) || (isptr(xty) && isptr(yty) && eqtype(xty->type,yty->type))) { Type ty = unsignedtype; l = cast(l, ty); r = cast(r, ty); return simplify(op + ttob(ty),inttype, l, r); }else if((isptr(yty) && isnullptr(l)) || (isptr(yty) && !isfunc(yty->type) && isvoidptype(xty))) { return eqtree(op, r, l); } return cmptree(op, l, r);}Type assign(Type xty, Tree e){ if(isarith(e->type) && isarith(xty)) return xty; else if(isptr(xty) && isnullptr(e)) return xty; else if((isvoidptype(xty) && isptr(e->type)) || (isvoidptype(e->type) && isptr(xty))) return xty; else if(isptr(xty) && isptr(e->type) && eqtype(xty, e->type)) return xty; return NULL;}/*asgntree:生成賦值樹*/Tree asgntree(int op, Tree l, Tree r){ Type ty; r = pointer(r);/*將數組和函數做為指針*/ ty = assign(l->type, r); if(ty) r = cast(r, ty); else { typeerror(ASGN, l,r); if(r->type == voidtype) r = retype(r, inttype); ty = r->type; } l = lvalue(l); /*使用l的左值*/ return tree(op + ttob(ty), ty, l, r);}Tree asgn(Symbol p, Tree e){ if(isarray(p->type)) /*對局部數組進行初始化賦值*/ e = tree(ASGN + A, p->type, idtree(p), tree(INDIR + A, e->type, e, NULL)); else e = asgntree(ASGN, idtree(p),e); return e; }/*subtree:處理減法運算*/static Tree subtree(int op, Tree l, Tree r){ Type ty = inttype; int n; DEBUG(fprint(2,"subtree begin\n")); if(isarith(l->type) && isarith(r->type)) { l = cast(l, ty); r = cast(r, ty); }else if(isptr(l->type) && !isfunc(l->type->type) && isarith(r->type)) { /*指針減去一個整形數后其結果為指針*/ ty = l->type; n = ty->size; if(0 == n) error("unknown size for type '%t'\n",ty->type); if(n > 1) r = multree(MUL, consttree(n, inttype), r); return simplify(SUB+P, ty, l, r); }else if(compatible(l->type, r->type)) { /*兼容指針相減的結果為指針引用元素的個數*/ ty = l->type; n = ty->type->size; if(0 == n) error("unknown size for type '%t'\n", ty->type); l = simplify(SUB+I, inttype, cast(l,unsignedtype),cast(r,unsignedtype)); return simplify(DIV+I,inttype,l, consttree(n,inttype)); }else typeerror(op,l,r); DEBUG(fprint(2,"subtree end\n")); return simplify(op, ty,l,r);}/*multree:處理乘法,除法,求余運算*/static Tree multree(int op, Tree l, Tree r){ Type ty = inttype; if(isarith(l->type) && isarith(r->type)) { l = cast(l, inttype); r = cast(r, inttype); }else typeerror(op, l, r); return simplify(op, ty, l, r);}void typeerror(int op, Tree l, Tree r){ int i; static struct {int op; char *name;} ops[] = { {ASGN, "="}, {INDIR, "*"}, {NEG, "-"}, {ADD, "+"}, {SUB, "-"}, {MOD, "%"}, {DIV, "/"}, {MUL, "*"}, {EQ, "=="}, {GE, ">="}, {GT, ">"}, {LE, "<="}, {LT, "<"}, {NE, "!="}, {NOT, "!"}, {0,0} }; op = generic(op); for(i = 0; ops[i].op; i++) if(op == ops[i].op) break; assert(ops[i].name); if(r) error("operands of %s have illegal types '%t' and '%t'\n", ops[i].name, l->type, r->type); else error("operand of unary %s has illegal type '%t'\n", ops[i].name,l->type); }
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -