int cmdexec(File *f, Cmd *cp) { int i; Addr *ap; Address a; if(f && f->state==Unread) load(f); if(f==0 && (cp->addr==0 || cp->addr->type!='"') && !wcschr(L"bBnqUXY!", (wchar_t)cp->cmdc) && cp->cmdc!=('c'|0x100) && !(cp->cmdc=='D' && cp->ctext)) error(Enofile); i = lookup(cp->cmdc); if(i >= 0 && cmdtab[i].defaddr != aNo){ if((ap=cp->addr)==0 && cp->cmdc!='\n'){ cp->addr = ap = newaddr(); ap->type = '.'; if(cmdtab[i].defaddr == aAll) ap->type = '*'; }else if(ap && ap->type=='"' && ap->next==0 && cp->cmdc!='\n'){ ap->next = newaddr(); ap->next->type = '.'; if(cmdtab[i].defaddr == aAll) ap->next->type = '*'; } if(cp->addr){ /* may be false for '\n' (only) */ static Address none = {{0,0},0}; if(f) addr = address(ap, f->dot, 0); else /* a " */ addr = address(ap, none, 0); f = addr.f; } } current(f); switch(cp->cmdc){ case '{': a = cp->addr? address(cp->addr, f->dot, 0): f->dot; for(cp = cp->ccmd; cp; cp = cp->next){ a.f->dot = a; cmdexec(a.f, cp); } break; default: i=(*cmdtab[i].fn)(f, cp); return i; } return 1; }
/** * 函数名:translate_struct * 作者:ao * 功能:翻译结构体的中间代码 */ Operand translate_struct(Operand op,Type type) { InterCode IC = (InterCode)malloc(sizeof(InterCode_)); IC->kind = _BINOP; IC->u.binop.result = newaddr(0); IC->u.binop.op1 = op; IC->u.binop.op2 = newiconst(_sizeof(0,type)); strcpy(IC->u.binop.o_kind,"+"); emit(IC); return IC->u.binop.result; }
Addr * compoundaddr(void) { Addr addr; Addr *ap, *next; addr.left = simpleaddr(); if((addr.type = skipbl())!=',' && addr.type!=';') return addr.left; getch(); next = addr.next = compoundaddr(); if(next && (next->type==',' || next->type==';') && next->left==0) error(Eaddress); ap = newaddr(); *ap = addr; return ap; }
Addr * simpleaddr(void) { Addr addr; Addr *ap, *nap; addr.next = 0; addr.left = 0; switch(skipbl()){ case '#': addr.type = getch(); addr.num = getnum(1); break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': addr.num = getnum(1); addr.type='l'; break; case '/': case '?': case '"': addr.are = getregexp(addr.type = getch()); break; case '.': case '$': case '+': case '-': case '\'': addr.type = getch(); break; default: return 0; } if(addr.next = simpleaddr()) switch(addr.next->type){ case '.': case '$': case '\'': if(addr.type!='"') case '"': error(Eaddress); break; case 'l': case '#': if(addr.type=='"') break; /* fall through */ case '/': case '?': if(addr.type!='+' && addr.type!='-'){ /* insert the missing '+' */ nap = newaddr(); nap->type='+'; nap->next = addr.next; addr.next = nap; } break; case '+': case '-': break; default: panic("simpleaddr"); } ap = newaddr(); *ap = addr; return ap; }