From 471da7c96240e4a061ed952d82ecdb85dbaceb6e Mon Sep 17 00:00:00 2001 From: Laurent Mazet Date: Fri, 20 Jan 2023 15:01:59 +0100 Subject: [PATCH] add constant feature --- calc.c | 6 +++-- parser.c | 67 +++++++++++++++++++++++++++++++++++++++++++++----------- parser.h | 5 +++-- 3 files changed, 61 insertions(+), 17 deletions(-) diff --git a/calc.c b/calc.c index b247ece..456443b 100644 --- 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: */ diff --git a/parser.c b/parser.c index 34d114d..f3836c0 100644 --- 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; diff --git a/parser.h b/parser.h index 629b1b4..619ebac 100644 --- 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 */ -- 2.30.2