]> git.kaiwu.me - klib.git/commitdiff
don't return a parse error if see undef func
authorHeng Li <lh3@me.com>
Fri, 22 May 2015 13:42:03 +0000 (09:42 -0400)
committerHeng Li <lh3@me.com>
Fri, 22 May 2015 13:42:03 +0000 (09:42 -0400)
kexpr.c
kexpr.h

diff --git a/kexpr.c b/kexpr.c
index a2e3b6583938111a93cb16437e7f7cbd31959f62..e8f4be768d5f1c20ce9fc754ea16d55fe9f2ed51 100644 (file)
--- a/kexpr.c
+++ b/kexpr.c
@@ -291,13 +291,8 @@ static ke1_t *ke_parse_core(const char *_s, int *_n, int *err)
                                        else if (strcmp(u->name, "exp2") == 0) u->func = ke_func1_exp2;
                                        else if (strcmp(u->name, "log10") == 0) u->func = ke_func1_log10;
                                        else if (strcmp(u->name, "sqrt") == 0) u->func = ke_func1_sqrt;
-                                       else { *err |= KEE_UNFUNC; break; }
                                } else if (u->n_args == 2) {
                                        if (strcmp(u->name, "pow") == 0) u->func = ke_func1_pow; // for now, this to test functions with multiple arguments
-                                       else { *err |= KEE_UNFUNC; break; }
-                               } else {
-                                       *err |= KEE_UNFUNC;
-                                       break;
                                }
                        }
                        ++p;
@@ -378,10 +373,20 @@ kexpr_t *ke_parse(const char *_s, int *err)
        return ke;
 }
 
-void ke_eval(const kexpr_t *ke, int64_t *_i, double *_r, int *int_ret)
+int ke_eval(const kexpr_t *ke, int64_t *_i, double *_r, int *int_ret)
 {
        ke1_t *stack, *p, *q;
-       int i, top = 0;
+       int i, top = 0, err = 0;
+       *_i = 0, *_r = 0., *int_ret = 0;
+       for (i = 0; i < ke->n; ++i) {
+               ke1_t *e = &ke->e[i];
+               if ((e->ttype == KET_OP || e->ttype == KET_FUNC) && e->func == 0)
+                       break;
+       }
+       if (i < ke->n) {
+               err |= KEE_UNFUNC;
+               return err;
+       }
        stack = (ke1_t*)malloc(ke->n * sizeof(ke1_t));
        for (i = 0; i < ke->n; ++i) {
                ke1_t *e = &ke->e[i];
@@ -396,6 +401,7 @@ void ke_eval(const kexpr_t *ke, int64_t *_i, double *_r, int *int_ret)
        }
        free(stack);
        *_i = stack->i, *_r = stack->r, *int_ret = (stack->vtype == KEV_INT);
+       return err;
 }
 
 void ke_destroy(kexpr_t *ke)
@@ -488,7 +494,7 @@ int main(int argc, char *argv[])
        }
        ke = ke_parse(argv[optind], &err);
        if (err) {
-               fprintf(stderr, "ERROR: 0x%x\n", err);
+               fprintf(stderr, "Parse error: 0x%x\n", err);
                return 1;
        }
        if (!to_print) {
@@ -504,7 +510,11 @@ int main(int argc, char *argv[])
                                ke_set_real(ke, s, strtod(p+1, &p));
                        }
                }
-               ke_eval(ke, &vi, &vr, &int_ret);
+               err |= ke_eval(ke, &vi, &vr, &int_ret);
+               if (err) {
+                       fprintf(stderr, "Evaluation error: 0x%x\n", err);
+                       return 1;
+               }
                if (is_int) printf("%lld\n", (long long)vi);
                else printf("%g\n", vr);
        } else ke_print(ke);
diff --git a/kexpr.h b/kexpr.h
index 1e49b5c53b8fb67935162d90657bca5601d6382f..e549073a22f50dd508cd7ecea6cc225f5582912c 100644 (file)
--- a/kexpr.h
+++ b/kexpr.h
@@ -11,8 +11,10 @@ typedef struct kexpr_s kexpr_t;
 #define KEE_UNRP    0x04 // unmatched right parentheses
 #define KEE_UNOP    0x08 // unknown operators
 #define KEE_FUNC    0x10 // wrong function
-#define KEE_UNFUNC  0x20 // undefined function
-#define KEE_ARG     0x40
+#define KEE_ARG     0x20
+
+#define KEE_UNFUNC  0x40 // undefined function
+#define KEE_UNVAR   0x80 // unassigned variable
 
 #ifdef __cplusplus
 extern "C" {
@@ -24,7 +26,7 @@ void ke_print(const kexpr_t *ke);
 int ke_set_int(kexpr_t *ke, const char *var, int64_t x);
 int ke_set_real(kexpr_t *ke, const char *var, double x);
 int ke_set_str(kexpr_t *ke, const char *var, const char *x);
-void ke_eval(const kexpr_t *ke, int64_t *_i, double *_r, int *int_ret);
+int ke_eval(const kexpr_t *ke, int64_t *_i, double *_r, int *int_ret);
 
 #ifdef __cplusplus
 }