summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog12
-rw-r--r--arith.c20
-rw-r--r--eval.c1
-rw-r--r--lib.h1
-rw-r--r--mpi-patches/add-bitops58
5 files changed, 85 insertions, 7 deletions
diff --git a/ChangeLog b/ChangeLog
index e74d082c..c53a774d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,17 @@
2012-09-16 Kaz Kylheku <kaz@kylheku.com>
+ Adding complementing function.
+
+ * arith.c (logcomp): New function.
+
+ * eval.c (eval_init): logcomp registered as intrinsic.
+
+ * lib.h (logcomp) declared.
+
+ * mpi-patches/add-bitops: Fixed bugs in mp_xor. Implemented mp_comp.
+
+2012-09-16 Kaz Kylheku <kaz@kylheku.com>
+
Starting work on adding bit operations. The semantics is that
negative integers behave as an "infinite bit two's complement".
diff --git a/arith.c b/arith.c
index 82189866..0202f121 100644
--- a/arith.c
+++ b/arith.c
@@ -1611,6 +1611,26 @@ bad:
uw_throwf(error_s, lit("logxor: operation failed on ~s ~s"), a, b, nao);
}
+val logcomp(val a)
+{
+ val b;
+
+ switch (type(a)) {
+ case NUM:
+ return num_fast(~c_num(a));
+ case BGNUM:
+ b = make_bignum();
+ if (mp_comp(mp(a), mp(b)) != MP_OKAY)
+ goto bad;
+ return b;
+ default:
+ uw_throwf(error_s, lit("logcomp: non-integral operand ~s"), a, nao);
+ }
+
+bad:
+ uw_throwf(error_s, lit("logcomp: operation failed on ~s"), a, nao);
+}
+
void arith_init(void)
{
mp_init(&NUM_MAX_MP);
diff --git a/eval.c b/eval.c
index 786fc0d4..e075555d 100644
--- a/eval.c
+++ b/eval.c
@@ -2234,6 +2234,7 @@ void eval_init(void)
reg_fun(intern(lit("logand"), user_package), func_n2(logand));
reg_fun(intern(lit("logior"), user_package), func_n2(logior));
reg_fun(intern(lit("logxor"), user_package), func_n2(logxor));
+ reg_fun(intern(lit("logcomp"), user_package), func_n1(logcomp));
reg_fun(intern(lit("regex-compile"), user_package), func_n1(regex_compile));
reg_fun(intern(lit("regexp"), user_package), func_n1(regexp));
diff --git a/lib.h b/lib.h
index 90975644..331c2fb4 100644
--- a/lib.h
+++ b/lib.h
@@ -474,6 +474,7 @@ val expo(val);
val logand(val, val);
val logior(val, val);
val logxor(val, val);
+val logcomp(val);
val string_own(wchar_t *str);
val string(const wchar_t *str);
val string_utf8(const char *str);
diff --git a/mpi-patches/add-bitops b/mpi-patches/add-bitops
index db4611de..7abb0306 100644
--- a/mpi-patches/add-bitops
+++ b/mpi-patches/add-bitops
@@ -1,7 +1,7 @@
Index: mpi-1.8.6/mpi.c
===================================================================
--- mpi-1.8.6.orig/mpi.c 2012-09-16 10:50:08.270639006 -0700
-+++ mpi-1.8.6/mpi.c 2012-09-16 13:31:03.146453506 -0700
++++ mpi-1.8.6/mpi.c 2012-09-16 20:01:35.403688256 -0700
@@ -16,6 +16,9 @@
#include <ctype.h>
#include <math.h>
@@ -12,7 +12,7 @@ Index: mpi-1.8.6/mpi.c
typedef unsigned char mem_t;
extern mem_t *chk_malloc(size_t size);
extern mem_t *chk_calloc(size_t n, size_t size);
-@@ -2330,6 +2333,232 @@
+@@ -2330,6 +2333,275 @@
/* }}} */
@@ -187,10 +187,12 @@ Index: mpi-1.8.6/mpi.c
+
+ ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);
+
-+ extent = MAX(USED(a), USED(b)) + 1;
++ if (a == b) {
++ mp_zero(c);
++ return MP_OKAY;
++ }
+
-+ if (a == b)
-+ return mp_copy(a, c);
++ extent = MAX(USED(a), USED(b));
+
+ if (ISNEG(a)) {
+ mp_init(&tmp_a);
@@ -242,13 +244,54 @@ Index: mpi-1.8.6/mpi.c
+ return MP_OKAY;
+}
+
++mp_err mp_comp(mp_int *a, mp_int *b)
++{
++ mp_err res;
++ mp_size ix, dig = USED(a);
++ mp_digit *pa, *pb;
++ mp_int tmp;
++
++ ARGCHK(a != NULL && b != NULL, MP_BADARG);
++
++ if (a != b)
++ res = mp_init_size(b, dig);
++ else
++ res = s_mp_pad(b, dig);
++
++ if (res != MP_OKAY)
++ return res;
++
++ if (ISNEG(a)) {
++ mp_init(&tmp);
++ if ((res = mp_2comp(a, &tmp, dig)) != MP_OKAY)
++ return res;
++ a = &tmp;
++ }
++
++ for (pa = DIGITS(a), pb = DIGITS(b), ix = 0; ix < dig; ix++)
++ pb[ix] = ~pa[ix];
++
++ USED(b) = dig;
++
++ if (ISNEG(a)) {
++ mp_clear(&tmp);
++ } else {
++ if ((res = mp_2comp(b, b, dig)) != MP_OKAY)
++ return res;
++ SIGN(b) = MP_NEG;
++ }
++
++ s_mp_clamp(b);
++ return MP_OKAY;
++}
++
mp_err mp_to_double(mp_int *mp, double *d)
{
int ix;
Index: mpi-1.8.6/mpi.h
===================================================================
--- mpi-1.8.6.orig/mpi.h 2012-09-16 10:50:08.046513006 -0700
-+++ mpi-1.8.6/mpi.h 2012-09-16 13:23:09.824359506 -0700
++++ mpi-1.8.6/mpi.h 2012-09-16 19:01:51.000595006 -0700
@@ -54,6 +54,7 @@
/* Macros for accessing the mp_int internals */
@@ -257,7 +300,7 @@ Index: mpi-1.8.6/mpi.h
#define USED(MP) ((MP)->used)
#define ALLOC(MP) ((MP)->alloc)
#define DIGITS(MP) ((MP)->dp)
-@@ -187,6 +188,13 @@
+@@ -187,6 +188,14 @@
#endif /* end MP_NUMTH */
/*------------------------------------------------------------------------*/
@@ -266,6 +309,7 @@ Index: mpi-1.8.6/mpi.h
+mp_err mp_and(mp_int *a, mp_int *b, mp_int *c);
+mp_err mp_or(mp_int *a, mp_int *b, mp_int *c);
+mp_err mp_xor(mp_int *a, mp_int *b, mp_int *c);
++mp_err mp_comp(mp_int *a, mp_int *b);
+
+/*------------------------------------------------------------------------*/
/* Conversions */