#include "config.h" #include "object.h" #include "construct.h" #include "instr.h" #include "operproto.h" #include "operdefine.h" #include "globals.h" #include "cache.h" int comma_oper(struct object *caller, struct object *obj, struct object *player, struct var_stack **rts) { struct var tmp; if (pop(&tmp,rts,obj)) return 1; clear_var(&tmp); if (pop(&tmp,rts,obj)) return 1; pushnocopy(&tmp,rts); return 0; } int eq_oper(struct object *caller, struct object *obj, struct object *player, struct var_stack **rts) { struct var tmp1,tmp2; int loop; struct ref_list *tmpref; if (pop(&tmp2,rts,obj)) return 1; if (pop(&tmp1,rts,obj)) { clear_var(&tmp2); return 1; } if (tmp1.type!=GLOBAL_L_VALUE && tmp1.type!=LOCAL_L_VALUE) { clear_var(&tmp1); clear_var(&tmp2); return 1; } if (tmp1.value.l_value.size!=1) { clear_var(&tmp2); return 1; } if (resolve_var(&tmp2,obj)) return 1; if (tmp1.type==GLOBAL_L_VALUE) { obj->obj_state=DIRTY; if (tmp2.type==OBJECT) { load_data(tmp2.value.objptr); tmp2.value.objptr->obj_state=DIRTY; tmpref=MALLOC(sizeof(struct ref_list)); tmpref->ref_obj=obj; tmpref->ref_num=tmp1.value.l_value.ref; tmpref->next=tmp2.value.objptr->refd_by; tmp2.value.objptr->refd_by=tmpref; } clear_global_var(obj,tmp1.value.l_value.ref); obj->globals[tmp1.value.l_value.ref]=tmp2; } else { clear_var(&(locals[tmp1.value.l_value.ref])); locals[tmp1.value.l_value.ref]=tmp2; } push(&tmp2,rts); return 0; } EQ_INT_OPER(intaddeq, += ) int pleq_oper(struct object *caller, struct object *obj, struct object *player, struct var_stack **rts) { struct var tmp1,tmp2; char *tmpstr; int tmp2_not_int; if (pop(&tmp2,rts,obj)) return 1; if (pop(&tmp1,rts,obj)) { clear_var(&tmp2); return 1; } if (tmp1.type!=GLOBAL_L_VALUE && tmp1.type!=LOCAL_L_VALUE) { clear_var(&tmp2); clear_var(&tmp1); return 1; } if (tmp1.value.l_value.size!=1) { clear_var(&tmp2); return 1; } if (resolve_var(&tmp2,obj)) { clear_var(&tmp1); clear_var(&tmp2); return 1; } if (tmp1.type==GLOBAL_L_VALUE) { if (tmp2.type==INTEGER && obj->globals[tmp1.value.l_value.ref].type== INTEGER) { push(&tmp1,rts); push(&tmp2,rts); return intaddeq(caller,obj,player,rts); } if (tmp2.type==INTEGER && tmp2.value.integer==0) { tmp2.type=STRING; tmp2.value.string=copy_string(""); } if (tmp2.type==STRING) { if (obj->globals[tmp1.value.l_value.ref].type==INTEGER && obj->globals [tmp1.value.l_value.ref].value.integer==0) { obj->globals[tmp1.value.l_value.ref].type=STRING; obj->globals[tmp1.value.l_value.ref].value.string=copy_string(""); } } if (tmp2.type!=STRING || obj->globals[tmp1.value.l_value.ref].type!= STRING) { clear_var(&tmp1); clear_var(&tmp2); return 1; } tmpstr=MALLOC(strlen(obj->globals[tmp1.value.l_value.ref].value.string)+ strlen(tmp2.value.string)+1); strcat(strcpy(tmpstr,obj->globals[tmp1.value.l_value.ref].value.string), tmp2.value.string); clear_global_var(obj,tmp1.value.l_value.ref); obj->globals[tmp1.value.l_value.ref].type=STRING; obj->globals[tmp1.value.l_value.ref].value.string=tmpstr; obj->obj_state=DIRTY; } else { if (tmp2.type==INTEGER && locals[tmp1.value.l_value.ref].type==INTEGER) { push(&tmp1,rts); push(&tmp2,rts); return intaddeq(caller,obj,player,rts); } if (tmp2.type==INTEGER && tmp2.value.integer==0) { tmp2.type=STRING; tmp2.value.string=copy_string(""); } if (tmp2.type==STRING) { if (locals[tmp1.value.l_value.ref].type==INTEGER && locals[tmp1.value. l_value.ref].value.integer==0) { locals[tmp1.value.l_value.ref].type=STRING; locals[tmp1.value.l_value.ref].value.string=copy_string(""); } } if (tmp2.type!=STRING || locals[tmp1.value.l_value.ref].type!= STRING) { clear_var(&tmp1); clear_var(&tmp2); return 1; } tmpstr=MALLOC(strlen(locals[tmp1.value.l_value.ref].value.string)+ strlen(tmp2.value.string)+1); strcat(strcpy(tmpstr,locals[tmp1.value.l_value.ref].value.string), tmp2.value.string); clear_var(&(locals[tmp1.value.l_value.ref])); locals[tmp1.value.l_value.ref].type=STRING; locals[tmp1.value.l_value.ref].value.string=tmpstr; } clear_var(&tmp1); clear_var(&tmp2); tmp1.type=STRING; tmp1.value.string=tmpstr; push(&tmp1,rts); return 0; } int cond_oper(struct object *caller, struct object *obj, struct object *player, struct var_stack **rts) { return 0; } int or_oper(struct object *caller, struct object *obj, struct object *player, struct var_stack **rts) { struct var tmp1,tmp2; int t1,t2; if (pop(&tmp2,rts,obj)) return 1; if (pop(&tmp1,rts,obj)) { clear_var(&tmp2); return 1; } if (resolve_var(&tmp1,obj)) { clear_var(&tmp1); clear_var(&tmp2); return 1; } if (resolve_var(&tmp2,obj)) { clear_var(&tmp1); clear_var(&tmp2); return 1; } t1=!(tmp1.type==INTEGER && tmp1.value.integer==0); t2=!(tmp2.type==INTEGER && tmp2.value.integer==0); clear_var(&tmp1); clear_var(&tmp2); tmp1.type=INTEGER; tmp1.value.integer=(t1 || t2); push(&tmp1,rts); return 0; } int and_oper(struct object *caller, struct object *obj, struct object *player, struct var_stack **rts) { struct var tmp1,tmp2; int t1,t2; if (pop(&tmp2,rts,obj)) return 1; if (pop(&tmp1,rts,obj)) { clear_var(&tmp2); return 1; } if (resolve_var(&tmp1,obj)) { clear_var(&tmp1); clear_var(&tmp2); return 1; } if (resolve_var(&tmp2,obj)) { clear_var(&tmp1); clear_var(&tmp2); return 1; } t1=!(tmp1.type==INTEGER && tmp1.value.integer==0); t2=!(tmp2.type==INTEGER && tmp2.value.integer==0); clear_var(&tmp1); clear_var(&tmp2); tmp1.type=INTEGER; tmp1.value.integer=(t1 && t2); push (&tmp1,rts); return 0; } int condeq_oper(struct object *caller, struct object *obj, struct object *player, struct var_stack **rts) { struct var tmp1,tmp2; int result; if (pop(&tmp2,rts,obj)) return 1; if (pop(&tmp1,rts,obj)) { clear_var(&tmp2); return 1; } if (resolve_var(&tmp1,obj)) { clear_var(&tmp1); clear_var(&tmp2); return 1; } if (resolve_var(&tmp2,obj)) { clear_var(&tmp1); clear_var(&tmp2); return 1; } if (tmp1.type==STRING && tmp2.type==STRING) { result=(!strcmp(tmp1.value.string,tmp2.value.string)); clear_var(&tmp1); clear_var(&tmp2); tmp1.type=INTEGER; tmp1.value.integer=result; push(&tmp1,rts); return 0; } result=(tmp1.type==tmp2.type && ((tmp1.type==INTEGER && tmp1.value.integer==tmp2.value.integer) || (tmp1.type==OBJECT && tmp1.value.objptr==tmp2.value.objptr))); clear_var(&tmp1); clear_var(&tmp2); tmp1.type=INTEGER; tmp1.value.integer=result; push(&tmp1,rts); return 0; } int noteq_oper(struct object *caller,struct object *obj, struct object *player, struct var_stack **rts) { struct var tmp; if (condeq_oper(caller,obj,player,rts)) return 1; if (pop(&tmp,rts,obj)) return 1; if (tmp.type!=INTEGER) { clear_var(&tmp); return 1; } tmp.value.integer=!(tmp.value.integer); push(&tmp,rts); return 0; } BI_INT_OPER(intadd, + ) int add_oper(struct object *caller, struct object *obj, struct object *player, struct var_stack **rts) { struct var tmp1,tmp2; char *tmpstr; if (pop(&tmp2,rts,obj)) return 1; if (pop(&tmp1,rts,obj)) { clear_var(&tmp2); return 1; } if (resolve_var(&tmp1,obj)) { clear_var(&tmp1); clear_var(&tmp2); return 1; } if (resolve_var(&tmp2,obj)) { clear_var(&tmp1); clear_var(&tmp2); return 1; } if (tmp1.type==INTEGER && tmp2.type==INTEGER) { push(&tmp1,rts); push(&tmp2,rts); return intadd(caller,obj,player,rts); } if (tmp1.type==INTEGER && tmp1.value.integer==0) { tmp1.type=STRING; tmp1.value.string=copy_string(""); } if (tmp2.type==INTEGER && tmp2.value.integer==0) { tmp2.type=STRING; tmp2.value.string=copy_string(""); } if (tmp2.type!=STRING || tmp1.type!=STRING) { clear_var(&tmp1); clear_var(&tmp2); return 1; } tmpstr=MALLOC(strlen(tmp1.value.string)+strlen(tmp2.value.string)+1); strcat(strcpy(tmpstr,tmp1.value.string),tmp2.value.string); clear_var(&tmp1); clear_var(&tmp2); tmp1.type=STRING; tmp1.value.string=tmpstr; pushnocopy(&tmp1,rts); return 0; }