static int isval(Node *n, vlong val) { vlong v; if (!islit(n, &v)) return 0; return v == val; }
bool matcher::matchop_lt(expression * e, matchable * item) { if (!item->has_attribute(e->name)) throw matcherexception(matcherexception::ATTRIB_UNAVAIL, e->name); std::istringstream islit(e->literal); std::istringstream isatt(item->get_attribute(e->name)); int ilit, iatt; islit >> ilit; isatt >> iatt; return iatt < ilit; }
static int exec_cond(int op, int arg1, int arg2) { int i; switch(op) { /* First the conditions */ case 0: cret(loc+first_room==arg1); /* AtLoc(Room) */ case 1: cret(loc+first_room>arg1); case 2: cret(loc+first_room<arg1); case 3: return musiccmd(-1,-1); /* SongPlaying */ case 4: return musiccmd(-2,-1); /* SoundIsOn */ case 5: cret(vb<=13 && vb>0 && room[loc].path[vb-1]>=first_room);/*DirOK*/ case 6: cret(vb==arg1); /* DirectionIs */ case 7: cret(loc+first_room>=arg1 && loc+first_room<=arg2); /* BetweenRooms ?? */ case 8: cret(room[arg1-first_room].seen); case 9: /* Entered Object? i.e. is iobj valid */ cret(do_disambig==1 || iobj>0); case 10: cret(curr_time>arg1); /* TimeGT */ case 11: cret(curr_time<arg1); /* TimeLT */ case 12: cret(first_visit_flag); case 13: cret(newlife_flag); case 14: cret(player_contents!=0); /* CarrySome */ case 15: cret(player_contents==0); /* CarryNo */ case 16: cret(player_worn!=0); /* WearSome */ case 18: cret(player_worn==0); /* WearNo */ case 17: /* CarryTreas */ contloop(i,1) if (tnoun(i) && noun[i-first_noun].points>=arg1) return 1; contloop(i,1000) if (tnoun(i) && noun[i-first_noun].points>=arg1) return 1; return 0; case 19:cret(totwt==arg1); case 20:cret(totwt>arg1); case 21:cret(totwt<arg1); case 22: case 23: case 24: case 25: case 26: case 27: case 28: return obj_cond(op-22,arg1,arg2); case 29:cret(it_loc(arg1)==it_loc(arg2)); case 30: case 31: return obj_cond(op-23,arg1,arg2); case 32:cret(it_group(arg1)); case 33: case 34: case 35: case 36: case 37: case 38: case 39: case 40: return obj_cond(op-24,arg1,arg2); case 41: case 42: case 43: case 44: case 45: case 46: case 47: case 48: case 49: case 50: case 51: case 52: case 53: case 54: case 55: case 56: case 57: return obj_cond(op-41,dobj,arg1); case 58:cretn(dobj,points==arg1); case 59:cretn(dobj,points>arg1); case 60:cretn(dobj,points<arg1); case 61:cretn(dobj,weight==arg1); case 62:cretn(dobj,weight>arg1); case 63:cretn(dobj,weight<arg1); case 64:cret(islit()); case 65:cret(room[loc].light!=0); case 66:cret(flag[arg1]); case 67:cret(!flag[arg1]); case 68:cret(room[loc].flag_noun_bits & (1 << (arg1-1) ) ); case 70:cret( !(room[loc].flag_noun_bits & (1 << (arg1-1) ) )); case 69:cret(room[loc].PIX_bits & (1 << (arg1-1) )); /* Room Pix here? */ case 71:cret(tscore==arg1); case 72:cret(tscore>arg1); case 73:cret(tscore<arg1); case 74:cret(agt_number==arg1); case 75:cret(agt_number>arg1); case 76:cret(agt_number<arg1); case 77:cret(agt_answer); case 78:cret(!agt_answer); case 79:cret(turncnt==arg1); case 80:cret(turncnt>arg1); case 81:cret(turncnt<arg1); case 82:cret(cnt_val(agt_counter[arg1])==arg2); case 83:cret(cnt_val(agt_counter[arg1])>arg2); case 84:cret(cnt_val(agt_counter[arg1])<arg2); case 85:cret(agt_var[arg1]==arg2); case 86:cret(agt_var[arg1]>arg2); case 87:cret(agt_var[arg1]<arg2); case 88:cret(agt_var[arg1]<agt_var[arg2]); case 89:cret(agt_var[arg1]<agt_rand(1,arg2)); case 90:cret( (actor!=0) && (it_loc(actor)==loc+first_room)); case 91:cret(actor==arg1); case 92:cret(dobj==arg1); case 93:cret(do_disambig==1 || iobj==arg1); case 94:cret(it_contents(arg1)!=0); case 95:cret(agt_rand(1,100)<=arg1); case 96:cret(yesno("Yes or no? ")); case 97:cret(!yesno("Yes or no? ")); case 98:cret(vb>0 && vb<=13); case 99:cret(tcreat(dobj)); case 100:cretc(dobj,gender==2); /* man */ case 101:cretc(dobj,gender==1); /* woman */ case 102:cretc(dobj,gender==0); /* thing */ case 103:cretc(iobj,gender==2); case 104:cretc(iobj,gender==1); /* woman */ case 105:cretc(iobj,gender==0); /* thing */ case 106:cret(do_disambig==1 || tcreat(iobj)); case 107:return (do_disambig==1 || obj_cond(0,iobj,0)); /* OR and NOT are handled higher up. */ /* The following are all v1.8x metacommands */ case 110:cret(beforecmd); case 111:cret(!beforecmd); case 112:cret(curr_time/100==arg1); /* HoursEqual */ case 113:cret(curr_time/100>arg1); case 114:cret(curr_time/100<arg1); case 115:cret(curr_time%100==arg1); /* MinutesEqual */ case 116:cret(curr_time%100>arg1); case 117:cret(curr_time%100<arg1); case 118:cret(curr_time<1200); /* IsAM */ case 119:cret(do_disambig); /* OnDisambig */ case 120:cretc(arg1,hostile); /* IsHostile */ case 121: /* HostilePresent */ creatloop(i) if (creature[i].location==loc+first_room && creature[i].hostile) return 1; return 0; /* Otherwise, we're in trouble. */ case 122: cret(actor_in_scope); /* NameWasPresent */ case 123: /* OncePerTurn */ if (beforecmd) cret(start_of_turn); else cret(end_of_turn); case 124: /* IsClass */ cret(arg2==0 || matchclass(arg1,arg2)); case 125: cret(getattr(arg1,arg2)); /* IsSet */ case 126: cret(is_numeric(dobj_rec)); case 127: cret(is_numeric(iobj_rec)); case 128: cret(arg1==arg2); case 129: cret(arg1>arg2); case 130: cret(arg1<arg2); case 131: cret(arg1>=arg2); case 132: cret(arg1<=arg2); case 133: cret(strcmp(userstr[arg1-1],userstr[arg2-1])==0); case 134: cret(strcmp(userstr[arg1-1],userstr[arg2-1])<0); case 135: cret(strcmp(userstr[arg1-1],userstr[arg2-1])>0); case 136: cret(strcasecmp(userstr[arg1-1],userstr[arg2-1])==0); case 137: cret(strcasecmp(userstr[arg1-1],userstr[arg2-1])<0); case 138: cret(strcasecmp(userstr[arg1-1],userstr[arg2-1])>0); case 139: cret(match_answer(rstrdup(userstr[arg1-1]),arg2-1)); /* Note that match_answer rfrees it's first argument */ case 140: cret(it_seen(arg1)); case 141: cret(op_objflag(2,arg1,arg2)); case 142: cret(!op_objflag(2,arg1,arg2)); case 143: i=it_room(arg1); cret( troom(i) && troom(room[i-first_room].path[arg2-1]) ); default: writeln("INTERNAL ERROR: Condition token not supported."); rprintf("Condition #%d",op); writeln(""); return 0; } }
Node *fold(Node *n, int foldvar) { Node **args, *r; Type *t; vlong a, b; size_t i; if (!n) return NULL; if (n->type != Nexpr) return n; r = NULL; args = n->expr.args; for (i = 0; i < n->expr.nargs; i++) args[i] = fold(args[i], foldvar); switch (exprop(n)) { case Ovar: if (foldvar && issmallconst(decls[n->expr.did])) r = fold(decls[n->expr.did]->decl.init, foldvar); break; case Oadd: /* x + 0 = 0 */ if (isval(args[0], 0)) r = args[1]; if (isval(args[1], 0)) r = args[0]; if (islit(args[0], &a) && islit(args[1], &b)) r = val(n->line, a + b, exprtype(n)); break; case Osub: /* x - 0 = 0 */ if (isval(args[1], 0)) r = args[0]; if (islit(args[0], &a) && islit(args[1], &b)) r = val(n->line, a - b, exprtype(n)); break; case Omul: /* 1 * x = x */ if (isval(args[0], 1)) r = args[1]; if (isval(args[1], 1)) r = args[0]; /* 0 * x = 0 */ if (isval(args[0], 0)) r = args[0]; if (isval(args[1], 0)) r = args[1]; if (islit(args[0], &a) && islit(args[1], &b)) r = val(n->line, a * b, exprtype(n)); break; case Odiv: /* x/1 = x */ if (isval(args[1], 1)) r = args[0]; /* 0/x = 0 */ if (isval(args[1], 0)) r = args[1]; if (islit(args[0], &a) && islit(args[1], &b)) r = val(n->line, a / b, exprtype(n)); break; case Omod: /* x%1 = x */ if (isval(args[1], 0)) r = args[0]; if (islit(args[0], &a) && islit(args[1], &b)) r = val(n->line, a % b, exprtype(n)); break; case Oneg: if (islit(args[0], &a)) r = val(n->line, -a, exprtype(n)); break; case Obsl: if (islit(args[0], &a) && islit(args[1], &b)) r = val(n->line, a << b, exprtype(n)); break; case Obsr: if (islit(args[0], &a) && islit(args[1], &b)) r = val(n->line, a >> b, exprtype(n)); break; case Obor: if (islit(args[0], &a) && islit(args[1], &b)) r = val(n->line, a | b, exprtype(n)); break; case Oband: if (islit(args[0], &a) && islit(args[1], &b)) r = val(n->line, a & b, exprtype(n)); break; case Obxor: if (islit(args[0], &a) && islit(args[1], &b)) r = val(n->line, a ^ b, exprtype(n)); break; case Omemb: t = tybase(exprtype(args[0])); /* we only fold lengths right now */ if (t->type == Tyarray && !strcmp(namestr(args[1]), "len")) r = t->asize; break; case Ocast: r = foldcast(n); break; default: break; } if (r) return r; else return n; }