diff --git a/src/modules/Parser/initstuff.h b/src/modules/Parser/initstuff.h
new file mode 100644
index 0000000000000000000000000000000000000000..a9d50a1e18258f94f32619dc69c1d1a6b3923e12
--- /dev/null
+++ b/src/modules/Parser/initstuff.h
@@ -0,0 +1,21 @@
+#ifndef PARSER_INITER
+#define PARSER_CLASS(a,b,c,what) extern struct program *what;
+#define PARSER_SUBMODULE(a,b,c) 
+#define PARSER_SUBMODMAG(a,b,c) 
+#define PARSER_FUNCTION(a,name,c,d) void name(INT32 args);
+#endif
+
+PARSER_CLASS("HTML", init_parser_html, exit_parser_html, 
+	    parser_html_program )
+
+   /*
+for documentation purpose:
+
+PARSER_SUBMODULE("ANY",   init_parser_any,  exit_parser_any  ) 
+PARSER_SUBMODMAG("PNG",   init_parser_png,  exit_parser_png  )
+
+PARSER_FUNCTION("lay",parser_lay,
+	       tOr(tFunc(tArr(tOr(tObj,tLayerMap)),tObj),
+		   tFunc(tArr(tOr(tObj,tLayerMap))
+			 tInt tInt tInt tInt,tObj)),0)
+   */
diff --git a/src/modules/Parser/parser.c b/src/modules/Parser/parser.c
index a97f04045378b037e5180cb41c1520f5875c3bd4..eb368c7057a4526974c19dda9e44d8af0ade5080 100644
--- a/src/modules/Parser/parser.c
+++ b/src/modules/Parser/parser.c
@@ -1,42 +1,220 @@
-/*
- * $Id: parser.c,v 1.2 1999/02/19 19:37:13 mirar Exp $
- */
-
 #include "global.h"
-#include "config.h"
-
+#include "stralloc.h"
+#include "global.h"
+RCSID("$Id: parser.c,v 1.3 1999/06/12 13:42:42 mirar Exp $");
+#include "pike_macros.h"
+#include "interpret.h"
 #include "program.h"
+#include "object.h"
+#include "operators.h"
 
 #include "parser.h"
 
-/*** module init & exit & stuff *****************************************/
+#define PARSER_INITER
 
-/* add other parsers here */
+/*#define DEBUG*/
+
+#define PARSER_CLASS(name,init,exit,prog) \
+    void init(void); void exit(void); struct program *prog;
+#define PARSER_SUBMODULE(name,init,exit)  \
+    void init(void); void exit(void); 
+#define PARSER_SUBMODMAG(name,init,exit) \
+    void init(void); void exit(void);
+#define PARSER_FUNCTION(name,func,def0,def1) \
+    void func(INT32 args);
+#include "initstuff.h"
+
+static struct 
+{
+   char *name;
+   void (*init)(void);
+   void (*exit)(void);
+   struct program **dest;
+} initclass[]=
+{
+#undef PARSER_CLASS
+#undef PARSER_SUBMODULE
+#undef PARSER_FUNCTION
+#undef PARSER_SUBMODMAG
+#define PARSER_SUBMODMAG(a,b,c) 
+#define PARSER_FUNCTION(a,b,c,d)
+#define PARSER_CLASS(name,init,exit,prog) { name,init,exit,&prog },
+#define PARSER_SUBMODULE(a,b,c)
+#include "initstuff.h"
+};
+
+static struct 
+{
+   char *name;
+   void (*init)(void);
+   void (*exit)(void);
+} initsubmodule[]=
+{
+#undef PARSER_CLASS
+#undef PARSER_SUBMODULE
+#define PARSER_CLASS(name,init,exit,prog) 
+#define PARSER_SUBMODULE(name,init,exit) { name,init,exit },
+#include "initstuff.h"
+};
 
-static struct parser_class
+static struct 
 {
    char *name;
-   void (*func)(void);
-} sub[] = {
-   {"HTML",init_parser_html},
+   void (*init)(void);
+   void (*exit)(void);
+   struct pike_string *ps;
+   struct object *o;
+} submagic[]=
+{
+#undef PARSER_SUBMODULE
+#undef PARSER_SUBMODMAG
+#define PARSER_SUBMODULE(a,b,c)
+#define PARSER_SUBMODMAG(name,init,exit) { name,init,exit,NULL,NULL },
+#include "initstuff.h"
 };
 
-void pike_module_exit(void)
+#ifdef PIKE_DEBUG
+#define PARSER_CHECK_STACK(X)	do { if (save_sp != sp) { fatal("%s:%d: %d droppings on stack! previous init: %s\n", __FILE__, __LINE__, sp - save_sp,X); } } while(0)
+#else
+#define PARSER_CHECK_STACK(X)
+#endif /* PIKE_DEBUG */
+
+
+static void parser_magic_index(INT32 args)
 {
+   struct svalue tmp;
+   int i;
+
+   if (args!=1) 
+      error("Parser.`[]: Too few or too many arguments\n");
+   if (sp[-1].type!=T_STRING)
+      error("Parser.`[]: Illegal type of argument\n");
+
+   for (i=0; i<(int)NELEM(submagic); i++)
+      if (sp[-1].u.string==submagic[i].ps)
+      {
+#ifdef PIKE_DEBUG
+   struct svalue *save_sp;
+#endif
+	 pop_stack();
+
+#ifdef PIKE_DEBUG
+	 save_sp = sp;
+#endif
+
+	 if (!submagic[i].o)
+	 {
+	    struct program *p;
+	    start_new_program();
+	    (submagic[i].init)();
+	    PARSER_CHECK_STACK(submagic[i].name);
+	    p=end_program();
+	    submagic[i].o=clone_object(p,0);
+	    free_program(p);
+	 }
+	 
+	 ref_push_object(submagic[i].o);
+	 return;
+      }
+
+   stack_dup();
+   ref_push_object(fp->current_object);
+   stack_swap();
+   f_arrow(2);
+
+   if (sp[-1].type==T_INT)
+   {
+      pop_stack();
+      stack_dup();
+      push_text("_Parser_");
+      stack_swap();
+      f_add(2);
+      push_int(0);
+      SAFE_APPLY_MASTER("resolv",2);
+   }
+   if (sp[-1].type==T_INT)
+   {
+      pop_stack();
+      stack_dup();
+      push_text("_Parser");
+      push_int(0);
+      SAFE_APPLY_MASTER("resolv",2);
+      stack_swap();
+      f_index(2);
+   }
+   stack_swap();
+   pop_stack();
 }
 
 void pike_module_init(void)
 {
+#ifdef PIKE_DEBUG
+   struct svalue *save_sp = sp;
+#endif
+
    int i;
-   
-   for (i=0; i<(int)(sizeof(sub)/sizeof(sub[0])); i++)
+   for (i=0; i<(int)NELEM(initclass); i++)
+   {
+      start_new_program();
+
+#ifdef DEBUG
+      fprintf(stderr,"Parser: initiating class \"Parser.%s\"...\n",
+	      initclass[i].name);
+#endif
+
+      (initclass[i].init)();
+      PARSER_CHECK_STACK(initclass[i].name);
+      initclass[i].dest[0]=end_program();
+      add_program_constant(initclass[i].name,initclass[i].dest[0],0);
+   }
+
+   for (i=0; i<(int)NELEM(initsubmodule); i++)
    {
       struct program *p;
+      struct pike_string *s;
 
+#ifdef DEBUG
+      fprintf(stderr,"Parser: initiating submodule \"Parser.%s\"...\n",
+	      initsubmodule[i].name);
+#endif
+      
       start_new_program();
-      sub[i].func();
+      (initsubmodule[i].init)();
+      PARSER_CHECK_STACK(initsubmodule[i].name);
       p=end_program();
-      add_program_constant(sub[i].name,p,0);
+      push_object(clone_object(p,0));
+      s=make_shared_string(initsubmodule[i].name);
+      add_constant(s,sp-1,0);
+      free_string(s);
       free_program(p);
+      pop_stack();
+   }
+
+   for (i=0; i<(int)NELEM(submagic); i++)
+      submagic[i].ps=make_shared_string(submagic[i].name);
+
+#undef PARSER_FUNCTION
+#define PARSER_FUNCTION(name,func,def0,def1) ADD_FUNCTION(name,func,def0,def1);
+#include "initstuff.h"
+
+   ADD_FUNCTION("`[]",parser_magic_index,
+		tFunc(tString,tMixed),0);
+}
+
+void pike_module_exit(void) 
+{
+   int i;
+   for (i=0; i<(int)NELEM(initclass); i++)
+   {
+      (initclass[i].exit)();
+      free_program(initclass[i].dest[0]);
    }
+   for (i=0; i<(int)NELEM(initsubmodule); i++)
+      (initsubmodule[i].exit)();
+   for (i=0; i<(int)NELEM(submagic); i++)
+      if (submagic[i].o)
+      {
+	 (submagic[i].exit)();
+	 free_object(submagic[i].o);
+      }
 }