From 1a3e1bc0aa1acd1e51c8208458d12f8f3f5fe9bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net> Date: Tue, 13 Apr 1999 13:10:10 -0700 Subject: [PATCH] better cast operator Rev: src/array.c:1.48 Rev: src/multiset.c:1.14 Rev: src/multiset.h:1.9 Rev: src/opcodes.c:1.36 Rev: src/pike_types.c:1.55 Rev: src/pike_types.h:1.19 --- src/array.c | 4 +- src/multiset.c | 7 +-- src/multiset.h | 4 +- src/opcodes.c | 125 +++++++++++++++++++++++++++++++++++++++++++++-- src/pike_types.c | 86 +++++++++++++++++++++++++++++++- src/pike_types.h | 3 +- 6 files changed, 217 insertions(+), 12 deletions(-) diff --git a/src/array.c b/src/array.c index def28759ca..f77414ccb2 100644 --- a/src/array.c +++ b/src/array.c @@ -20,7 +20,7 @@ #include "main.h" #include "security.h" -RCSID("$Id: array.c,v 1.47 1999/04/12 05:27:46 hubbe Exp $"); +RCSID("$Id: array.c,v 1.48 1999/04/13 20:10:04 hubbe Exp $"); struct array empty_array= { @@ -1610,7 +1610,7 @@ void apply_array(struct array *a, INT32 args) argp=sp-args - evaluator_stack; check_stack(a->size + args + 1); - + check_array_for_destruct(a); for(e=0;e<a->size;e++) { assign_svalues_no_free(sp,evaluator_stack+argp,args,BIT_MIXED); diff --git a/src/multiset.c b/src/multiset.c index 09ca4b1489..57b32395df 100644 --- a/src/multiset.c +++ b/src/multiset.c @@ -16,7 +16,7 @@ #include "gc.h" #include "security.h" -RCSID("$Id: multiset.c,v 1.13 1999/01/21 09:15:07 hubbe Exp $"); +RCSID("$Id: multiset.c,v 1.14 1999/04/13 20:10:05 hubbe Exp $"); struct multiset *first_multiset; @@ -28,7 +28,7 @@ int multiset_member(struct multiset *l, struct svalue *ind) /* * allocate and init a new multiset */ -static struct multiset *allocate_multiset(struct array *ind) +struct multiset *allocate_multiset(struct array *ind) { struct multiset *l; GC_ALLOC(); @@ -69,7 +69,8 @@ void really_free_multiset(struct multiset *l) GC_FREE(); } -static void order_multiset(struct multiset *l) + +void order_multiset(struct multiset *l) { INT32 *order; if(l->ind->size < 2) return; diff --git a/src/multiset.h b/src/multiset.h index b7f8bae4ee..87c4a1aeae 100644 --- a/src/multiset.h +++ b/src/multiset.h @@ -5,7 +5,7 @@ \*/ /* - * $Id: multiset.h,v 1.8 1999/01/21 09:15:08 hubbe Exp $ + * $Id: multiset.h,v 1.9 1999/04/13 20:10:06 hubbe Exp $ */ #ifndef MULTISET_H #define MULTISET_H @@ -30,7 +30,9 @@ extern struct multiset *first_multiset; /* Prototypes begin here */ int multiset_member(struct multiset *l, struct svalue *ind); +struct multiset *allocate_multiset(struct array *ind); void really_free_multiset(struct multiset *l); +void order_multiset(struct multiset *l); struct multiset *mkmultiset(struct array *ind); void multiset_insert(struct multiset *l, struct svalue *ind); diff --git a/src/opcodes.c b/src/opcodes.c index fc44aa71ad..14ab7ceb8b 100644 --- a/src/opcodes.c +++ b/src/opcodes.c @@ -23,7 +23,7 @@ #include "module_support.h" #include "security.h" -RCSID("$Id: opcodes.c,v 1.35 1999/01/21 09:15:11 hubbe Exp $"); +RCSID("$Id: opcodes.c,v 1.36 1999/04/13 20:10:08 hubbe Exp $"); void index_no_free(struct svalue *to,struct svalue *what,struct svalue *ind) { @@ -124,8 +124,7 @@ void o_cast(struct pike_string *type, INT32 run_time_type) free_svalue(sp-2); sp[-2]=sp[-1]; sp--; - return; - } + }else switch(run_time_type) { @@ -134,6 +133,23 @@ void o_cast(struct pike_string *type, INT32 run_time_type) case T_MIXED: return; + + case T_MAPPING: + switch(sp[-1].type) + { + case T_ARRAY: + { + f_transpose(1); + sp--; + push_array_items(sp->u.array); + f_mkmapping(2); + break; + } + + default: + error("Cannot cast %s to mapping.\n",get_name_of_type(sp[-1].type)); + } + break; case T_ARRAY: switch(sp[-1].type) @@ -377,7 +393,6 @@ void o_cast(struct pike_string *type, INT32 run_time_type) ref_push_array(a); }else{ INT32 e,i; - struct pike_string *s; #ifdef PIKE_DEBUG struct svalue *save_sp=sp+1; #endif @@ -402,6 +417,108 @@ void o_cast(struct pike_string *type, INT32 run_time_type) } pop_stack(); } + break; + + case T_MULTISET: + { + struct pike_string *itype; + INT32 run_time_itype; + + push_string(itype=key_type(type,0)); + run_time_itype=compile_type_to_runtime_type(itype); + + if(run_time_itype != T_MIXED) + { + struct multiset *m; + struct array *tmp=sp[-2].u.multiset->ind; + DECLARE_CYCLIC(); + + if((m=(struct multiset *)BEGIN_CYCLIC(tmp,0))) + { + ref_push_multiset(m); + }else{ + INT32 e,i; + struct array *a; +#ifdef PIKE_DEBUG + struct svalue *save_sp=sp+1; +#endif + push_multiset(m=allocate_multiset(a=allocate_array(tmp->size))); + + SET_CYCLIC_RET(m); + + for(e=0;e<a->size;e++) + { + push_svalue(tmp->item+e); + o_cast(itype, run_time_itype); + array_set_index(a,e,sp-1); + pop_stack(); + } +#ifdef PIKE_DEBUG + if(save_sp!=sp) + fatal("o_cast left stack droppings.\n"); +#endif + order_multiset(m); + END_CYCLIC(); + } + assign_svalue(sp-3,sp-1); + pop_stack(); + } + pop_stack(); + } + break; + + case T_MAPPING: + { + struct pike_string *itype,*vtype; + INT32 run_time_itype; + INT32 run_time_vtype; + + push_string(itype=key_type(type,0)); + run_time_itype=compile_type_to_runtime_type(itype); + + push_string(vtype=index_type(type,0)); + run_time_vtype=compile_type_to_runtime_type(vtype); + + if(run_time_itype != T_MIXED || + run_time_vtype != T_MIXED) + { + struct mapping *m; + struct mapping *tmp=sp[-3].u.mapping; + DECLARE_CYCLIC(); + + if((m=(struct mapping *)BEGIN_CYCLIC(tmp,0))) + { + ref_push_mapping(m); + }else{ + INT32 e,i; + struct keypair *k; +#ifdef PIKE_DEBUG + struct svalue *save_sp=sp+1; +#endif + push_mapping(m=allocate_mapping(tmp->size)); + + SET_CYCLIC_RET(m); + + MAPPING_LOOP(tmp) + { + push_svalue(& k->ind); + o_cast(itype, run_time_itype); + push_svalue(& k->val); + o_cast(vtype, run_time_vtype); + mapping_insert(m,sp-2,sp-1); + pop_n_elems(2); + } +#ifdef PIKE_DEBUG + if(save_sp!=sp) + fatal("o_cast left stack droppings.\n"); +#endif + END_CYCLIC(); + } + assign_svalue(sp-4,sp-1); + pop_stack(); + } + pop_n_elems(2); + } } } diff --git a/src/pike_types.c b/src/pike_types.c index a6f91b7a83..68236c7f12 100644 --- a/src/pike_types.c +++ b/src/pike_types.c @@ -5,7 +5,7 @@ \*/ /**/ #include "global.h" -RCSID("$Id: pike_types.c,v 1.54 1999/03/02 03:13:25 hubbe Exp $"); +RCSID("$Id: pike_types.c,v 1.55 1999/04/13 20:10:09 hubbe Exp $"); #include <ctype.h> #include "svalue.h" #include "pike_types.h" @@ -1491,6 +1491,90 @@ struct pike_string *index_type(struct pike_string *type, node *n) return t; } + +#ifdef DEBUG_MALLOC +#define low_key_type(X,Y) ((struct pike_string *)debug_malloc_touch(debug_low_key_type((X),(Y)))) +#else +#define low_key_type debug_low_key_type +#endif + +/* FIXME, add the index */ +static struct pike_string *debug_low_key_type(char *t, node *n) +{ + switch(EXTRACT_UCHAR(t++)) + { + case T_OBJECT: + { + struct program *p=id_to_program(extract_type_int(t+1)); + if(p && n) + { + if(n->token == F_ARROW) + { + if(FIND_LFUN(p,LFUN_ARROW)!=-1 || FIND_LFUN(p,LFUN_ASSIGN_ARROW)!=-1) + { + reference_shared_string(mixed_type_string); + return mixed_type_string; + } + }else{ + if(FIND_LFUN(p,LFUN_INDEX) != -1 || FIND_LFUN(p,LFUN_ASSIGN_INDEX) != -1) + { + reference_shared_string(mixed_type_string); + return mixed_type_string; + } + } + } + reference_shared_string(string_type_string); + return string_type_string; + } + default: + reference_shared_string(mixed_type_string); + return mixed_type_string; + + case T_VOID: + case T_FLOAT: + case T_INT: + return 0; + + case T_OR: + { + struct pike_string *a,*b; + a=low_key_type(t,n); + t+=type_length(t); + b=low_key_type(t,n); + if(!b) return a; + if(!a) return b; + type_stack_mark(); + medium_or_pike_types(a,b); + free_string(a); + free_string(b); + return pop_unfinished_type(); + } + + case T_AND: + return low_key_type(t+type_length(t),n); + + case T_ARRAY: + case T_STRING: /* always int */ + reference_shared_string(int_type_string); + return int_type_string; + + case T_MAPPING: + case T_MULTISET: + return make_shared_binary_string(t, type_length(t)); + } +} + +struct pike_string *key_type(struct pike_string *type, node *n) +{ + struct pike_string *t; + clear_markers(); + t=low_key_type(type->str,n); + if(!t) copy_shared_string(t,mixed_type_string); + return t; +} + + + static int low_check_indexing(char *type, char *index_type, node *n) { switch(EXTRACT_UCHAR(type++)) diff --git a/src/pike_types.h b/src/pike_types.h index 6bab1535a0..42b74723a4 100644 --- a/src/pike_types.h +++ b/src/pike_types.h @@ -5,7 +5,7 @@ \*/ /* - * $Id: pike_types.h,v 1.18 1999/03/02 03:13:27 hubbe Exp $ + * $Id: pike_types.h,v 1.19 1999/04/13 20:10:10 hubbe Exp $ */ #ifndef PIKE_TYPES_H #define PIKE_TYPES_H @@ -120,6 +120,7 @@ struct pike_string *describe_type(struct pike_string *type); TYPE_T compile_type_to_runtime_type(struct pike_string *s); int match_types(struct pike_string *a,struct pike_string *b); struct pike_string *index_type(struct pike_string *type, node *n); +struct pike_string *key_type(struct pike_string *type, node *n); int check_indexing(struct pike_string *type, struct pike_string *index_type, node *n); -- GitLab