diff --git a/src/ChangeLog b/src/ChangeLog
index e14319deab94c66f05bba387cb81472114a43523..35d4e3c644ad5f7bab8707ef681199598287effe 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,8 @@
+Thu Mar 13 17:06:09 1997  Fredrik Hubinette  <hubbe@cytocin.hubbe.net>
+
+	* changed check_args() and check_all_args(), they are much more
+	  flexible and a bit easier to use now.
+
 Wed Mar 12 03:58:53 1997  Fredrik Hubinette  <hubbe@cytocin.hubbe.net>
 
 	* renamed clone() to clone_object(), threads works with linux now.
diff --git a/src/interpret.c b/src/interpret.c
index 937dd84105dc5caff5ffdb9b8b6d6c83ef5d1e6d..276c946f1a8d2cdb99b1d19c3dca45ee6be3b83d 100644
--- a/src/interpret.c
+++ b/src/interpret.c
@@ -4,7 +4,7 @@
 ||| See the files COPYING and DISCLAIMER for more information.
 \*/
 #include "global.h"
-RCSID("$Id: interpret.c,v 1.35 1997/03/12 12:15:27 hubbe Exp $");
+RCSID("$Id: interpret.c,v 1.36 1997/03/14 04:37:14 hubbe Exp $");
 #include "interpret.h"
 #include "object.h"
 #include "program.h"
@@ -954,6 +954,11 @@ static void eval_instruction(unsigned char *pc)
 	break;
       }
 
+      CASE(F_RETURN_1);
+      pop_n_elems(sp-fp->locals);
+      push_int(1);
+      goto do_return;
+
       CASE(F_RETURN_0);
       pop_n_elems(sp-fp->locals);
       push_int(0);
@@ -1055,6 +1060,9 @@ static void eval_instruction(unsigned char *pc)
       CASE(F_DIVIDE);   o_divide();   break;
       CASE(F_MOD);      o_mod();      break;
 
+      CASE(F_ADD_INT); push_int(GET_ARG()); f_add(2); break;
+      CASE(F_ADD_NEG_INT); push_int(-GET_ARG()); f_add(2); break;
+
       CASE(F_PUSH_ARRAY);
       if(sp[-1].type!=T_ARRAY) error("Bad argument to @\n");
       sp--;
@@ -1137,6 +1145,15 @@ static void eval_instruction(unsigned char *pc)
       pop_stack();
       break;
 
+    CASE(F_MARK_APPLY);
+      strict_apply_svalue(fp->context.prog->constants + GET_ARG(), 0);
+      break;
+
+    CASE(F_MARK_APPLY_POP);
+      strict_apply_svalue(fp->context.prog->constants + GET_ARG(), 0);
+      pop_stack();
+      break;
+
     CASE(F_APPLY);
       strict_apply_svalue(fp->context.prog->constants + GET_ARG(), sp - *--mark_sp );
       break;
diff --git a/src/language.yacc b/src/language.yacc
index 5502aa48d1d7b1edcd4725ba248bb212b92362d3..742996f4038688b257795f77813668d464f6bebd 100644
--- a/src/language.yacc
+++ b/src/language.yacc
@@ -13,7 +13,7 @@
 %token F_PREFIX_CHARX256 F_PREFIX_WORDX256 F_PREFIX_24BITX256
 %token F_POP_VALUE F_POP_N_ELEMS F_MARK F_MARK2
 %token F_CALL_LFUN F_CALL_LFUN_AND_POP
-%token F_APPLY F_APPLY_AND_POP
+%token F_APPLY F_APPLY_AND_POP F_MARK_APPLY F_MARK_APPLY_POP
 
 %token F_BRANCH F_BRANCH_WHEN_ZERO F_BRANCH_WHEN_NON_ZERO
 %token F_BRANCH_WHEN_LT F_BRANCH_WHEN_GT
@@ -43,12 +43,12 @@
 %token F_INC F_DEC F_POST_INC F_POST_DEC F_INC_AND_POP F_DEC_AND_POP
 %token F_INC_LOCAL F_INC_LOCAL_AND_POP F_POST_INC_LOCAL
 %token F_DEC_LOCAL F_DEC_LOCAL_AND_POP F_POST_DEC_LOCAL
-%token F_RETURN F_DUMB_RETURN F_RETURN_0 F_THROW_ZERO
+%token F_RETURN F_DUMB_RETURN F_RETURN_0 F_RETURN_1 F_THROW_ZERO
 
 %token F_ASSIGN F_ASSIGN_AND_POP
 %token F_ASSIGN_LOCAL F_ASSIGN_LOCAL_AND_POP
 %token F_ASSIGN_GLOBAL F_ASSIGN_GLOBAL_AND_POP
-%token F_ADD F_SUBTRACT
+%token F_ADD F_SUBTRACT F_ADD_INT F_ADD_NEG_INT
 %token F_MULTIPLY F_DIVIDE F_MOD
 
 %token F_LT F_GT F_EQ F_GE F_LE F_NE
@@ -158,7 +158,7 @@
 /* This is the grammar definition of Pike. */
 
 #include "global.h"
-RCSID("$Id: language.yacc,v 1.31 1997/03/11 22:31:21 grubba Exp $");
+RCSID("$Id: language.yacc,v 1.32 1997/03/14 04:37:15 hubbe Exp $");
 #ifdef HAVE_MEMORY_H
 #include <memory.h>
 #endif
diff --git a/src/lex.c b/src/lex.c
index 248d9dc15f4fbb6774950bdc1abd7bf431c6a9d7..6760ba7e7037693bbe60a4f7206027785e0e1e4c 100644
--- a/src/lex.c
+++ b/src/lex.c
@@ -4,7 +4,7 @@
 ||| See the files COPYING and DISCLAIMER for more information.
 \*/
 #include "global.h"
-RCSID("$Id: lex.c,v 1.18 1997/03/11 03:36:41 hubbe Exp $");
+RCSID("$Id: lex.c,v 1.19 1997/03/14 04:37:16 hubbe Exp $");
 #include "language.h"
 #include "array.h"
 #include "lex.h"
@@ -243,6 +243,7 @@ struct keyword instr_names[]=
 { "range",              F_RANGE },
 { "return",		F_RETURN },
 { "return 0",		F_RETURN_0 },
+{ "return 1",		F_RETURN_1 },
 { "sscanf",		F_SSCANF, I_HASARG },	
 { "string",             F_STRING, I_HASARG },
 { "switch",		F_SWITCH, I_HASARG },
@@ -277,6 +278,10 @@ struct keyword instr_names[]=
 { "2 locals",           F_2_LOCALS, I_HASARG },
 { "byte",               F_BYTE, I_HASARG },
 { "nop",                F_NOP },
+{ "add integer",        F_ADD_INT, I_HASARG },
+{ "add -integer",       F_ADD_NEG_INT, I_HASARG },
+{ "mark & call",        F_MARK_APPLY, I_HASARG },
+{ "mark, call & pop",   F_MARK_APPLY_POP, I_HASARG },
 };
 
 struct instr instrs[F_MAX_INSTR - F_OFFSET];
diff --git a/src/mapping.c b/src/mapping.c
index 2a21191824dbee67182c8f1c456ec4041cf251fe..5e234522dcac312f2340779aea904d949947b5d3 100644
--- a/src/mapping.c
+++ b/src/mapping.c
@@ -4,7 +4,7 @@
 ||| See the files COPYING and DISCLAIMER for more information.
 \*/
 #include "global.h"
-RCSID("$Id: mapping.c,v 1.14 1997/03/11 23:32:28 grubba Exp $");
+RCSID("$Id: mapping.c,v 1.15 1997/03/14 04:37:16 hubbe Exp $");
 #include "main.h"
 #include "types.h"
 #include "object.h"
@@ -764,12 +764,19 @@ node * make_node_from_mapping(struct mapping *m)
     node *n;
     ind=mapping_indices(m);
     val=mapping_indices(m);
-    n=mkefuncallnode("mkmapping",mknode(F_ARG_LIST,make_node_from_array(ind),make_node_from_array(val)));
+    n=mkefuncallnode("mkmapping",
+		     mknode(F_ARG_LIST,
+			    make_node_from_array(ind),
+			    make_node_from_array(val)));
     free_array(ind);
     free_array(val);
     return n;
   }else{
     struct svalue s;
+
+    if(!m->size)
+      return mkefuncallnode("aggregate_mapping",0);
+
     s.type=T_MAPPING;
     s.subtype=0;
     s.u.mapping=m;
diff --git a/src/module_support.c b/src/module_support.c
index 5d8f0f58df8da2fd53f7a71eee252efa09d79b9a..d5d77a685bb25922ed9f529967092a958d55b741 100644
--- a/src/module_support.c
+++ b/src/module_support.c
@@ -4,65 +4,127 @@
 #include "svalue.h"
 #include "stralloc.h"
 
-/* Checks that minargs arguments are OK.
- *
- * Returns the number of the first bad argument,
- * or 0 if all arguments were OK.
+enum error_type {
+  ERR_NONE,
+  ERR_TOO_FEW,
+  ERR_TOO_MANY,
+  ERR_BAD_ARG,
+};
+
+struct expect_result {
+  enum error_type error_type;
+  int argno;                 /* Which argument was it */
+  unsigned INT32 expected;   /* What type was expected */
+  TYPE_T got;               /* What type did we actually receive */
+};
+
+/* Checks that args_to_check arguments are OK.
+ * Returns 1 if everything worked ok, zero otherwise.
+ * If something went wrong, 'exepect_result' tells you what went wrong.
+ * Make sure to finish the argument list with a zero.
  */
-int va_check_args(struct svalue *s, int minargs, va_list arglist)
+static int va_check_args(struct svalue *s,
+			 int args_to_check,
+			 struct expect_result *res,
+			 va_list arglist)
 {
-  int argno;
-
-  for (argno=0; argno < minargs; argno++)
+  res->error_type = ERR_NONE;
+  res->expected = 0;
+  
+  for (res->argno=0; res->argno < args_to_check; res->argno++)
   {
-    int type_mask = va_arg(arglist, unsigned INT32);
+    if(!(res->expected & BIT_MANY))
+    {
+      res->expected = va_arg(arglist, unsigned int);
+      if(!res->expected)
+      {
+	res->error_type = ERR_TOO_MANY;
+	return 0;
+      }
+    }
 
-    if (!((1UL << s[argno].type) & type_mask))
+    if (!((1UL << s[res->argno].type) & res->expected))
     {
-      return(argno+1);
+      res->got=s[res->argno].type;
+      res->error_type = ERR_BAD_ARG;
+      return 0;
     }
   }
 
-  return(0);
+  if(!(res->expected & BIT_MANY))
+  {
+    res->expected = va_arg(arglist, unsigned int);
+  }
+
+  if(!res->expected || (res->expected & BIT_VOID)) return 1;
+  res->error_type = ERR_TOO_FEW;
+  return 0;
 }
 
 /* Returns the number of the first bad argument,
+ * -X if there were too few arguments
  * or 0 if all arguments were OK.
  */
-int check_args(int args, int minargs, ...)
+int check_args(int args, ...)
 {
   va_list arglist;
-  int argno;
+  struct expect_result tmp;
   
-  if (args < minargs) {
-    return(args+1);
-  }
-
-  va_start(arglist, minargs);
-  argno = va_check_args(sp - args, minargs, arglist);
+  va_start(arglist, args);
+  va_check_args(sp - args, args, &tmp, arglist);
   va_end(arglist);
 
-  return(argno);
+  if(tmp.error_type == ERR_NONE) return 0;
+  return tmp.argno+1;
 }
 
 /* This function generates errors if any of the minargs first arguments
  * is not OK.
  */
-void check_all_args(const char *fnname, int args, int minargs, ... )
+void check_all_args(const char *fnname, int args, ... )
 {
   va_list arglist;
+  struct expect_result tmp;
   int argno;
 
-  if (args < minargs) {
-    error("Too few arguments to %s()\n", fnname);
-  }
-
-  va_start(arglist, minargs);
-  argno = va_check_args(sp - args, minargs, arglist);
+  va_start(arglist, args);
+  va_check_args(sp - args, args, &tmp, arglist);
   va_end(arglist);
 
-  if (argno) {
-    error("Bad argument %d to %s()\n", argno, fnname);
+  switch(tmp.error_type)
+  {
+  case ERR_NONE: return;
+  case ERR_TOO_FEW:
+    error("Too few arguments to %s()\n",fnname);
+  case ERR_TOO_MANY:
+    error("Too many argumens to %s()\n",fnname);
+
+  case ERR_BAD_ARG:
+  {
+    char buf[1000];
+    int e,d;
+    buf[0]=0;
+    for(e=0;e<16;e++)
+    {
+      if(tmp.expected & (1<<e))
+      {
+	if(buf[0])
+	{
+	  if(tmp.expected & 0xffff & (0xffff << e))
+	    strcat(buf,", ");
+	  else
+	    strcat(buf," or ");
+	}
+	strcat(buf, get_name_of_type(e));
+      }
+    }
+	
+    error("Bad argument %d to %s(), (expecting %s, got %s)\n", 
+	  tmp.argno+1,
+	  fnname,
+	  buf,
+	  get_name_of_type(tmp.got));
+  }
   }
 }
 
diff --git a/src/module_support.h b/src/module_support.h
index 67636a372a87020c53da524901177048cf255c83..f2dd99c4a62563c027911c4c0e3462bcda68bbed 100644
--- a/src/module_support.h
+++ b/src/module_support.h
@@ -8,9 +8,10 @@
 #include <stdarg.h>
 
 /* Prototypes begin here */
-int va_check_args(struct svalue *s, int minargs, va_list arglist);
-int check_args(int args, int minargs, ...);
-void check_all_args(const char *fnname, int args, int minargs, ... );
+enum error_type;
+struct expect_result;
+int check_args(int args, ...);
+void check_all_args(const char *fnname, int args, ... );
 int va_get_args(struct svalue *s,
 		INT32 num_args,
 		char *fmt,
diff --git a/src/modules/Yp/yp.c b/src/modules/Yp/yp.c
index 693b5e619f5a4703792deac11b43b96ce4167386..cb47767b72727fed9ecbdacd29e529186eedaa90 100644
--- a/src/modules/Yp/yp.c
+++ b/src/modules/Yp/yp.c
@@ -65,7 +65,7 @@ static void f_create(INT32 args)
     f_default_yp_domain(0);
     args = 1;
   }
-  check_all_args("yp->create", args, 1, BIT_STRING);
+  check_all_args("yp->create", args, BIT_STRING,0);
 
   if(this->domain)
   {
@@ -84,7 +84,7 @@ static void f_all(INT32 args)
   int retlen, retkeylen;
   char *map;
   struct mapping *res_map;
-  check_all_args("yp->all", args, 1, BIT_STRING);
+  check_all_args("yp->all", args, BIT_STRING, 0);
 
   map = sp[-1].u.string->str;
   res_map = allocate_mapping( (this->last_size?this->last_size+2:40) );
@@ -120,7 +120,7 @@ void f_map(INT32 args)
 
   struct svalue *f = &sp[-1];
 
-  check_all_args("map", args, 2, BIT_STRING, BIT_FUNCTION|BIT_ARRAY );
+  check_all_args("map", args, BIT_STRING, BIT_FUNCTION|BIT_ARRAY, 0 );
   
   map = sp[-2].u.string->str;
 
@@ -143,7 +143,7 @@ static void f_order(INT32 args)
 {
   int err;
   unsigned long ret;
-  check_all_args("yp->order()", args, 1, BIT_STRING);
+  check_all_args("yp->order", args, BIT_STRING, 0);
   
   err = yp_order( this->domain, sp[-args].u.string->str, &ret);
   YPERROR("order", err );
@@ -157,7 +157,7 @@ static void f_match(INT32 args)
   char *retval;
   int retlen;
   
-  check_all_args("yp->match", args, 2, BIT_STRING, BIT_STRING);
+  check_all_args("yp->match", args, BIT_STRING, BIT_STRING, 0);
 
   err = yp_match( this->domain, sp[-args].u.string->str,
 		  sp[-args+1].u.string->str, sp[-args+1].u.string->len,
diff --git a/src/modules/files/file.c b/src/modules/files/file.c
index 7ea1159fea4d511f920a9900437baee5eb2d9ca2..bde0cf767327d62ba382effb54194b25faf75421 100644
--- a/src/modules/files/file.c
+++ b/src/modules/files/file.c
@@ -6,7 +6,7 @@
 #define READ_BUFFER 8192
 
 #include "global.h"
-RCSID("$Id: file.c,v 1.29 1997/03/12 12:21:50 hubbe Exp $");
+RCSID("$Id: file.c,v 1.30 1997/03/14 04:38:54 hubbe Exp $");
 #include "types.h"
 #include "interpret.h"
 #include "svalue.h"
@@ -1220,7 +1220,7 @@ static void file_open_socket(INT32 args)
 static void file_set_keepalive(INT32 args)
 {
   int tmp, i;
-  check_all_args("file->set_keepalive()",args, 1, T_INT);
+  check_all_args("file->set_keepalive",args, T_INT,0);
   tmp=sp[-args].u.integer;
   i=setsockopt(FD,SOL_SOCKET, SO_KEEPALIVE, (char *)&tmp, sizeof(tmp));
   if(i)
diff --git a/src/modules/system/system.c b/src/modules/system/system.c
index a2e821e2671cbc226df43398d761f0382d77d0fc..fc494825a95bc5325a13fc08c8a2e3710fbfd418 100644
--- a/src/modules/system/system.c
+++ b/src/modules/system/system.c
@@ -1,5 +1,5 @@
 /*
- * $Id: system.c,v 1.13 1997/03/05 14:52:02 grubba Exp $
+ * $Id: system.c,v 1.14 1997/03/14 04:39:20 hubbe Exp $
  *
  * System-call module for Pike
  *
@@ -14,7 +14,7 @@
 #include "system.h"
 
 #include <global.h>
-RCSID("$Id: system.c,v 1.13 1997/03/05 14:52:02 grubba Exp $");
+RCSID("$Id: system.c,v 1.14 1997/03/14 04:39:20 hubbe Exp $");
 #include <module_support.h>
 #include <las.h>
 #include <interpret.h>
@@ -376,9 +376,9 @@ void f_chroot(INT32 args)
   int res;
 
 #ifdef HAVE_FCHROOT
-  check_all_args("chroot", args, 1, BIT_STRING|BIT_OBJECT);
+  check_all_args("chroot", args, BIT_STRING|BIT_OBJECT, 0);
 #else
-  check_all_args("chroot", args, 1, BIT_STRING);
+  check_all_args("chroot", args, BIT_STRING, 0);
 #endif /* HAVE_FCHROOT */
 
 
diff --git a/src/operators.c b/src/operators.c
index 0e26ab803db982310f255b71676347d804d7f2b4..fef1e67c0e5282b55164fd30a30ae2e2514b96d9 100644
--- a/src/operators.c
+++ b/src/operators.c
@@ -5,7 +5,7 @@
 \*/
 #include <math.h>
 #include "global.h"
-RCSID("$Id: operators.c,v 1.11 1997/03/11 23:32:32 grubba Exp $");
+RCSID("$Id: operators.c,v 1.12 1997/03/14 04:37:17 hubbe Exp $");
 #include "interpret.h"
 #include "svalue.h"
 #include "multiset.h"
@@ -511,6 +511,44 @@ void o_and()
   }
 }
 
+/* This function is used to speed up or/xor/and on
+ * arrays multisets and mappings. This is done by
+ * calling the operator for each pair of arguments
+ * first, then recursively doing the same on the
+ * results until only one value remains.
+ */
+static void speedup(INT32 args, void (*func)(void))
+{
+  switch(sp[-args].type)
+  {
+  case T_MAPPING:
+  case T_ARRAY:
+  case T_MULTISET:
+  {
+    int e=-1;
+    while(args > 1)
+    {
+      struct svalue tmp;
+      func();
+      args--;
+      e++;
+      if(e - args >= -1)
+      {
+	e=0;
+      }else{
+	tmp=sp[e-args];
+	sp[e-args]=sp[-1];
+	sp[-1]=tmp;
+      }
+    }
+    return;
+  }
+
+  default:
+    while(--args > 0) func();
+  }
+}
+
 void f_and(INT32 args)
 {
   switch(args)
@@ -523,7 +561,7 @@ void f_and(INT32 args)
     {
       CALL_OPERATOR(LFUN_AND, args);
     }else{
-      while(--args > 0) o_and();
+      speedup(args, o_and);
     }
   }
 }
@@ -623,7 +661,7 @@ void f_or(INT32 args)
     {
       CALL_OPERATOR(LFUN_OR, args);
     } else {
-      while(--args > 0) o_or();
+      speedup(args, o_or);
     }
   }
 }
@@ -724,7 +762,7 @@ void f_xor(INT32 args)
     {
       CALL_OPERATOR(LFUN_XOR, args);
     } else {
-      while(--args > 0) o_xor();
+      speedup(args, o_xor);
     }
   }
 }
diff --git a/src/peep.in b/src/peep.in
index 49481badcf9ce7e4030f8cbc0366708c2889ecec..7b48f5b1140c9de8d05f5a0e18d7cb43ce0759af 100644
--- a/src/peep.in
+++ b/src/peep.in
@@ -12,6 +12,8 @@ ASSIGN_GLOBAL POP_VALUE : ASSIGN_GLOBAL_AND_POP($1a)
 ASSIGN_LOCAL  POP_VALUE : ASSIGN_LOCAL_AND_POP($1a)
 CALL_LFUN POP_VALUE : CALL_LFUN_AND_POP($1a)
 APPLY POP_VALUE : APPLY_AND_POP($1a)
+MARK APPLY : MARK_APPLY($2a)
+MARK_APPLY POP_VALUE : MARK_APPLY_POP($1a)
 NUMBER(0) : CONST0
 NUMBER(1) : CONST1
 NUMBER(-1) : CONST_1
@@ -22,6 +24,8 @@ CONST_1 NEGATE : CONST1
 NUMBER NEGATE : NEG_NUMBER($1a)
 NUMBER [$1a < 0] : NEG_NUMBER (-$1a)
 NEG_NUMBER NEGATE : NUMBER ($1a)
+NEGATE NEGATE :
+COMPL COMPL :
 NEGATE CONST_1 ADD : COMPL
 NEGATE CONST1 SUBTRACT : COMPL
 CONST0 ASSIGN_LOCAL_AND_POP : CLEAR_LOCAL($2a)
@@ -42,6 +46,7 @@ CONST0 XOR:
 CONST_1 XOR: COMPL
 EQ CONST0: NOT
 CONST0 RETURN: RETURN_0
+CONST1 RETURN: RETURN_1
 INC POP_VALUE: INC_AND_POP
 POST_INC POP_VALUE: INC_AND_POP
 DEC POP_VALUE: DEC_AND_POP
@@ -117,3 +122,28 @@ NUMBER [$1a < 0] INDEX: NEG_INT_INDEX (-$1a)
 NUMBER [$1a >= 0] INDEX: POS_INT_INDEX ($1a)
 NEG_NUMBER [$1a >= 0] INDEX: NEG_INT_INDEX ($1a)
 NEG_NUMBER [$1a < 0] INDEX: POS_INT_INDEX (-$1a)
+
+BRANCH_WHEN_ZERO BRANCH LABEL ($1a): BRANCH_WHEN_NON_ZERO($2a) LABEL($1a)
+BRANCH_WHEN_NON_ZERO BRANCH LABEL ($1a): BRANCH_WHEN_ZERO($2a) LABEL($1a)
+
+BRANCH_WHEN_EQ BRANCH LABEL ($1a) : BRANCH_WHEN_NE($2a) LABEL($1a)
+BRANCH_WHEN_NE BRANCH LABEL ($1a) : BRANCH_WHEN_EQ($2a) LABEL($1a)
+
+BRANCH_WHEN_LT BRANCH LABEL ($1a) : BRANCH_WHEN_GE($2a) LABEL($1a)
+BRANCH_WHEN_GE BRANCH LABEL ($1a) : BRANCH_WHEN_LT($2a) LABEL($1a)
+
+BRANCH_WHEN_LE BRANCH LABEL ($1a) : BRANCH_WHEN_GT($2a) LABEL($1a)
+BRANCH_WHEN_GT BRANCH LABEL ($1a) : BRANCH_WHEN_LE($2a) LABEL($1a)
+
+
+CONST0 ADD: ADD_INT (0)
+CONST1 ADD: ADD_INT (1)
+CONST_1 ADD: ADD_NEG_INT (1)
+NUMBER [$1a >= 0] ADD : ADD_INT ($1a)
+NUMBER [$1a < 0] ADD : ADD_NEG_INT (-$1a)
+
+CONST0 SUBTRACT: ADD_INT (0)
+CONST1 SUBTRACT: ADD_NEG_INT (-1)
+CONST_1 SUBTRACT: ADD_INT (1)
+NUMBER [$1a >= 0] SUBTRACT : ADD_NEG_INT ($1a)
+NUMBER [$1a < 0] SUBTRACT : ADD_INT (-$1a)
diff --git a/src/pike_types.c b/src/pike_types.c
index 0f18b28531c432c904a015a5e31043f1d5dc3cec..0a5ae85b8cebe2239143cf292fd9cc4a88c9122d 100644
--- a/src/pike_types.c
+++ b/src/pike_types.c
@@ -4,7 +4,7 @@
 ||| See the files COPYING and DISCLAIMER for more information.
 \*/
 #include "global.h"
-RCSID("$Id: pike_types.c,v 1.18 1997/03/08 12:54:08 hubbe Exp $");
+RCSID("$Id: pike_types.c,v 1.19 1997/03/14 04:37:18 hubbe Exp $");
 #include <ctype.h>
 #include "svalue.h"
 #include "pike_types.h"
@@ -1218,6 +1218,7 @@ char *get_name_of_type(int t)
     case T_OBJECT: return "object";
     case T_PROGRAM: return "program";
     case T_STRING: return "string";
+    case T_VOID: return "void";
     default: return "unknown";
   }
 }
diff --git a/src/svalue.h b/src/svalue.h
index 296293ad83cf78e1f736f3c701645cfbfc74b1e9..965388fffd2d4b4f5b68813a2f3c7bc706c4d38f 100644
--- a/src/svalue.h
+++ b/src/svalue.h
@@ -85,15 +85,16 @@ struct svalue
 #define T_FLOAT 7
 #define T_INT 8
 
+#define T_VOID 16
+#define T_MANY 17
+
 #define T_DELETED 246
 #define T_NOT 247
 #define T_AND 248
 #define T_UNKNOWN 249
-#define T_MANY 250
 #define T_OR 251
 #define T_SHORT_LVALUE 252
 #define T_LVALUE 253
-#define T_VOID 254
 #define T_MIXED 255
 
 #define BIT_ARRAY (1<<T_ARRAY)
@@ -106,10 +107,20 @@ struct svalue
 #define BIT_INT (1<<T_INT)
 #define BIT_FLOAT (1<<T_FLOAT)
 
-/* Used to signifiy that this array might not be finished yet */
+/* Used to signify that this array might not be finished yet */
 /* garbage collect uses this */
 #define BIT_UNFINISHED (1<<15)
 
+/* This is only used in typechecking to signify that this 
+ * argument may be omitted.
+ */
+#define BIT_VOID (1<< T_VOID)
+
+/* This is used in typechecking to signify that the rest of the
+ * arguments has to be of this type.
+ */
+#define BIT_MANY (1 << T_MANY)
+
 #define BIT_NOTHING 0
 #define BIT_MIXED 0x7fff
 #define BIT_BASIC (BIT_INT|BIT_FLOAT|BIT_STRING)