[gcalctool] Merged parser improvements from gcalctool-newui2 branch
- From: Robert Ancell <rancell src gnome org>
- To: svn-commits-list gnome org
- Subject: [gcalctool] Merged parser improvements from gcalctool-newui2 branch
- Date: Sun, 28 Jun 2009 06:10:07 +0000 (UTC)
commit 65657629b9d9a170f84b73fabd59368cc844a5eb
Author: Robert Ancell <robert ancell gmail com>
Date: Sun Jun 28 16:09:03 2009 +1000
Merged parser improvements from gcalctool-newui2 branch
src/mp-convert.c | 184 ++++++++++++++++++++--------------------------
src/mp-equation-lexer.l | 68 +++++++++++++----
src/mp-equation-parser.y | 56 +++++---------
src/mp-equation.c | 2 +-
src/unittest.c | 37 ++++++---
5 files changed, 178 insertions(+), 169 deletions(-)
---
diff --git a/src/mp-convert.c b/src/mp-convert.c
index c7d1a3f..4a3512e 100644
--- a/src/mp-convert.c
+++ b/src/mp-convert.c
@@ -479,29 +479,19 @@ mp_cast_to_double(const MPNumber *x)
* maximum number of digits specified.
*/
void
-mp_cast_to_string(const MPNumber *MPnumber, int base, int accuracy, int trim_zeroes, char *buffer, int buffer_length)
+mp_cast_to_string(const MPNumber *x, int base, int accuracy, int trim_zeroes, char *buffer, int buffer_length)
{
static char digits[] = "0123456789ABCDEF";
- char *optr, *start, *end, *stopper, *last_non_zero;
MPNumber number, integer_component, fractional_component, MPbase, temp;
- int i;
-
- optr = buffer;
- stopper = buffer + buffer_length - 1;
-
- /* Insert sign */
- if (mp_is_negative(MPnumber)) {
- if (optr + strlen("â??") >= stopper) {
- mperr(_("Number too big to represent"));
- *optr = '\0';
- return;
- }
- strcpy(optr, "â??");
- optr += strlen("â??");
- mp_abs(MPnumber, &number);
- } else {
- mp_set_from_mp(MPnumber, &number);
- }
+ int i, last_non_zero;
+ GString *string;
+
+ string = g_string_sized_new(buffer_length);
+
+ if (mp_is_negative(x))
+ mp_abs(x, &number);
+ else
+ mp_set_from_mp(x, &number);
/* Add rounding factor */
mp_set_from_integer(base, &MPbase);
@@ -515,7 +505,6 @@ mp_cast_to_string(const MPNumber *MPnumber, int base, int accuracy, int trim_zer
mp_fractional_component(&number, &fractional_component);
/* Write out the integer component least significant digit to most */
- start = optr;
mp_set_from_mp(&integer_component, &temp);
do {
MPNumber t, t2, t3;
@@ -527,29 +516,13 @@ mp_cast_to_string(const MPNumber *MPnumber, int base, int accuracy, int trim_zer
mp_subtract(&temp, &t2, &t3);
mp_integer_component(&t3, &t3);
- if (optr == stopper) {
- mperr(_("Number too big to represent"));
- *optr = '\0';
- return;
- }
- *optr++ = digits[mp_cast_to_int(&t3)];
+ g_string_prepend_c(string, digits[mp_cast_to_int(&t3)]);
mp_set_from_mp(&t, &temp);
} while (!mp_is_zero(&temp));
-
- /* Reverse digits */
- end = optr - 1;
- while(start < end) {
- char t;
- t = *start;
- *start = *end;
- *end = t;
- start++;
- end--;
- }
-
- last_non_zero = optr;
- *optr++ = '.';
+
+ last_non_zero = string->len;
+ g_string_append_c(string, '.');
/* Write out the fractional component */
mp_set_from_mp(&fractional_component, &temp);
@@ -561,29 +534,24 @@ mp_cast_to_string(const MPNumber *MPnumber, int base, int accuracy, int trim_zer
mp_integer_component(&temp, &digit);
d = mp_cast_to_int(&digit);
- if (optr == stopper) {
- mperr(_("Number too big to represent"));
- *optr = '\0';
- return;
- }
- *optr++ = digits[d];
+ g_string_append_c(string, digits[d]);
if(d != 0)
- last_non_zero = optr;
+ last_non_zero = string->len;
mp_subtract(&temp, &digit, &temp);
}
/* Strip trailing zeroes */
if (trim_zeroes || accuracy == 0)
- optr = last_non_zero;
-
- *optr = '\0';
+ g_string_truncate(string, last_non_zero);
/* Remove negative sign if the number was rounded down to zero */
- if (strcmp(buffer, "â??0") == 0) {
- buffer[0] = '0';
- buffer[1] = '\0';
- }
+ if (mp_is_negative(x) && strcmp(string->str, "0") != 0)
+ g_string_prepend(string, "â??");
+
+ // FIXME: Check for truncation
+ strncpy(buffer, string->str, buffer_length);
+ g_string_free(string, TRUE);
}
@@ -606,81 +574,93 @@ char_val(char chr, int base)
}
-/* Convert string into an MP number, in the given base
- */
+/* Convert string into an MP number */
void
-mp_set_from_string(const char *str, int base, MPNumber *MPval)
+mp_set_from_string(const char *str, int base, MPNumber *z)
{
- const char *optr;
- int inum;
- int negate = 0;
-
- optr = str;
-
- /* Remove leading whitespace */
- while (isspace(*optr)) {
- optr++;
- }
+ int i, negate = 0;
+ const char *c, *end;
+ 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};
+
+ end = str;
+ while (*end != '\0')
+ end++;
- /* Check if this is a negative number. */
- if (*optr == '-') {
+ /* Check if this is a negative number */
+ c = str;
+ if (*c == '-') {
negate = 1;
- optr++;
- } else if (strncmp(optr, "â??", strlen("â??")) == 0) {
+ c++;
+ } else if (strncmp(c, "â??", strlen("â??")) == 0) {
negate = 1;
- optr += strlen("â??");
+ c += strlen("â??");
}
/* Convert integer part */
- mp_set_from_integer(0, MPval);
- while ((inum = char_val(*optr, base)) >= 0) {
- mp_multiply_integer(MPval, base, MPval);
- mp_add_integer(MPval, inum, MPval);
- optr++;
+ mp_set_from_integer(0, z);
+ while ((i = char_val(*c, base)) >= 0) {
+ 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 (*optr == '.') {
+ if (*c == '.') {
MPNumber numerator, denominator;
- optr++;
+ c++;
mp_set_from_integer(0, &numerator);
mp_set_from_integer(1, &denominator);
- while ((inum = char_val(*optr, base)) >= 0) {
+ while ((i = char_val(*c, base)) >= 0) {
mp_multiply_integer(&denominator, base, &denominator);
mp_multiply_integer(&numerator, base, &numerator);
- mp_add_integer(&numerator, inum, &numerator);
- optr++;
+ mp_add_integer(&numerator, i, &numerator);
+ c++;
}
mp_divide(&numerator, &denominator, &numerator);
- mp_add(MPval, &numerator, MPval);
+ mp_add(z, &numerator, z);
}
/* Convert exponential part */
- if (*optr == 'e' || *optr == 'E') {
+ if (*c == 'e' || *c == 'E') {
int negate = 0;
MPNumber MPbase, MPexponent, temp;
- optr++;
+ c++;
/* Get sign */
- if (*optr == '-') {
+ if (*c == '-') {
negate = 1;
- optr++;
- } else if (strncmp(optr, "â??", strlen("â??")) == 0) {
+ c++;
+ } else if (strncmp(c, "â??", strlen("â??")) == 0) {
negate = 1;
- optr += strlen("â??");
- } else if (*optr == '+') {
- optr++;
+ c += strlen("â??");
+ } else if (*c == '+') {
+ c++;
}
/* Get magnitude */
mp_set_from_integer(0, &MPexponent);
- while ((inum = char_val(*optr, base)) >= 0) {
+ while ((i = char_val(*c, base)) >= 0) {
mp_multiply_integer(&MPexponent, base, &MPexponent);
- mp_add_integer(&MPexponent, inum, &MPexponent);
- optr++;
+ mp_add_integer(&MPexponent, i, &MPexponent);
+ c++;
}
if (negate) {
mp_invert_sign(&MPexponent, &MPexponent);
@@ -688,19 +668,13 @@ mp_set_from_string(const char *str, int base, MPNumber *MPval)
mp_set_from_integer(base, &MPbase);
mp_pwr(&MPbase, &MPexponent, &temp);
- mp_multiply(MPval, &temp, MPval);
- }
-
- /* Strip trailing whitespace */
- while (isspace(*optr)) {
- optr++;
+ mp_multiply(z, &temp, z);
}
- if (*optr != '\0') {
+ 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 3c1a971..d6e35be 100644
--- a/src/mp-equation-lexer.l
+++ b/src/mp-equation-lexer.l
@@ -10,6 +10,7 @@
/* $Header: /cvs/gnome/gcalctool/gcalctool/ce_tokeniser.l,v 1.16 2006/12/15 15:27:37 richb Exp $
*
* Copyright (C) 2004-2008 Sami Pietila
+ * Copyright (C) 2008-2009 Robert Ancell
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -35,19 +36,56 @@
#include "calctool.h"
#include "mp-equation.h"
#include "mp-equation-parser.h"
+
+static int super_atoi(const char *data)
+{
+ int i, value = 0;
+ const char *digits[11] = {"�", "¹", "²", "³", "�", "�", "�", "�", "�", "�", NULL};
+
+ while(*data != '\0') {
+ for(i = 0; digits[i] != NULL && strncmp(data, digits[i], strlen(digits[i])) != 0; i++);
+ if(digits[i] == NULL)
+ return 0;
+ value = value * 10 + i;
+ data += strlen(digits[i]);
+ }
+
+ return value;
+}
+
+static int sub_atoi(const char *data)
+{
+ int i, value = 0;
+ const char *digits[11] = {"â??", "â??", "â??", "â??", "â??", "â??", "â??", "â??", "â??", "â??", NULL};
+
+ while(*data != '\0') {
+ for(i = 0; digits[i] != NULL && strncmp(data, digits[i], strlen(digits[i])) != 0; i++);
+ if(digits[i] == NULL)
+ return 0;
+ data += strlen(digits[i]);
+ value = value * 10 + i;
+ }
+
+ return value;
+}
%}
-DECIMAL "."|","
-SIGN "+"|"-"|"â??"
-BIN [0-1]
-OCT [0-7]
-DEC [0-9]
-HEX [0-9]|[A-F]|[a-f]
-EXP "e"|"e+"|"e-"|"E"|"E+"|"E-"
-HEX_NUM {HEX}+|{HEX}*{DECIMAL}{HEX}*
-DEC_NUM{DEC}+|{DEC}*{DECIMAL}{DEC}*
-OCT_NUM{OCT}+|{OCT}*{DECIMAL}{OCT}*
-BIN_NUM{BIN}+|{BIN}*{DECIMAL}{BIN}*
+DECIMAL "."|","
+BIN [0-1]
+OCT [0-7]
+DEC [0-9]
+HEX [0-9]|[A-F]|[a-f]
+EXP "e"|"e+"|"e-"|"E"|"E+"|"E-"
+SUPER_DIGITS "�"|"¹"|"²"|"³"|"�"|"�"|"�"|"�"|"�"|"�"
+SUB_DIGITS "â??"|"â??"|"â??"|"â??"|"â??"|"â??"|"â??"|"â??"|"â??"|"â??"
+FRACTION "½"|"â??"|"â??"|"¼"|"¾"|"â??"|"â??"|"â??"|"â??"|"â??"|"â??"|"â??"|"â??"|"â??"|"â??"
+
+HEX_NUM {HEX}+|{HEX}*{DECIMAL}{HEX}+
+DEC_NUM {DEC}+|{DEC}*{DECIMAL}{DEC}+|{FRACTION}|{DEC}{FRACTION}
+OCT_NUM {OCT}+|{OCT}*{DECIMAL}{OCT}+
+BIN_NUM {BIN}+|{BIN}*{DECIMAL}{BIN}+
+SUP_NUM {SUPER_DIGITS}+
+SUB_NUM {SUB_DIGITS}+
%%
@@ -77,8 +115,7 @@ BIN_NUM{BIN}+|{BIN}*{DECIMAL}{BIN}*
"frac"|"Frac"|"FRAC" {return tFRAC;}
"int"|"Int"|"INT" {return tINT;}
"ln"|"Ln"|"LN" {return tLN;}
-"log"|"Log"|"LOG" {return tLOG10;}
-"logâ??"|"Logâ??"|"log_2"|"Log_2"|"LOG_2" {return tLOG2;}
+"log"|"Log"|"LOG" {return tLOG;}
"mod"|"Mod"|"MOD" {return tMOD;}
"¬"|"~" {return tNOT;}
"â?¨"|"or"|"Or"|"OR" {return tOR;}
@@ -88,8 +125,6 @@ BIN_NUM{BIN}+|{BIN}*{DECIMAL}{BIN}*
"â??"|"sqrt"|"Sqrt"|"SQRT" {return tROOT;}
"â??"|"cbrt"|"Cbrt"|"CBRT" {return tROOT3;}
"â??" {return tROOT4;}
-"²" {return tSQUARED;}
-"³" {return tCUBED;}
"sto"|"Sto"|"STO" {return tSTO;}
"trunc"|"Trunc"|"TRUNC" {return tTRUNC;}
"ones" {return t1S;}
@@ -102,6 +137,9 @@ yylval->integer = atoi(yytext+1);
return tREG;
}
+{SUP_NUM} { yylval->integer = super_atoi(yytext); return tSUPNUM; }
+{SUB_NUM} { yylval->integer = sub_atoi(yytext); return tSUBNUM; }
+
{DEC_NUM}{EXP}{DEC_NUM} {
if (_mp_equation_get_extra(yyscanner)->base == 16) REJECT;
if (strlen(yytext) > MAX_DIGITS) yyextra->error = -PARSER_ERR_TOO_LONG_NUMBER;
diff --git a/src/mp-equation-parser.y b/src/mp-equation-parser.y
index a8c6976..e14b8c7 100644
--- a/src/mp-equation-parser.y
+++ b/src/mp-equation-parser.y
@@ -3,6 +3,7 @@
/* $Header: /cvs/gnome/gcalctool/gcalctool/ce_parser.y,v 1.16 2006/12/08 15:54:43 richb Exp $
*
* Copyright (C) 2004-2008 Sami Pietila
+ * Copyright (C) 2008-2009 Robert Ancell
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -65,8 +66,7 @@
%token tFRAC
%token tINT
%token tLN
-%token tLOG10
-%token tLOG2
+%token tLOG
%token tMOD
%token t1S
%token t2S
@@ -80,8 +80,6 @@
%token tROOT
%token tROOT3
%token tROOT4
-%token tSQUARED
-%token tCUBED
%token tSQRT
%token tSTO
%token tTAN
@@ -91,11 +89,11 @@
%token tXOR
%token <int_t> tNUMBER
-%token <integer> tREG
+%token <integer> tREG tSUBNUM tSUPNUM
%token NEG
-%type <int_t> exp rcl value term reg func number parenthesis
+%type <int_t> exp rcl value term func number
%start statement
%left tADD tSUBTRACT tMULTIPLY tDIVIDE
@@ -148,17 +146,13 @@ value:
exp:
term {mp_set_from_mp(&$1, &$$);}
-
| exp tADD term '%' {mp_add_integer(&$3, 100, &$3); mp_divide_integer(&$3, 100, &$3); mp_multiply(&$1, &$3, &$$);}
| exp tSUBTRACT term '%' {mp_add_integer(&$3, -100, &$3); mp_divide_integer(&$3, -100, &$3); mp_multiply(&$1, &$3, &$$);}
-
| exp tROOT term {MPNumber t; mp_sqrt(&$3, &t); mp_multiply(&$1, &t, &$$);}
| exp tROOT3 term {MPNumber t; mp_root(&$3, 3, &t); mp_multiply(&$1, &t, &$$);}
| exp tROOT4 term {MPNumber t; mp_root(&$3, 4, &t); mp_multiply(&$1, &t, &$$);}
-
| exp tADD exp {mp_add(&$1, &$3, &$$);}
| 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;
@@ -168,7 +162,6 @@ exp:
}
}
}
-
| exp tAND exp {
if (!mp_is_natural(&$1) || !mp_is_natural(&$3)) {
(_mp_equation_get_extra(yyscanner))->error = -PARSER_ERR_BITWISEOP;
@@ -200,16 +193,16 @@ term:
number {mp_set_from_mp(&$1, &$$);}
| tPI {mp_get_pi(&$$);}
| rcl {mp_set_from_mp(&$1, &$$);}
+| tSUBNUM tROOT term {mp_root(&$3, $1, &$$);}
| tROOT term {mp_sqrt(&$2, &$$);}
| tROOT3 term {mp_root(&$2, 3, &$$);}
| tROOT4 term {mp_root(&$2, 4, &$$);}
| term tDIVIDE term {mp_divide(&$1, &$3, &$$);}
| term tMULTIPLY term {mp_multiply(&$1, &$3, &$$);}
-| tABS exp tABS {mp_abs(&$2, &$$);}
+| tABS exp tABS {mp_abs(&$2, &$$);}
| 'e' '^' term {mp_epowy(&$3, &$$);}
| term '!' {mp_factorial(&$1, &$$);}
-| term tSQUARED {mp_pwr_integer(&$1, 2, &$$);}
-| term tCUBED {mp_pwr_integer(&$1, 3, &$$);}
+| term tSUPNUM {mp_pwr_integer(&$1, $2, &$$);}
| term '%' {mp_divide_integer(&$1, 100, &$$);}
| tNOT term %prec LNEG {
if (!mp_is_natural(&$2)) {
@@ -219,49 +212,42 @@ term:
}
mp_not(&$2, _mp_equation_get_extra(yyscanner)->wordlen, &$$);
}
-| tSUBTRACT term %prec NEG {mp_invert_sign(&$2, &$$);}
-| tADD term %prec POS {mp_set_from_mp(&$2, &$$);}
+| tSUBTRACT term {mp_invert_sign(&$2, &$$);}
+| tADD term {mp_set_from_mp(&$2, &$$);}
| term '^' term {mp_xpowy(&$1, &$3, &$$);}
-
| term func {mp_multiply(&$1, &$2, &$$);}
| func {mp_set_from_mp(&$1, &$$);}
-| reg {mp_set_from_mp(&$1, &$$);}
-
-| parenthesis {mp_set_from_mp(&$1, &$$);}
+| tREG {register_get($1, &$$);}
+| '(' exp ')' {mp_set_from_mp(&$2, &$$);}
;
-parenthesis:
- '(' exp ')' {mp_set_from_mp(&$2, &$$);}
- ;
-
-reg:
- tREG {register_get($1, &$$);}
- ;
-
func:
- tLOG10 term %prec HIGH {mp_logarithm(10, &$2, &$$);}
-| tLOG2 term %prec HIGH {mp_logarithm(2, &$2, &$$);}
-| tSQRT term %prec HIGH {mp_sqrt(&$2, &$$);}
+ tLOG term %prec HIGH {mp_logarithm(10, &$2, &$$);}
| tLN term %prec HIGH {mp_ln(&$2, &$$);}
+| tLOG tSUBNUM term %prec HIGH {mp_logarithm($2, &$3, &$$);}
| tRAND %prec HIGH {mp_set_from_random(&$$);}
| tABS_FUNC term %prec HIGH {mp_abs(&$2, &$$);}
| tFRAC term %prec HIGH {mp_fractional_component(&$2, &$$);}
| tINT term %prec HIGH {mp_integer_component(&$2, &$$);}
| tCHS term %prec HIGH {mp_invert_sign(&$2, &$$);}
-
| tSIN term %prec HIGH {mp_sin(&$2, _mp_equation_get_extra(yyscanner)->angle_units, &$$);}
| tCOS term %prec HIGH {mp_cos(&$2, _mp_equation_get_extra(yyscanner)->angle_units, &$$);}
| tTAN term %prec HIGH {mp_tan(&$2, _mp_equation_get_extra(yyscanner)->angle_units, &$$);}
+| tSIN tSUPNUM term %prec HIGH {MPNumber t; mp_sin(&$3, _mp_equation_get_extra(yyscanner)->angle_units, &t); mp_pwr_integer(&t, $2, &$$);}
+| tCOS tSUPNUM term %prec HIGH {MPNumber t; mp_cos(&$3, _mp_equation_get_extra(yyscanner)->angle_units, &t); mp_pwr_integer(&t, $2, &$$);}
+| tTAN tSUPNUM term %prec HIGH {MPNumber t; mp_tan(&$3, _mp_equation_get_extra(yyscanner)->angle_units, &t); mp_pwr_integer(&t, $2, &$$);}
| tASIN term %prec HIGH {mp_asin(&$2, _mp_equation_get_extra(yyscanner)->angle_units, &$$);}
| tACOS term %prec HIGH {mp_acos(&$2, _mp_equation_get_extra(yyscanner)->angle_units, &$$);}
| tATAN term %prec HIGH {mp_atan(&$2, _mp_equation_get_extra(yyscanner)->angle_units, &$$);}
| tSINH term %prec HIGH {mp_sinh(&$2, &$$);}
| tCOSH term %prec HIGH {mp_cosh(&$2, &$$);}
| tTANH term %prec HIGH {mp_tanh(&$2, &$$);}
+| tSINH tSUPNUM term %prec HIGH {MPNumber t; mp_sinh(&$3, &t); mp_pwr_integer(&t, $2, &$$);}
+| tCOSH tSUPNUM term %prec HIGH {MPNumber t; mp_cosh(&$3, &t); mp_pwr_integer(&t, $2, &$$);}
+| tTANH tSUPNUM term %prec HIGH {MPNumber t; mp_tanh(&$3, &t); mp_pwr_integer(&t, $2, &$$);}
| tASINH term %prec HIGH {mp_asinh(&$2, &$$);}
| tACOSH term %prec HIGH {mp_acosh(&$2, &$$);}
| tATANH term %prec HIGH {mp_atanh(&$2, &$$);}
-
| tTRUNC term %prec HIGH {mp_mask(&$2, _mp_equation_get_extra(yyscanner)->wordlen, &$$);}
| t1S term %prec HIGH {
if (!mp_is_natural(&$2)) {
@@ -290,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/mp-equation.c b/src/mp-equation.c
index e5b3e9b..b93427c 100644
--- a/src/mp-equation.c
+++ b/src/mp-equation.c
@@ -43,7 +43,7 @@ mp_equation_parse_(const char *expression, MPNumber *result, int need_result)
state.angle_units = v->ttype;
mp_set_from_mp(display_get_answer(&v->display), &state.ans);
v->math_error = 0;
-
+
_mp_equation_lex_init_extra(&state, &yyscanner);
buffer = _mp_equation__scan_string(expression, yyscanner);
diff --git a/src/unittest.c b/src/unittest.c
index 58278e0..5271ed2 100644
--- a/src/unittest.c
+++ b/src/unittest.c
@@ -97,7 +97,7 @@ test_parser()
v->ttype = MP_DEGREES;
v->wordlen = 32;
v->accuracy = 9;
-
+
test("0", "0", 0);
test("1", "1", 0);
test("+1", "1", 0);
@@ -105,12 +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("1e3", "1000", 0);
- test("1e+3", "1000", 0);
- test("1e-3", "0.001", 0);
+ test("e^1", "2.718281828", 0);
test("0+0", "0", 0);
test("1+1", "2", 0);
@@ -130,6 +130,12 @@ test_parser()
test("â??2Ã?3", "â??6", 0);
test("2Ã?â??3", "â??6", 0);
test("â??2Ã?â??3", "6", 0);
+
+ test("2e3", "2000", 0);
+ test("2e+3", "2000", 0);
+ test("2e-3", "0.002", 0);
+ test("2Ã?10^3", "2000", 0);
+ test("2Ã?10^â??3", "0.002", 0);
test("6/3", "2", 0);
test("6÷3", "2", 0);
@@ -168,6 +174,7 @@ test_parser()
test("2²", "4", 0);
test("2³", "8", 0);
+ test("2¹�", "1024", 0);
test("2^0", "1", 0);
test("2^1", "2", 0);
test("2^2", "4", 0);
@@ -183,6 +190,8 @@ test_parser()
test("â??4â??2", "0", 0);
test("â??8", "2", 0);
test("â??16", "2", 0);
+ test("â??â??8", "2", 0);
+ test("â??â??â??1024", "2", 0);
test("â??(2+2)", "2", 0);
test("2â??4", "4", 0);
test("2Ã?â??4", "4", 0);
@@ -231,6 +240,7 @@ test_parser()
test("sin 90", "1", 0);
test("sin 180", "0", 0);
test("2 sin 90", "2", 0);
+ test("sin²45", "0.5", 0);
test("cos 0", "1", 0);
test("cos 45 â?? 1÷â??2", "0", 0);
@@ -238,10 +248,13 @@ test_parser()
test("cos 90", "0", 0);
test("cos 180", "â??1", 0);
test("2 cos 0", "2", 0);
+ test("cos²45", "0.5", 0);
test("tan 0", "0", 0);
test("tan 10 â?? sin 10÷cos 10", "0", 0);
test("tan 90", "", -20001);
+ test("tan 10", "0.176326981", 0);
+ test("tan²10", "0.031091204", 0);
test("cos�¹ 0", "90", 0);
test("cos�¹ 1", "0", 0);
@@ -254,15 +267,15 @@ test_parser()
test("sinâ?»Â¹ (1÷â??2)", "45", 0);
test("cosh 0", "1", 0);
- test("cosh 10 â?? (e^(10)+e^(â??10))÷2", "0", 0);
+ test("cosh 10 â?? (e^10 + e^â??10)÷2", "0", 0);
test("sinh 0", "0", 0);
- test("sinh 10 â?? (e^(10)â??e^(â??10))÷2", "0", 0);
+ test("sinh 10 â?? (e^10 â?? e^â??10)÷2", "0", 0);
test("sinh â??10 + sinh 10", "0", 0);
- test("(cosh â??5)² â?? (sinh â??5)²", "1", 0);
+ test("cosh² â??5 â?? sinh² â??5", "1", 0);
test("tanh 0", "0", 0);
- test("tanh 10 â?? sinh(10)÷cosh(10)", "0", 0);
+ test("tanh 10 â?? sinh 10 ÷ cosh 10", "0", 0);
test("atanh 0", "0", 0);
test("atanh (1÷10) â?? 0.5 ln(11÷9)", "0", 0);
@@ -277,10 +290,10 @@ test_parser()
test("sin 100", "1", 0);
v->base = HEX;
- test("3 And 5", "1", 0);
- test("3 Or 5", "7", 0);
- test("3 Xor 5", "6", 0);
- test("3 Xnor 5", "FFFFFFF9", 0);
+ test("3 and 5", "1", 0);
+ test("3 or 5", "7", 0);
+ test("3 xor 5", "6", 0);
+ test("3 xnor 5", "FFFFFFF9", 0);
test("~7A", "FFFFFF85", 0);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]