preliminary version
authorLaurent Mazet <mazet@softndesign.org>
Sun, 25 Dec 2022 10:38:40 +0000 (11:38 +0100)
committerLaurent Mazet <mazet@softndesign.org>
Sun, 25 Dec 2022 10:38:40 +0000 (11:38 +0100)
calc.c
makefile
parser.c
parser.h

diff --git a/calc.c b/calc.c
index 5c57927af9348aa09084704c4bc783147b014c4f..1c4099f13d7df7b11da1a4fc99f440df967c9921 100644 (file)
--- a/calc.c
+++ b/calc.c
@@ -98,7 +98,7 @@ int main (int argc, char *argv[])
             if (buffer[i] == '\n') {
                 buffer[i] = 0;
                 VERBOSE (DEBUG, PRINTOUT ("line(%d): %s\n", j, buffer + j));
-                element_t *element = parser (buffer);
+                element_t *element = parser (buffer, NULL);
                 if (element == (void *)(-1)) {
                     VERBOSE (WARNING, PRINTOUT ("error while parsing: %s\n", buffer));
                } else {
index 772aca4a9a1888fff18b1e8b20152f6ded4e6d99..34218b4f15a8fe793b568ec3bfcc8a647cd98372 100644 (file)
--- a/makefile
+++ b/makefile
@@ -22,7 +22,7 @@ ALLEXE += skel
 
 SHELL = bash
 
-MAKE = mingw32-make
+#MAKE = mingw32-make
 MAKEFLAGS += -s
 
 # Functions
index 677f9a4e0a3ea1deee747888ebc74dfffc60db4e..2190178ecba23fc5898a4cac2a2dc22db343f982 100644 (file)
--- a/parser.c
+++ b/parser.c
@@ -64,9 +64,10 @@ keyword_t functions[NB_FUNCTIONS] = {
 
 /* parser function */
 
-element_t *parser (char *str) {
+element_t *parser (char *str, char **next)
+{
     element_t *root = NULL;
-    int i;
+    int i, j;
 
     /* main loop */
     while (*str != '\0') {
@@ -81,6 +82,57 @@ element_t *parser (char *str) {
             continue;
         }
 
+        /* skip commas */
+
+        if (*str == ',') {
+            if (root == NULL) {
+                return ERROR_OP;
+            } else if (root->func != Set) {
+                new = newelement (Set, MAX_OPERANDS);
+                new->ops[0] = root;
+                root = new;
+            }
+            str++;
+            continue;
+        }
+
+        /* check for parent */
+
+        if (*str == ')') {
+            if (next != NULL) {
+                *next = str + 1;
+            }
+            return root;
+        }
+        if (*str == '(') {
+            new = parser (str + 1, &str);
+            if (new == (void *)(-1)) {
+                return new;
+            }
+            if (root) {
+                for (i = 0, j = 0; i < root->nbops; i++) {
+                    if (root->ops[i] == NULL) {
+                        if (new->func == Set) {
+                            root->ops[i] = new->ops[j++];
+                            if (new->ops[j] == NULL) {
+                                found = 1;
+                                break;
+                            }
+                        } else {
+                            root->ops[i] = new;
+                            found = 1;
+                            break;
+                        }
+                    }
+                }
+                if (!found) {
+                    return ERROR_OP;
+                }
+            } else {
+                return root;
+            }
+        }
+
         /* look for operators */
 
         for (i = 0; i < NB_OPERATORS; i++) {
@@ -90,12 +142,12 @@ element_t *parser (char *str) {
                     VERBOSE (DEBUG, PRINTOUT ("Oper: %d\n", operator->func));
                     new = newelement (operator->func, operator->nbops);
                     if (new == NULL) {
-                        return (element_t *)-1;
+                        return ERROR_OP;
                     }
                     new->ops[0] = root;
                     root = new;
                  } else {
-                    return (element_t *)(-1);
+                    return ERROR_OP;
                 }
                 str += operator->offset;
                 found = 1;
@@ -116,11 +168,11 @@ element_t *parser (char *str) {
                     VERBOSE (DEBUG, PRINTOUT ("Func: %d\n", function->func));
                     new = newelement (function->func, function->nbops);
                     if (new == NULL) {
-                        return (element_t *)-1;
+                        return ERROR_OP;
                     }
                     root = new;
                  } else {
-                    return (element_t *)(-1);
+                    return ERROR_OP;
                 }
                 str += function->offset;
                 found = 1;
@@ -132,19 +184,19 @@ element_t *parser (char *str) {
             continue;
         }
 
-       /* last attend to detect addition and substraction */
+        /* last attend to detect addition and substraction */
 
-       if (((*str == '-') || (*str == '+')) &&
-           ((*(str + 1) >= '0') && (*(str + 1) <= '9')) &&
-           ((root) && (root->func == Val))) {
+        if (((*str == '-') || (*str == '+')) &&
+            ((*(str + 1) >= '0') && (*(str + 1) <= '9')) &&
+            ((root) && (root->func == Val))) {
             VERBOSE (DEBUG, PRINTOUT ("Oper: %d\n", Add));
             new = newelement (Add, 2);
             if (new == NULL) {
-                return (element_t *)-1;
+                return ERROR_OP;
             }
             new->ops[0] = root;
             root = new;
-       }
+        }
 
         /* look for number */
 
@@ -157,11 +209,19 @@ element_t *parser (char *str) {
                 new = newelement (Val, 1);
                 new->value = value;
                 if (new == NULL) {
-                    return (element_t *)-1;
+                    return ERROR_OP;
                 }
                 if (root == NULL) {
                     root = new;
                 } else {
+                    if (root->func == Val) {
+                        element_t *set = newelement (Set, MAX_OPERANDS);
+                        if (set == NULL) {
+                            return ERROR_OP;
+                        }
+                        set->ops[0] = root;
+                        root = set;
+                    }
                     for (i = 0; i < root->nbops; i++) {
                         if (root->ops[i] == NULL) {
                             root->ops[i] = new;
@@ -170,7 +230,7 @@ element_t *parser (char *str) {
                         }
                     }
                     if (!found) {
-                        return (element_t *)-1;
+                        return ERROR_OP;
                     }
                 }
                 str = pt;
@@ -181,7 +241,7 @@ element_t *parser (char *str) {
         /* error */
 
         if (!found) {
-            return (element_t *)-1;
+            return ERROR_OP;
         }
 
     }
@@ -205,6 +265,7 @@ void print_element (element_t *root, int level)
 
     switch (root->func) {
     case Val: func = "Value"; break;
+    case Set: func = "Set"; break;
     case Add: func = "Addition"; break;
     case Sub: func = "Subtraction"; break;
     case Mul: func = "Multiplication"; break;
index 46500073105fd206140e36f2c53979a0309f69d5..7d486a330c764bc3aecd2bbe32e01eb79a85b5bf 100644 (file)
--- a/parser.h
+++ b/parser.h
@@ -4,7 +4,7 @@
 /* function type */
 
 typedef enum {
-    Val = 0,
+    Val = 0, Set,
     Add, Sub,
     Mul, Div, Pow,
     Sqr,
@@ -23,7 +23,7 @@ typedef struct _keyword_t {
 
 /* calculus element type */
 
-#define MAX_OPERANDS 2
+#define MAX_OPERANDS 10
 typedef struct _element_t {
     func_t func;
     int nbops;
@@ -31,9 +31,11 @@ typedef struct _element_t {
     float value;
 } element_t;
 
+#define ERROR_OP ((element_t *)(-1))
+
 /* parser function */
 
-element_t *parser (char *str);
+element_t *parser (char *str, char **next);
 
 void print_element (element_t *root, int level);