[gcalctool/gcalctool-newui2] Support fractional characters



commit f542cbd1c2b69ed5db2a44d5bca38bb76dbe5000
Author: Robert Ancell <robert ancell gmail com>
Date:   Sat Jun 27 15:11:22 2009 +1000

    Support fractional characters

 src/mp-convert.c         |   31 +++++++++++++++++++++++--------
 src/mp-equation-lexer.l  |    3 ++-
 src/mp-equation-parser.y |    4 +---
 src/unittest.c           |    4 +++-
 4 files changed, 29 insertions(+), 13 deletions(-)
---
diff --git a/src/mp-convert.c b/src/mp-convert.c
index 0a01914..fef376b 100644
--- a/src/mp-convert.c
+++ b/src/mp-convert.c
@@ -592,12 +592,15 @@ char_val(char chr, int base)
 
 /* Convert string into an MP number */
 void
-mp_set_from_string(const char *str, MPNumber *MPval)
+mp_set_from_string(const char *str, MPNumber *z)
 {
     int i, base, negate = 0;
     const char *c, *end;
     const char *base_suffixes[] = {"â??", "â??", "â??â??", NULL};
     int base_values[] = {2, 8, 16, 10};
+    const char *fractions[] = {"½", "â??", "â??", "¼", "¾", "â??", "â??", "â??", "â??", "â??", "â??", "â??", "â??", "â??", "â??", NULL};
+    int numerators[]        = { 1,   1,   2,   1,   3,   1,   2,   3,   4,   1,   5,   1,   3,   5,   7};
+    int denominators[]      = { 2,   3,   3,   4,   4,   5,   5,   5,   5,   6,   6,   8,   8,   8,   8};    
     
     /* Find the base */
     end = str;
@@ -622,12 +625,25 @@ mp_set_from_string(const char *str, MPNumber *MPval)
     }
     
     /* Convert integer part */
-    mp_set_from_integer(0, MPval);
+    mp_set_from_integer(0, z);
     while ((i = char_val(*c, base)) >= 0) {
-        mp_multiply_integer(MPval, base, MPval);
-        mp_add_integer(MPval, i, MPval);
+        mp_multiply_integer(z, base, z);
+        mp_add_integer(z, i, z);
         c++;
     }
+    
+    /* Look for fraction characters */
+    for (i = 0; fractions[i] != NULL; i++) {
+        if (end - strlen(fractions[i]) < str)
+            continue;
+        if (strcmp(end - strlen(fractions[i]), fractions[i]) == 0)
+            break;
+    }
+    if (fractions[i] != NULL) {
+        MPNumber fraction;
+        mp_set_from_fraction(numerators[i], denominators[i], &fraction);
+        mp_add(z, &fraction, z);
+    }
    
     /* Convert fractional part */
     if (*c == '.') {
@@ -644,14 +660,13 @@ mp_set_from_string(const char *str, MPNumber *MPval)
             c++;
         }
         mp_divide(&numerator, &denominator, &numerator);
-        mp_add(MPval, &numerator, MPval);
+        mp_add(z, &numerator, z);
     }
    
     if (c != end) {
        // FIXME: Error decoding
     }
  
-    if (negate == 1) {
-        mp_invert_sign(MPval, MPval);
-    }
+    if (negate == 1)
+        mp_invert_sign(z, z);
 }
diff --git a/src/mp-equation-lexer.l b/src/mp-equation-lexer.l
index e5edb3e..89e5bb8 100644
--- a/src/mp-equation-lexer.l
+++ b/src/mp-equation-lexer.l
@@ -80,9 +80,10 @@ HEX          [0-9]|[A-F]|[a-f]
 HEX_SUFFIX   "â??â??"
 SUPER_DIGITS "�"|"¹"|"²"|"³"|"�"|"�"|"�"|"�"|"�"|"�"
 SUB_DIGITS   "â??"|"â??"|"â??"|"â??"|"â??"|"â??"|"â??"|"â??"|"â??"|"â??"
+FRACTION     "½"|"â??"|"â??"|"¼"|"¾"|"â??"|"â??"|"â??"|"â??"|"â??"|"â??"|"â??"|"â??"|"â??"|"â??"
 
 HEX_NUM {HEX}+{HEX_SUFFIX}|{HEX}*{DECIMAL}{HEX}+{HEX_SUFFIX}
-DEC_NUM {DEC}+|{DEC}*{DECIMAL}{DEC}+
+DEC_NUM {DEC}+|{DEC}*{DECIMAL}{DEC}+|{FRACTION}|{DEC}{FRACTION}
 OCT_NUM {OCT}+{OCT_SUFFIX}|{OCT}*{DECIMAL}{OCT}+{OCT_SUFFIX}
 BIN_NUM {BIN}+{BIN_SUFFIX}|{BIN}*{DECIMAL}{BIN}+{BIN_SUFFIX}
 SUP_NUM {SUPER_DIGITS}+
diff --git a/src/mp-equation-parser.y b/src/mp-equation-parser.y
index fff7456..37db7bc 100644
--- a/src/mp-equation-parser.y
+++ b/src/mp-equation-parser.y
@@ -276,9 +276,7 @@ rcl:
 
 number:
   tNUMBER {mp_set_from_mp(&$1, &$$);}
-| tANS {
-  mp_set_from_mp(&_mp_equation_get_extra(yyscanner)->ans, &$$);
-}
+| tANS {mp_set_from_mp(&_mp_equation_get_extra(yyscanner)->ans, &$$);}
 ;
 
 %%
diff --git a/src/unittest.c b/src/unittest.c
index 1c02e48..d4ecef5 100644
--- a/src/unittest.c
+++ b/src/unittest.c
@@ -105,10 +105,12 @@ test_parser()
     test("â??â??1", "1", 0);
     test("255", "255", 0);
     test("256", "256", 0);
+    test("½", "0.5", 0);
+    test("1½", "1.5", 0);    
     test("1.00", "1", 0);
     test("1.01", "1.01", 0);
     test("Ï?", "3.141592654", 0);
-    test("e", "2.718281828", 0);    
+    test("e", "2.718281828", 0);
 
     test("0+0", "0", 0);
     test("1+1", "2", 0);



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