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