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