add constant feature
authorLaurent Mazet <laurent.mazet@thalesgroup.com>
Fri, 20 Jan 2023 14:01:59 +0000 (15:01 +0100)
committerLaurent Mazet <laurent.mazet@thalesgroup.com>
Fri, 20 Jan 2023 14:01:59 +0000 (15:01 +0100)
calc.c
parser.c
parser.h

diff --git a/calc.c b/calc.c
index b247eceb440bdbaa5bcebe308236bf0830f741b5..456443bd4dfeee49173f6e921a4f9959fae6482a 100644 (file)
--- a/calc.c
+++ b/calc.c
@@ -237,7 +237,9 @@ int main (int argc, char *argv[])
 // test: echo -e '1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1\n1 + 1' | calc.exe -n | grep -q 2
 // test: echo -e '1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1\n1 + 1' | calc.exe | grep -q 64
 // test: echo -e '1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1\n1 + 1' | calc.exe | grep -q 2
-// test: echo -e '-cos (1)\n1 + 1\n1 - 1\n1 * 1\n1 / 1\n3%2\n2^2\nsqrt (2)\ncos (0)\nsin (0)\natan (0)\nlog (1)\nexp (1)\nhelp\nquit' | calc.exe -v 3 | grep -q bye
-// test: echo -e '1 +\n1 -\n1 * 1\n1 /\n3%\n2^\nsqrt ()\ncos ()\nsin ()\natan ()\nlog ()\nexp ()\n1 + (' | calc.exe |grep -c error |xargs test 11 =
+// test: echo -e '-cos (1)\n1 + 1\n1 - 1\n1 * 1\n1 / 1\n3%2\n2^2\nsqrt (2)\ncos (0)\nsin (0)\natan (0)\nlog (1)\nexp (1)\ne\n\pi\nhelp\nquit' | calc.exe -v 3 | grep -q bye
+// test: echo -e '1 +\n1 -\n1 * 1\n1 /\n3%\n2^\nsqrt ()\ncos ()\nsin ()\natan ()\nlog ()\nexp ()\n1 + (' | calc.exe | grep -c error | xargs test 11 =
+// test: echo -e 'sin (pi / 2)' | calc.exe | grep -q 1
+// test: echo -e 'e ^ 2' | calc.exe | grep -q '7\.38906'
 
 /* vim: set ts=4 sw=4 et: */
index 34d114d0060ae67370dfebdb963d441548141759..f3836c0e83550feeb75b1e5672054e3c46bf5546 100644 (file)
--- a/parser.c
+++ b/parser.c
@@ -79,11 +79,17 @@ keyword_t functions[NB_FUNCTIONS] = {
     { "pow",  Pow, 2, 3, 5},
     { "cos",  Cos, 1, 3, 5},
     { "sin",  Sin, 1, 3, 5},
-    { "atan", Atn, 1, 4, 5},
+    { "atan", Atan, 1, 4, 5},
     { "exp",  Exp, 1, 3, 5},
     { "log",  Log, 1, 3, 5},
-    { "quit", Qui, 0, 4, 5},
-    { "help", Hel, 0, 4, 5}
+    { "quit", Quit, 0, 4, 5},
+    { "help", Help, 0, 4, 5}
+};
+
+#define NB_CONSTANTS 2
+keyword_t constants[NB_CONSTANTS] = {
+    { "e",  E,  0, 1, 5},
+    { "pi", Pi, 0, 2, 5}
 };
 
 /* subparser function */
@@ -248,6 +254,33 @@ element_t *parser (char *str, char **next, int prio)
             continue;
         }
 
+        /* look for constant */
+
+        for (i = 0; i < NB_CONSTANTS; i++) {
+            keyword_t *constant = constants + i;
+            if (codecmp (constant->keyword, str) == 0) {
+                VERBOSE (DEBUG, fprintf (stdout, "start processing constant\n"));
+                if (root == NULL) {
+                    VERBOSE (INFO, fprintf (stdout, "Func: %d\n", constant->func));
+                    new = newelement (constant->func, constant->nbops, constant->prio);
+                    if (new == NULL) {
+                        return ERROR_OP;
+                    }
+                    root = new;
+                } else {
+                    delelement (root);
+                    return ERROR_OP;
+                }
+                str += constant->offset;
+                found = 1;
+                VERBOSE (DEBUG, fprintf (stdout, "stop processing constant\n"));
+                break;
+            }
+        }
+        if (found) {
+            continue;
+        }
+
         /* look for number */
 
         if (((*str >= '0') && (*str <= '9')) ||
@@ -332,11 +365,13 @@ void print_element (element_t *root, int level)
     case Sqr: func = "Square Root"; break;
     case Cos: func = "Cosine"; break;
     case Sin: func = "Sine"; break;
-    case Atn: func = "Arc Tangent"; break;
+    case Atan: func = "Arc Tangent"; break;
     case Log: func = "Logarithm"; break;
     case Exp: func = "Exponantial"; break;
-    case Qui: func = "Quit"; break;
-    case Hel: func = "Help"; break;
+    case Quit: func = "Quit"; break;
+    case Help: func = "Help"; break;
+    case Pi: func = "Pi"; break;
+    case E: func = "E"; break;
     }
 
     fprintf (stdout, "Function: %s\n", func);
@@ -371,7 +406,9 @@ void help (void)
     fprintf (stdout, "supported functions:\n");
     fprintf (stdout, " pow sqrt cos sin atan log exp\n\n");
     fprintf (stdout, "miscellaneous functions:\n");
-    fprintf (stdout, " quit help\n");
+    fprintf (stdout, " quit help\n\n");
+    fprintf (stdout, "supported constants:\n");
+    fprintf (stdout, " e pi\n");
 }
 
 /* evaluate element tree */
@@ -430,7 +467,7 @@ double evaluate_element (element_t *root, char mask)
     case Sqr:
     case Cos:
     case Sin:
-    case Atn:
+    case Atan:
     case Log:
     case Exp:
         if (root->ops[0]) {
@@ -440,8 +477,10 @@ double evaluate_element (element_t *root, char mask)
             return 0;
         }
         break;
-    case Qui:
-    case Hel:
+    case Quit:
+    case Help:
+    case Pi:
+    case E:
         break;
     }
 
@@ -457,11 +496,13 @@ double evaluate_element (element_t *root, char mask)
     case Sqr: return sqrt (op0);
     case Cos: return cos (op0);
     case Sin: return sin (op0);
-    case Atn: return atan (op0);
+    case Atan: return atan (op0);
     case Log: return log (op0);
     case Exp: return exp (op0);
-    case Qui: quit (); break;
-    case Hel: help (); break;
+    case Quit: quit (); break;
+    case Help: help (); break;
+    case Pi: return M_PI;
+    case E: return M_E;
     }
 
     return 0;
index 629b1b49a83272210f7faa1af41a7668506f54c9..619ebac68b87c2b8a9f447d60608ffa7218fae0b 100644 (file)
--- a/parser.h
+++ b/parser.h
@@ -8,9 +8,10 @@ typedef enum {
     Add, Sub,
     Mul, Div, Mod,
     Pow, Sqr,
-    Cos, Sin, Atn,
+    Cos, Sin, Atan,
     Log, Exp,
-    Qui, Hel
+    Quit, Help,
+    E, Pi
 } func_t;
 
 /* keyword type */