[gcalctool/gcalctool-newui2] ...



commit d7978ab1a0333fac4b42663bd056c48f27915393
Author: Robert Ancell <robert ancell gmail com>
Date:   Tue Jul 14 17:32:51 2009 +1000

    ...

 src/functions.c          |   16 ++++++++---
 src/mp-binary.c          |    6 ++--
 src/mp-equation-lexer.l  |    3 +-
 src/mp-equation-parser.y |   24 ++++++++--------
 src/mp-equation.c        |   44 +++++++++++++++++++++++--------
 src/mp-equation.h        |   16 ++++++-----
 src/mp.c                 |   65 +++++++++++++++++++++++++++++++++++++++------
 src/mp.h                 |    6 ++--
 8 files changed, 130 insertions(+), 50 deletions(-)
---
diff --git a/src/functions.c b/src/functions.c
index d71780e..48ff9da 100644
--- a/src/functions.c
+++ b/src/functions.c
@@ -388,10 +388,6 @@ do_expression(int function, int arg, int cursor_start, int cursor_end)
                         display_set_answer(&v->display);
                         break;
 
-                    case -PARSER_ERR_INVALID_BASE:
-                        message = _("Invalid number for the current base");
-                        break;
-
                     case -PARSER_ERR_TOO_LONG_NUMBER:
                         message = _("Too long number");
                         break;
@@ -417,6 +413,18 @@ do_expression(int function, int arg, int cursor_start, int cursor_end)
                        message = _("Overflow. Try a bigger word size");
                        break;
 
+                    case -PARSER_ERR_UNKNOWN_VARIABLE:
+                        /* Translators; Error displayd to user when they
+                         * an unknown variable is entered */
+                       message = _("Unknown variable");
+                       break;
+
+                    case -PARSER_ERR_UNKNOWN_FUNCTION:
+                        /* Translators; Error displayd to user when they
+                         * an unknown function is entered */
+                       message = _("Unknown function");
+                       break;
+
                     case -MPMATH_ERR:
                         message = v->math_error_text;
                         break;
diff --git a/src/mp-binary.c b/src/mp-binary.c
index e3499c0..5b6914f 100644
--- a/src/mp-binary.c
+++ b/src/mp-binary.c
@@ -139,7 +139,7 @@ mp_shift(const MPNumber *x, int count, MPNumber *z)
 
 
 void
-mp_1s_complement(const MPNumber *x, int wordlen, MPNumber *z)
+mp_ones_complement(const MPNumber *x, int wordlen, MPNumber *z)
 {
     MPNumber t;
     mp_set_from_integer(0, &t);
@@ -149,8 +149,8 @@ mp_1s_complement(const MPNumber *x, int wordlen, MPNumber *z)
 
 
 void
-mp_2s_complement(const MPNumber *x, int wordlen, MPNumber *z)
+mp_twos_complement(const MPNumber *x, int wordlen, MPNumber *z)
 {
-    mp_1s_complement (x, wordlen, z);
+    mp_ones_complement (x, wordlen, z);
     mp_add_integer (z, 1, z);
 }
diff --git a/src/mp-equation-lexer.l b/src/mp-equation-lexer.l
index cb02f49..2f99417 100644
--- a/src/mp-equation-lexer.l
+++ b/src/mp-equation-lexer.l
@@ -101,7 +101,8 @@ SUB_NUM  {SUB_DIGITS}+
 NUMBER   {BIN_NUM}|{OCT_NUM}|{DEC_NUM}|{HEX_NUM}
 GREEKS   "α"|"β"|"γ"|"δ"|"ε"|"ζ"|"η"|"θ"|"ι"|"κ"|"λ"|"μ"|"ν"|"ξ"|"ο"|"Ï?"|"Ï?"|"Ï?"|"Ï?"|"Ï?"|"Ï?"|"Ï?"|"Ï?"|"Ï?"|"Ï?"
 REGISTERS "Râ??"|"Râ??"|"Râ??"|"Râ??"|"Râ??"|"Râ??"|"Râ??"|"Râ??"|"Râ??"|"Râ??"
-VARIABLE {REGISTERS}|{GREEKS}|"e"
+ANS      [aA][nN][sS]
+VARIABLE {REGISTERS}|{GREEKS}|"e"|{ANS}
 VARIABLE_NAME [a-zA-Z]+
 FUNCTION {VARIABLE_NAME}|{VARIABLE_NAME}{INVERSE}|{VARIABLE_NAME}{SUB_NUM}
 
diff --git a/src/mp-equation-parser.y b/src/mp-equation-parser.y
index 86329ea..66aee9f 100644
--- a/src/mp-equation-parser.y
+++ b/src/mp-equation-parser.y
@@ -32,9 +32,15 @@
 // treat exp NAME exp as a function always and pass both arguments, i.e.
 // can do mod using both and all others use $1 * NAME($3)
 
+static void set_error(yyscan_t yyscanner, int error)
+{
+    _mp_equation_get_extra(yyscanner)->error = error;
+}
+
 static void get_variable(yyscan_t yyscanner, const char *name, MPNumber *z)
 {
-    _mp_equation_get_extra(yyscanner)->get_variable(_mp_equation_get_extra(yyscanner), name, z);
+    if (!_mp_equation_get_extra(yyscanner)->get_variable(_mp_equation_get_extra(yyscanner), name, z))
+        set_error(yyscanner, -PARSER_ERR_UNKNOWN_VARIABLE);
 }
 
 static void set_variable(yyscan_t yyscanner, const char *name, MPNumber *x)
@@ -44,12 +50,8 @@ static void set_variable(yyscan_t yyscanner, const char *name, MPNumber *x)
 
 static void get_function(yyscan_t yyscanner, const char *name, const MPNumber *x, MPNumber *z)
 {
-    _mp_equation_get_extra(yyscanner)->get_function(_mp_equation_get_extra(yyscanner), name, x, z);
-}
-
-static void set_error(yyscan_t yyscanner, int error)
-{
-    _mp_equation_get_extra(yyscanner)->error = error;
+    if (!_mp_equation_get_extra(yyscanner)->get_function(_mp_equation_get_extra(yyscanner), name, x, z))
+        set_error(yyscanner, -PARSER_ERR_UNKNOWN_FUNCTION);
 }
 
 static void do_bitwise(yyscan_t yyscanner, void (*mp_fn)(const MPNumber *x, const MPNumber *y, MPNumber *z), const MPNumber *x, const MPNumber *y, MPNumber *z)
@@ -75,9 +77,7 @@ static void do_mod(yyscan_t yyscanner, const MPNumber *x, const MPNumber *y, MPN
     if (!mp_is_integer(x) || !mp_is_integer(y)) {
 	set_error(yyscanner, -PARSER_ERR_MODULUSOP);
     } else {
-      if (mp_modulus_divide(x, y, z)) {
-        set_error(yyscanner, -EINVAL);
-      }
+        mp_modulus_divide(x, y, z);
     }
 }
 %}
@@ -114,8 +114,8 @@ static void do_mod(yyscan_t yyscanner, const MPNumber *x, const MPNumber *y, MPN
 %%
 
 statement:
-  exp { mp_set_from_mp(&$1, &(_mp_equation_get_extra(yyscanner))->ret); set_error(yyscanner, 0);}
-| tVARIABLE '=' exp {set_variable(yyscanner, $1, &$3); set_error(yyscanner, 0);}
+  exp { mp_set_from_mp(&$1, &(_mp_equation_get_extra(yyscanner))->ret);}
+| tVARIABLE '=' exp {set_variable(yyscanner, $1, &$3);}
 ;
 
 exp:
diff --git a/src/mp-equation.c b/src/mp-equation.c
index fa52d22..0ff8d58 100644
--- a/src/mp-equation.c
+++ b/src/mp-equation.c
@@ -30,19 +30,30 @@
 
 extern int _mp_equation_parse(yyscan_t yyscanner);
 
-static void
+static int
 get_variable(MPEquationParserState *state, const char *name, MPNumber *z)
 {
-    if (name[0] == 'R' || name[0] == 'r')
+    char *c, *lower_name;
+    int result = 1;
+    
+    lower_name = strdup(name);
+    for (c = lower_name; *c; c++)
+        *c = tolower(*c);
+
+    if (lower_name[0] == 'r')
         mp_set_from_mp(register_get_value(atoi(name+1)), z);
-    else if (strcmp(name, "ans") == 0)
+    else if (strcmp(lower_name, "ans") == 0)
         mp_set_from_mp(display_get_answer(&v->display), z);
     else if (strcmp(name, "e") == 0)
         mp_get_eulers(z);
     else if (strcmp(name, "Ï?") == 0)
         mp_get_pi(z);
     else
-        mp_set_from_integer(0, z); // FIXME
+        result = 0;
+    
+    free(lower_name);
+    
+    return result;
 }
 
 static void
@@ -58,10 +69,11 @@ set_variable(MPEquationParserState *state, const char *name, MPNumber *x)
 // letters+numbers = numbers+letters+numbers = function
 
 
-static void
+static int
 get_function(MPEquationParserState *state, const char *name, const MPNumber *x, MPNumber *z)
 {
     char *c, *lower_name;
+    int result = 1;
     
     lower_name = strdup(name);
     for (c = lower_name; *c; c++)
@@ -105,17 +117,23 @@ get_function(MPEquationParserState *state, const char *name, const MPNumber *x,
         mp_acosh(x, z);
     else if (strcmp(lower_name, "tanh�¹") == 0 || strcmp(lower_name, "atanh") == 0)
         mp_atanh(x, z);
+    else if (strcmp(lower_name, "ones") == 0)
+        mp_ones_complement(x, state->wordlen, z);
+    else if (strcmp(lower_name, "twos") == 0)
+        mp_twos_complement(x, state->wordlen, z);    
     else
-        mp_set_from_integer(0, z); // FIXME
+        result = 0;
     
     free(lower_name);
+    
+    return result;
 }
 
 
 int 
 mp_equation_parse(const char *expression, MPNumber *result)
 {
-    int ret = 0;
+    int ret;
     MPEquationParserState state;
     yyscan_t yyscanner;
     YY_BUFFER_STATE buffer;
@@ -130,9 +148,9 @@ mp_equation_parse(const char *expression, MPNumber *result)
     state.get_variable = get_variable;
     state.set_variable = set_variable;
     state.get_function = get_function;    
-    state.error = -EINVAL;
+    state.error = 0;
     v->math_error = 0;
-        
+
     _mp_equation_lex_init_extra(&state, &yyscanner);
     buffer = _mp_equation__scan_string(expression, yyscanner);
 
@@ -141,9 +159,13 @@ mp_equation_parse(const char *expression, MPNumber *result)
     _mp_equation__delete_buffer(buffer, yyscanner);
     _mp_equation_lex_destroy(yyscanner);
 
-    ret = (state.error) ? state.error : ret;
+    /* Failed to parse */
     if (ret)
-        return ret;
+        return -PARSER_ERR_INVALID;
+        
+    /* Error during parsing */
+    if (state.error)
+        return state.error;
 
     if (v->math_error)
         return v->math_error;
diff --git a/src/mp-equation.h b/src/mp-equation.h
index 41f9d9c..e43d768 100644
--- a/src/mp-equation.h
+++ b/src/mp-equation.h
@@ -25,11 +25,13 @@
 
 #include "mp.h"
 
-#define PARSER_ERR_INVALID_BASE     10000
-#define PARSER_ERR_TOO_LONG_NUMBER  10001
-#define PARSER_ERR_BITWISEOP        10002
-#define PARSER_ERR_MODULUSOP        10003
-#define PARSER_ERR_OVERFLOW         10004
+#define PARSER_ERR_INVALID          1
+#define PARSER_ERR_TOO_LONG_NUMBER  2
+#define PARSER_ERR_BITWISEOP        3
+#define PARSER_ERR_MODULUSOP        4
+#define PARSER_ERR_OVERFLOW         5
+#define PARSER_ERR_UNKNOWN_VARIABLE 6
+#define PARSER_ERR_UNKNOWN_FUNCTION 7
 
 typedef struct MPEquationParserState MPEquationParserState;
 
@@ -45,13 +47,13 @@ struct MPEquationParserState {
     MPAngleUnit angle_units;
     
     /* Function to get variable values */
-    void (*get_variable)(MPEquationParserState *state, const char *name, MPNumber *z);
+    int (*get_variable)(MPEquationParserState *state, const char *name, MPNumber *z);
     
     /* Function to set variable values */
     void (*set_variable)(MPEquationParserState *state, const char *name, MPNumber *x);    
 
     /* Function to solve functions */
-    void (*get_function)(MPEquationParserState *state, const char *name, const MPNumber *x, MPNumber *z);
+    int (*get_function)(MPEquationParserState *state, const char *name, const MPNumber *x, MPNumber *z);
     
     // FIXME: get_operator??
 
diff --git a/src/mp.c b/src/mp.c
index 69cf983..e9f8044 100644
--- a/src/mp.c
+++ b/src/mp.c
@@ -1227,6 +1227,58 @@ mp_multiply(const MPNumber *x, const MPNumber *y, MPNumber *z)
 }
 
 
+void
+mp_multiply_new(const MPNumber *x, const MPNumber *y, MPNumber *z)
+{
+    int i, j, offset, y_length;
+    int fraction[MP_SIZE*2];
+
+    /* x*0 or 0*y or 0*0 = 0 */
+    if (x->sign * y->sign == 0) {
+        mp_set_from_integer(0, z);
+        return;
+    }
+
+    /* Calculate length of each fraction */
+    y_length = MP_SIZE;
+    while (y_length > 0 && y->fraction[y_length - 1] == 0)
+        y_length--;
+    
+    /* Multiply together */
+    memset(fraction, 0, sizeof(fraction));
+    for (i = MP_SIZE - 1; i >= 0; i--) {
+        if (x->fraction[i] == 0)
+            continue;
+        for (j = y_length - 1; j >= 0; j--) {
+            int pos = i + j + 1;
+            
+            fraction[pos] += x->fraction[i] * y->fraction[j];
+            fraction[pos-1] += fraction[pos] / MP_BASE;
+            fraction[pos] = fraction[pos] % MP_BASE;
+        }
+    }
+
+    offset = 0;
+    for (i = 0; i < MP_SIZE && fraction[offset] == 0; i++)
+        offset++;
+    z->sign = x->sign * y->sign;
+    z->exponent = x->exponent + y->exponent - offset;
+    for (i = 0; i < MP_SIZE; i++) {
+        if (i + offset >= MP_SIZE*2)
+            z->fraction[i] = 0;
+        else
+            z->fraction[i] = fraction[i + offset];
+    }
+    
+    /*for (i = MP_SIZE + offset; i < MP_SIZE * 2; i++) {
+        if (fraction[i] != 0) {
+            printf("truncated\n");
+            break;
+        }
+    }*/
+}
+
+
 /*  MULTIPLIES MP X BY SINGLE-PRECISION INTEGER IY GIVING MP Z.
  *  MULTIPLICATION BY 1 MAY BE USED TO NORMALIZE A NUMBER
  *  EVEN IF SOME DIGITS ARE GREATER THAN B-1.
@@ -1799,15 +1851,12 @@ mp_factorial(const MPNumber *x, MPNumber *z)
         mp_multiply_integer(z, i, z);
 }
 
-int
+
+void
 mp_modulus_divide(const MPNumber *x, const MPNumber *y, MPNumber *z)
 {
     MPNumber t1, t2;
 
-    if (!mp_is_integer(x) || !mp_is_integer(y)) {
-        return -EINVAL;
-    }
-
     mp_divide(x, y, &t1);
     mp_integer_component(&t1, &t1);
     mp_multiply(&t1, y, &t2);
@@ -1817,8 +1866,6 @@ mp_modulus_divide(const MPNumber *x, const MPNumber *y, MPNumber *z)
     if ((mp_is_less_than(y, &t1) && mp_is_greater_than(z, &t1)) || mp_is_less_than(z, &t1)) {
         mp_add(z, y, z);
     }
-
-    return 0;
 }
 
 
@@ -1864,8 +1911,8 @@ mp_xpowy_integer(const MPNumber *x, int n, MPNumber *z)
         mp_set_from_mp(x, &t);
 
     /* Multply x n times */
+    // FIXME: Can do mp_multiply(z, z, z) until close to answer (each call doubles number of multiples) */
     mp_set_from_integer(1, z);
-    for (i = 0; i < n; i++) {
+    for (i = 0; i < n; i++)
         mp_multiply(z, &t, z);
-    }
 }
diff --git a/src/mp.h b/src/mp.h
index 1cede21..377cc57 100644
--- a/src/mp.h
+++ b/src/mp.h
@@ -168,7 +168,7 @@ void   mp_sqrt(const MPNumber *x, MPNumber *z);
 void   mp_factorial(const MPNumber *x, MPNumber *z);
 
 /* Sets z = x mod y */
-int    mp_modulus_divide(const MPNumber *x, const MPNumber *y, MPNumber *z);
+void  mp_modulus_divide(const MPNumber *x, const MPNumber *y, MPNumber *z);
 
 /* Sets z = x^y */
 void   mp_xpowy(const MPNumber *x, const MPNumber *y, MPNumber *z);
@@ -279,9 +279,9 @@ void   mp_mask(const MPNumber *x, int wordlen, MPNumber *z);
 void   mp_shift(const MPNumber *x, int count, MPNumber *z);
 
 /* Sets z to be the ones complement of x for word of length 'wordlen' */
-void   mp_1s_complement(const MPNumber *x, int wordlen, MPNumber *z);
+void   mp_ones_complement(const MPNumber *x, int wordlen, MPNumber *z);
 
 /* Sets z to be the twos complement of x for word of length 'wordlen' */
-void   mp_2s_complement(const MPNumber *x, int wordlen, MPNumber *z);
+void   mp_twos_complement(const MPNumber *x, int wordlen, MPNumber *z);
 
 #endif /* MP_H */



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]