diff --git a/src/operators.c b/src/operators.c index 8a646d73c6bc28533253debfd9bd235633696f53..c407413987f1c01c252e1e809588a9cdbefabf9b 100644 --- a/src/operators.c +++ b/src/operators.c @@ -6,7 +6,7 @@ /**/ #include "global.h" #include <math.h> -RCSID("$Id: operators.c,v 1.88 2000/04/08 15:29:02 grubba Exp $"); +RCSID("$Id: operators.c,v 1.89 2000/04/12 11:14:50 mirar Exp $"); #include "interpret.h" #include "svalue.h" #include "multiset.h" @@ -652,12 +652,45 @@ static int call_lfun(int left, int right) return 0; } +struct mapping *merge_mapping_array_ordered(struct mapping *a, + struct array *b, INT32 op); +struct mapping *merge_mapping_array_unordered(struct mapping *a, + struct array *b, INT32 op); + void o_subtract(void) { if (sp[-2].type != sp[-1].type && !float_promote()) { if(call_lfun(LFUN_SUBTRACT, LFUN_RSUBTRACT)) return; + + if (sp[-2].type==T_MAPPING) + switch (sp[-1].type) + { + case T_ARRAY: + { + struct mapping *m; + + m=merge_mapping_array_unordered(sp[-2].u.mapping, + sp[-1].u.array, + PIKE_ARRAY_OP_SUB); + pop_n_elems(2); + push_mapping(m); + return; + } + case T_MULTISET: + { + struct mapping *m; + + m=merge_mapping_array_ordered(sp[-2].u.mapping, + sp[-1].u.multiset->ind, + PIKE_ARRAY_OP_SUB); + pop_n_elems(2); + push_mapping(m); + return; + } + } + bad_arg_error("`-", sp-2, 2, 2, get_name_of_type(sp[-2].type), sp-1, "Subtract on different types.\n"); } @@ -782,44 +815,76 @@ void o_and(void) { if(sp[-1].type != sp[-2].type) { - if(call_lfun(LFUN_AND, LFUN_RAND)) { - return; - } else if (((sp[-1].type == T_TYPE) || (sp[-1].type == T_PROGRAM) || - (sp[-1].type == T_FUNCTION)) && - ((sp[-2].type == T_TYPE) || (sp[-2].type == T_PROGRAM) || - (sp[-2].type == T_FUNCTION))) { - if (sp[-2].type != T_TYPE) { - struct program *p = program_from_svalue(sp - 2); - if (!p) { - int args = 2; - SIMPLE_BAD_ARG_ERROR("`&", 1, "type"); + if(call_lfun(LFUN_AND, LFUN_RAND)) + return; + else if (((sp[-1].type == T_TYPE) || (sp[-1].type == T_PROGRAM) || + (sp[-1].type == T_FUNCTION)) && + ((sp[-2].type == T_TYPE) || (sp[-2].type == T_PROGRAM) || + (sp[-2].type == T_FUNCTION))) + { + if (sp[-2].type != T_TYPE) + { + struct program *p = program_from_svalue(sp - 2); + if (!p) { + int args = 2; + SIMPLE_BAD_ARG_ERROR("`&", 1, "type"); + } + type_stack_mark(); + push_type_int(p->id); + push_type(0); + push_type(T_OBJECT); + free_svalue(sp - 2); + sp[-2].u.string = pop_unfinished_type(); + sp[-2].type = T_TYPE; } - type_stack_mark(); - push_type_int(p->id); - push_type(0); - push_type(T_OBJECT); - free_svalue(sp - 2); - sp[-2].u.string = pop_unfinished_type(); - sp[-2].type = T_TYPE; - } - if (sp[-1].type != T_TYPE) { - struct program *p = program_from_svalue(sp - 1); - if (!p) { - int args = 2; - SIMPLE_BAD_ARG_ERROR("`&", 2, "type"); + if (sp[-1].type != T_TYPE) + { + struct program *p = program_from_svalue(sp - 1); + if (!p) + { + int args = 2; + SIMPLE_BAD_ARG_ERROR("`&", 2, "type"); + } + type_stack_mark(); + push_type_int(p->id); + push_type(0); + push_type(T_OBJECT); + free_svalue(sp - 1); + sp[-1].u.string = pop_unfinished_type(); + sp[-1].type = T_TYPE; } - type_stack_mark(); - push_type_int(p->id); - push_type(0); - push_type(T_OBJECT); - free_svalue(sp - 1); - sp[-1].u.string = pop_unfinished_type(); - sp[-1].type = T_TYPE; - } - } else { - int args = 2; - SIMPLE_BAD_ARG_ERROR("`&", 2, get_name_of_type(sp[-2].type)); - } + } + else if (sp[-2].type==T_MAPPING) + switch (sp[-1].type) + { + case T_ARRAY: + { + struct mapping *m; + + m=merge_mapping_array_unordered(sp[-2].u.mapping, + sp[-1].u.array, + PIKE_ARRAY_OP_AND); + pop_n_elems(2); + push_mapping(m); + return; + } + case T_MULTISET: + { + struct mapping *m; + + m=merge_mapping_array_ordered(sp[-2].u.mapping, + sp[-1].u.multiset->ind, + PIKE_ARRAY_OP_AND); + pop_n_elems(2); + push_mapping(m); + return; + } + } + else + { + int args = 2; + SIMPLE_BAD_ARG_ERROR("`&", 2, get_name_of_type(sp[-2].type)); + } } switch(sp[-2].type) @@ -2514,27 +2579,59 @@ void init_operators(void) tFuncV(tOr(tInt,tFlt),tOr(tInt,tFlt),tFlt)), tFuncV(tArr(tSetvar(0,tMix)),tArray,tArr(tVar(0))), tFuncV(tMap(tSetvar(1,tMix),tSetvar(2,tMix)), - tMapping,tMap(tVar(1),tVar(2))), + tOr3(tMapping,tArray,tMultiset), + tMap(tVar(1),tVar(2))), tFunc(tSet(tSetvar(3,tMix)) tMultiset,tSet(tVar(3))), tFuncV(tStr,tStr,tStr)), OPT_TRY_OPTIMIZE,0,generate_minus); +/* + +object & mixed -> mixed +mixed & object -> mixed + +int & int -> int +array & array -> array +multiset & multiset -> multiset +mapping & mapping -> mapping +string & string -> string +type|program & type|program -> type|program + +mapping & array -> mapping +array & mapping -> mapping +mapping & multiset -> mapping +multiset & mapping -> mapping + + */ + + +#define F_AND_TYPE(Z) \ + tOr(tFunc(tSetvar(0,Z),tVar(0)), \ + tIfnot(tFunc(Z,tMix), \ + tFuncV(tSetvar(1,Z),tSetvar(2,Z), \ + tOr(tVar(1),tVar(2))))) + + ADD_EFUN2("`&",f_and, - tOr8(tFunc(tSetvar(0,tMix),tVar(0)), - tOr(tFuncV(tMix tObj,tMix,tMix), - tFuncV(tObj tMix,tMix,tMix)), - tFuncV(tInt tInt,tInt,tInt), - tOr(tFunc(tMapping tSetvar(1,tMapping),tVar(1)), - tFuncV(tMapping tMapping tSetvar(2,tMapping), - tSetvar(3,tMapping),tOr(tVar(2),tVar(3)))), - tOr(tFunc(tMultiset tSetvar(4,tMultiset),tVar(4)), - tFuncV(tMultiset tMultiset tSetvar(5,tMultiset), - tSetvar(6,tMultiset),tOr(tVar(5),tVar(6)))), - tOr(tFunc(tArray tSetvar(7,tArray),tVar(7)), - tFuncV(tArray tArray tSetvar(8,tArray), - tSetvar(9,tArray),tOr(tVar(8),tVar(9)))), - tFuncV(tString tString,tString,tString), - tFuncV(tOr(tType,tPrg) tOr(tType,tPrg),tOr(tType,tPrg),tType)), + tOr4( + tFunc(tSetvar(0,tMix),tVar(0)), + + tOr(tFuncV(tMix tObj,tMix,tMix), + tFuncV(tObj tMix,tMix,tMix)), + + tOr6( F_AND_TYPE(tInt), + F_AND_TYPE(tArray), + F_AND_TYPE(tMapping), + F_AND_TYPE(tMultiset), + F_AND_TYPE(tString), + F_AND_TYPE(tOr(tType,tPrg)) ), + + tIfnot(tFuncV(tNone,tOr(tArray,tMultiset),tMix), + tFuncV(tNone, + tOr3(tArray,tMultiset,tSetvar(4,tMapping)), + tVar(4)) ) + ), + OPT_TRY_OPTIMIZE,optimize_binary,generate_and); #define LOG_TYPE \