static Node * mkcast(SrcPos *p, Node *o, CTy *to) { Node *n; if(sametype(o->type, to)) return o; n = mknode(NCAST, p); n->type = to; n->Cast.operand = o; return n; }
void dpcheck(Node *n) { char *s; Node *a, *b; Tname *l; int i; if(n == Z) return; b = n->left; if(b == Z || b->op != ONAME) return; s = b->sym->name; for(l=tname; l; l=l->link) if(strcmp(s, l->name) == 0) break; if(l == 0) return; i = l->param; a = nil; b = n->right; a = Z; while(i > 0) { b = nextarg(b, &a); i--; } if(a == Z) { warn(n, "cant find format arg"); return; } if(!sametype(indchar, a->type)) { warn(n, "format arg type %T", a->type); return; } if(a->op != OADDR || a->left->op != ONAME || a->left->sym != symstring) { /* warn(n, "format arg not constant string");*/ return; } s = a->left->cstring; checkargs(b, s, l->param); }
static CTy * usualarithconv(Node **a, Node **b) { Node **large, **small; CTy *t; if(!isarithtype((*a)->type) || !isarithtype((*b)->type)) panic("internal error\n"); if(convrank((*a)->type) < convrank((*b)->type)) { large = a; small = b; } else { large = b; small = a; } if(isftype((*large)->type)) { *small = mkcast(&(*small)->pos, *small, (*large)->type); return (*large)->type; } *large = ipromote(*large); *small = ipromote(*small); if(sametype((*large)->type, (*small)->type)) return (*large)->type; if((*large)->type->Prim.issigned == (*small)->type->Prim.issigned ) { *small = mkcast(&(*small)->pos, *small, (*large)->type); return (*large)->type; } if(!(*large)->type->Prim.issigned) { *small = mkcast(&(*small)->pos, *small, (*large)->type); return (*large)->type; } if((*large)->type->Prim.issigned && canrepresent((*large)->type, (*small)->type)) { *small = mkcast(&(*small)->pos, *small, (*large)->type); return (*large)->type; } t = gcmalloc(sizeof(CTy)); *t = *((*large)->type); t->Prim.issigned = 0; *large = mkcast(&(*large)->pos, *large, t); *small = mkcast(&(*small)->pos, *small, t); return t; }
void newprot(Sym *m, Type *t, char *s) { Bits flag; Tprot *l; if(t == T) { warn(Z, "%s: newprot: type not defined", m->name); return; } flag = getflag(s); for(l=tprot; l; l=l->link) if(beq(flag, l->flag) && sametype(t, l->type)) return; l = alloc(sizeof(*l)); l->type = t; l->flag = flag; l->link = tprot; tprot = l; }
void checkargs(Node *nn, char *s, int pos) { Node *a, *n; Bits flag; Tprot *l; if(!debug['F']) return; n = nn; for(;;) { s = strchr(s, '%'); if(s == 0) { nextarg(n, &a); if(a != Z) warn(nn, "more arguments than format %T", a->type); return; } s++; flag = getflag(s); while(nstar > 0) { n = nextarg(n, &a); pos++; nstar--; if(a == Z) { warn(nn, "more format than arguments %s", fmtbuf); return; } if(a->type == T) continue; if(!sametype(types[TINT], a->type) && !sametype(types[TUINT], a->type)) warn(nn, "format mismatch '*' in %s %T, arg %d", fmtbuf, a->type, pos); } for(l=tprot; l; l=l->link) if(sametype(types[TVOID], l->type)) { if(beq(flag, l->flag)) { s++; goto loop; } } n = nextarg(n, &a); pos++; if(a == Z) { warn(nn, "more format than arguments %s", fmtbuf); return; } if(a->type == 0) continue; for(l=tprot; l; l=l->link) if(sametype(a->type, l->type)) { /*print("checking %T/%ulx %T/%ulx\n", a->type, flag.b[0], l->type, l->flag.b[0]);*/ if(beq(flag, l->flag)) goto loop; } warn(nn, "format mismatch %s %T, arg %d", fmtbuf, a->type, pos); loop:; } }
static Sym * definesym(SrcPos *p, int sclass, char *name, CTy *type, Node *n) { Sym *sym; if(sclass == SCAUTO || n != 0) if(type->incomplete) errorposf(p, "cannot use incomplete type in this context"); if(sclass == SCAUTO && isglobal()) errorposf(p, "defining local symbol in global scope"); sym = mapget(syms[nscopes - 1], name); if(sym) { switch(sym->k) { case SYMTYPE: if(sclass != SCTYPEDEF || !sametype(sym->type, type)) errorposf(p, "incompatible redefinition of typedef %s", name); break; case SYMGLOBAL: if(sym->Global.sclass != sclass) errorposf(p, "redefinition of %s with differing storage class", name); if(sym->init && n) errorposf(p, "%s already initialized", name); if(!sym->init && n) { sym->init = n; emitsym(sym); removetentativesym(sym); } break; default: errorposf(p, "redefinition of %s", name); } return sym; } sym = gcmalloc(sizeof(Sym)); sym->name = name; sym->type = type; sym->init = n; switch(sclass) { case SCAUTO: sym->k = SYMLOCAL; sym->Local.slot = gcmalloc(sizeof(StkSlot)); sym->Local.slot->size = sym->type->size; sym->Local.slot->align = sym->type->align; vecappend(curfunc->Func.stkslots, sym->Local.slot); break; case SCTYPEDEF: sym->k = SYMTYPE; break; case SCGLOBAL: sym->k = SYMGLOBAL; sym->Global.label = name; sym->Global.sclass = SCGLOBAL; break; case SCSTATIC: sym->k = SYMGLOBAL; sym->Global.label = newlabel(); sym->Global.sclass = SCSTATIC; break; } if(sym->k == SYMGLOBAL) { if(sym->init) emitsym(sym); else if(!isfunc(sym->type)) addtentativesym(sym); } if(!define(syms, name, sym)) panic("internal error"); return sym; }
int main() { int tcase; int i,j; scanf("%d", &tcase); while(tcase--) { char buf[LIMIT] = {}; int buflen; struct data s[LIMIT] = {}; int s_idx=0; struct data nums[LIMIT] = {}; int nums_idx=0; int b_close = 0; int temp=0, error=0; scanf("%s", buf); buflen = strlen(buf); // printf("start\n"); for(i=0;i<buflen;i++) { if(OPEN(buf[i])) { s[s_idx].data = buf[i]; s[s_idx++].index = i; b_close = 0; } else if(sametype(s[s_idx-1].data, buf[i])) { temp = 0; if(b_close) { while(nums[nums_idx-1].index > s[s_idx-1].index) { temp += nums[--nums_idx].data; // printf("add %d to temp : %d\n", nums[nums_idx+1].data, temp); } temp *= bton(s[--s_idx].data); nums[nums_idx++].data = temp; // printf("multi data temp %d\n", temp); } else { nums[nums_idx].data = bton(s[s_idx-1].data); nums[nums_idx++].index = s[--s_idx].index; /* printf("push num stack %d index %d\n", nums[nums_idx-1].data, nums[nums_idx-1].index); for(j=0;j<nums_idx;j++) { printf("%d ", nums[j].data); } putchar ('\n'); */ } b_close = 1; } else { printf("0\n"); error = 1; break; } } if(error) continue; /* for(j=0;j<nums_idx;j++) { printf("%d ", nums[j].data); } putchar ('\n');*/ if(s_idx){ printf("0\n"); continue; } temp = 0; while(nums_idx--) { temp += nums[nums_idx].data; } printf("%d\n", temp); } return 0; }
int sametype(CTy *l, CTy *r) { int i; NameTy *lnt, *rnt; StructMember *lsm, *rsm; if(l == r) return 1; switch(l->t) { case CENUM: if(r->t != CENUM) return 0; return 1; case CVOID: if(r->t != CVOID) return 0; return 1; case CPRIM: if(r->t != CPRIM) return 0; if(l->Prim.issigned != r->Prim.issigned) return 0; if(l->Prim.type != r->Prim.type) return 0; return 1; case CPTR: if(r->t != CPTR) return 0; return sametype(l->Ptr.subty, r->Ptr.subty); case CFUNC: if(r->t != CFUNC) return 0; if(!sametype(l->Func.rtype, r->Func.rtype)) return 0; if(l->Func.isvararg != r->Func.isvararg) return 0; if(l->Func.params->len != r->Func.params->len) return 0; for(i = 0; i < l->Func.params->len; i++) { lnt = vecget(l->Func.params, i); rnt = vecget(r->Func.params, i); if(!sametype(lnt->type, rnt->type)) return 0; } return 1; case CSTRUCT: if(r->t != CSTRUCT) return 0; if(l->incomplete || r->incomplete) return l->incomplete == r->incomplete; if(l->Struct.members->len != r->Struct.members->len) return 0; for(i = 0; i < l->Struct.members->len; i++) { lsm = vecget(l->Struct.members, i); rsm = vecget(r->Struct.members, i); if(!sametype(lsm->type, rsm->type)) return 0; } return 1; case CARR: if(r->t != CARR) return 0; if(r->Arr.dim != l->Arr.dim) return 0; return 1; default: panic("unimplemented same type"); } return 0; }