diff --git a/src/docode.c b/src/docode.c
index d94322088acfa80d35a9087f5a0256093dd4505a..9b9358c4ba0e38856e32a32aca0af440114b34ed 100644
--- a/src/docode.c
+++ b/src/docode.c
@@ -5,7 +5,7 @@
 \*/
 /**/
 #include "global.h"
-RCSID("$Id: docode.c,v 1.75 2000/07/07 01:28:57 hubbe Exp $");
+RCSID("$Id: docode.c,v 1.76 2000/07/12 12:38:40 grubba Exp $");
 #include "las.h"
 #include "program.h"
 #include "pike_types.h"
@@ -299,13 +299,26 @@ static int do_docode2(node *n,int flags)
     return 1;
       
   case F_EXTERNAL:
-    if(flags & WANT_LVALUE)
     {
-      emit2(F_EXTERNAL_LVALUE, n->u.integer.b,n->u.integer.a);
-      return 2;
-    }else{
-      emit2(F_EXTERNAL, n->u.integer.b,n->u.integer.a);
-      return 1;
+      int level = 0;
+      struct program_state *state = Pike_compiler->previous;
+      while (state && (state->new_program->id != n->u.integer.a)) {
+	state = state->previous;
+	level++;
+      }
+      if (!state) {
+	my_yyerror("Program parent %d lost during compiling.", n->u.integer.a);
+	emit1(F_NUMBER,0);
+	return 1;
+      }
+      if(flags & WANT_LVALUE)
+      {
+	emit2(F_EXTERNAL_LVALUE, n->u.integer.b, level);
+	return 2;
+      }else{
+	emit2(F_EXTERNAL, n->u.integer.b, level);
+	return 1;
+      }
     }
     break;
 
@@ -1225,10 +1238,10 @@ static int do_docode2(node *n,int flags)
 	{
 	  int x=0;
 	  struct object *o;
-	  
+
 	  for(o=Pike_compiler->fake_object->parent;o!=n->u.sval.u.object;o=o->parent)
 	    x++;
-	  emit2(F_EXTERNAL, n->u.sval.subtype,x);
+	  emit2(F_EXTERNAL, n->u.sval.subtype, x);
 	  Pike_compiler->new_program->flags |= PROGRAM_USES_PARENT;
 	  return 1;
 	}
diff --git a/src/language.yacc b/src/language.yacc
index 9e402c24744acb69a4826c6db11bc7d4c3c2822b..75900c79f9df81dbdc08c0e4d0114d31f7ec8a02 100644
--- a/src/language.yacc
+++ b/src/language.yacc
@@ -109,7 +109,7 @@
 /* This is the grammar definition of Pike. */
 
 #include "global.h"
-RCSID("$Id: language.yacc,v 1.200 2000/07/10 18:21:33 grubba Exp $");
+RCSID("$Id: language.yacc,v 1.201 2000/07/12 12:38:41 grubba Exp $");
 #ifdef HAVE_MEMORY_H
 #include <memory.h>
 #endif
@@ -1963,6 +1963,10 @@ class: modifiers TOK_CLASS optional_identifier
       low_start_new_program(0, $3->u.sval.u.string,
 			    $1,
 			    &$<number>$);
+
+      /* fprintf(stderr, "Pass 1: Program %s has id %d\n",
+	 $3->u.sval.u.string->str, Pike_compiler->new_program->id); */
+
       if(lex.current_file)
       {
 	store_linenumber(lex.current_line, lex.current_file);
@@ -1993,6 +1997,10 @@ class: modifiers TOK_CLASS optional_identifier
 				  $3->u.sval.u.string,
 				  $1,
 				  &$<number>$);
+
+	    /* fprintf(stderr, "Pass 2: Program %s has id %d\n",
+	       $3->u.sval.u.string->str, Pike_compiler->new_program->id); */
+
 	  }else{
 	    yyerror("Pass 2: constant redefined!");
 	    low_start_new_program(Pike_compiler->new_program, 0,
@@ -2636,8 +2644,7 @@ low_idents: TOK_IDENTIFIER
 
       if (id != -1) {
 	if (inherit_depth >= 0) {
-	  $$ = mkexternalnode(inherit_depth, id,
-			      ID_FROM_INT(inherit_state->new_program, id));
+	  $$ = mkexternalnode(inherit_state->new_program, id);
 	} else {
 	  $$ = mkidentifiernode(id);
 	}
diff --git a/src/las.c b/src/las.c
index 7fa78b354932394ff2c7163cd221936c48d95919..042bcb6f703ea5899e454e8345db85c8674943b1 100644
--- a/src/las.c
+++ b/src/las.c
@@ -5,7 +5,7 @@
 \*/
 /**/
 #include "global.h"
-RCSID("$Id: las.c,v 1.185 2000/07/12 01:20:21 hubbe Exp $");
+RCSID("$Id: las.c,v 1.186 2000/07/12 12:38:40 grubba Exp $");
 
 #include "language.h"
 #include "interpret.h"
@@ -108,11 +108,14 @@ void check_tree(node *n, int depth)
     case F_EXTERNAL:
       if(n->type)
       {
-	int level = n->u.integer.a;
+	int parent_id = n->u.integer.a;
 	int id_no = n->u.integer.b;
-	struct program *p = parent_compilation(level);
-	if (p) {
-	  struct identifier *id = ID_FROM_INT(p, id_no);
+	struct program_state *state = Pike_compiler->previous;
+	while (state && (state->new_program->id != parent_id)) {
+	  state = state->previous;
+	}
+	if (state) {
+	  struct identifier *id = ID_FROM_INT(state->new_program, id_no);
 	  if (id) {
 #ifdef PIKE_DEBUG
 	    if(id->type != n->type)
@@ -383,9 +386,10 @@ static node *freeze_node(node *orig)
   check_tree(orig);
   return orig;
 }
-#endif
-
+#else /* !PIKE_DEBUG */
 #define freeze_node(X) (X)
+#endif /* PIKE_DEBUG */
+
 #endif /* SHARED_NODES */
 
 void free_all_nodes(void)
@@ -926,11 +930,10 @@ node *debug_mktrampolinenode(int i)
   return res;
 }
 
-node *debug_mkexternalnode(int level,
-			   int i,
-			   struct identifier *id)
+node *debug_mkexternalnode(struct program *parent_prog, int i)
 {
   node *res = mkemptynode();
+  struct identifier *id;
   res->token = F_EXTERNAL;
 #ifdef PIKE_DEBUG
   if(d_flag)
@@ -940,8 +943,7 @@ node *debug_mkexternalnode(int level,
   }
 #endif
 
-  /* Kludge */
-  id = ID_FROM_INT(parent_compilation(level), i);
+  id = ID_FROM_INT(parent_prog, i);
 
   copy_shared_string(res->type, id->type);
 
@@ -957,16 +959,13 @@ node *debug_mkexternalnode(int level,
 #ifdef __CHECKER__
   _CDR(res) = 0;
 #endif
-  res->u.integer.a = level;
+  res->u.integer.a = parent_prog->id;
   res->u.integer.b = i;
 
   /* Bzot-i-zot */
   Pike_compiler->new_program->flags |= PROGRAM_USES_PARENT;
 
-  /* Can't freeze the node, since the type-info may become wrong. */
-  /* return freeze_node(res); */
-  res->hash = hash_node(res);
-  return res;
+  return freeze_node(res);
 }
 
 node *debug_mkcastnode(struct pike_string *type,node *n)
@@ -1077,14 +1076,21 @@ void resolv_constant(node *n)
       return;
 
     case F_EXTERNAL:
-      p=parent_compilation(n->u.integer.a);
-      if(!p)
       {
-	yyerror("Failed to resolv external constant");
-	push_int(0);
-	return;
+	struct program_state *state = Pike_compiler->previous;
+
+	while (state && (state->new_program->id != n->u.integer.a)) {
+	  state = state->previous;
+	}
+	if(!state)
+	{
+	  yyerror("Failed to resolv external constant");
+	  push_int(0);
+	  return;
+	}
+	p = state->new_program;
+	numid=n->u.integer.b;
       }
-      numid=n->u.integer.b;
       break;
 
     case F_IDENTIFIER:
@@ -1455,12 +1461,7 @@ node *debug_mksvaluenode(struct svalue *s)
 
       if(s->u.object->next == s->u.object)
       {
-	int x=0;
-	struct object *o;
-	for(o=Pike_compiler->fake_object->parent;o!=s->u.object;o=o->parent) x++;
-	return mkexternalnode(x, s->subtype,
-			      ID_FROM_INT(o->prog, s->subtype));
-
+	return mkexternalnode(s->u.object->prog, s->subtype);
       }
 
 /*      yyerror("Non-constant function pointer! (should not happen!)"); */
@@ -2419,12 +2420,18 @@ void fix_type_field(node *n)
 
       case F_EXTERNAL:
 	{
-	  int level = CAR(n)->u.integer.a;
+	  int program_id = CAR(n)->u.integer.a;
 	  int id_no = CAR(n)->u.integer.b;
-	  struct program *p = parent_compilation(level);
+	  struct program_state *state = Pike_compiler->previous;
+
 	  name="external symbol";
-	  if (p) {
-	    struct identifier *id = ID_FROM_INT(p, id_no);
+
+	  while (state && (state->new_program->id != program_id)) {
+	    state = state->previous;
+	  }
+
+	  if (state) {
+	    struct identifier *id = ID_FROM_INT(state->new_program, id_no);
 	    if (id && id->name) {
 	      name = id->name->str;
 #ifdef PIKE_DEBUG
diff --git a/src/las.h b/src/las.h
index b4ba37b84fa8b74be1c375ee8259d4cec622d05b..74d388ff9ae87cb0e70dda9a914e03a2d233e246 100644
--- a/src/las.h
+++ b/src/las.h
@@ -5,7 +5,7 @@
 \*/
 
 /*
- * $Id: las.h,v 1.39 2000/06/24 00:48:13 hubbe Exp $
+ * $Id: las.h,v 1.40 2000/07/12 12:38:41 grubba Exp $
  */
 #ifndef LAS_H
 #define LAS_H
@@ -126,9 +126,7 @@ node *debug_mkopernode(char *oper_id, node *arg1, node *arg2);
 node *debug_mklocalnode(int var, int depth);
 node *debug_mkidentifiernode(int i);
 node *debug_mktrampolinenode(int i);
-node *debug_mkexternalnode(int level,
-			   int i,
-			   struct identifier *id);
+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);
 void resolv_constant(node *n);
@@ -176,7 +174,7 @@ void resolv_program(node *n);
 #define mklocalnode(var, depth) dmalloc_touch(node *, debug_mklocalnode(var, depth))
 #define mkidentifiernode(i) dmalloc_touch(node *, debug_mkidentifiernode(i))
 #define mktrampolinenode(i) dmalloc_touch(node *, debug_mktrampolinenode(i))
-#define mkexternalnode(level, i, id) dmalloc_touch(node *, debug_mkexternalnode(level, i, id))
+#define mkexternalnode(parent_prog, i) dmalloc_touch(node *, debug_mkexternalnode(parent_prog, i))
 #define mkcastnode(type, n) dmalloc_touch(node *, debug_mkcastnode(type, dmalloc_touch(node *, n)))
 #define mksoftcastnode(type, n) dmalloc_touch(node *, debug_mksoftcastnode(type, dmalloc_touch(node *, n)))
 #define mktypenode(t)       dmalloc_touch(node *, debug_mktypenode(t))
diff --git a/src/program.c b/src/program.c
index 037b4d7c214931df9244cde83d3f662e60467d42..cc64155704c4a49f0ba25eca6f93ce67b091a527 100644
--- a/src/program.c
+++ b/src/program.c
@@ -5,7 +5,7 @@
 \*/
 /**/
 #include "global.h"
-RCSID("$Id: program.c,v 1.249 2000/07/11 03:45:10 mast Exp $");
+RCSID("$Id: program.c,v 1.250 2000/07/12 12:38:41 grubba Exp $");
 #include "program.h"
 #include "object.h"
 #include "dynamic_buffer.h"
@@ -350,9 +350,7 @@ struct node_s *find_module_identifier(struct pike_string *ident,
 						   SEE_STATIC);
 	if(i!=-1)
 	{
-	  struct identifier *id;
-	  id=ID_FROM_INT(p->new_program, i);
-	  return mkexternalnode(n, i, id);
+	  return mkexternalnode(p->new_program, i);
 	}
       }
       
@@ -1622,7 +1620,7 @@ node *reference_inherited_identifier(struct pike_string *super_name,
       id=low_reference_inherited_identifier(state,e,function_name,SEE_STATIC);
 
       if(id!=-1)
-	return mkexternalnode(n,id,ID_FROM_INT(state->new_program, id));
+	return mkexternalnode(p, id);
 
       if(ISCONSTSTR(function_name,"`->") ||
 	 ISCONSTSTR(function_name,"`[]"))
@@ -1860,14 +1858,20 @@ void compiler_do_inherit(node *n,
       goto continue_inherit;
 
     case F_EXTERNAL:
-      p=parent_compilation(n->u.integer.a);
-      offset=n->u.integer.a;
-      numid=n->u.integer.b;
-
-      if(!p)
       {
-	yyerror("Failed to resolv external constant.\n");
-	return;
+	struct program_state *state = Pike_compiler->previous;
+
+	offset = 0;	/* FIXME: Should this be zero or 1? */
+	while (state && (state->new_program->id != n->u.integer.a)) {
+	  state = state->previous;
+	  offset++;
+	}
+	if (!state) {
+	  yyerror("Failed to resolv external constant.\n");
+	  return;
+	}
+	p = state->new_program;
+	numid = n->u.integer.b;
       }
 
   continue_inherit: