[gcalctool/gcalctool-newui2] ...



commit 4e1f5085d7813824ee508857296b6482d4d6a1c2
Author: Robert Ancell <robert ancell gmail com>
Date:   Mon Jul 6 20:44:06 2009 +1000

    ...

 src/display.c            |   61 +++++-----------------
 src/gtk.c                |  126 +++++++++++++++++++++++++++++++---------------
 src/mp-equation-lexer.l  |   69 +++++++++++++------------
 src/mp-equation-parser.y |   55 ++++++++++-----------
 src/unittest.c           |   13 +++--
 5 files changed, 170 insertions(+), 154 deletions(-)
---
diff --git a/src/display.c b/src/display.c
index 1fa3690..757a3e9 100644
--- a/src/display.c
+++ b/src/display.c
@@ -45,26 +45,6 @@ get_state(GCDisplay *display)
     return &(display->h.e[display->h.current]);
 }
 
-static gboolean
-exp_has_postfix(char *str, char *postfix)
-{
-    int len, plen;
-
-    if (!str) {
-        return FALSE;
-    }
-
-    assert(postfix);
-
-    len = strlen(str);
-    plen = strlen(postfix);
-
-    if (plen > len) {
-        return FALSE;
-    }
-
-    return strcasecmp(str + len - plen, postfix) == 0;
-}
 
 static char *
 str_replace(char *str, char *from, char *to)
@@ -247,30 +227,26 @@ display_set_number(GCDisplay *display, const MPNumber *MPval)
 void
 display_set_answer(GCDisplay *display)
 {
-    display_set_string(display, "Ans", -1);
+    display_set_string(display, "ans", -1);
 }
 
 
 static void
 display_make_text(GCDisplay *display, char *localized, int length, int *cursor)
 {
-    int i;
-    char temp[MAX_LOCALIZED], *str, reg[3];
+    char *str;
     GCDisplayState *e;
 
     e = get_state(display);
-    str = strdup(e->expression);
         
     /* Substitute answer register */
-    display_make_number(display, temp, MAX_LOCALIZED, &e->ans, v->base, TRUE);
-    str = str_replace(str, "Ans", temp);
-
-    /* Replace registers with values. */
-    for (i = 0; i < 10; i++) {
-        SNPRINTF(reg, 3, "R%d", i);
-        display_make_number(display, temp, MAX_LOCALIZED, register_get_value(i), v->base, FALSE);
-        str = str_replace(str, reg, temp);
+    if (display_is_result(display)) {
+        char temp[MAX_LOCALIZED];
+        display_make_number(display, temp, MAX_LOCALIZED, &e->ans, v->base, TRUE);
+        str = strdup(temp);
     }
+    else
+        str = strdup(e->expression);
 
     localize_expression(localized, str, length, cursor);
     free(str);
@@ -375,7 +351,7 @@ void display_push(GCDisplay *display)
         do {
             i = ((i + 1) % UNDO_HISTORY_LENGTH);
             free(display->h.e[i].expression);
-            display->h.e[i].expression = strdup("Ans");
+            display->h.e[i].expression = strdup("ans");
         } while (i != display->h.end);
     }
 
@@ -495,9 +471,9 @@ display_insert_number(GCDisplay *display, int cursor_start, int cursor_end, cons
 void
 display_backspace(GCDisplay *display, int cursor_start, int cursor_end)
 {
-    char buf[MAX_DISPLAY] = "", buf2[MAX_DISPLAY];
+    char buf[MAX_DISPLAY] = "";
     GCDisplayState *e = get_state(display);
-    int i, cursor;
+    int cursor;
     
     /* Can't delete empty display */
     if (display_is_empty(display))
@@ -511,18 +487,9 @@ display_backspace(GCDisplay *display, int cursor_start, int cursor_end)
         
         len = g_utf8_strlen(ui_get_display(), -1);
         
-        if (exp_has_postfix(e->expression, "Ans")) {
+        if (display_is_result(display)) {
             display_make_number(display, buf, MAX_DISPLAY, &e->ans, v->base, FALSE);
-            e->expression = str_replace(e->expression, "Ans", buf);
-        } else {
-            for (i = 0; i < 10; i++) {
-                SNPRINTF(buf, MAX_DISPLAY, "R%d", i);
-                if (exp_has_postfix(e->expression, buf)) {
-                    display_make_number(display, buf2, MAX_DISPLAY, register_get_value(i), v->base, FALSE);
-                    SNPRINTF(buf, MAX_DISPLAY, "%.*s%s", strlen(e->expression) - 2, e->expression - 2, buf2);
-                    break;
-                }
-            }
+            e->expression = str_replace(e->expression, "ans", buf);
         }
 
         display_insert(display, len - 1, len, "");
@@ -565,7 +532,7 @@ display_is_empty(GCDisplay *display)
 gboolean
 display_is_result(GCDisplay *display)
 {
-    if (strcmp(display_get_text(display), "Ans") == 0)
+    if (strcmp(display_get_text(display), "ans") == 0)
         return TRUE;
     
     return FALSE;
diff --git a/src/gtk.c b/src/gtk.c
index ed03167..81bd1c3 100644
--- a/src/gtk.c
+++ b/src/gtk.c
@@ -1354,49 +1354,89 @@ main_window_key_press_cb(GtkWidget *widget, GdkEventKey *event)
     }
     
     /* Shortcuts */
-    if (state == GDK_CONTROL_MASK || state == GDK_MOD1_MASK) {
-        gboolean do_sub = state == GDK_MOD1_MASK;
-        switch (event->keyval) {
-            case GDK_0:
-                do_text(do_sub ? "â??" : "â?°");
-                return TRUE;
-            case GDK_1:
-                do_text(do_sub ? "â??" : "¹");
-                return TRUE;
-            case GDK_2:
-                do_text(do_sub ? "â??" : "²");
-                return TRUE;
-            case GDK_3:
-                do_text(do_sub ? "â??" : "³");
-                return TRUE;
-            case GDK_4:
-                do_text(do_sub ? "â??" : "â?´");
-                return TRUE;
-            case GDK_5:
-                do_text(do_sub ? "â??" : "â?µ");
-                return TRUE;
-            case GDK_6:
-                do_text(do_sub ? "â??" : "â?¶");
-                return TRUE;
-            case GDK_7:
-                do_text(do_sub ? "â??" : "â?·");
-                return TRUE;
-            case GDK_8:
-                do_text(do_sub ? "â??" : "â?¸");
-                return TRUE;
-            case GDK_9:
-                do_text(do_sub ? "â??" : "â?¹");
-                return TRUE;
-            case GDK_minus:
-            case GDK_KP_Subtract:
-                do_text(do_sub ? "â??" : "â?»");
-                return TRUE;
+    if (state == GDK_CONTROL_MASK) {
+        switch(event->keyval)
+        {
+        case GDK_0:
+            do_text("â?°");
+            return TRUE;
+        case GDK_1:
+            do_text("¹");
+            return TRUE;
+        case GDK_2:
+            do_text("²");
+            return TRUE;
+        case GDK_3:
+            do_text("³");
+            return TRUE;
+        case GDK_4:
+            do_text("â?´");
+            return TRUE;
+        case GDK_5:
+            do_text("â?µ");
+            return TRUE;
+        case GDK_6:
+            do_text("â?¶");
+            return TRUE;
+        case GDK_7:
+            do_text("â?·");
+            return TRUE;
+        case GDK_8:
+            do_text("â?¸");
+            return TRUE;
+        case GDK_9:
+            do_text("â?¹");
+            return TRUE;
+        case GDK_u:
+            do_text("µ");
+            return TRUE;            
+        case GDK_e:
+            do_text("Ã?10^");
+            return TRUE;
+        case GDK_r:
+            do_text("â??");
+            return TRUE;
+        case GDK_i:
+            do_text("�¹");
+            return TRUE;
+        case GDK_p:
+            do_text("Ï?");
+            return TRUE;
         }
     }
-
-    if (state == GDK_CONTROL_MASK) {
+    else if (state == GDK_MOD1_MASK) {
         switch(event->keyval)
         {
+        case GDK_0:
+            do_text("â??");
+            return TRUE;
+        case GDK_1:
+            do_text("â??");
+            return TRUE;
+        case GDK_2:
+            do_text("â??");
+            return TRUE;
+        case GDK_3:
+            do_text("â??");
+            return TRUE;
+        case GDK_4:
+            do_text("â??");
+            return TRUE;
+        case GDK_5:
+            do_text("â??");
+            return TRUE;
+        case GDK_6:
+            do_text("â??");
+            return TRUE;
+        case GDK_7:
+            do_text("â??");
+            return TRUE;
+        case GDK_8:
+            do_text("â??");
+            return TRUE;
+        case GDK_9:
+            do_text("â??");
+            return TRUE;
         case GDK_u:
             do_text("µ");
             return TRUE;            
@@ -1464,10 +1504,14 @@ main_window_key_press_cb(GtkWidget *widget, GdkEventKey *event)
     case '\n':
         do_button(FN_CALCULATE, 0);
         return TRUE;
-    default:
-        do_text(event->string); // FIXME: Only if printable
+    }
+    
+    if (event->string[0] != '\0') {
+        do_text(event->string);
         return TRUE;
     }
+    
+    return FALSE;
 }
 
 
diff --git a/src/mp-equation-lexer.l b/src/mp-equation-lexer.l
index 081c12a..d6d7021 100644
--- a/src/mp-equation-lexer.l
+++ b/src/mp-equation-lexer.l
@@ -68,40 +68,42 @@ static int sub_atoi(const char *data)
 %}
 
 
-ZERO         "0"|"Ù "|"Û°"|"ß?"|"०"|"০"|"੦"|"૦"|"à­¦"|"௦"|"౦"|"೦"|"൦"|"à¹?"|"à»?"|"༠"|"á??"|"á??"|"á? "|"á ?"|"á¥?"|"á§?"|"á­?"|"á®°"|"á±?"|"á±?"|"ê? "|"ê£?"|"ê¤?"|"ê©?"|"ð?? "
-ONE          "1"|"Ù¡"|"Û±"|"ß?"|"१"|"১"|"੧"|"૧"|"à­§"|"௧"|"౧"|"೧"|"൧"|"à¹?"|"à»?"|"༡"|"á??"|"á??"|"á?¡"|"á ?"|"á¥?"|"á§?"|"á­?"|"á®±"|"á±?"|"á±?"|"ê?¡"|"ê£?"|"ê¤?"|"ê©?"|"ð??¡"
-TWO          "2"|"Ù¢"|"Û²"|"ß?"|"२"|"২"|"੨"|"૨"|"à­¨"|"௨"|"౨"|"೨"|"൨"|"à¹?"|"à»?"|"༢"|"á??"|"á??"|"á?¢"|"á ?"|"á¥?"|"á§?"|"á­?"|"᮲"|"á±?"|"á±?"|"ê?¢"|"ê£?"|"ê¤?"|"ê©?"|"ð??¢"
-THREE        "3"|"Ù£"|"Û³"|"ß?"|"३"|"৩"|"à©©"|"à«©"|"à­©"|"௩"|"౩"|"೩"|"൩"|"à¹?"|"à»?"|"༣"|"á??"|"á??"|"á?£"|"á ?"|"á¥?"|"á§?"|"á­?"|"᮳"|"á±?"|"á±?"|"ê?£"|"ê£?"|"ê¤?"|"ê©?"|"ð??£"
-FOUR         "4"|"Ù¤"|"Û´"|"ß?"|"४"|"৪"|"੪"|"૪"|"à­ª"|"௪"|"౪"|"೪"|"൪"|"à¹?"|"à»?"|"༤"|"á??"|"á??"|"á?¤"|"á ?"|"á¥?"|"á§?"|"á­?"|"á®´"|"á±?"|"á±?"|"ê?¤"|"ê£?"|"ê¤?"|"ê©?"|"ð??¤"
-FIVE         "5"|"Ù¥"|"Ûµ"|"ß?"|"५"|"৫"|"à©«"|"à««"|"à­«"|"௫"|"౫"|"೫"|"൫"|"à¹?"|"à»?"|"༥"|"á??"|"á??"|"á?¥"|"á ?"|"á¥?"|"á§?"|"á­?"|"᮵"|"á±?"|"á±?"|"ê?¥"|"ê£?"|"ê¤?"|"ê©?"|"ð??¥"
-SIX          "6"|"Ù¦"|"Û¶"|"ß?"|"६"|"৬"|"੬"|"૬"|"à­¬"|"௬"|"౬"|"೬"|"൬"|"à¹?"|"à»?"|"༦"|"á??"|"á??"|"á?¦"|"á ?"|"á¥?"|"á§?"|"á­?"|"᮶"|"á±?"|"á±?"|"ê?¦"|"ê£?"|"ê¤?"|"ê©?"|"ð??¦"
-SEVEN        "7"|"Ù§"|"Û·"|"ß?"|"७"|"৭"|"à©­"|"à«­"|"à­­"|"௭"|"à±­"|"à³­"|"൭"|"à¹?"|"à»?"|"༧"|"á??"|"á??"|"á?§"|"á ?"|"á¥?"|"á§?"|"á­?"|"á®·"|"á±?"|"á±?"|"ê?§"|"ê£?"|"ê¤?"|"ê©?"|"ð??§"
-EIGHT        "8"|"Ù¨"|"Û¸"|"ß?"|"८"|"৮"|"à©®"|"à«®"|"à­®"|"௮"|"à±®"|"à³®"|"൮"|"à¹?"|"à»?"|"༨"|"á??"|"á??"|"á?¨"|"á ?"|"á¥?"|"á§?"|"á­?"|"᮸"|"á±?"|"á±?"|"ê?¨"|"ê£?"|"ê¤?"|"ê©?"|"ð??¨"
-NINE         "9"|"Ù©"|"Û¹"|"ß?"|"९"|"৯"|"੯"|"૯"|"à­¯"|"௯"|"౯"|"೯"|"൯"|"à¹?"|"à»?"|"༩"|"á??"|"á??"|"á?©"|"á ?"|"á¥?"|"á§?"|"á­?"|"᮹"|"á±?"|"á±?"|"ê?©"|"ê£?"|"ê¤?"|"ê©?"|"ð??©"
-DECIMAL	     "."|","
-BIN          {ZERO}|{ONE}
-BIN_SUFFIX   "â??"
-OCT          {ZERO}|{ONE}|{TWO}|{THREE}|{FOUR}|{FIVE}|{SIX}|{SEVEN}
-OCT_SUFFIX   "â??"
-DEC          {ZERO}|{ONE}|{TWO}|{THREE}|{FOUR}|{FIVE}|{SIX}|{SEVEN}|{EIGHT}|{NINE}
-HEX          {DEC}|[A-F]|[a-f]
-HEX_SUFFIX   "â??â??"
-SI_SUFFIX    "T"|"G"|"M"|"k"|"d"|"c"|"m"|"u"|"µ"|"n"|"p"|"f"
-SUPER_DIGITS "�"|"¹"|"²"|"³"|"�"|"�"|"�"|"�"|"�"|"�"
-SUB_DIGITS   "â??"|"â??"|"â??"|"â??"|"â??"|"â??"|"â??"|"â??"|"â??"|"â??"
-FRACTION     "½"|"â??"|"â??"|"¼"|"¾"|"â??"|"â??"|"â??"|"â??"|"â??"|"â??"|"â??"|"â??"|"â??"|"â??"
-VARIABLE_C   [a-z]|[A-Z]
-INVERSE      "�¹"
+ZERO          "0"|"Ù "|"Û°"|"ß?"|"०"|"০"|"੦"|"૦"|"à­¦"|"௦"|"౦"|"೦"|"൦"|"à¹?"|"à»?"|"༠"|"á??"|"á??"|"á? "|"á ?"|"á¥?"|"á§?"|"á­?"|"á®°"|"á±?"|"á±?"|"ê? "|"ê£?"|"ê¤?"|"ê©?"|"ð?? "
+ONE           "1"|"Ù¡"|"Û±"|"ß?"|"१"|"১"|"੧"|"૧"|"à­§"|"௧"|"౧"|"೧"|"൧"|"à¹?"|"à»?"|"༡"|"á??"|"á??"|"á?¡"|"á ?"|"á¥?"|"á§?"|"á­?"|"á®±"|"á±?"|"á±?"|"ê?¡"|"ê£?"|"ê¤?"|"ê©?"|"ð??¡"
+TWO           "2"|"Ù¢"|"Û²"|"ß?"|"२"|"২"|"੨"|"૨"|"à­¨"|"௨"|"౨"|"೨"|"൨"|"à¹?"|"à»?"|"༢"|"á??"|"á??"|"á?¢"|"á ?"|"á¥?"|"á§?"|"á­?"|"᮲"|"á±?"|"á±?"|"ê?¢"|"ê£?"|"ê¤?"|"ê©?"|"ð??¢"
+THREE         "3"|"Ù£"|"Û³"|"ß?"|"३"|"৩"|"à©©"|"à«©"|"à­©"|"௩"|"౩"|"೩"|"൩"|"à¹?"|"à»?"|"༣"|"á??"|"á??"|"á?£"|"á ?"|"á¥?"|"á§?"|"á­?"|"᮳"|"á±?"|"á±?"|"ê?£"|"ê£?"|"ê¤?"|"ê©?"|"ð??£"
+FOUR          "4"|"Ù¤"|"Û´"|"ß?"|"४"|"৪"|"੪"|"૪"|"à­ª"|"௪"|"౪"|"೪"|"൪"|"à¹?"|"à»?"|"༤"|"á??"|"á??"|"á?¤"|"á ?"|"á¥?"|"á§?"|"á­?"|"á®´"|"á±?"|"á±?"|"ê?¤"|"ê£?"|"ê¤?"|"ê©?"|"ð??¤"
+FIVE          "5"|"Ù¥"|"Ûµ"|"ß?"|"५"|"৫"|"à©«"|"à««"|"à­«"|"௫"|"౫"|"೫"|"൫"|"à¹?"|"à»?"|"༥"|"á??"|"á??"|"á?¥"|"á ?"|"á¥?"|"á§?"|"á­?"|"᮵"|"á±?"|"á±?"|"ê?¥"|"ê£?"|"ê¤?"|"ê©?"|"ð??¥"
+SIX           "6"|"Ù¦"|"Û¶"|"ß?"|"६"|"৬"|"੬"|"૬"|"à­¬"|"௬"|"౬"|"೬"|"൬"|"à¹?"|"à»?"|"༦"|"á??"|"á??"|"á?¦"|"á ?"|"á¥?"|"á§?"|"á­?"|"᮶"|"á±?"|"á±?"|"ê?¦"|"ê£?"|"ê¤?"|"ê©?"|"ð??¦"
+SEVEN         "7"|"Ù§"|"Û·"|"ß?"|"७"|"৭"|"à©­"|"à«­"|"à­­"|"௭"|"à±­"|"à³­"|"൭"|"à¹?"|"à»?"|"༧"|"á??"|"á??"|"á?§"|"á ?"|"á¥?"|"á§?"|"á­?"|"á®·"|"á±?"|"á±?"|"ê?§"|"ê£?"|"ê¤?"|"ê©?"|"ð??§"
+EIGHT         "8"|"Ù¨"|"Û¸"|"ß?"|"८"|"৮"|"à©®"|"à«®"|"à­®"|"௮"|"à±®"|"à³®"|"൮"|"à¹?"|"à»?"|"༨"|"á??"|"á??"|"á?¨"|"á ?"|"á¥?"|"á§?"|"á­?"|"᮸"|"á±?"|"á±?"|"ê?¨"|"ê£?"|"ê¤?"|"ê©?"|"ð??¨"
+NINE          "9"|"Ù©"|"Û¹"|"ß?"|"९"|"৯"|"੯"|"૯"|"à­¯"|"௯"|"౯"|"೯"|"൯"|"à¹?"|"à»?"|"༩"|"á??"|"á??"|"á?©"|"á ?"|"á¥?"|"á§?"|"á­?"|"᮹"|"á±?"|"á±?"|"ê?©"|"ê£?"|"ê¤?"|"ê©?"|"ð??©"
+DECIMAL	      "."|","
+BIN           {ZERO}|{ONE}
+BIN_SUFFIX    "â??"
+OCT           {ZERO}|{ONE}|{TWO}|{THREE}|{FOUR}|{FIVE}|{SIX}|{SEVEN}
+OCT_SUFFIX    "â??"
+DEC           {ZERO}|{ONE}|{TWO}|{THREE}|{FOUR}|{FIVE}|{SIX}|{SEVEN}|{EIGHT}|{NINE}
+HEX           {DEC}|[A-F]|[a-f]
+HEX_SUFFIX    "â??â??"
+SI_SUFFIX     "T"|"G"|"M"|"k"|"d"|"c"|"m"|"u"|"µ"|"n"|"p"|"f"
+SUPER_DIGITS  "�"|"¹"|"²"|"³"|"�"|"�"|"�"|"�"|"�"|"�"
+SUB_DIGITS    "â??"|"â??"|"â??"|"â??"|"â??"|"â??"|"â??"|"â??"|"â??"|"â??"
+FRACTION      "½"|"â??"|"â??"|"¼"|"¾"|"â??"|"â??"|"â??"|"â??"|"â??"|"â??"|"â??"|"â??"|"â??"|"â??"
+VARIABLE_C    [a-z]|[A-Z]
+INVERSE       "�¹"
 
-HEX_NUM {HEX}+{HEX_SUFFIX}|{HEX}*{DECIMAL}{HEX}+{HEX_SUFFIX}
-DEC_NUM {DEC}+|{DEC}+{SI_SUFFIX}|{DEC}*{DECIMAL}{DEC}+|{DEC}*{SI_SUFFIX}{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}+
-SUB_NUM {SUB_DIGITS}+
-NUMBER  {BIN_NUM}|{OCT_NUM}|{DEC_NUM}|{HEX_NUM}
-GREEKS  "α"|"β"|"γ"|"δ"|"ε"|"ζ"|"η"|"θ"|"ι"|"κ"|"λ"|"μ"|"ν"|"ξ"|"ο"|"Ï?"|"Ï?"|"Ï?"|"Ï?"|"Ï?"|"Ï?"|"Ï?"|"Ï?"|"Ï?"|"Ï?"
-VARIABLE {VARIABLE_C}+|{GREEKS}|{VARIABLE_C}+{INVERSE}|{VARIABLE_C}+{SUB_NUM}
+HEX_NUM  {HEX}+{HEX_SUFFIX}|{HEX}*{DECIMAL}{HEX}+{HEX_SUFFIX}
+DEC_NUM  {DEC}+|{DEC}+{SI_SUFFIX}|{DEC}*{DECIMAL}{DEC}+|{DEC}*{SI_SUFFIX}{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}+
+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"
+FUNCTION {VARIABLE_C}+|{VARIABLE_C}+{INVERSE}|{VARIABLE_C}+{SUB_NUM}
 
 MOD  [mM][oO][dD]
 AND  "â?§"|[aA][nN][dD]
@@ -127,6 +129,7 @@ NOT  "¬"|"~"|[nN][oO][tT]
 {SUB_NUM}  {yylval->integer = sub_atoi(yytext); return tSUBNUM; }
 {NUMBER}   {mp_set_from_string(yytext, &yylval->int_t); return tNUMBER;}
 {VARIABLE} {yylval->name = strdup(yytext); return tVARIABLE;}
+{FUNCTION} {yylval->name = strdup(yytext); return tFUNCTION;}
 {INVERSE}  {return tINVERSE;}
 [ \t\n]
 .          {return *yytext;}
diff --git a/src/mp-equation-parser.y b/src/mp-equation-parser.y
index 869cd7e..94ac6b4 100644
--- a/src/mp-equation-parser.y
+++ b/src/mp-equation-parser.y
@@ -85,20 +85,16 @@ static void do_mod(yyscan_t yyscanner, const MPNumber *x, const MPNumber *y, MPN
   char *name;
 }
 
-%token <int_t>   tNUMBER
-%token <integer> tSUBNUM tSUPNUM
-%token <name>    tVARIABLE
-
+%left <int_t> tNUMBER
 %left UNARY_PLUS
 %left tADD tSUBTRACT
 %left tAND tOR tXOR tXNOR
-%left tMULTIPLY tDIVIDE tMOD
+%left tMULTIPLY tDIVIDE tMOD MULTIPLICATION
 %left tNOT
-%right '^' tSQUARED tCUBED tINVERSE
 %left tROOT tROOT3 tROOT4
-%right '!'
-%left VARIABLE
-%left FUNCTION
+%left <name> tVARIABLE tFUNCTION
+%right '^' tINVERSE '!'
+%right <integer> tSUBNUM tSUPNUM
 %left BOOLEAN_OPERATOR
 %left PERCENTAGE
 %left UNARY_MINUS
@@ -113,41 +109,42 @@ statement:
 ;
 
 exp:
-  tNUMBER {mp_set_from_mp(&$1, &$$);}
-| tSUBTRACT exp %prec UNARY_MINUS {mp_invert_sign(&$2, &$$);}
-| tADD tNUMBER %prec UNARY_PLUS {mp_set_from_mp(&$2, &$$);}
+  '(' exp ')' {mp_set_from_mp(&$2, &$$);}
+| '|' exp '|' {mp_abs(&$2, &$$);}
+| exp '^' exp {mp_xpowy(&$1, &$3, &$$);}
+| exp tSUPNUM {mp_pwr_integer(&$1, $2, &$$);}
+| exp tINVERSE {mp_reciprocal(&$1, &$$);}
+| exp '!' {mp_factorial(&$1, &$$);}
 | tVARIABLE {get_variable(yyscanner, $1, &$$); free($1);}
-| tNUMBER tVARIABLE %prec VARIABLE {get_variable(yyscanner, $2, &$$); mp_multiply(&$1, &$$, &$$); free($2);}
+| tVARIABLE tVARIABLE {MPNumber t; get_variable(yyscanner, $1, &t); get_variable(yyscanner, $2, &$$); mp_multiply(&t, &$$, &$$); free($1);}
 | function {mp_set_from_mp(&$1, &$$);}
-| tNUMBER function %prec FUNCTION {mp_multiply(&$1, &$2, &$$);}
+| tNUMBER function  %prec MULTIPLICATION {mp_multiply(&$1, &$2, &$$);}
+| tNUMBER tVARIABLE %prec MULTIPLICATION {get_variable(yyscanner, $2, &$$); mp_multiply(&$1, &$$, &$$); free($2);}
+| tSUBTRACT exp %prec UNARY_MINUS {mp_invert_sign(&$2, &$$);}
+| tADD tNUMBER %prec UNARY_PLUS {mp_set_from_mp(&$2, &$$);}
 | exp tDIVIDE exp {mp_divide(&$1, &$3, &$$);}
 | exp tMOD exp {do_mod(yyscanner, &$1, &$3, &$$);}
 | exp tMULTIPLY exp {mp_multiply(&$1, &$3, &$$);}
-| exp tADD exp {mp_add(&$1, &$3, &$$);}
-| exp tSUBTRACT exp {mp_subtract(&$1, &$3, &$$);}
 | exp tADD exp '%' %prec PERCENTAGE {mp_add_integer(&$3, 100, &$3); mp_divide_integer(&$3, 100, &$3); mp_multiply(&$1, &$3, &$$);}
 | exp tSUBTRACT exp '%' %prec PERCENTAGE {mp_add_integer(&$3, -100, &$3); mp_divide_integer(&$3, -100, &$3); mp_multiply(&$1, &$3, &$$);}
-| exp '^' exp {mp_xpowy(&$1, &$3, &$$);}
-| exp tSUPNUM {mp_pwr_integer(&$1, $2, &$$);}
-| exp tINVERSE {mp_reciprocal(&$1, &$$);}
-| '(' exp ')' {mp_set_from_mp(&$2, &$$);}
-| '|' exp '|' {mp_abs(&$2, &$$);}
-| exp '!' {mp_factorial(&$1, &$$);}
+| exp tADD exp {mp_add(&$1, &$3, &$$);}
+| exp tSUBTRACT exp {mp_subtract(&$1, &$3, &$$);}
+| exp '%' {mp_divide_integer(&$1, 100, &$$);}
 | tNOT exp {do_not(yyscanner, &$2, &$$);}
 | exp tAND exp %prec BOOLEAN_OPERATOR {do_bitwise(yyscanner, mp_and, &$1, &$3, &$$);}
 | exp tOR exp %prec BOOLEAN_OPERATOR {do_bitwise(yyscanner, mp_or, &$1, &$3, &$$);}
 | exp tXOR exp %prec BOOLEAN_OPERATOR {do_bitwise(yyscanner, mp_xor, &$1, &$3, &$$);}
-| exp '%' {mp_divide_integer(&$1, 100, &$$);}
+| tNUMBER {mp_set_from_mp(&$1, &$$);}
 ;
 
 
 function:
-  tVARIABLE exp %prec FUNCTION {get_function(yyscanner, $1, &$2, &$$); free($1);}
-| tVARIABLE tSUPNUM exp %prec FUNCTION {get_function(yyscanner, $1, &$3, &$$); mp_pwr_integer(&$$, $2, &$$); free($1);}
-| tSUBNUM tROOT exp %prec FUNCTION {mp_root(&$3, $1, &$$);}
-| tROOT exp %prec FUNCTION {mp_sqrt(&$2, &$$);}
-| tROOT3 exp %prec FUNCTION {mp_root(&$2, 3, &$$);}
-| tROOT4 exp %prec FUNCTION {mp_root(&$2, 4, &$$);}
+  tFUNCTION exp {get_function(yyscanner, $1, &$2, &$$); free($1);}
+| tFUNCTION tSUPNUM exp {get_function(yyscanner, $1, &$3, &$$); mp_pwr_integer(&$$, $2, &$$); free($1);}
+| tSUBNUM tROOT exp {mp_root(&$3, $1, &$$);}
+| tROOT exp {mp_sqrt(&$2, &$$);}
+| tROOT3 exp {mp_root(&$2, 3, &$$);}
+| tROOT4 exp {mp_root(&$2, 4, &$$);}
 ;
 
 %%
diff --git a/src/unittest.c b/src/unittest.c
index dc2e05c..63ff1d7 100644
--- a/src/unittest.c
+++ b/src/unittest.c
@@ -141,12 +141,17 @@ test_parser()
     //test("2p3", "0.0000000000023", 0); // FIXME: Need to print out significant figures, not decimal places
     //test("2f3", "0.0000000000000023", 0); // FIXME: Need to print out significant figures, not decimal places
     test("Ï?", "3.141592654", 0);
-    test("2Ï?", "6.283185307", 0);
     test("e", "2.718281828", 0);
+    
+    test("2Ï?", "6.283185307", 0);
     test("2e", "5.436563657", 0);
-    test("Ï?e", "1", 0);
-    test("eÏ?", "1", 0);
-    test("2Ï?e", "1", 0);
+    test("2Ï?²", "19.739208802", 0);
+    test("2e²", "14.778112198", 0);
+    test("e2", "", 1);
+    test("Ï?2", "", 1);
+    test("Ï?e", "8.539734223", 0);
+    test("eÏ?", "8.539734223", 0);
+    test("2Ï?e", "17.079468445", 0);
     
     test("١٢٣٤٥٦٧٨٩٠", "1234567890", 0);
     test("Û±Û²Û³Û´ÛµÛ¶Û·Û¸Û¹Û°", "1234567890", 0);



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