diff --git a/src/builtin_functions.c b/src/builtin_functions.c
index dad24c3e6df4cff99cd3b4f68761ac811d6a918b..648011ce7570c9ab9c62a0e92c3f53da3f711c8e 100644
--- a/src/builtin_functions.c
+++ b/src/builtin_functions.c
@@ -5,7 +5,7 @@
 \*/
 /**/
 #include "global.h"
-RCSID("$Id: builtin_functions.c,v 1.341 2001/02/06 23:48:23 nilsson Exp $");
+RCSID("$Id: builtin_functions.c,v 1.342 2001/02/19 23:49:57 grubba Exp $");
 #include "interpret.h"
 #include "svalue.h"
 #include "pike_macros.h"
@@ -2067,7 +2067,7 @@ void f_this_object(INT32 args)
 
 node *fix_this_object_type(node *n)
 {
-  free_string(n->type);
+  free_type(n->type);
   type_stack_mark();
   push_type_int(Pike_compiler->new_program->id);
   /*  push_type(1);   We are rather sure that we contain ourselves... */
@@ -2401,7 +2401,7 @@ static node *fix_overloaded_type(node *n, int lfun, const char *deftype, int def
 	   (t2=check_call(function_type_string , ID_FROM_INT(p, fun)->type,
 			  0)))
 	{
-	  free_string(n->type);
+	  free_type(n->type);
 	  n->type=t2;
 	  return 0;
 	}
@@ -2417,8 +2417,8 @@ static node *fix_overloaded_type(node *n, int lfun, const char *deftype, int def
       t2=make_shared_binary_string(deftype, deftypelen);
       t=n->type;
       n->type=or_pike_types(t,t2,0);
-      free_string(t);
-      free_string(t2);
+      free_type(t);
+      free_type(t2);
     }
 #endif
   }
@@ -2438,9 +2438,9 @@ static node *fix_values_type(node *n)
 
 static node *fix_aggregate_mapping_type(node *n)
 {
-  struct pike_string *types[2] = { NULL, NULL };
+  struct pike_type *types[2] = { NULL, NULL };
   node *args = CDR(n);
-  struct pike_string *new_type = NULL;
+  struct pike_type *new_type = NULL;
 
 #ifdef PIKE_DEBUG
   if (l_flag > 2) {
@@ -2512,7 +2512,7 @@ static node *fix_aggregate_mapping_type(node *n)
       do {
 	if (types[argno]) {
 	  struct pike_string *t = or_pike_types(types[argno], arg->type, 0);
-	  free_string(types[argno]);
+	  free_type(types[argno]);
 	  types[argno] = t;
 #ifdef PIKE_DEBUG
 	  if (l_flag > 4) {
@@ -2542,8 +2542,8 @@ static node *fix_aggregate_mapping_type(node *n)
     }
 
     type_stack_mark();
-    push_unfinished_type(types[1]->str);
-    push_unfinished_type(types[0]->str);
+    push_finished_type(types[1]);
+    push_finished_type(types[0]);
     push_type(T_MAPPING);
     new_type = pop_unfinished_type();
   } else {
@@ -2552,7 +2552,7 @@ static node *fix_aggregate_mapping_type(node *n)
   }
   if (new_type) {
   set_type:
-    free_string(n->type);
+    free_type(n->type);
     n->type = new_type;
 
 #ifdef PIKE_DEBUG
@@ -2572,10 +2572,10 @@ static node *fix_aggregate_mapping_type(node *n)
     args->parent = n;
   }
   if (types[1]) {
-    free_string(types[1]);
+    free_type(types[1]);
   }
   if (types[0]) {
-    free_string(types[0]);
+    free_type(types[0]);
   }
   return NULL;
 }
@@ -2768,7 +2768,7 @@ node *fix_object_program_type(node *n)
   /* Perform the actual conversion. */
   new_type = object_type_to_program_type(nn->type);
   if (new_type) {
-    free_string(n->type);
+    free_type(n->type);
     n->type = new_type;
   }
   return NULL;
diff --git a/src/constants.c b/src/constants.c
index 09e07f88ac16cea5c6a67787d58b7a864e6732e7..93ea934bc31594c7fe85f87eed8922dfb41af769 100644
--- a/src/constants.c
+++ b/src/constants.c
@@ -16,7 +16,7 @@
 #include "pike_error.h"
 #include "block_alloc.h"
 
-RCSID("$Id: constants.c,v 1.24 2000/12/01 08:09:44 hubbe Exp $");
+RCSID("$Id: constants.c,v 1.25 2001/02/19 23:49:59 grubba Exp $");
 
 struct mapping *builtin_constants = 0;
 
@@ -66,7 +66,7 @@ PMOD_EXPORT void add_global_program(char *name, struct program *p)
 
 #undef EXIT_BLOCK
 #define EXIT_BLOCK(X) do {		\
-  free_string(X->type);			\
+  free_type(X->type);			\
   free_string(X->name);			\
 }while(0)
 BLOCK_ALLOC(callable,128)
diff --git a/src/constants.h b/src/constants.h
index 49fd7f64b45082fd005f8ca68bbcff7abc9006f6..6c3bc74241f4c6f67fed4faee0aa35798e3e7d06 100644
--- a/src/constants.h
+++ b/src/constants.h
@@ -5,7 +5,7 @@
 \*/
 
 /*
- * $Id: constants.h,v 1.15 2000/12/13 21:23:35 hubbe Exp $
+ * $Id: constants.h,v 1.16 2001/02/19 23:49:59 grubba Exp $
  */
 #ifndef ADD_EFUN_H
 #define ADD_EFUN_H
@@ -25,7 +25,7 @@ struct callable
   struct object *prot;
 #endif
   c_fun function;
-  struct pike_string *type;
+  struct pike_type *type;
   struct pike_string *name;
   INT16 flags;
 #ifdef PIKE_DEBUG
@@ -44,7 +44,7 @@ PMOD_EXPORT void add_global_program(char *name, struct program *p);
 BLOCK_ALLOC(callable,128)
 PMOD_EXPORT struct callable *low_make_callable(c_fun fun,
 				   struct pike_string *name,
-				   struct pike_string *type,
+				   struct pike_type *type,
 				   INT16 flags,
 				   optimize_fun optimize,
 				   docode_fun docode);
diff --git a/src/docode.c b/src/docode.c
index 5fa59374e91d1ef87bcb63a7f7ae1377db39f1d1..d3ca9376c60818a0b95648037e357ac00c6172af 100644
--- a/src/docode.c
+++ b/src/docode.c
@@ -5,7 +5,7 @@
 \*/
 /**/
 #include "global.h"
-RCSID("$Id: docode.c,v 1.103 2001/02/05 21:13:10 grubba Exp $");
+RCSID("$Id: docode.c,v 1.104 2001/02/19 23:49:59 grubba Exp $");
 #include "las.h"
 #include "program.h"
 #include "pike_types.h"
@@ -163,7 +163,7 @@ static INT32 current_switch_case;
 static INT32 current_switch_default;
 static INT32 current_switch_values_on_stack;
 static INT32 *current_switch_jumptable =0;
-static struct pike_string *current_switch_type = NULL;
+static struct pike_type *current_switch_type = NULL;
 
 void upd_int(int offset, INT32 tmp)
 {
@@ -1011,8 +1011,14 @@ static int do_docode2(node *n, INT16 flags)
       DO_CODE_BLOCK(CAR(n));
       return 0;
     }
-    tmp1=store_prog_string(n->type);
-    emit1(F_STRING, DO_NOT_WARN((INT32)tmp1));
+    {
+      struct svalue sv;
+      sv.type = T_TYPE;
+      sv.subtype = 0;
+      sv.u.type = n->type;
+      tmp1 = store_constant(&sv, 1, n->name);
+      emit1(F_CONSTANT, DO_NOT_WARN((INT32)tmp1));
+    }
 
     tmp1=do_docode(CAR(n),0);
     if(!tmp1) { emit0(F_CONST0); tmp1=1; }
@@ -1023,8 +1029,14 @@ static int do_docode2(node *n, INT16 flags)
 
   case F_SOFT_CAST:
     if (runtime_options & RUNTIME_CHECK_TYPES) {
-      tmp1 = store_prog_string(n->type);
-      emit1(F_STRING, DO_NOT_WARN((INT32)tmp1));
+      {
+	struct svalue sv;
+	sv.type = T_TYPE;
+	sv.subtype = 0;
+	sv.u.type = n->type;
+	tmp1 = store_constant(&sv, 1, n->name);
+	emit1(F_CONSTANT, DO_NOT_WARN((INT32)tmp1));
+      }
       tmp1 = do_docode(CAR(n), 0);
       if (!tmp1) { emit0(F_CONST0); tmp1 = 1; }
       if (tmp1 > 1) do_pop(DO_NOT_WARN((INT32)(tmp1 - 1)));
diff --git a/src/global.h b/src/global.h
index 6498c304fa423cb7c72696cd3258da9e837d5643..53a5d1f09618800ede4743c24ef8e4ad730a200a 100644
--- a/src/global.h
+++ b/src/global.h
@@ -5,7 +5,7 @@
 \*/
 
 /*
- * $Id: global.h,v 1.56 2000/12/23 07:33:49 hubbe Exp $
+ * $Id: global.h,v 1.57 2001/02/19 23:49:59 grubba Exp $
  */
 #ifndef GLOBAL_H
 #define GLOBAL_H
@@ -408,4 +408,14 @@ char *crypt(char *, char *);
  */
 #define Pike_error_present
 
+/* This stuff is here to avoid circularities with
+ * svalue.h and pike_types.h
+ */
+#ifndef USE_PIKE_TYPE
+/*
+ * The old type type.
+ */
+#define pike_type	pike_string
+#endif /* !USE_PIKE_TYPE */
+
 #endif
diff --git a/src/interpret.h b/src/interpret.h
index 13f7c491620750ae6eea5fe2c149b28a129d5d81..bc42cd8666d0397bea6d19cf0602a60d6168abca 100644
--- a/src/interpret.h
+++ b/src/interpret.h
@@ -5,7 +5,7 @@
 \*/
 
 /*
- * $Id: interpret.h,v 1.76 2001/01/24 08:17:27 hubbe Exp $
+ * $Id: interpret.h,v 1.77 2001/02/19 23:49:59 grubba Exp $
  */
 #ifndef INTERPRET_H
 #define INTERPRET_H
@@ -151,6 +151,7 @@ PMOD_EXPORT const char *Pike_check_c_stack_errmsg;
 #define push_array(A) do{ struct array *_=(A); debug_malloc_touch(_); Pike_sp->u.array=_ ;Pike_sp++->type=PIKE_T_ARRAY; }while(0)
 #define push_multiset(L) do{ struct multiset *_=(L); debug_malloc_touch(_); Pike_sp->u.multiset=_; Pike_sp++->type=PIKE_T_MULTISET; }while(0)
 #define push_string(S) do{ struct pike_string *_=(S); debug_malloc_touch(_); Pike_sp->subtype=0; Pike_sp->u.string=_; Pike_sp++->type=PIKE_T_STRING; }while(0)
+#define push_type_value(S) do{ struct pike_type *_=(S); debug_malloc_touch(_); Pike_sp->u.type=_; Pike_sp++->type=PIKE_T_TYPE; }while(0)
 #define push_object(O) do{ struct object  *_=(O); debug_malloc_touch(_); Pike_sp->u.object=_; Pike_sp++->type=PIKE_T_OBJECT; }while(0)
 #define push_float(F) do{ FLOAT_TYPE _=(F); Pike_sp->u.float_number=_; Pike_sp++->type=PIKE_T_FLOAT; }while(0)
 #define push_text(T) push_string(make_shared_string((T)))
@@ -161,6 +162,7 @@ PMOD_EXPORT const char *Pike_check_c_stack_errmsg;
 #define ref_push_array(A) do{ struct array *_=(A); debug_malloc_touch(_); _->refs++; Pike_sp->u.array=_ ;Pike_sp++->type=PIKE_T_ARRAY; }while(0)
 #define ref_push_multiset(L) do{ struct multiset *_=(L); debug_malloc_touch(_); _->refs++; Pike_sp->u.multiset=_; Pike_sp++->type=PIKE_T_MULTISET; }while(0)
 #define ref_push_string(S) do{ struct pike_string *_=(S); debug_malloc_touch(_); _->refs++; Pike_sp->subtype=0; Pike_sp->u.string=_; Pike_sp++->type=PIKE_T_STRING; }while(0)
+#define ref_push_type_value(S) do{ struct pike_type *_=(S); debug_malloc_touch(_); _->refs++; Pike_sp->u.type=_; Pike_sp++->type=PIKE_T_TYPE; }while(0)
 #define ref_push_object(O) do{ struct object  *_=(O); debug_malloc_touch(_); _->refs++; Pike_sp->u.object=_; Pike_sp++->type=PIKE_T_OBJECT; }while(0)
 
 #define push_svalue(S) do { struct svalue *_=(S); assign_svalue_no_free(Pike_sp,_); Pike_sp++; }while(0)
diff --git a/src/interpret_functions.h b/src/interpret_functions.h
index c05de733731dcd9442866650b15e80a1a08b6a3d..9ffd7a7f7f81771759dea28ee0c96c6f8fe2cb42 100644
--- a/src/interpret_functions.h
+++ b/src/interpret_functions.h
@@ -1,5 +1,5 @@
 /*
- * $Id: interpret_functions.h,v 1.44 2001/02/05 21:13:10 grubba Exp $
+ * $Id: interpret_functions.h,v 1.45 2001/02/19 23:49:59 grubba Exp $
  *
  * Opcode definitions for the interpreter.
  */
@@ -1401,8 +1401,8 @@ OPCODE0(F_SOFT_CAST, "soft cast")
   }
 #endif /* PIKE_DEBUG */
   if (runtime_options & RUNTIME_CHECK_TYPES) {
-    struct pike_string *sval_type = get_type_of_svalue(Pike_sp-1);
-    if (!pike_types_le(sval_type, Pike_sp[-2].u.string)) {
+    struct pike_type *sval_type = get_type_of_svalue(Pike_sp-1);
+    if (!pike_types_le(sval_type, Pike_sp[-2].u.type)) {
       /* get_type_from_svalue() doesn't return a fully specified type
        * for array, mapping and multiset, so we perform a more lenient
        * check for them.
@@ -1430,7 +1430,7 @@ OPCODE0(F_SOFT_CAST, "soft cast")
 	t2 = describe_type(sval_type);
 	SET_ONERROR(tmp2, do_free_string, t2);
 	  
-	free_string(sval_type);
+	free_type(sval_type);
 
 	bad_arg_error(NULL, Pike_sp-1, 1, 1, t1->str, Pike_sp-1,
 		      "%s(): Soft cast failed. Expected %s, got %s\n",
@@ -1442,10 +1442,10 @@ OPCODE0(F_SOFT_CAST, "soft cast")
 	free_string(t1);
       }
     }
-    free_string(sval_type);
+    free_type(sval_type);
 #ifdef PIKE_DEBUG
     if (d_flag > 2) {
-      struct pike_string *t = describe_type(Pike_sp[-2].u.string);
+      struct pike_string *t = describe_type(Pike_sp[-2].u.type);
       fprintf(stderr, "Soft cast to %s\n", t->str);
       free_string(t);
     }
diff --git a/src/language.yacc b/src/language.yacc
index fa9c01686200230b5354b6e277236e75edda12d4..f2d6f43980ddba12a4a4927e32c68749fdcf8911 100644
--- a/src/language.yacc
+++ b/src/language.yacc
@@ -110,7 +110,7 @@
 /* This is the grammar definition of Pike. */
 
 #include "global.h"
-RCSID("$Id: language.yacc,v 1.223 2001/01/20 01:15:44 grubba Exp $");
+RCSID("$Id: language.yacc,v 1.224 2001/02/19 23:50:00 grubba Exp $");
 #ifdef HAVE_MEMORY_H
 #include <memory.h>
 #endif
@@ -546,8 +546,8 @@ type_or_error: simple_type
     check_type_string(check_node_hash($1)->u.sval.u.string);
 #endif /* PIKE_DEBUG */
     if(Pike_compiler->compiler_frame->current_type)
-      free_string(Pike_compiler->compiler_frame->current_type); 
-    copy_shared_string(Pike_compiler->compiler_frame->current_type,$1->u.sval.u.string);
+      free_type(Pike_compiler->compiler_frame->current_type); 
+    copy_type(Pike_compiler->compiler_frame->current_type, $1->u.sval.u.type);
     free_node($1);
   }
   ;
@@ -587,11 +587,11 @@ push_compiler_frame0: /* empty */
        !Pike_compiler->compiler_frame->previous->current_type)
     {
       yyerror("Internal compiler fault.");
-      copy_shared_string(Pike_compiler->compiler_frame->current_type,
-			 mixed_type_string);
+      copy_type(Pike_compiler->compiler_frame->current_type,
+		mixed_type_string);
     }else{
-      copy_shared_string(Pike_compiler->compiler_frame->current_type,
-			 Pike_compiler->compiler_frame->previous->current_type);
+      copy_type(Pike_compiler->compiler_frame->current_type,
+		Pike_compiler->compiler_frame->previous->current_type);
     }
   }
   ;
@@ -608,7 +608,7 @@ def: modifiers type_or_error optional_stars TOK_IDENTIFIER push_compiler_frame0
     while(--$3>=0) push_type(T_ARRAY);
     
     if(Pike_compiler->compiler_frame->current_return_type)
-      free_string(Pike_compiler->compiler_frame->current_return_type);
+      free_type(Pike_compiler->compiler_frame->current_return_type);
     Pike_compiler->compiler_frame->current_return_type=compiler_pop_type();
     
     push_finished_type(Pike_compiler->compiler_frame->current_return_type);
@@ -651,7 +651,7 @@ def: modifiers type_or_error optional_stars TOK_IDENTIFIER push_compiler_frame0
 #endif
 
 	      new_type = or_pike_types(s, id->type, 1);
-	      free_string(s);
+	      free_type(s);
 	      s = new_type;
 
 	      fprintf(stderr, "Resulting type:\n");
@@ -681,8 +681,8 @@ def: modifiers type_or_error optional_stars TOK_IDENTIFIER push_compiler_frame0
 	    fprintf(stderr, "Pass %d: Identifier %s:\n",
 		    Pike_compiler->compiler_pass, $4->u.sval.u.string->str);
 
-	    free_string(s);
-	    copy_shared_string(s, id->type);
+	    free_type(s);
+	    copy_type(s, id->type);
 
 	    fprintf(stderr, "Resulting type:\n");
 #ifdef PIKE_DEBUG
@@ -696,7 +696,7 @@ def: modifiers type_or_error optional_stars TOK_IDENTIFIER push_compiler_frame0
       }
 
       $<n>$=mkstrnode(s);
-      free_string(s);
+      free_type(s);
     }
 
 
@@ -772,8 +772,8 @@ def: modifiers type_or_error optional_stars TOK_IDENTIFIER push_compiler_frame0
 		/* The following is needed to go around the optimization in
 		 * mksoftcastnode().
 		 */
-		free_string(local_node->type);
-		copy_shared_string(local_node->type, mixed_type_string);
+		free_type(local_node->type);
+		copy_type(local_node->type, mixed_type_string);
 
 		check_args =
 		  mknode(F_COMMA_EXPR, check_args,
@@ -852,7 +852,7 @@ def: modifiers type_or_error optional_stars TOK_IDENTIFIER push_compiler_frame0
   }
   | modifiers type_or_error optional_stars bad_identifier
   {
-    free_string(compiler_pop_type());
+    free_type(compiler_pop_type());
   }
     '(' arguments ')' block_or_semi
   {
@@ -1052,7 +1052,7 @@ cast: '(' type ')'
     {
       struct pike_string *s=compiler_pop_type();
       $$=mkstrnode(s);
-      free_string(s);
+      free_type(s);
     }
     ;
 
@@ -1060,7 +1060,7 @@ soft_cast: '[' type ']'
     {
       struct pike_string *s=compiler_pop_type();
       $$=mkstrnode(s);
-      free_string(s);
+      free_type(s);
     }
     ;
 
@@ -1096,7 +1096,7 @@ simple_type: type4
 	    s, s->str, $$->u.sval.u.string, $$->u.sval.u.string->str);
     }
 #endif /* PIKE_DEBUG */
-    free_string(s);
+    free_type(s);
   }
   ;
 
@@ -1110,7 +1110,7 @@ simple_type2: type2
 	    s, s->str, $$->u.sval.u.string, $$->u.sval.u.string->str);
     }
 #endif /* PIKE_DEBUG */
-    free_string(s);
+    free_type(s);
   }
   ;
 
@@ -1124,7 +1124,7 @@ simple_identifier_type: identifier_type
 	    s, s->str, $$->u.sval.u.string, $$->u.sval.u.string->str);
     }
 #endif /* PIKE_DEBUG */
-    free_string(s);
+    free_type(s);
   }
   ;
 
@@ -1406,7 +1406,7 @@ new_name: optional_stars TOK_IDENTIFIER
     type=compiler_pop_type();
     define_variable($2->u.sval.u.string, type,
 		    Pike_compiler->current_modifiers);
-    free_string(type);
+    free_type(type);
     free_node($2);
   }
   | optional_stars bad_identifier {}
@@ -1425,7 +1425,7 @@ new_name: optional_stars TOK_IDENTIFIER
     }
     $<number>$=define_variable($2->u.sval.u.string, type,
 			       Pike_compiler->current_modifiers & (~ID_EXTERN));
-    free_string(type);
+    free_type(type);
   }
   expr0
   {
@@ -1703,8 +1703,9 @@ lambda: TOK_LAMBDA push_compiler_frame1
   {
     debug_malloc_touch(Pike_compiler->compiler_frame->current_return_type);
     if(Pike_compiler->compiler_frame->current_return_type)
-      free_string(Pike_compiler->compiler_frame->current_return_type);
-    copy_shared_string(Pike_compiler->compiler_frame->current_return_type,any_type_string);
+      free_type(Pike_compiler->compiler_frame->current_return_type);
+    copy_type(Pike_compiler->compiler_frame->current_return_type,
+	      any_type_string);
   }
   func_args
   {
@@ -1724,7 +1725,7 @@ lambda: TOK_LAMBDA push_compiler_frame1
 
     if(type) {
       push_finished_type(type);
-      free_string(type);
+      free_type(type);
     } else
       push_type(T_MIXED);
     
@@ -1767,7 +1768,7 @@ lambda: TOK_LAMBDA push_compiler_frame1
       $$ = mkidentifiernode(f);
     }
     free_string(name);
-    free_string(type);
+    free_type(type);
     pop_compiler_frame();
   }
   | TOK_LAMBDA push_compiler_frame1 error
@@ -1787,9 +1788,9 @@ local_function: TOK_IDENTIFIER push_compiler_frame1 func_args
 
     debug_malloc_touch(Pike_compiler->compiler_frame->current_return_type);
     if(Pike_compiler->compiler_frame->current_return_type)
-      free_string(Pike_compiler->compiler_frame->current_return_type);
-    copy_shared_string(Pike_compiler->compiler_frame->current_return_type,
-		       $<n>0->u.sval.u.string);
+      free_type(Pike_compiler->compiler_frame->current_return_type);
+    copy_type(Pike_compiler->compiler_frame->current_return_type,
+	      $<n>0->u.sval.u.type);
 
 
     /***/
@@ -1909,7 +1910,7 @@ local_function2: optional_stars TOK_IDENTIFIER push_compiler_frame1 func_args
     while($1--) push_type(T_ARRAY);
 
     if(Pike_compiler->compiler_frame->current_return_type)
-      free_string(Pike_compiler->compiler_frame->current_return_type);
+      free_type(Pike_compiler->compiler_frame->current_return_type);
     Pike_compiler->compiler_frame->current_return_type=compiler_pop_type();
 
     /***/
@@ -2035,7 +2036,7 @@ create_arg: modifiers type_or_error optional_stars TOK_IDENTIFIER
 		    Pike_compiler->current_modifiers);
     add_local_name($4->u.sval.u.string, type, 0);
 
-    /* free_string(type); */
+    /* free_type(type); */
     free_node($4);
     $$=0;
   }
@@ -2117,8 +2118,8 @@ optional_create_arguments: /* empty */ { $$ = 0; }
 	  /* The following is needed to go around the optimization in
 	   * mksoftcastnode().
 	   */
-	  free_string(local_node->type);
-	  copy_shared_string(local_node->type, mixed_type_string);
+	  free_type(local_node->type);
+	  copy_type(local_node->type, mixed_type_string);
 	  
 	  local_node = mksoftcastnode(Pike_compiler->compiler_frame->
 				      variable[e].type, local_node);
@@ -2158,7 +2159,7 @@ optional_create_arguments: /* empty */ { $$ = 0; }
 
     pop_compiler_frame();
     free_node($4);
-    free_string(type);
+    free_type(type);
     free_string(create_string);
   }
   ;
@@ -2656,8 +2657,9 @@ optional_block: /* EMPTY */ { $$=0; }
   {
     debug_malloc_touch(Pike_compiler->compiler_frame->current_return_type);
     if(Pike_compiler->compiler_frame->current_return_type)
-      free_string(Pike_compiler->compiler_frame->current_return_type);
-    copy_shared_string(Pike_compiler->compiler_frame->current_return_type,any_type_string);
+      free_type(Pike_compiler->compiler_frame->current_return_type);
+    copy_type(Pike_compiler->compiler_frame->current_return_type,
+	      any_type_string);
 
     /* block code */
     $<number>1=Pike_compiler->num_used_modules;
@@ -2680,7 +2682,7 @@ optional_block: /* EMPTY */ { $$=0; }
 
     if(type) {
       push_finished_type(type);
-      free_string(type);
+      free_type(type);
     } else
       push_type(T_MIXED);
     
@@ -2716,7 +2718,7 @@ optional_block: /* EMPTY */ { $$=0; }
       $$ = mkidentifiernode(f);
     }
     free_string(name);
-    free_string(type);
+    free_type(type);
     pop_compiler_frame();
   }
   ;
@@ -3466,8 +3468,8 @@ int low_add_local_name(struct compiler_frame *frame,
 	yywarning("Declaring local variable with type void "
 		  "(converted to type zero).");
       }
-      free_string(type);
-      copy_shared_string(type, zero_type_string);
+      free_type(type);
+      copy_type(type, zero_type_string);
     }
     frame->variable[frame->current_number_of_locals].type = type;
     frame->variable[frame->current_number_of_locals].name = str;
diff --git a/src/las.c b/src/las.c
index 22a5fe9420c81e169be31ef8f97b18e940ea4811..44109eb983523a172c7998b44fecad958b134dd6 100644
--- a/src/las.c
+++ b/src/las.c
@@ -5,7 +5,7 @@
 \*/
 /**/
 #include "global.h"
-RCSID("$Id: las.c,v 1.233 2001/02/09 10:29:54 hubbe Exp $");
+RCSID("$Id: las.c,v 1.234 2001/02/19 23:50:00 grubba Exp $");
 
 #include "language.h"
 #include "interpret.h"
@@ -290,9 +290,9 @@ INT32 count_args(node *n)
 }
 
 /* FIXME: Ought to use parent pointer to avoid recursion. */
-struct pike_string *find_return_type(node *n)
+struct pike_type *find_return_type(node *n)
 {
-  struct pike_string *a,*b;
+  struct pike_type *a, *b;
 
   check_tree(n,0);
 
@@ -303,7 +303,7 @@ struct pike_string *find_return_type(node *n)
   if (n->token == F_RETURN) {
     if (CAR(n)) {
       if (CAR(n)->type) {
-	copy_shared_string(a, CAR(n)->type);
+	copy_type(a, CAR(n)->type);
       } else {
 #ifdef PIKE_DEBUG
 	if (l_flag > 2) {
@@ -311,10 +311,10 @@ struct pike_string *find_return_type(node *n)
 	  print_tree(n);
 	}
 #endif /* PIKE_DEBUG */
-	copy_shared_string(a, mixed_type_string);
+	copy_type(a, mixed_type_string);
       }
     } else {
-      copy_shared_string(a, zero_type_string);
+      copy_type(a, zero_type_string);
     }
     return a;
   }
@@ -335,12 +335,12 @@ struct pike_string *find_return_type(node *n)
   {
     if(b) {
       if (a != b) {
-	struct pike_string *res = or_pike_types(a, b, 1);
-	free_string(a);
-	free_string(b);
+	struct pike_type *res = or_pike_types(a, b, 1);
+	free_type(a);
+	free_type(b);
 	return res;
       }
-      free_string(b);
+      free_type(b);
     }
     return a;
   }
@@ -1305,7 +1305,7 @@ node *debug_mkexternalnode(struct program *parent_prog, int i)
   return res;
 }
 
-node *debug_mkcastnode(struct pike_string *type,node *n)
+node *debug_mkcastnode(struct pike_type *type, node *n)
 {
   node *res;
 
@@ -1323,7 +1323,7 @@ node *debug_mkcastnode(struct pike_string *type,node *n)
 
   res = mkemptynode();
   res->token = F_CAST;
-  copy_shared_string(res->type,type);
+  copy_type(res->type, type);
 
   if(match_types(object_type_string, type) ||
      match_types(program_type_string, type))
@@ -1339,7 +1339,7 @@ node *debug_mkcastnode(struct pike_string *type,node *n)
   return freeze_node(res);
 }
 
-node *debug_mksoftcastnode(struct pike_string *type,node *n)
+node *debug_mksoftcastnode(struct pike_type *type, node *n)
 {
   node *res;
 
@@ -1382,7 +1382,7 @@ node *debug_mksoftcastnode(struct pike_string *type,node *n)
 
   res = mkemptynode();
   res->token = F_SOFT_CAST;
-  copy_shared_string(res->type, type);
+  copy_type(res->type, type);
 
   res->tree_info |= n->tree_info;
 
@@ -1718,13 +1718,13 @@ int node_is_eq(node *a,node *b)
   }
 }
 
-node *debug_mktypenode(struct pike_string *t)
+node *debug_mktypenode(struct pike_type *t)
 {
   node *res = mkemptynode();
   res->token = F_CONSTANT;
-  copy_shared_string(res->u.sval.u.string, t);
+  copy_type(res->u.sval.u.type, t);
   res->u.sval.type = T_TYPE;
-  copy_shared_string(res->type, type_type_string);
+  copy_type(res->type, type_type_string);
   return freeze_node(res);
 }
 
@@ -2921,8 +2921,8 @@ static void low_build_function_type(node *n)
   }
 }
 
-void yytype_error(char *msg, struct pike_string *expected_t,
-		  struct pike_string *got_t, unsigned int flags)
+void yytype_error(char *msg, struct pike_type *expected_t,
+		  struct pike_type *got_t, unsigned int flags)
 {
   if (msg)
   {
@@ -2937,8 +2937,8 @@ void yytype_error(char *msg, struct pike_string *expected_t,
 
 void fix_type_field(node *n)
 {
-  struct pike_string *type_a,*type_b;
-  struct pike_string *old_type;
+  struct pike_type *type_a,*type_b;
+  struct pike_type *old_type;
 
   if (n->type && !(n->node_info & OPT_TYPE_NOT_FIXED))
     return; /* assume it is correct */
@@ -2967,24 +2967,24 @@ void fix_type_field(node *n)
     /* FALL_THROUGH */
   case F_CAST:
     /* Type-field is correct by definition. */
-    copy_shared_string(n->type, old_type);
+    copy_type(n->type, old_type);
     break;
 
   case F_LAND:
   case F_LOR:
     if (!CAR(n) || CAR(n)->type == void_type_string) {
       yyerror("Conditional uses void expression.");
-      copy_shared_string(n->type, mixed_type_string);
+      copy_type(n->type, mixed_type_string);
       break;
     }
     if(!match_types(CAR(n)->type,mixed_type_string))
       yyerror("Bad conditional expression.");
 
     if (!CDR(n) || CDR(n)->type == void_type_string)
-      copy_shared_string(n->type,void_type_string);
+      copy_type(n->type,void_type_string);
     else if(n->token == F_LAND || CAR(n)->type == CDR(n)->type)
     {
-      copy_shared_string(n->type,CDR(n)->type);
+      copy_type(n->type,CDR(n)->type);
     }else{
       n->type = or_pike_types(CAR(n)->type, CDR(n)->type, 0);
     }
@@ -2993,7 +2993,7 @@ void fix_type_field(node *n)
   case F_ASSIGN:
     if (!CAR(n) || (CAR(n)->type == void_type_string)) {
       my_yyerror("Assigning a void expression.");
-      copy_shared_string(n->type, void_type_string);
+      copy_type(n->type, void_type_string);
       break;
     } else if(CAR(n) && CDR(n)) {
       /* Ensure that the type-fields are up to date. */
@@ -3030,7 +3030,7 @@ void fix_type_field(node *n)
     if (!CAR(n) || (CAR(n)->type == void_type_string)) {
       my_yyerror("Indexing a void expression.");
       /* The optimizer converts this to an expression returning 0. */
-      copy_shared_string(n->type, zero_type_string);
+      copy_type(n->type, zero_type_string);
     } else {
       type_a=CAR(n)->type;
       type_b=CDR(n)->type;
@@ -3045,8 +3045,8 @@ void fix_type_field(node *n)
     if (!CAR(n) || (CAR(n)->type == void_type_string)) {
       my_yyerror("Calling a void expression.");
     } else {
-      struct pike_string *s;
-      struct pike_string *f;
+      struct pike_type *s;
+      struct pike_type *f;
       char *name;
       INT32 max_args,args;
 
@@ -3071,7 +3071,7 @@ void fix_type_field(node *n)
 
       if (n->type) {
 	/* Type/argument-check OK. */
-	free_string(s);
+	free_type(s);
 	break;
       }
 
@@ -3166,8 +3166,8 @@ void fix_type_field(node *n)
       {
 	if(TEST_COMPAT(0,6))
 	{
-	  free_string(s);
-	  copy_shared_string(n->type, mixed_type_string);
+	  free_type(s);
+	  copy_type(n->type, mixed_type_string);
 	  break;
 	}
 	my_yyerror("Too many arguments to %s.",name);
@@ -3184,9 +3184,9 @@ void fix_type_field(node *n)
 
       /* print_tree(n); */
 
-      free_string(s);
+      free_type(s);
     }
-    copy_shared_string(n->type, mixed_type_string);
+    copy_type(n->type, mixed_type_string);
     break;
 
   case '?':
@@ -3199,13 +3199,13 @@ void fix_type_field(node *n)
        CADR(n)->type == void_type_string ||
        CDDR(n)->type == void_type_string)
     {
-      copy_shared_string(n->type,void_type_string);
+      copy_type(n->type, void_type_string);
       break;
     }
     
     if(CADR(n)->type == CDDR(n)->type)
     {
-      copy_shared_string(n->type,CADR(n)->type);
+      copy_type(n->type, CADR(n)->type);
       break;
     }
 
@@ -3233,9 +3233,9 @@ void fix_type_field(node *n)
     if (CAR(n)) {
       /* The expression gets the type from the variable. */
       /* FIXME: Ought to strip non-applicable subtypes from the type. */
-      copy_shared_string(n->type, CAR(n)->type);
+      copy_type(n->type, CAR(n)->type);
     } else {
-      copy_shared_string(n->type, mixed_type_string);
+      copy_type(n->type, mixed_type_string);
     }
     break;
 
@@ -3247,7 +3247,7 @@ void fix_type_field(node *n)
 	sub_node(n);
 #endif /* SHARED_NODES */
 	_CAR(n) = mkintnode(0);
-	copy_shared_string(n->type, CAR(n)->type);
+	copy_type(n->type, CAR(n)->type);
 #ifdef SHARED_NODES
 	if (!(n->tree_info & OPT_NOT_SHARED)) {
 	  n->hash = hash_node(n);
@@ -3257,15 +3257,18 @@ void fix_type_field(node *n)
 #endif /* SHARED_NODES */
 	break;
       }
-    } else if(Pike_compiler->compiler_frame && Pike_compiler->compiler_frame->current_return_type) {
-      if (!pike_types_le(CAR(n)->type, Pike_compiler->compiler_frame->current_return_type) &&
-	    !(
-	      Pike_compiler->compiler_frame->current_return_type==void_type_string &&
-	      CAR(n)->token == F_CONSTANT &&
-	      IS_ZERO(& CAR(n)->u.sval)
-	      )
+    } else if(Pike_compiler->compiler_frame &&
+	      Pike_compiler->compiler_frame->current_return_type) {
+      if (!pike_types_le(CAR(n)->type,
+			 Pike_compiler->compiler_frame->current_return_type) &&
+	  !(
+	    Pike_compiler->compiler_frame->current_return_type==void_type_string &&
+	    CAR(n)->token == F_CONSTANT &&
+	    IS_ZERO(& CAR(n)->u.sval)
+	    )
 	  ) {
-	if (!match_types(Pike_compiler->compiler_frame->current_return_type,CAR(n)->type))
+	if (!match_types(Pike_compiler->compiler_frame->current_return_type,
+			 CAR(n)->type))
 	{
 	  yyerror("Wrong return type.");
 	  yyexplain_nonmatching_types(Pike_compiler->compiler_frame->current_return_type,
@@ -3280,7 +3283,7 @@ void fix_type_field(node *n)
 	}
       }
     }
-    copy_shared_string(n->type,void_type_string);
+    copy_type(n->type, void_type_string);
     break;
 
   case F_CASE:
@@ -3320,7 +3323,7 @@ void fix_type_field(node *n)
   case F_BREAK:
   case F_DEFAULT:
   case F_POP_VALUE:
-    copy_shared_string(n->type,void_type_string);
+    copy_type(n->type, void_type_string);
     break;
 
   case F_DO:
@@ -3328,7 +3331,7 @@ void fix_type_field(node *n)
       yyerror("do - while(): Conditional expression is void.");
     } else if(!match_types(CDR(n)->type,mixed_type_string))
       yyerror("Bad conditional expression do - while().");
-    copy_shared_string(n->type,void_type_string);
+    copy_type(n->type, void_type_string);
     break;
     
   case F_FOR:
@@ -3336,7 +3339,7 @@ void fix_type_field(node *n)
       yyerror("for(): Conditional expression is void.");
     } else if(!match_types(CAR(n)->type,mixed_type_string))
       yyerror("Bad conditional expression for().");
-    copy_shared_string(n->type,void_type_string);
+    copy_type(n->type, void_type_string);
     break;
 
   case F_SWITCH:
@@ -3344,7 +3347,7 @@ void fix_type_field(node *n)
       yyerror("switch(): Conditional expression is void.");
     } else if(!match_types(CAR(n)->type,mixed_type_string))
       yyerror("Bad switch expression.");
-    copy_shared_string(n->type,void_type_string);
+    copy_type(n->type, void_type_string);
     break;
 
   case F_CONSTANT:
@@ -3358,7 +3361,7 @@ void fix_type_field(node *n)
       if (!CAAR(n) || pike_types_le(CAAR(n)->type, void_type_string)) {
 	yyerror("foreach(): Looping over a void expression.");
       } else {
-	struct pike_string *array_zero;
+	struct pike_type *array_zero;
 	MAKE_CONSTANT_SHARED_STRING(array_zero, tArr(tZero));
 
 	if (!pike_types_le(array_zero, CAAR(n)->type)) {
@@ -3375,7 +3378,7 @@ void fix_type_field(node *n)
 	  if (!CDAR(n) || pike_types_le(CDAR(n)->type, void_type_string)) {
 	    yyerror("Bad argument 2 to foreach().");
 	  } else {
-	    struct pike_string *value_type = array_value_type(CAAR(n)->type);
+	    struct pike_type *value_type = array_value_type(CAAR(n)->type);
 
 	    if (!pike_types_le(value_type, CDAR(n)->type)) {
 	      if (!match_types(value_type, CDAR(n)->type)) {
@@ -3386,13 +3389,13 @@ void fix_type_field(node *n)
 			     value_type, CDAR(n)->type, YYTE_IS_WARNING);
 	      }
 	    }
-	    free_string(value_type);
+	    free_type(value_type);
 	  }
 	}
-	free_string(array_zero);
+	free_type(array_zero);
       }
     }
-    copy_shared_string(n->type, void_type_string);
+    copy_type(n->type, void_type_string);
     break;
 
   case F_SSCANF:
@@ -3436,24 +3439,24 @@ void fix_type_field(node *n)
     if(!CAR(n) || CAR(n)->type==void_type_string)
     {
       if(CDR(n))
-	copy_shared_string(n->type,CDR(n)->type);
+	copy_type(n->type, CDR(n)->type);
       else
-	copy_shared_string(n->type,void_type_string);
+	copy_type(n->type, void_type_string);
       break;
     }
 
     if(!CDR(n) || CDR(n)->type==void_type_string)
     {
       if(CAR(n))
-	copy_shared_string(n->type,CAR(n)->type);
+	copy_type(n->type, CAR(n)->type);
       else
-	copy_shared_string(n->type,void_type_string);
+	copy_type(n->type, void_type_string);
       break;
     }
     if (n->token == F_ARG_LIST) {
       n->type = or_pike_types(CAR(n)->type, CDR(n)->type, 0);
     } else {
-      copy_shared_string(n->type, CDR(n)->type);
+      copy_type(n->type, CDR(n)->type);
     }
     break;
 
@@ -3469,7 +3472,7 @@ void fix_type_field(node *n)
   case F_CATCH:
     /* FALL_THROUGH */
   default:
-    copy_shared_string(n->type,mixed_type_string);
+    copy_type(n->type, mixed_type_string);
   }
 
   if (n->type != old_type) {
@@ -3478,7 +3481,7 @@ void fix_type_field(node *n)
     }
   }
   if (old_type) {
-    free_string(old_type);
+    free_type(old_type);
   }
 #ifdef PIKE_DEBUG
   check_type_string(n->type);
@@ -3813,15 +3816,15 @@ static node *low_localopt(node *n,
       /* Assignment of local variable */
       if (!(usage[CDR(n)->u.integer.a] & 1)) {
 	/* Value isn't used. */
-	struct pike_string *ref_type;
+	struct pike_type *ref_type;
 	MAKE_CONSTANT_SHARED_STRING(ref_type, tOr(tComplex, tString));
 	if (!match_types(CDR(n)->type, ref_type)) {
 	  /* The variable doesn't hold a refcounted value. */
-	  free_string(ref_type);
+	  free_type(ref_type);
 	  return low_localopt(CAR(n), usage, switch_u, cont_u,
 			      break_u, catch_u);
 	}
-	free_string(ref_type);
+	free_type(ref_type);
       }
       usage[CDR(n)->u.integer.a] = 0;
       cdr = CDR(n);
@@ -4700,7 +4703,7 @@ static int is_null_branch(node *n)
 static struct svalue *is_stupid_func(node *n,
 				     int args,
 				     int vargs,
-				     struct pike_string *type)
+				     struct pike_type *type)
 {
   node *a,*b;
   int tmp;
@@ -4748,7 +4751,7 @@ static struct svalue *is_stupid_func(node *n,
 
 int dooptcode(struct pike_string *name,
 	      node *n,
-	      struct pike_string *type,
+	      struct pike_type *type,
 	      int modifiers)
 {
   union idptr tmp;
diff --git a/src/las.h b/src/las.h
index 907857940a55efe9be5cc0130ba4f5f0e5e2a5d0..3d549959d8a219a7ecfd8d0a6f027f9a843bad65 100644
--- a/src/las.h
+++ b/src/las.h
@@ -5,7 +5,7 @@
 \*/
 
 /*
- * $Id: las.h,v 1.46 2001/02/09 10:29:54 hubbe Exp $
+ * $Id: las.h,v 1.47 2001/02/19 23:50:01 grubba Exp $
  */
 #ifndef LAS_H
 #define LAS_H
@@ -24,8 +24,8 @@ typedef void (*c_fun)(INT32);
 /* Flags used by yytype_error() */
 #define YYTE_IS_WARNING	1
 
-void yytype_error(char *msg, struct pike_string *expected_t,
-		  struct pike_string *got_t, unsigned int flags);
+void yytype_error(char *msg, struct pike_type *expected_t,
+		  struct pike_type *got_t, unsigned int flags);
 void yyerror(char *s);
 int islocal(struct pike_string *str);
 int verify_declared(struct pike_string *str);
@@ -36,7 +36,7 @@ extern int cumulative_parse_error;
 struct local_variable
 {
   struct pike_string *name;
-  struct pike_string *type;
+  struct pike_type *type;
   node *def;
   struct pike_string *file;
   int line;
@@ -46,8 +46,8 @@ struct compiler_frame
 {
   struct compiler_frame *previous;
 
-  struct pike_string *current_type;
-  struct pike_string *current_return_type;
+  struct pike_type *current_type;
+  struct pike_type *current_return_type;
   int current_number_of_locals;
   int max_number_of_locals;
   int last_block_level; /* used to detect variables declared in same block */
@@ -118,7 +118,7 @@ int car_is_node(node *n);
 int cdr_is_node(node *n);
 void check_tree(node *n, int depth);
 INT32 count_args(node *n);
-struct pike_string *find_return_type(node *n);
+struct pike_type *find_return_type(node *n);
 int check_tailrecursion(void);
 struct node_chunk;
 void free_all_nodes(void);
@@ -137,14 +137,14 @@ node *debug_mklocalnode(int var, int depth);
 node *debug_mkidentifiernode(int i);
 node *debug_mktrampolinenode(int i);
 node *debug_mkexternalnode(struct program *prog, int i);
-node *debug_mkcastnode(struct pike_string *type,node *n);
-node *debug_mksoftcastnode(struct pike_string *type,node *n);
+node *debug_mkcastnode(struct pike_type *type, node *n);
+node *debug_mksoftcastnode(struct pike_type *type, node *n);
 void resolv_constant(node *n);
 void resolv_class(node *n);
 void resolv_class(node *n);
 node *index_node(node *n, char *node_name, struct pike_string *id);
 int node_is_eq(node *a,node *b);
-node *debug_mktypenode(struct pike_string *t);
+node *debug_mktypenode(struct pike_type *t);
 node *debug_mkconstantsvaluenode(struct svalue *s);
 node *debug_mkliteralsvaluenode(struct svalue *s);
 node *debug_mksvaluenode(struct svalue *s);
@@ -164,7 +164,7 @@ struct timer_oflo;
 ptrdiff_t eval_low(node *n);
 int dooptcode(struct pike_string *name,
 	      node *n,
-	      struct pike_string *type,
+	      struct pike_type *type,
 	      int modifiers);
 void resolv_program(node *n);
 /* Prototypes end here */
diff --git a/src/opcodes.c b/src/opcodes.c
index f02ca96496b4355a6b76d018f422ec420fd9e803..8242d62ee8e1f8a637fa6f9e037ed066e487b30b 100644
--- a/src/opcodes.c
+++ b/src/opcodes.c
@@ -26,7 +26,7 @@
 #include "bignum.h"
 #include "operators.h"
 
-RCSID("$Id: opcodes.c,v 1.98 2001/01/31 15:11:28 grubba Exp $");
+RCSID("$Id: opcodes.c,v 1.99 2001/02/19 23:50:01 grubba Exp $");
 
 void index_no_free(struct svalue *to,struct svalue *what,struct svalue *ind)
 {
@@ -132,7 +132,7 @@ void o_index(void)
   sp++;
 }
 
-void o_cast(struct pike_string *type, INT32 run_time_type)
+void o_cast(struct pike_type *type, INT32 run_time_type)
 {
   INT32 i;
 
@@ -492,10 +492,10 @@ void o_cast(struct pike_string *type, INT32 run_time_type)
   {
     case T_ARRAY:
     {
-      struct pike_string *itype;
+      struct pike_type *itype;
       INT32 run_time_itype;
 
-      push_string(itype=index_type(type,int_type_string,0));
+      push_type_value(itype = index_type(type, int_type_string, 0));
       run_time_itype=compile_type_to_runtime_type(itype);
 
       if(run_time_itype != T_MIXED)
@@ -537,10 +537,10 @@ void o_cast(struct pike_string *type, INT32 run_time_type)
 
     case T_MULTISET:
     {
-      struct pike_string *itype;
+      struct pike_type *itype;
       INT32 run_time_itype;
 
-      push_string(itype=key_type(type,0));
+      push_type_value(itype = key_type(type, 0));
       run_time_itype=compile_type_to_runtime_type(itype);
 
       if(run_time_itype != T_MIXED)
@@ -585,14 +585,14 @@ void o_cast(struct pike_string *type, INT32 run_time_type)
 
     case T_MAPPING:
     {
-      struct pike_string *itype,*vtype;
+      struct pike_type *itype, *vtype;
       INT32 run_time_itype;
       INT32 run_time_vtype;
 
-      push_string(itype=key_type(type,0));
+      push_type_value(itype = key_type(type, 0));
       run_time_itype=compile_type_to_runtime_type(itype);
 
-      push_string(vtype=index_type(type,mixed_type_string,0));
+      push_type_value(vtype = index_type(type, mixed_type_string, 0));
       run_time_vtype=compile_type_to_runtime_type(vtype);
 
       if(run_time_itype != T_MIXED ||
@@ -643,10 +643,10 @@ PMOD_EXPORT void f_cast(void)
 {
 #ifdef PIKE_DEBUG
   struct svalue *save_sp=sp;
-  if(sp[-2].type != T_STRING)
+  if(sp[-2].type != T_TYPE)
     fatal("Cast expression destroyed stack or left droppings!\n");
 #endif
-  o_cast(sp[-2].u.string,
+  o_cast(sp[-2].u.type,
 	 compile_type_to_runtime_type(sp[-2].u.string));
 #ifdef PIKE_DEBUG
   if(save_sp != sp)
diff --git a/src/opcodes.h b/src/opcodes.h
index 62291e2d8190db21ce7518b0c06e7431b091010c..109f70880ff21aa6ac7cd4257acb197d1460ebb6 100644
--- a/src/opcodes.h
+++ b/src/opcodes.h
@@ -5,7 +5,7 @@
 \*/
 
 /*
- * $Id: opcodes.h,v 1.11 2001/01/31 21:54:33 mast Exp $
+ * $Id: opcodes.h,v 1.12 2001/02/19 23:50:01 grubba Exp $
  */
 #ifndef OPCODES_H
 #define OPCODES_H
@@ -152,7 +152,7 @@ enum Pike_opcodes
 /* Prototypes begin here */
 void index_no_free(struct svalue *to,struct svalue *what,struct svalue *ind);
 void o_index(void);
-void o_cast(struct pike_string *type, INT32 run_time_type);
+void o_cast(struct pike_type *type, INT32 run_time_type);
 PMOD_EXPORT void f_cast(void);
 void o_sscanf(INT32 args);
 PMOD_EXPORT void f_sscanf(INT32 args);
diff --git a/src/pike_types.c b/src/pike_types.c
index a64e86cc743bf2505689e322ec720a7ab63f2bed..2fb46145382f287147ff22b8ff12ce74836295a1 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.146 2001/02/09 10:29:54 hubbe Exp $");
+RCSID("$Id: pike_types.c,v 1.147 2001/02/19 23:50:02 grubba Exp $");
 #include <ctype.h>
 #include "svalue.h"
 #include "pike_types.h"
@@ -68,23 +68,23 @@ static int low_check_indexing(char *type, char *index_type, node *n);
  * Everything except T_VOID matches T_ZERO.
  */
 
-PMOD_EXPORT struct pike_string *string_type_string;
-PMOD_EXPORT struct pike_string *int_type_string;
-PMOD_EXPORT struct pike_string *float_type_string;
-PMOD_EXPORT struct pike_string *function_type_string;
-PMOD_EXPORT struct pike_string *object_type_string;
-PMOD_EXPORT struct pike_string *program_type_string;
-PMOD_EXPORT struct pike_string *array_type_string;
-PMOD_EXPORT struct pike_string *multiset_type_string;
-PMOD_EXPORT struct pike_string *mapping_type_string;
-PMOD_EXPORT struct pike_string *type_type_string;
-PMOD_EXPORT struct pike_string *mixed_type_string;
-PMOD_EXPORT struct pike_string *void_type_string;
-PMOD_EXPORT struct pike_string *zero_type_string;
-PMOD_EXPORT struct pike_string *any_type_string;
-PMOD_EXPORT struct pike_string *weak_type_string;	/* array|mapping|multiset|function */
-
-static struct pike_string *a_markers[10],*b_markers[10];
+PMOD_EXPORT struct pike_type *string_type_string;
+PMOD_EXPORT struct pike_type *int_type_string;
+PMOD_EXPORT struct pike_type *float_type_string;
+PMOD_EXPORT struct pike_type *function_type_string;
+PMOD_EXPORT struct pike_type *object_type_string;
+PMOD_EXPORT struct pike_type *program_type_string;
+PMOD_EXPORT struct pike_type *array_type_string;
+PMOD_EXPORT struct pike_type *multiset_type_string;
+PMOD_EXPORT struct pike_type *mapping_type_string;
+PMOD_EXPORT struct pike_type *type_type_string;
+PMOD_EXPORT struct pike_type *mixed_type_string;
+PMOD_EXPORT struct pike_type *void_type_string;
+PMOD_EXPORT struct pike_type *zero_type_string;
+PMOD_EXPORT struct pike_type *any_type_string;
+PMOD_EXPORT struct pike_type *weak_type_string;	/* array|mapping|multiset|function */
+
+static struct pike_type *a_markers[10],*b_markers[10];
 
 static struct program *implements_a;
 static struct program *implements_b;
@@ -96,19 +96,19 @@ static void clear_markers(void)
   {
     if(a_markers[e])
     {
-      free_string(a_markers[e]);
+      free_type(a_markers[e]);
       a_markers[e]=0;
     }
     if(b_markers[e])
     {
-      free_string(b_markers[e]);
+      free_type(b_markers[e]);
       b_markers[e]=0;
     }
   }
 }
 
 #ifdef PIKE_DEBUG
-void check_type_string(struct pike_string *s)
+void check_type_string(struct pike_type *s)
 {
   if(debug_findstring(s) != s)
     fatal("Type string not shared.\n");
@@ -275,7 +275,7 @@ void push_unfinished_type(char *s)
 }
 
 static void push_unfinished_type_with_markers(char *s,
-					      struct pike_string **am)
+					      struct pike_type **am)
 {
   int d,e,c;
   ptrdiff_t len=type_length(s);
@@ -323,14 +323,14 @@ static void push_unfinished_type_with_markers(char *s,
   type_stack_reverse();
 }
 
-void push_finished_type(struct pike_string *type)
+void push_finished_type(struct pike_type *type)
 {
   ptrdiff_t e;
   check_type_string(type);
   for(e=type->len-1;e>=0;e--) push_type(type->str[e]);
 }
 
-void push_finished_type_backwards(struct pike_string *type)
+void push_finished_type_backwards(struct pike_type *type)
 {
   int e;
   check_type_string(type);
@@ -338,10 +338,10 @@ void push_finished_type_backwards(struct pike_string *type)
   Pike_compiler->type_stackp+=type->len;
 }
 
-struct pike_string *debug_pop_unfinished_type(void)
+struct pike_type *debug_pop_unfinished_type(void)
 {
   ptrdiff_t len, e;
-  struct pike_string *s;
+  struct pike_type *s;
   len=pop_stack_mark();
   s=begin_shared_string(len);
   Pike_compiler->type_stackp-=len;
@@ -352,15 +352,15 @@ struct pike_string *debug_pop_unfinished_type(void)
   return s;
 }
 
-struct pike_string *debug_pop_type(void)
+struct pike_type *debug_pop_type(void)
 {
-  struct pike_string *s;
+  struct pike_type *s;
   s=pop_unfinished_type();
   type_stack_mark();
   return s;
 }
 
-struct pike_string *debug_compiler_pop_type(void)
+struct pike_type *debug_compiler_pop_type(void)
 {
   if(Pike_compiler->num_parse_error)
   {
@@ -373,7 +373,7 @@ struct pike_string *debug_compiler_pop_type(void)
     reference_shared_string(mixed_type_string);
     return mixed_type_string;
   }else{
-    struct pike_string *s;
+    struct pike_type *s;
     s=pop_unfinished_type();
     type_stack_mark();
     return s;
@@ -733,9 +733,9 @@ static void internal_parse_type(char **s)
  * It takes a string on the exact same format as Pike and returns a type
  * struct.
  */
-struct pike_string *parse_type(char *s)
+struct pike_type *parse_type(char *s)
 {
-  struct pike_string *ret;
+  struct pike_type *ret;
 #ifdef PIKE_DEBUG
   unsigned char *ts=Pike_compiler->type_stackp;
   unsigned char **ptms=Pike_compiler->pike_type_mark_stackp;
@@ -813,7 +813,7 @@ void stupid_describe_type(char *a, ptrdiff_t len)
   printf("\n");
 }
 
-void simple_describe_type(struct pike_string *s)
+void simple_describe_type(struct pike_type *s)
 {
   stupid_describe_type(s->str,s->len);
 }
@@ -1040,7 +1040,7 @@ char *low_describe_type(char *t)
   return t;
 }
 
-struct pike_string *describe_type(struct pike_string *type)
+struct pike_string *describe_type(struct pike_type *type)
 {
   check_type_string(type);
   if(!type) return make_shared_string("mixed");
@@ -1094,7 +1094,7 @@ static TYPE_T low_compile_type_to_runtime_type(char *t)
   }
 }
 
-TYPE_T compile_type_to_runtime_type(struct pike_string *s)
+TYPE_T compile_type_to_runtime_type(struct pike_type *s)
 {
   return low_compile_type_to_runtime_type(s->str);
 }
@@ -1200,16 +1200,16 @@ static void low_or_pike_types(char *t1, char *t2, int zero_implied)
   }
 }
 
-static void medium_or_pike_types(struct pike_string *a,
-				 struct pike_string *b,
+static void medium_or_pike_types(struct pike_type *a,
+				 struct pike_type *b,
 				 int zero_implied)
 {
   low_or_pike_types( a ? a->str : 0 , b ? b->str : 0 , zero_implied);
 }
 
-struct pike_string *or_pike_types(struct pike_string *a,
-				  struct pike_string *b,
-				  int zero_implied)
+struct pike_type *or_pike_types(struct pike_type *a,
+				struct pike_type *b,
+				int zero_implied)
 {
   type_stack_mark();
   medium_or_pike_types(a,b,1 /*zero_implied*/);
@@ -1422,21 +1422,21 @@ static void low_and_pike_types(char *t1, char *t2)
   }
 }
 
-static void medium_and_pike_types(struct pike_string *a,
-				  struct pike_string *b)
+static void medium_and_pike_types(struct pike_type *a,
+				  struct pike_type *b)
 {
   low_and_pike_types( a ? a->str : 0 , b ? b->str : 0 );
 }
 
-struct pike_string *and_pike_types(struct pike_string *a,
-				   struct pike_string *b)
+struct pike_type *and_pike_types(struct pike_type *a,
+				 struct pike_type *b)
 {
   type_stack_mark();
   medium_and_pike_types(a,b);
   return pop_unfinished_type();
 }
 
-static struct pike_string *low_object_lfun_type(char *t, short lfun)
+static struct pike_type *low_object_lfun_type(char *t, short lfun)
 {
   struct program *p;
   int i;
@@ -1581,15 +1581,15 @@ static char *low_match_types2(char *a,char *b, int flags)
       if(ret && EXTRACT_UCHAR(b)!=T_VOID)
       {
 	int m=EXTRACT_UCHAR(a+1)-'0';
-	struct pike_string *tmp;
+	struct pike_type *tmp;
 	type_stack_mark();
 	push_unfinished_type_with_markers(b, b_markers);
 	tmp=pop_unfinished_type();
 
 	type_stack_mark();
 	medium_or_pike_types(a_markers[m], tmp, 0);
-	if(a_markers[m]) free_string(a_markers[m]);
-	free_string(tmp);
+	if(a_markers[m]) free_type(a_markers[m]);
+	free_type(tmp);
 	a_markers[m]=pop_unfinished_type();
 
 #ifdef PIKE_TYPE_DEBUG
@@ -1666,15 +1666,15 @@ static char *low_match_types2(char *a,char *b, int flags)
       if(ret && EXTRACT_UCHAR(a)!=T_VOID)
       {
 	int m=EXTRACT_UCHAR(b+1)-'0';
-	struct pike_string *tmp;
+	struct pike_type *tmp;
 	type_stack_mark();
 	push_unfinished_type_with_markers(a, a_markers);
 	tmp=pop_unfinished_type();
 
 	type_stack_mark();
 	medium_or_pike_types(b_markers[m], tmp, 0);
-	if(b_markers[m]) free_string(b_markers[m]);
-	free_string(tmp);
+	if(b_markers[m]) free_type(b_markers[m]);
+	free_type(tmp);
 	b_markers[m]=pop_unfinished_type();
 #ifdef PIKE_TYPE_DEBUG
 	if (l_flag>2) {
@@ -1782,7 +1782,7 @@ static char *low_match_types2(char *a,char *b, int flags)
 
   case TWOT(T_OBJECT, T_FUNCTION):
   {
-    struct pike_string *s;
+    struct pike_type *s;
     if((s=low_object_lfun_type(a, LFUN_CALL)))
        return low_match_types(s->str,b,flags);
     if (flags & B_EXACT) {
@@ -1794,7 +1794,7 @@ static char *low_match_types2(char *a,char *b, int flags)
 
   case TWOT(T_FUNCTION, T_OBJECT):
   {
-    struct pike_string *s;
+    struct pike_type *s;
     if((s=low_object_lfun_type(b, LFUN_CALL)))
        return low_match_types(a,s->str,flags);
     if (flags & A_EXACT) {
@@ -2093,7 +2093,7 @@ static int low_pike_types_le2(char *a, char *b,
     if(ret && EXTRACT_UCHAR(b)!=T_VOID)
     {
       int m=EXTRACT_UCHAR(a+1)-'0';
-      struct pike_string *tmp;
+      struct pike_type *tmp;
       int i;
       type_stack_mark();
       push_unfinished_type_with_markers(b, b_markers);
@@ -2103,8 +2103,8 @@ static int low_pike_types_le2(char *a, char *b,
       
       type_stack_mark();
       medium_or_pike_types(a_markers[m], tmp, 0);
-      if(a_markers[m]) free_string(a_markers[m]);
-      free_string(tmp);
+      if(a_markers[m]) free_type(a_markers[m]);
+      free_type(tmp);
       a_markers[m]=pop_unfinished_type();
 #ifdef PIKE_TYPE_DEBUG
       if (l_flag>2) {
@@ -2168,7 +2168,7 @@ static int low_pike_types_le2(char *a, char *b,
     if(ret && EXTRACT_UCHAR(a)!=T_VOID)
     {
       int m=EXTRACT_UCHAR(b+1)-'0';
-      struct pike_string *tmp;
+      struct pike_type *tmp;
       int i;
       type_stack_mark();
       push_unfinished_type_with_markers(a, a_markers);
@@ -2178,8 +2178,8 @@ static int low_pike_types_le2(char *a, char *b,
       
       type_stack_mark();
       medium_or_pike_types(b_markers[m], tmp, 0);
-      if(b_markers[m]) free_string(b_markers[m]);
-      free_string(tmp);
+      if(b_markers[m]) free_type(b_markers[m]);
+      free_type(tmp);
       b_markers[m]=pop_unfinished_type();
 #ifdef PIKE_TYPE_DEBUG
       if (l_flag>2) {
@@ -2283,7 +2283,7 @@ static int low_pike_types_le2(char *a, char *b,
 
   case TWOT(T_OBJECT, T_FUNCTION):
     {
-      struct pike_string *s;
+      struct pike_type *s;
       if((s=low_object_lfun_type(a, LFUN_CALL)))
 	return low_pike_types_le(s->str, b, array_cnt, flags);
       return 1;
@@ -2291,7 +2291,7 @@ static int low_pike_types_le2(char *a, char *b,
 
   case TWOT(T_FUNCTION, T_OBJECT):
     {
-      struct pike_string *s;
+      struct pike_type *s;
       if((s=low_object_lfun_type(b, LFUN_CALL)))
 	return low_pike_types_le(a, s->str, array_cnt, flags);
       return 1;
@@ -2497,7 +2497,7 @@ int strict_check_call(char *fun_type, char *arg_type)
  * Note: This uses a weaker check of function arguments, since
  *       people get confused otherwise.
  */
-int check_soft_cast(struct pike_string *to, struct pike_string *from)
+int check_soft_cast(struct pike_type *to, struct pike_type *from)
 {
   return low_pike_types_le(to->str, from->str, 0, LE_WEAK_OBJECTS);
 }
@@ -2512,7 +2512,7 @@ static int low_get_return_type(char *a,char *b)
   {
   case T_OR:
     {
-      struct pike_string *o1,*o2;
+      struct pike_type *o1, *o2;
       a++;
       o1=o2=0;
 
@@ -2532,8 +2532,8 @@ static int low_get_return_type(char *a,char *b)
 
       medium_or_pike_types(o1,o2, 0);
 
-      if(o1) free_string(o1);
-      if(o2) free_string(o2);
+      if(o1) free_type(o1);
+      if(o2) free_type(o2);
 
       return 1;
     }
@@ -2588,7 +2588,7 @@ static int low_get_return_type(char *a,char *b)
 }
 
 
-int match_types(struct pike_string *a,struct pike_string *b)
+int match_types(struct pike_type *a, struct pike_type *b)
 {
   check_type_string(a);
   check_type_string(b);
@@ -2596,7 +2596,7 @@ int match_types(struct pike_string *a,struct pike_string *b)
   return 0!=low_match_types(a->str, b->str,0);
 }
 
-int pike_types_le(struct pike_string *a,struct pike_string *b)
+int pike_types_le(struct pike_type *a, struct pike_type *b)
 {
   check_type_string(a);
   check_type_string(b);
@@ -2606,17 +2606,17 @@ int pike_types_le(struct pike_string *a,struct pike_string *b)
 
 
 #ifdef DEBUG_MALLOC
-#define low_index_type(X,Y,Z) ((struct pike_string *)debug_malloc_pass(debug_low_index_type((X),(Y),(Z))))
+#define low_index_type(X,Y,Z) ((struct pike_type *)debug_malloc_pass(debug_low_index_type((X),(Y),(Z))))
 #else
 #define low_index_type debug_low_index_type
 #endif
 
 /* FIXME, add the index */
-static struct pike_string *debug_low_index_type(char *t,
-						char *index_type,
-						node *n)
+static struct pike_type *debug_low_index_type(char *t,
+					      char *index_type,
+					      node *n)
 {
-  struct pike_string *tmp;
+  struct pike_type *tmp;
   struct program *p;
 
   switch(low_check_indexing(t, index_type, n))
@@ -2722,7 +2722,7 @@ static struct pike_string *debug_low_index_type(char *t,
 
   case T_OR:
   {
-    struct pike_string *a,*b;
+    struct pike_type *a, *b;
     a=low_index_type(t,index_type,n);
     t+=type_length(t);
     b=low_index_type(t,index_type,n);
@@ -2730,8 +2730,8 @@ static struct pike_string *debug_low_index_type(char *t,
     if(!a) return b;
     type_stack_mark();
     medium_or_pike_types(a,b,1);
-    free_string(a);
-    free_string(b);
+    free_type(a);
+    free_type(b);
     return pop_unfinished_type();
   }
 
@@ -2749,14 +2749,14 @@ static struct pike_string *debug_low_index_type(char *t,
 
   case T_ARRAY:
     {
-      struct pike_string *a;
+      struct pike_type *a;
 
       if(low_pike_types_le(tString, index_type, 0, 0) &&
 	 (a = low_index_type(t, tString, n))) {
 	/* Possible to index the array with a string. */
 	type_stack_mark();
 	push_finished_type(a);
-	free_string(a);
+	free_type(a);
 	push_type(T_ARRAY);
 
 	if (low_match_types(tInt, index_type, 0)) {
@@ -2776,11 +2776,11 @@ static struct pike_string *debug_low_index_type(char *t,
   }
 }
 
-struct pike_string *index_type(struct pike_string *type,
-			       struct pike_string *index_type,
-			       node *n)
+struct pike_type *index_type(struct pike_type *type,
+			     struct pike_type *index_type,
+			     node *n)
 {
-  struct pike_string *t;
+  struct pike_type *t;
   clear_markers();
   t=low_index_type(type->str,index_type->str,n);
   if(!t) copy_shared_string(t,mixed_type_string);
@@ -2788,10 +2788,10 @@ struct pike_string *index_type(struct pike_string *type,
 }
 
 
-static struct pike_string *low_array_value_type(char *arr_t)
+static struct pike_type *low_array_value_type(char *arr_t)
 {
-  struct pike_string *res = NULL;
-  struct pike_string *sub_t;
+  struct pike_type *res = NULL;
+  struct pike_type *sub_t;
 
   while (EXTRACT_UCHAR(arr_t) == T_OR) {
     arr_t++;
@@ -2799,9 +2799,9 @@ static struct pike_string *low_array_value_type(char *arr_t)
     arr_t += type_length(arr_t);
     if (sub_t) {
       if (res) {
-	struct pike_string *new = or_pike_types(res, sub_t, 1);
-	free_string(res);
-	free_string(sub_t);
+	struct pike_type *new = or_pike_types(res, sub_t, 1);
+	free_type(res);
+	free_type(sub_t);
 	res = new;
       } else {
 	res = sub_t;
@@ -2813,30 +2813,30 @@ static struct pike_string *low_array_value_type(char *arr_t)
   arr_t++;
   sub_t = make_shared_binary_string(arr_t, type_length(arr_t));
   if (res) {
-    struct pike_string *new = or_pike_types(res, sub_t, 1);
-    free_string(res);
-    free_string(sub_t);
+    struct pike_type *new = or_pike_types(res, sub_t, 1);
+    free_type(res);
+    free_type(sub_t);
     return new;
   }
   return sub_t;
 }
 
-struct pike_string *array_value_type(struct pike_string *array_type)
+struct pike_type *array_value_type(struct pike_type *array_type)
 {
-  struct pike_string *t = low_array_value_type(array_type->str);
+  struct pike_type *t = low_array_value_type(array_type->str);
   if (!t) copy_shared_string(t, mixed_type_string);
   return t;
 }
 
 
 #ifdef DEBUG_MALLOC
-#define low_key_type(X,Y) ((struct pike_string *)debug_malloc_pass(debug_low_key_type((X),(Y))))
+#define low_key_type(X,Y) ((struct pike_type *)debug_malloc_pass(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)
+static struct pike_type *debug_low_key_type(char *t, node *n)
 {
   switch(EXTRACT_UCHAR(t++))
   {
@@ -2876,7 +2876,7 @@ static struct pike_string *debug_low_key_type(char *t, node *n)
 
   case T_OR:
   {
-    struct pike_string *a,*b;
+    struct pike_type *a, *b;
     a=low_key_type(t,n);
     t+=type_length(t);
     b=low_key_type(t,n);
@@ -2884,8 +2884,8 @@ static struct pike_string *debug_low_key_type(char *t, node *n)
     if(!a) return b;
     type_stack_mark();
     medium_or_pike_types(a,b,1);
-    free_string(a);
-    free_string(b);
+    free_type(a);
+    free_type(b);
     return pop_unfinished_type();
   }
 
@@ -2903,9 +2903,9 @@ static struct pike_string *debug_low_key_type(char *t, node *n)
   }
 }
 
-struct pike_string *key_type(struct pike_string *type, node *n)
+struct pike_type *key_type(struct pike_type *type, node *n)
 {
-  struct pike_string *t;
+  struct pike_type *t;
   clear_markers();
   t=low_key_type(type->str,n);
   if(!t) copy_shared_string(t,mixed_type_string);
@@ -2974,8 +2974,8 @@ static int low_check_indexing(char *type, char *index_type, node *n)
   }
 }
 				 
-int check_indexing(struct pike_string *type,
-		   struct pike_string *index_type,
+int check_indexing(struct pike_type *type,
+		   struct pike_type *index_type,
 		   node *n)
 {
   check_type_string(type);
@@ -3025,7 +3025,7 @@ static int low_count_arguments(char *q)
  * return -1-n if the function can take number of arguments
  * >= n  (varargs)
  */
-int count_arguments(struct pike_string *s)
+int count_arguments(struct pike_type *s)
 {
   check_type_string(s);
 
@@ -3062,7 +3062,7 @@ static int low_minimum_arguments(char *q)
 
 /* Count the minimum number of arguments for a funciton type.
  */
-int minimum_arguments(struct pike_string *s)
+int minimum_arguments(struct pike_type *s)
 {
   int ret;
   check_type_string(s);
@@ -3078,9 +3078,9 @@ int minimum_arguments(struct pike_string *s)
   return ret;
 }
 
-struct pike_string *check_call(struct pike_string *args,
-			       struct pike_string *type,
-			       int strict)
+struct pike_type *check_call(struct pike_type *args,
+			     struct pike_type *type,
+			     int strict)
 {
   check_type_string(args);
   check_type_string(type);
@@ -3115,32 +3115,32 @@ struct pike_string *check_call(struct pike_string *args,
   }
 }
 
-INT32 get_max_args(struct pike_string *type)
+INT32 get_max_args(struct pike_type *type)
 {
   INT32 ret,tmp=max_correct_args;
   check_type_string(type);
   clear_markers();
   type = check_call(function_type_string, type, 0);
-  if(type) free_string(type);
+  if(type) free_type(type);
   ret=max_correct_args;
   max_correct_args=tmp;
   return tmp;
 }
 
 
-struct pike_string *zzap_function_return(char *a, INT32 id)
+struct pike_type *zzap_function_return(char *a, INT32 id)
 {
   switch(EXTRACT_UCHAR(a))
   {
     case T_OR:
     {
-      struct pike_string *ar, *br, *ret=0;
+      struct pike_type *ar, *br, *ret=0;
       a++;
       ar=zzap_function_return(a,id);
       br=zzap_function_return(a+type_length(a),id);
       if(ar && br) ret=or_pike_types(ar,br,0);
-      if(ar) free_string(ar);
-      if(br) free_string(br);
+      if(ar) free_type(ar);
+      if(br) free_type(br);
       return ret;
     }
       
@@ -3182,9 +3182,9 @@ struct pike_string *zzap_function_return(char *a, INT32 id)
   return NULL;
 }
 
-struct pike_string *get_type_of_svalue(struct svalue *s)
+struct pike_type *get_type_of_svalue(struct svalue *s)
 {
-  struct pike_string *ret;
+  struct pike_type *ret;
   switch(s->type)
   {
   case T_FUNCTION:
@@ -3208,7 +3208,7 @@ struct pike_string *get_type_of_svalue(struct svalue *s)
   case T_MULTISET:
   case T_ARRAY:
     {
-      struct pike_string *arg_type;
+      struct pike_type *arg_type;
       struct array *a;
 
       if (s->type == T_MULTISET) {
@@ -3222,10 +3222,10 @@ struct pike_string *get_type_of_svalue(struct svalue *s)
       /* FIXME: Circular structures? */
       copy_shared_string(arg_type, zero_type_string);
       for (i = 0; i < a->size; i++) {
-	struct pike_string *tmp1 = get_type_of_svalue(a->item+i);
-	struct pike_string *tmp2 = or_pike_types(arg_type, tmp1, 1);
-	free_string(arg_type);
-	free_string(tmp1);
+	struct pike_type *tmp1 = get_type_of_svalue(a->item+i);
+	struct pike_type *tmp2 = or_pike_types(arg_type, tmp1, 1);
+	free_type(arg_type);
+	free_type(tmp1);
 	arg_type = tmp2;
       }
 #else /* !0 */
@@ -3236,7 +3236,7 @@ struct pike_string *get_type_of_svalue(struct svalue *s)
 #endif /* 0 */
       type_stack_mark();
       push_unfinished_type(arg_type->str);
-      free_string(arg_type);
+      free_type(arg_type);
       push_type(s->type);
       return pop_unfinished_type();
     }
@@ -3298,7 +3298,7 @@ struct pike_string *get_type_of_svalue(struct svalue *s)
   case T_PROGRAM:
   {
     char *a;
-    struct pike_string *tmp;
+    struct pike_type *tmp;
     int id;
 
     if(s->u.program->identifiers)
@@ -3333,10 +3333,10 @@ struct pike_string *get_type_of_svalue(struct svalue *s)
   }
 }
 
-static struct pike_string *low_object_type_to_program_type(char *obj_t)
+static struct pike_type *low_object_type_to_program_type(char *obj_t)
 {
-  struct pike_string *res = NULL;
-  struct pike_string *sub;
+  struct pike_type *res = NULL;
+  struct pike_type *sub;
   struct svalue sval;
   int id;
 
@@ -3345,14 +3345,14 @@ static struct pike_string *low_object_type_to_program_type(char *obj_t)
     sub = low_object_type_to_program_type(obj_t);
     if (!sub) {
       if (res) {
-	free_string(res);
+	free_type(res);
       }
       return NULL;
     }
     if (res) {
-      struct pike_string *tmp = or_pike_types(res, sub, 1);
-      free_string(res);
-      free_string(sub);
+      struct pike_type *tmp = or_pike_types(res, sub, 1);
+      free_type(res);
+      free_type(sub);
       res = tmp;
     } else {
       res = sub;
@@ -3365,22 +3365,22 @@ static struct pike_string *low_object_type_to_program_type(char *obj_t)
       (!(sval.u.program = id_to_program(id))) ||
       (!(sub = get_type_of_svalue(&sval)))) {
     if (res) {
-      free_string(res);
+      free_type(res);
     }
     return NULL;
   }
   /* FIXME: obj_t + 1 should propagate to the return-type in sub. */
   if (res) {
-    struct pike_string *tmp = or_pike_types(res, sub, 1);
-    free_string(res);
-    free_string(sub);
+    struct pike_type *tmp = or_pike_types(res, sub, 1);
+    free_type(res);
+    free_type(sub);
     return tmp;
   }
   return sub;
 }
 
 /* Used by fix_object_program_type() */
-struct pike_string *object_type_to_program_type(struct pike_string *obj_t)
+struct pike_type *object_type_to_program_type(struct pike_type *obj_t)
 {
   return low_object_type_to_program_type(obj_t->str);
 }
@@ -3409,21 +3409,21 @@ char *get_name_of_type(int t)
 
 void cleanup_pike_types(void)
 {
-  free_string(string_type_string);
-  free_string(int_type_string);
-  free_string(float_type_string);
-  free_string(function_type_string);
-  free_string(object_type_string);
-  free_string(program_type_string);
-  free_string(array_type_string);
-  free_string(multiset_type_string);
-  free_string(mapping_type_string);
-  free_string(type_type_string);
-  free_string(mixed_type_string);
-  free_string(void_type_string);
-  free_string(zero_type_string);
-  free_string(any_type_string);
-  free_string(weak_type_string);
+  free_type(string_type_string);
+  free_type(int_type_string);
+  free_type(float_type_string);
+  free_type(function_type_string);
+  free_type(object_type_string);
+  free_type(program_type_string);
+  free_type(array_type_string);
+  free_type(multiset_type_string);
+  free_type(mapping_type_string);
+  free_type(type_type_string);
+  free_type(mixed_type_string);
+  free_type(void_type_string);
+  free_type(zero_type_string);
+  free_type(any_type_string);
+  free_type(weak_type_string);
 }
 
 
@@ -3465,8 +3465,8 @@ int type_may_overload(char *type, int lfun)
 }
 
 
-void yyexplain_nonmatching_types(struct pike_string *type_a,
-				 struct pike_string *type_b,
+void yyexplain_nonmatching_types(struct pike_type *type_a,
+				 struct pike_type *type_b,
 				 int flags)
 {
   implements_a=0;
@@ -3500,7 +3500,7 @@ void yyexplain_nonmatching_types(struct pike_string *type_a,
 }
 
 
-struct pike_string *make_pike_type(char *t)
+struct pike_type *make_pike_type(char *t)
 {
   return make_shared_binary_string(t, type_length(t));
 }
@@ -3539,4 +3539,6 @@ int pike_type_allow_premature_toss(char *type)
     case T_STRING:
       return 1;
   }
+  /* NOT_REACHED */
+  return 0;
 }
diff --git a/src/pike_types.h b/src/pike_types.h
index e7ef9f08d8ba54b8b04e785dd9d883ef0d895f40..03a8bd397fc966089d19892292dae1442d488c65 100644
--- a/src/pike_types.h
+++ b/src/pike_types.h
@@ -5,13 +5,39 @@
 \*/
 
 /*
- * $Id: pike_types.h,v 1.47 2001/02/09 10:29:54 hubbe Exp $
+ * $Id: pike_types.h,v 1.48 2001/02/19 23:50:02 grubba Exp $
  */
 #ifndef PIKE_TYPES_H
 #define PIKE_TYPES_H
 
 #include "svalue.h"
 
+#ifdef USE_PIKE_TYPE
+/*
+ * The new type type.
+ */
+struct pike_type
+{
+  INT32 refs;
+  unsigned INT32 hash;
+  struct pike_type *next;
+  unsigned INT32 type;
+  struct pike_type *car;
+  struct pike_type *cdr;
+};
+void free_type(struct pike_type *t);
+#define copy_type(D, S)	add_ref(D = (S))
+#else /* !USE_PIKE_TYPE */
+/*
+ * The old type type.
+ */
+/* Note that pike_type in this case is defined in global.h
+ * to avoid circularities with svalue.h and this file.
+ */
+#define free_type(T)	free_string(T)
+#define copy_type(D, S)	copy_shared_string(D, S)
+#endif /* USE_PIKE_TYPE */
+
 /* Also used in struct node_identifier */
 union node_data
 {
@@ -45,7 +71,7 @@ struct node_s
 #ifdef PIKE_DEBUG
   struct pike_string *current_file;
 #endif
-  struct pike_string *type;
+  struct pike_type *type;
   struct pike_string *name;
   struct node_s *parent;
   unsigned INT16 line_number;
@@ -82,21 +108,21 @@ extern unsigned char type_stack[PIKE_TYPE_STACK_SIZE];
 extern unsigned char *pike_type_mark_stack[PIKE_TYPE_STACK_SIZE/4];
 
 extern int max_correct_args;
-PMOD_EXPORT extern struct pike_string *string_type_string;
-PMOD_EXPORT extern struct pike_string *int_type_string;
-PMOD_EXPORT extern struct pike_string *float_type_string;
-PMOD_EXPORT extern struct pike_string *object_type_string;
-PMOD_EXPORT extern struct pike_string *function_type_string;
-PMOD_EXPORT extern struct pike_string *program_type_string;
-PMOD_EXPORT extern struct pike_string *array_type_string;
-PMOD_EXPORT extern struct pike_string *list_type_string;
-PMOD_EXPORT extern struct pike_string *mapping_type_string;
-PMOD_EXPORT extern struct pike_string *type_type_string;
-PMOD_EXPORT extern struct pike_string *mixed_type_string;
-PMOD_EXPORT extern struct pike_string *void_type_string;
-PMOD_EXPORT extern struct pike_string *zero_type_string;
-PMOD_EXPORT extern struct pike_string *any_type_string;
-PMOD_EXPORT extern struct pike_string *weak_type_string;
+PMOD_EXPORT extern struct pike_type *string_type_string;
+PMOD_EXPORT extern struct pike_type *int_type_string;
+PMOD_EXPORT extern struct pike_type *float_type_string;
+PMOD_EXPORT extern struct pike_type *object_type_string;
+PMOD_EXPORT extern struct pike_type *function_type_string;
+PMOD_EXPORT extern struct pike_type *program_type_string;
+PMOD_EXPORT extern struct pike_type *array_type_string;
+PMOD_EXPORT extern struct pike_type *list_type_string;
+PMOD_EXPORT extern struct pike_type *mapping_type_string;
+PMOD_EXPORT extern struct pike_type *type_type_string;
+PMOD_EXPORT extern struct pike_type *mixed_type_string;
+PMOD_EXPORT extern struct pike_type *void_type_string;
+PMOD_EXPORT extern struct pike_type *zero_type_string;
+PMOD_EXPORT extern struct pike_type *any_type_string;
+PMOD_EXPORT extern struct pike_type *weak_type_string;
 
 #define CONSTTYPE(X) make_shared_binary_string(X,CONSTANT_STRLEN(X))
 
@@ -147,7 +173,7 @@ PMOD_EXPORT extern struct pike_string *weak_type_string;
 } while(0)
 
 /* Prototypes begin here */
-void check_type_string(struct pike_string *s);
+void check_type_string(struct pike_type *s);
 void init_types(void);
 ptrdiff_t pop_stack_mark(void);
 void pop_type_stack(void);
@@ -157,50 +183,50 @@ void push_type_int(INT32 i);
 void push_type_int_backwards(INT32 i);
 INT32 extract_type_int(char *p);
 void push_unfinished_type(char *s);
-void push_finished_type(struct pike_string *type);
-void push_finished_type_backwards(struct pike_string *type);
-struct pike_string *debug_pop_unfinished_type(void);
-struct pike_string *debug_pop_type(void);
-struct pike_string *debug_compiler_pop_type(void);
-struct pike_string *parse_type(char *s);
+void push_finished_type(struct pike_type *type);
+void push_finished_type_backwards(struct pike_type *type);
+struct pike_type *debug_pop_unfinished_type(void);
+struct pike_type *debug_pop_type(void);
+struct pike_type *debug_compiler_pop_type(void);
+struct pike_type *parse_type(char *s);
 void stupid_describe_type(char *a, ptrdiff_t len);
-void simple_describe_type(struct pike_string *s);
+void simple_describe_type(struct pike_type *s);
 char *low_describe_type(char *t);
-struct pike_string *describe_type(struct pike_string *type);
-TYPE_T compile_type_to_runtime_type(struct pike_string *s);
-struct pike_string *or_pike_types(struct pike_string *a,
-				  struct pike_string *b,
-				  int zero_implied);
-struct pike_string *and_pike_types(struct pike_string *a,
-				   struct pike_string *b);
+struct pike_string *describe_type(struct pike_type *type);
+TYPE_T compile_type_to_runtime_type(struct pike_type *s);
+struct pike_type *or_pike_types(struct pike_type *a,
+				struct pike_type *b,
+				int zero_implied);
+struct pike_type *and_pike_types(struct pike_type *a,
+				 struct pike_type *b);
 int strict_check_call(char *fun_type, char *arg_type);
-int check_soft_cast(struct pike_string *to, struct pike_string *from);
-int match_types(struct pike_string *a,struct pike_string *b);
-int pike_types_le(struct pike_string *a,struct pike_string *b);
-struct pike_string *index_type(struct pike_string *type,
-			       struct pike_string *index_type,
-			       node *n);
-struct pike_string *array_value_type(struct pike_string *array_type);
-struct pike_string *key_type(struct pike_string *type, node *n);
-int check_indexing(struct pike_string *type,
-		   struct pike_string *index_type,
+int check_soft_cast(struct pike_type *to, struct pike_type *from);
+int match_types(struct pike_type *a,struct pike_type *b);
+int pike_types_le(struct pike_type *a, struct pike_type *b);
+struct pike_type *index_type(struct pike_type *type,
+			     struct pike_type *index_type,
+			     node *n);
+struct pike_type *array_value_type(struct pike_type *array_type);
+struct pike_type *key_type(struct pike_type *type, node *n);
+int check_indexing(struct pike_type *type,
+		   struct pike_type *index_type,
 		   node *n);
-int count_arguments(struct pike_string *s);
-int minimum_arguments(struct pike_string *s);
+int count_arguments(struct pike_type *s);
+int minimum_arguments(struct pike_type *s);
 struct pike_string *check_call(struct pike_string *args,
 			       struct pike_string *type,
 			       int strict);
-INT32 get_max_args(struct pike_string *type);
-struct pike_string *zzap_function_return(char *a, INT32 id);
-struct pike_string *get_type_of_svalue(struct svalue *s);
-struct pike_string *object_type_to_program_type(struct pike_string *obj_t);
+INT32 get_max_args(struct pike_type *type);
+struct pike_type *zzap_function_return(char *a, INT32 id);
+struct pike_type *get_type_of_svalue(struct svalue *s);
+struct pike_type *object_type_to_program_type(struct pike_type *obj_t);
 char *get_name_of_type(int t);
 void cleanup_pike_types(void);
 int type_may_overload(char *type, int lfun);
-void yyexplain_nonmatching_types(struct pike_string *type_a,
-				 struct pike_string *type_b,
+void yyexplain_nonmatching_types(struct pike_type *type_a,
+				 struct pike_type *type_b,
 				 int flags);
-struct pike_string *make_pike_type(char *t);
+struct pike_type *make_pike_type(char *t);
 int pike_type_allow_premature_toss(char *type);
 /* Prototypes end here */
 
@@ -260,10 +286,10 @@ int pike_type_allow_premature_toss(char *type);
 } while (0)
 
 #ifdef DEBUG_MALLOC
-#define pop_type() ((struct pike_string *)debug_malloc_pass(debug_pop_type()))
-#define compiler_pop_type() ((struct pike_string *)debug_malloc_pass(debug_compiler_pop_type()))
+#define pop_type() ((struct pike_type *)debug_malloc_pass(debug_pop_type()))
+#define compiler_pop_type() ((struct pike_type *)debug_malloc_pass(debug_compiler_pop_type()))
 #define pop_unfinished_type() \
- ((struct pike_string *)debug_malloc_pass(debug_pop_unfinished_type()))
+ ((struct pike_type *)debug_malloc_pass(debug_pop_unfinished_type()))
 #else
 #define pop_type debug_pop_type
 #define compiler_pop_type debug_compiler_pop_type
diff --git a/src/program.c b/src/program.c
index 5031df0f81015566bd3def10de3f3346bdf4605d..05be165e9e49f69730c44584fe402d491ed11330 100644
--- a/src/program.c
+++ b/src/program.c
@@ -5,7 +5,7 @@
 \*/
 /**/
 #include "global.h"
-RCSID("$Id: program.c,v 1.294 2001/02/09 13:43:23 grubba Exp $");
+RCSID("$Id: program.c,v 1.295 2001/02/19 23:50:02 grubba Exp $");
 #include "program.h"
 #include "object.h"
 #include "dynamic_buffer.h"
@@ -1145,7 +1145,7 @@ void low_start_new_program(struct program *p,
       if (id < 0)
 	fatal("Program constant disappeared in second pass.\n");
       i=ID_FROM_INT(Pike_compiler->new_program, id);
-      free_string(i->type);
+      free_type(i->type);
       i->type=get_type_of_svalue(&tmp);
     }
     e=2;
@@ -1283,7 +1283,8 @@ void low_start_new_program(struct program *p,
   Pike_compiler->num_parse_error=0;
 
   push_compiler_frame(0);
-  add_ref(Pike_compiler->compiler_frame->current_return_type=void_type_string);
+  copy_type(Pike_compiler->compiler_frame->current_return_type,
+	    void_type_string);
 
   debug_malloc_touch(Pike_compiler->fake_object);
   debug_malloc_touch(Pike_compiler->fake_object->storage);
@@ -1326,7 +1327,7 @@ PMOD_EXPORT void really_free_program(struct program *p)
       if(p->identifiers[e].name)
 	free_string(p->identifiers[e].name);
       if(p->identifiers[e].type)
-	free_string(p->identifiers[e].type);
+	free_type(p->identifiers[e].type);
     }
   }
 
@@ -1970,7 +1971,7 @@ int find_inherit(struct program *p, struct pike_string *name)
 }
 
 node *reference_inherited_identifier(struct pike_string *super_name,
-				   struct pike_string *function_name)
+				     struct pike_string *function_name)
 {
   int n,e,id;
   struct program_state *state=Pike_compiler->previous;
@@ -2475,7 +2476,7 @@ int isidentifier(struct pike_string *s)
 
 /* argument must be a shared string */
 int low_define_variable(struct pike_string *name,
-			struct pike_string *type,
+			struct pike_type *type,
 			INT32 flags,
 			size_t offset,
 			INT32 run_time_type)
@@ -2526,7 +2527,8 @@ PMOD_EXPORT int map_variable(char *name,
 		 INT32 run_time_type)
 {
   int ret;
-  struct pike_string *n,*t;
+  struct pike_string *n;
+  struct pike_type *t;
 
 #ifdef PROGRAM_BUILD_DEBUG
   fprintf (stderr, "%.*sdefining variable (pass=%d): %s %s\n",
@@ -2537,7 +2539,7 @@ PMOD_EXPORT int map_variable(char *name,
   t=parse_type(type);
   ret=low_define_variable(n,t,flags,offset,run_time_type);
   free_string(n);
-  free_string(t);
+  free_type(t);
   return ret;
 }
 
@@ -2550,7 +2552,8 @@ PMOD_EXPORT int quick_map_variable(char *name,
 		       INT32 flags)
 {
   int ret;
-  struct pike_string *n,*t;
+  struct pike_string *n;
+  struct pike_type *t;
 
 #ifdef PROGRAM_BUILD_DEBUG
   fprintf (stderr, "%.*sdefining variable (pass=%d): %s %s\n",
@@ -2561,13 +2564,13 @@ PMOD_EXPORT int quick_map_variable(char *name,
   t=make_shared_binary_string(type,type_length);
   ret=low_define_variable(n,t,flags,offset,run_time_type);
   free_string(n);
-  free_string(t);
+  free_type(t);
   return ret;
 }
 
 /* argument must be a shared string */
 int define_variable(struct pike_string *name,
-		    struct pike_string *type,
+		    struct pike_type *type,
 		    INT32 flags)
 {
   int n, run_time_type;
@@ -2601,7 +2604,7 @@ int define_variable(struct pike_string *name,
     else {
       struct identifier *id;
       id=ID_FROM_INT(Pike_compiler->new_program,n);
-      free_string(id->type);
+      free_type(id->type);
       copy_shared_string(id->type, type);
       return n;
     }
@@ -2687,13 +2690,14 @@ PMOD_EXPORT int simple_add_variable(char *name,
 			INT32 flags)
 {
   INT32 ret;
-  struct pike_string *name_s, *type_s;
+  struct pike_string *name_s;
+  struct pike_type *type_s;
   name_s=make_shared_string(name);
   type_s=parse_type(type);
 
   ret=define_variable(name_s, type_s, flags);
   free_string(name_s);
-  free_string(type_s);
+  free_type(type_s);
   return ret;
 }
 
@@ -2708,16 +2712,18 @@ PMOD_EXPORT int add_constant(struct pike_string *name,
 #ifdef PROGRAM_BUILD_DEBUG
   {
     if (c) {
-      struct pike_string *t = get_type_of_svalue (c);
+      struct pike_type *t = get_type_of_svalue(c);
       struct pike_string *d = describe_type (t);
       fprintf (stderr, "%.*sdefining constant (pass=%d): %s ",
-	       compilation_depth, "                ", Pike_compiler->compiler_pass, d->str);
-      free_string (t);
+	       compilation_depth, "                ",
+	       Pike_compiler->compiler_pass, d->str);
+      free_type(t);
       free_string (d);
     }
     else
       fprintf (stderr, "%.*sdeclaring constant (pass=%d): ",
-	       compilation_depth, "                ", Pike_compiler->compiler_pass);
+	       compilation_depth, "                ",
+	       Pike_compiler->compiler_pass);
     push_string (name);
     print_svalue (stderr, --Pike_sp);
     putc ('\n', stderr);
@@ -2754,18 +2760,18 @@ PMOD_EXPORT int add_constant(struct pike_string *name,
       id=ID_FROM_INT(Pike_compiler->new_program,n);
       if(id->func.offset>=0)
       {
-	struct pike_string *s;
+	struct pike_type *s;
 	struct svalue *c=&PROG_FROM_INT(Pike_compiler->new_program,n)->
 	  constants[id->func.offset].sval;
 	s=get_type_of_svalue(c);
-	free_string(id->type);
+	free_type(id->type);
 	id->type=s;
       }
       else {
 #ifdef PIKE_DEBUG
 	if (!c) fatal("Can't declare constant during second compiler pass\n");
 #endif
-	free_string(id->type);
+	free_type(id->type);
 	id->type = get_type_of_svalue(c);
 	id->run_time_type = c->type;
 	id->func.offset = store_constant(c, 0, 0);
@@ -2966,7 +2972,7 @@ PMOD_EXPORT int debug_end_class(char *name, ptrdiff_t namelen, INT32 flags)
  * if func isn't given, it is supposed to be a prototype.
  */
 INT32 define_function(struct pike_string *name,
-		      struct pike_string *type,
+		      struct pike_type *type,
 		      unsigned INT8 flags,
 		      unsigned INT8 function_flags,
 		      union idptr *func,
@@ -3058,7 +3064,7 @@ INT32 define_function(struct pike_string *name,
 
       funp->opt_flags &= opt_flags;
 
-      free_string(funp->type);
+      free_type(funp->type);
       copy_shared_string(funp->type, type);
     }else{
 
@@ -3869,7 +3875,8 @@ PMOD_EXPORT int pike_add_function2(char *name, void (*cfun)(INT32),
 				   unsigned INT16 opt_flags)
 {
   int ret;
-  struct pike_string *name_tmp,*type_tmp;
+  struct pike_string *name_tmp;
+  struct pike_type *type_tmp;
   union idptr tmp;
 
   name_tmp=make_shared_string(name);
@@ -3893,7 +3900,7 @@ PMOD_EXPORT int pike_add_function2(char *name, void (*cfun)(INT32),
 			opt_flags);
   }
   free_string(name_tmp);
-  free_string(type_tmp);
+  free_type(type_tmp);
   return ret;
 }
 
@@ -3906,7 +3913,8 @@ PMOD_EXPORT int quick_add_function(char *name,
 				   unsigned INT16 opt_flags)
 {
   int ret;
-  struct pike_string *name_tmp,*type_tmp;
+  struct pike_string *name_tmp;
+  struct pike_type *type_tmp;
   union idptr tmp;
 /*  fprintf(stderr,"ADD_FUNC: %s\n",name); */
   name_tmp = make_shared_binary_string(name,name_length);
@@ -3930,7 +3938,7 @@ PMOD_EXPORT int quick_add_function(char *name,
 			opt_flags);
   }
   free_string(name_tmp);
-  free_string(type_tmp);
+  free_type(type_tmp);
   return ret;
 }
 
@@ -4042,7 +4050,7 @@ void init_program(void)
 
     val.u.string = make_pike_type(raw_lfun_types[i]);
     mapping_insert(lfun_types, &key, &val);
-    free_string(val.u.string);
+    free_type(val.u.string);
   }
   start_new_program();
   debug_malloc_touch(Pike_compiler->fake_object);
@@ -4396,7 +4404,7 @@ void pop_local_variables(int level)
     int e;
     e=--(Pike_compiler->compiler_frame->current_number_of_locals);
     free_string(Pike_compiler->compiler_frame->variable[e].name);
-    free_string(Pike_compiler->compiler_frame->variable[e].type);
+    free_type(Pike_compiler->compiler_frame->variable[e].type);
     if(Pike_compiler->compiler_frame->variable[e].def)
       free_node(Pike_compiler->compiler_frame->variable[e].def);
 
@@ -4417,10 +4425,10 @@ void pop_compiler_frame(void)
 
   pop_local_variables(0);
   if(f->current_type)
-    free_string(f->current_type);
+    free_type(f->current_type);
 
   if(f->current_return_type)
-    free_string(f->current_return_type);
+    free_type(f->current_return_type);
 
   Pike_compiler->compiler_frame=f->previous;
   dmfree((char *)f);
diff --git a/src/program.h b/src/program.h
index 4adaf341ce764705562e45e17758821c012f8a3a..ed5a399d7309fa72ffb38e046d3683b696bde277 100644
--- a/src/program.h
+++ b/src/program.h
@@ -5,7 +5,7 @@
 \*/
 
 /*
- * $Id: program.h,v 1.115 2001/02/05 21:13:11 grubba Exp $
+ * $Id: program.h,v 1.116 2001/02/19 23:50:03 grubba Exp $
  */
 #ifndef PROGRAM_H
 #define PROGRAM_H
@@ -148,7 +148,7 @@ union idptr
 struct identifier
 {
   struct pike_string *name;
-  struct pike_string *type;
+  struct pike_type *type;
   unsigned INT8 identifier_flags;	/* IDENTIFIER_??? */
   unsigned INT8 run_time_type;		/* PIKE_T_??? */
   unsigned INT16 opt_flags;		/* OPT_??? */
@@ -366,7 +366,7 @@ int low_reference_inherited_identifier(struct program_state *q,
 				       int flags);
 int find_inherit(struct program *p, struct pike_string *name);
 node *reference_inherited_identifier(struct pike_string *super_name,
-				   struct pike_string *function_name);
+				     struct pike_string *function_name);
 void rename_last_inherit(struct pike_string *n);
 void low_inherit(struct program *p,
 		 struct object *parent,
@@ -385,7 +385,7 @@ void simple_do_inherit(struct pike_string *s,
 		       struct pike_string *name);
 int isidentifier(struct pike_string *s);
 int low_define_variable(struct pike_string *name,
-			struct pike_string *type,
+			struct pike_type *type,
 			INT32 flags,
 			size_t offset,
 			INT32 run_time_type);
@@ -402,40 +402,41 @@ PMOD_EXPORT int quick_map_variable(char *name,
 		       INT32 run_time_type,
 		       INT32 flags);
 int define_variable(struct pike_string *name,
-		    struct pike_string *type,
+		    struct pike_type *type,
 		    INT32 flags);
 PMOD_EXPORT int simple_add_variable(char *name,
-			char *type,
-			INT32 flags);
+				    char *type,
+				    INT32 flags);
 PMOD_EXPORT int add_constant(struct pike_string *name,
-		 struct svalue *c,
-		 INT32 flags);
+			     struct svalue *c,
+			     INT32 flags);
 PMOD_EXPORT int simple_add_constant(char *name,
-			struct svalue *c,
-			INT32 flags);
+				    struct svalue *c,
+				    INT32 flags);
 PMOD_EXPORT int add_integer_constant(char *name,
-			 INT32 i,
-			 INT32 flags);
+				     INT32 i,
+				     INT32 flags);
 PMOD_EXPORT int quick_add_integer_constant(char *name,
-			       int name_length,
-			       INT32 i,
-			       INT32 flags);
+					   int name_length,
+					   INT32 i,
+					   INT32 flags);
 PMOD_EXPORT int add_float_constant(char *name,
-			 double f,
-			 INT32 flags);
+				   double f,
+				   INT32 flags);
 PMOD_EXPORT int add_string_constant(char *name,
-			char *str,
-			INT32 flags);
+				    char *str,
+				    INT32 flags);
 PMOD_EXPORT int add_program_constant(char *name,
-			 struct program *p,
-			 INT32 flags);
+				     struct program *p,
+				     INT32 flags);
 PMOD_EXPORT int add_object_constant(char *name,
-			struct object *o,
-			INT32 flags);
-PMOD_EXPORT int add_function_constant(char *name, void (*cfun)(INT32), char * type, INT16 flags);
+				    struct object *o,
+				    INT32 flags);
+PMOD_EXPORT int add_function_constant(char *name, void (*cfun)(INT32),
+				      char * type, INT16 flags);
 PMOD_EXPORT int debug_end_class(char *name, ptrdiff_t namelen, INT32 flags);
 INT32 define_function(struct pike_string *name,
-		      struct pike_string *type,
+		      struct pike_type *type,
 		      unsigned INT8 flags,
 		      unsigned INT8 function_flags,
 		      union idptr *func,
@@ -469,8 +470,8 @@ struct program *compile(struct pike_string *prog,
 			int major,
 			int minor);
 PMOD_EXPORT int pike_add_function2(char *name, void (*cfun)(INT32),
-		       char *type, unsigned INT8 flags,
-		       unsigned INT16 opt_flags);
+				   char *type, unsigned INT8 flags,
+				   unsigned INT16 opt_flags);
 PMOD_EXPORT int quick_add_function(char *name,
 				   int name_length,
 				   void (*cfun)(INT32),
diff --git a/src/svalue.h b/src/svalue.h
index eba48647022c4a716c27d8b264caf6bc6f3aefc6..937fa2b08776f01e314e930ea8870777ffec0466 100644
--- a/src/svalue.h
+++ b/src/svalue.h
@@ -5,7 +5,7 @@
 \*/
 
 /*
- * $Id: svalue.h,v 1.75 2000/12/16 05:52:17 marcus Exp $
+ * $Id: svalue.h,v 1.76 2001/02/19 23:50:03 grubba Exp $
  */
 #ifndef SVALUE_H
 #define SVALUE_H
@@ -62,6 +62,7 @@ union anything
   struct object *object;
   struct program *program;
   struct pike_string *string;
+  struct pike_type *type;
   INT32 *refs;
   INT_TYPE integer;
   FLOAT_TYPE float_number;
diff --git a/src/treeopt.in b/src/treeopt.in
index 7be27144238694a691276afe4778b3f15fc5a4dd..50c93d0fd3572bc1d108391e60c645ee0c5ca6d1 100644
--- a/src/treeopt.in
+++ b/src/treeopt.in
@@ -1,6 +1,6 @@
 // -*- c -*-
 //
-// $Id: treeopt.in,v 1.55 2001/01/12 02:28:07 mast Exp $
+// $Id: treeopt.in,v 1.56 2001/02/19 23:50:03 grubba Exp $
 //
 // The tree optimizer
 //
@@ -292,7 +292,7 @@ F_CAST(0 = +[$$->type == void_type_string], *):
 // // Propagate casts towards the leaves
 // 0 = F_CAST(F_COMMA_EXPR(1, 2), *):
 // {
-//   struct pike_string *type = $0->type;
+//   struct pike_type *type = $0->type;
 //   $$ = mknode(F_COMMA_EXPR, mkcastnode(void_type_string, $1),
 // 		 mkcastnode(type, $2));
 // }
@@ -301,7 +301,7 @@ F_CAST(0 = +[$$->type == void_type_string], *):
 // // Propagate casts toward the leaves
 // 0 = F_CAST('?'(1, ':'(2, 3)), *):
 // {
-//   struct pike_string *type = $0->type;
+//   struct pike_type *type = $0->type;
 //   $$ = mknode('?', $1, mknode(':', mkcastnode(type, $2),
 // 				 mkcastnode(type, $3)));
 // }
@@ -385,7 +385,7 @@ F_COMMA_EXPR(F_CAST(0, *), 1 = +):
 // Propagate casts towards the root.
 F_COMMA_EXPR(0, 1 = F_CAST(2, *)):
 {
-  struct pike_string *type = $1->type;
+  struct pike_type *type = $1->type;
   $$ = mkcastnode(type, mknode(F_COMMA_EXPR, $0, $2));
 }
 ;
@@ -953,10 +953,10 @@ F_FOR(0 = F_APPLY(1 = F_CONSTANT
 // Prepare for the return if true optimization.
 '?'(0 = +[ node_is_tossable($$) ], ':'( F_RETURN($0, *), 1)) :
 {
-  struct pike_string *type = $0->type;
+  struct pike_type *type = $0->type;
   struct pike_string *tmpname;
   int tmpvar;
-  void add_local_name(struct pike_string *,struct pike_string *, node *);
+  void add_local_name(struct pike_string *, struct pike_type *, node *);
 
   MAKE_CONSTANT_SHARED_STRING(tmpname, " ");
   tmpvar = islocal(tmpname);