From 39ac736ba0868c47c11cca48d428e3bb09746331 Mon Sep 17 00:00:00 2001
From: Fredrik Noring <noring@nocrew.org>
Date: Wed, 20 Oct 1999 00:21:32 +0200
Subject: [PATCH] Bignum additions: a) small number function call emulation
 using Gmp, b) intp, c) sprintf %O (describe_svalue), d) sqrt and e) casting
 from float to integer.

Rev: src/bignum.c:1.4
Rev: src/bignum.h:1.5
Rev: src/builtin_functions.c:1.188
Rev: src/modules/_math/math.c:1.23
Rev: src/opcodes.c:1.44
Rev: src/svalue.c:1.46
---
 src/bignum.c             | 15 ++++++++++++---
 src/bignum.h             |  2 ++
 src/builtin_functions.c  | 20 ++++++++++++++++++--
 src/modules/_math/math.c | 13 +++++++++++--
 src/opcodes.c            | 19 ++++++++++++++++++-
 src/svalue.c             | 19 ++++++++++++++++++-
 6 files changed, 79 insertions(+), 9 deletions(-)

diff --git a/src/bignum.c b/src/bignum.c
index f60992c1f9..555a8de2f9 100644
--- a/src/bignum.c
+++ b/src/bignum.c
@@ -8,7 +8,6 @@
 #include "svalue.h"
 #include "error.h"
 
-
 struct svalue auto_bignum_program = { T_INT };
 
 static void resolve_auto_bignum_program(void)
@@ -41,18 +40,28 @@ void convert_stack_top_to_bignum(void)
     error("Gmp.mpz conversion failed.\n");
 }
 
+int is_bignum_object(struct object *o)
+{
+  resolve_auto_bignum_program();
+  return o->prog == program_from_function(&auto_bignum_program);
+}
+
+int is_bignum_object_in_svalue(struct svalue *sv)
+{
+  return sv->type == T_OBJECT && is_bignum_object(sv->u.object);
+}
 
 struct object *make_bignum_object(void)
 {
   convert_stack_top_to_bignum();
-  return  (--sp)->u.object;
+  return (--sp)->u.object;
 }
 
 struct object *bignum_from_svalue(struct svalue *s)
 {
   push_svalue(s);
   convert_stack_top_to_bignum();
-  return  (--sp)->u.object;
+  return (--sp)->u.object;
 }
 
 struct pike_string *string_from_bignum(struct object *o, int base)
diff --git a/src/bignum.h b/src/bignum.h
index 544d10494e..a4e80dcea6 100644
--- a/src/bignum.h
+++ b/src/bignum.h
@@ -35,6 +35,8 @@ struct object *make_bignum_object(void);
 struct object *bignum_from_svalue(struct svalue *s);
 struct pike_string *string_from_bignum(struct object *o, int base);
 void convert_svalue_to_bignum(struct svalue *s);
+int is_bignum_object(struct object *o);
+int is_bignum_object_in_svalue(struct svalue *sv);
 /* Prototypes end here */
 
 #endif /* AUTO_BIGNUM */
diff --git a/src/builtin_functions.c b/src/builtin_functions.c
index 156ff649d5..41c4f20d3c 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.187 1999/10/19 15:30:43 hubbe Exp $");
+RCSID("$Id: builtin_functions.c,v 1.188 1999/10/19 22:21:28 noring Exp $");
 #include "interpret.h"
 #include "svalue.h"
 #include "pike_macros.h"
@@ -39,6 +39,7 @@ RCSID("$Id: builtin_functions.c,v 1.187 1999/10/19 15:30:43 hubbe Exp $");
 #include "signal_handler.h"
 #include "security.h"
 #include "builtin_functions.h"
+#include "bignum.h"
 
 #ifdef HAVE_POLL
 #ifdef HAVE_POLL_H
@@ -2087,7 +2088,22 @@ void f_programp(INT32 args)
   }
 }
 
-TYPEP(f_intp, "intpp", T_INT)
+#ifdef AUTO_BIGNUM
+void f_intp(INT32 args)
+{
+  int t;
+  
+  if(args<1)
+    SIMPLE_TOO_FEW_ARGS_ERROR("intp", 1);
+  
+  t = (sp[-args].type == T_INT) || is_bignum_object_in_svalue(&sp[-args]);
+  pop_n_elems(args);
+  push_int(t);
+}
+#else
+TYPEP(f_intp, "intp", T_INT)
+#endif /* AUTO_BIGNUM */
+     
 TYPEP(f_mappingp, "mappingp", T_MAPPING)
 TYPEP(f_arrayp, "arrayp", T_ARRAY)
 TYPEP(f_multisetp, "multisetp", T_MULTISET)
diff --git a/src/modules/_math/math.c b/src/modules/_math/math.c
index e153f3e510..63406e7dd8 100644
--- a/src/modules/_math/math.c
+++ b/src/modules/_math/math.c
@@ -12,6 +12,7 @@
 #include "error.h"
 #include "module_support.h"
 #include "operators.h"
+#include "bignum.h"
 
 #ifdef PC
 #undef PC
@@ -25,7 +26,7 @@
 #include <floatingpoint.h>
 #endif
 
-RCSID("$Id: math.c,v 1.22 1999/09/22 23:15:48 hubbe Exp $");
+RCSID("$Id: math.c,v 1.23 1999/10/19 22:21:32 noring Exp $");
 
 #ifndef M_PI
 #define M_PI 3.1415926535897932384626433832795080
@@ -152,7 +153,15 @@ void f_sqrt(INT32 args)
       return;
     }
     sp[-args].u.float_number=sqrt(sp[-args].u.float_number);
-  }else{
+  }
+#ifdef AUTO_BIGNUM
+  else if(is_bignum_object_in_svalue(&sp[-args]))
+  {
+    safe_apply(sp[-args].u.object, "sqrt", 1);
+  }
+#endif /* AUTO_BIGNUM */
+  else
+  {
     error("Bad argument 1 to sqrt().\n");
   }
 }
diff --git a/src/opcodes.c b/src/opcodes.c
index 3697f834ce..c6f5252f58 100644
--- a/src/opcodes.c
+++ b/src/opcodes.c
@@ -22,8 +22,9 @@
 #include "builtin_functions.h"
 #include "module_support.h"
 #include "security.h"
+#include "bignum.h"
 
-RCSID("$Id: opcodes.c,v 1.43 1999/08/21 23:21:07 noring Exp $");
+RCSID("$Id: opcodes.c,v 1.44 1999/10/19 22:21:30 noring Exp $");
 
 void index_no_free(struct svalue *to,struct svalue *what,struct svalue *ind)
 {
@@ -37,6 +38,13 @@ void index_no_free(struct svalue *to,struct svalue *what,struct svalue *ind)
 
   switch(what->type)
   {
+#ifdef AUTO_BIGNUM
+  case T_INT:
+    convert_svalue_to_bignum(what);
+    index_no_free(to, what, ind);
+    break;
+#endif /* AUTO_BIGNUM */
+    
   case T_ARRAY:
     simple_array_index_no_free(to,what->u.array,ind);
     break;
@@ -186,6 +194,15 @@ void o_cast(struct pike_string *type, INT32 run_time_type)
 	{
 	  case T_FLOAT:
 	    i=(int)(sp[-1].u.float_number);
+#ifdef AUTO_BIGNUM
+	    if((i < 0 ? -i : i) < fabs(floor(sp[-1].u.float_number)))
+	    {
+	      /* Note: This includes the case when i = 0x80000000, i.e.
+		 the absolute value is not computable. */
+	      convert_stack_top_to_bignum();
+	      return;
+	    }
+#endif /* AUTO_BIGNUM */
 	    break;
 	    
 	  case T_STRING:
diff --git a/src/svalue.c b/src/svalue.c
index 574b535195..415f2b7895 100644
--- a/src/svalue.c
+++ b/src/svalue.c
@@ -21,8 +21,9 @@
 #include "pike_macros.h"
 #include <ctype.h>
 #include "queue.h"
+#include "bignum.h"
 
-RCSID("$Id: svalue.c,v 1.45 1999/09/14 19:38:51 hubbe Exp $");
+RCSID("$Id: svalue.c,v 1.46 1999/10/19 22:21:31 noring Exp $");
 
 struct svalue dest_ob_zero = { T_INT, 0 };
 
@@ -839,8 +840,24 @@ void describe_svalue(struct svalue *s,int indent,struct processing *p)
       break;
 
     case T_OBJECT:
+#ifdef AUTO_BIGNUM
+      if(is_bignum_object(s->u.object))
+      {
+	struct pike_string *str;
+	int i;
+	
+	str = string_from_bignum(s->u.object, 10);
+	for(i = 0; i < str->len; i++)
+	  my_putchar(str->str[i]);
+	free_string(str);
+      }
+      else
+	my_strcat("object");
+      break;
+#else
       my_strcat("object");
       break;
+#endif /* AUTO_BIGNUM */
 
     case T_PROGRAM:
       my_strcat("program");
-- 
GitLab