[gcalctool/gcalctool-newui2] ...



commit c22c64db1a04f127f8d627b65657d80f2205e5e1
Author: Robert Ancell <robert ancell gmail com>
Date:   Tue Jun 30 11:43:54 2009 +1000

    ...

 src/mp-equation-parser.y |   57 ++++++++++++++++++++++++++-------------------
 src/mp-equation.c        |   15 +++++++-----
 src/mp-equation.h        |   18 +++++---------
 3 files changed, 49 insertions(+), 41 deletions(-)
---
diff --git a/src/mp-equation-parser.y b/src/mp-equation-parser.y
index 5d18d18..97a8051 100644
--- a/src/mp-equation-parser.y
+++ b/src/mp-equation-parser.y
@@ -29,6 +29,23 @@
 #include "mp-equation.h"
 #include "mp-equation-parser.h"
 #include "mp-equation-lexer.h"
+
+static const MPNumber *get_variable(yyscan_t yyscanner, const char *name)
+{
+    return _mp_equation_get_extra(yyscanner)->get_variable(_mp_equation_get_extra(yyscanner), name);
+}
+
+static const MPNumber *get_register(yyscan_t yyscanner, int index)
+{
+    char name[3];
+    snprintf(name, 3, "R%d", index);
+    return get_variable(yyscanner, name);
+}
+
+static void set_error(yyscan_t yyscanner, int error)
+{
+    _mp_equation_get_extra(yyscanner)->error = error;
+}
 %}
 
 %define api.pure
@@ -90,7 +107,7 @@
 %token <int_t> tNUMBER
 %token <integer> tREG tSUBNUM tSUPNUM
 
-%type  <int_t> exp rcl term func number constant
+%type  <int_t> exp term func number constant
 
 %start statement
 %left tADD tSUBTRACT tMULTIPLY tDIVIDE
@@ -102,7 +119,7 @@
 %%
 
 statement: 
-  exp { mp_set_from_mp(&$1, &(_mp_equation_get_extra(yyscanner))->ret); (_mp_equation_get_extra(yyscanner))->have_result = 1; }
+  exp { mp_set_from_mp(&$1, &(_mp_equation_get_extra(yyscanner))->ret); set_error(yyscanner, 0); }
 ;
 
 exp: 
@@ -116,34 +133,34 @@ exp:
 | exp tSUBTRACT exp {mp_subtract(&$1, &$3, &$$);}
 | exp tMOD exp %prec MED {
     if (!mp_is_integer(&$1) || !mp_is_integer(&$3)) {
-	(_mp_equation_get_extra(yyscanner))->error = -PARSER_ERR_MODULUSOP;
+	set_error(yyscanner, -PARSER_ERR_MODULUSOP);
     } else {
       if (mp_modulus_divide(&$1, &$3, &$$)) {
-        (_mp_equation_get_extra(yyscanner))->error = -EINVAL;
+        set_error(yyscanner, -EINVAL);
       }			   
     }
 }
 | exp tAND exp {
     if (!mp_is_natural(&$1) || !mp_is_natural(&$3)) {
-	(_mp_equation_get_extra(yyscanner))->error = -PARSER_ERR_BITWISEOP;
+	set_error(yyscanner, -PARSER_ERR_BITWISEOP);
     }
     mp_and(&$1, &$3, &$$);
 }
 | exp tOR exp {
     if (!mp_is_natural(&$1) || !mp_is_natural(&$3)) {
-	(_mp_equation_get_extra(yyscanner))->error = -PARSER_ERR_BITWISEOP;
+	set_error(yyscanner, -PARSER_ERR_BITWISEOP);
     }
     mp_or(&$1, &$3, &$$);
 }
 | exp tXNOR exp {
     if (!mp_is_natural(&$1) || !mp_is_natural(&$3)) {
-	(_mp_equation_get_extra(yyscanner))->error = -PARSER_ERR_BITWISEOP;
+	set_error(yyscanner, -PARSER_ERR_BITWISEOP);
     }
     mp_xnor(&$1, &$3, _mp_equation_get_extra(yyscanner)->wordlen, &$$);
 }
 | exp tXOR exp {
     if (!mp_is_natural(&$1) || !mp_is_natural(&$3)) {
-	(_mp_equation_get_extra(yyscanner))->error = -PARSER_ERR_BITWISEOP;
+	set_error(yyscanner, -PARSER_ERR_BITWISEOP);
     }
     mp_xor(&$1, &$3, &$$);
 }
@@ -154,7 +171,6 @@ term:
   number {mp_set_from_mp(&$1, &$$);}
 | constant {mp_set_from_mp(&$1, &$$);}  
 | number constant {mp_multiply(&$1, &$2, &$$);}  
-| rcl {mp_set_from_mp(&$1, &$$);}
 | tSUBNUM tROOT term {mp_root(&$3, $1, &$$);}
 | tROOT term {mp_sqrt(&$2, &$$);}
 | tROOT3 term {mp_root(&$2, 3, &$$);}
@@ -167,9 +183,9 @@ term:
 | term '%' {mp_divide_integer(&$1, 100, &$$);}
 | tNOT term %prec LNEG {
     if (!mp_is_natural(&$2)) {
-	(_mp_equation_get_extra(yyscanner))->error = -PARSER_ERR_BITWISEOP;
+	set_error(yyscanner, -PARSER_ERR_BITWISEOP);
     } else if (!mp_is_overflow(&$2, _mp_equation_get_extra(yyscanner)->wordlen)) {
-	(_mp_equation_get_extra(yyscanner))->error = -PARSER_ERR_OVERFLOW;
+	set_error(yyscanner, -PARSER_ERR_OVERFLOW);
     }
     mp_not(&$2, _mp_equation_get_extra(yyscanner)->wordlen, &$$);
 }
@@ -178,7 +194,7 @@ term:
 | term '^' term {mp_xpowy(&$1, &$3, &$$);}
 | term func {mp_multiply(&$1, &$2, &$$);}
 | func {mp_set_from_mp(&$1, &$$);}
-| tREG {mp_set_from_mp(_mp_equation_get_extra(yyscanner)->get_variable($1), &$$);}
+| tREG {mp_set_from_mp(get_register(yyscanner, $1), &$$);}
 | '(' exp ')' {mp_set_from_mp(&$2, &$$);}
 ;
 
@@ -211,32 +227,25 @@ func:
 | tTRUNC term %prec HIGH {mp_mask(&$2, _mp_equation_get_extra(yyscanner)->wordlen, &$$);}
 | t1S term %prec HIGH  {
     if (!mp_is_natural(&$2)) {
-	(_mp_equation_get_extra(yyscanner))->error = -PARSER_ERR_BITWISEOP;
+	set_error(yyscanner, -PARSER_ERR_BITWISEOP);
     } else if (!mp_is_overflow(&$2, _mp_equation_get_extra(yyscanner)->wordlen)) {
-	(_mp_equation_get_extra(yyscanner))->error = -PARSER_ERR_OVERFLOW;
+	set_error(yyscanner, -PARSER_ERR_OVERFLOW);
     }
     mp_1s_complement(&$2, _mp_equation_get_extra(yyscanner)->wordlen, &$$);
 }
 | t2S term %prec HIGH {
     if (!mp_is_natural(&$2)) {
-	(_mp_equation_get_extra(yyscanner))->error = -PARSER_ERR_BITWISEOP;
+	set_error(yyscanner, -PARSER_ERR_BITWISEOP);
     } else if (!mp_is_overflow(&$2, _mp_equation_get_extra(yyscanner)->wordlen)) {
-	(_mp_equation_get_extra(yyscanner))->error = -PARSER_ERR_OVERFLOW;
+	set_error(yyscanner, -PARSER_ERR_OVERFLOW);
     }
     mp_2s_complement(&$2, _mp_equation_get_extra(yyscanner)->wordlen, &$$);
 }
 ;
 
-rcl:
-  tRCL '(' tNUMBER ')' {
-    int val = mp_cast_to_int(&$3);
-    mp_set_from_mp(_mp_equation_get_extra(yyscanner)->get_variable(val), &$$);
-  }
-  ;
-
 number:
   tNUMBER {mp_set_from_mp(&$1, &$$);}
-| tANS {mp_set_from_mp(&_mp_equation_get_extra(yyscanner)->ans, &$$);}
+| tANS {mp_set_from_mp(get_variable(yyscanner, "ans"), &$$);}
 ;
 
 constant:
diff --git a/src/mp-equation.c b/src/mp-equation.c
index d25c0ca..e5e252d 100644
--- a/src/mp-equation.c
+++ b/src/mp-equation.c
@@ -28,9 +28,14 @@
 extern int _mp_equation_parse(yyscan_t yyscanner);
 
 static const MPNumber *
-get_variable(int index)
+get_variable(MPEquationParserState *state, const char *name)
 {
-    return register_get_value(index);
+    if (name[0] == 'R' || name[0] == 'r')
+        return register_get_value(atoi(name+1));
+    else if (strcmp(name, "ans") == 0)
+        return display_get_answer(&v->display);
+    else
+        return NULL;
 }
 
 int 
@@ -49,7 +54,7 @@ mp_equation_parse(const char *expression, MPNumber *result)
     state.wordlen = v->wordlen;
     state.angle_units = v->ttype;
     state.get_variable = get_variable;
-    mp_set_from_mp(display_get_answer(&v->display), &state.ans);
+    state.error = -EINVAL;
     v->math_error = 0;
         
     _mp_equation_lex_init_extra(&state, &yyscanner);
@@ -64,13 +69,11 @@ mp_equation_parse(const char *expression, MPNumber *result)
     if (ret)
         return ret;
 
-    if (!state.have_result)
-        return -EINVAL;
-
     if (v->math_error)
         return v->math_error;
 
     mp_set_from_mp(&state.ret, result);
+
     return 0;
 }
 
diff --git a/src/mp-equation.h b/src/mp-equation.h
index e610c0b..37eac5b 100644
--- a/src/mp-equation.h
+++ b/src/mp-equation.h
@@ -30,8 +30,10 @@
 #define PARSER_ERR_MODULUSOP        10003
 #define PARSER_ERR_OVERFLOW         10004
 
+typedef struct MPEquationParserState MPEquationParserState;
+
 /* State for parser */
-typedef struct {
+struct MPEquationParserState {
     /* The numeric base (e.g 2, 8, 10, 16) */
     int base;
 
@@ -40,22 +42,16 @@ typedef struct {
     
     /* Units for angles (e.g. radians, degrees) */
     MPAngleUnit angle_units;
+    
+    /* Function to get variable values */
+    const MPNumber *(*get_variable)(MPEquationParserState *state, const char *name);
 
     /* Error returned from parser */
     int error;
-    
-    /* Value of Ans variable */
-    MPNumber ans;
-
-    /* TRUE if have a result */
-    int have_result;
-    
-    /* Function to get variable values */
-    const MPNumber *(*get_variable)(int value);
 
     /* Value returned from parser */
     MPNumber ret;
-} MPEquationParserState;
+};
 
 int mp_equation_parse(const char *expression, MPNumber *result);
 int _mp_equation_error(void *yylloc, MPEquationParserState *state, char *text);



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