8 Expr = Or | Or '?' Expr ':' Expr
10 And = Eq | And '&&' Eq
11 Eq = Rel | Eq '==' Rel | Eq '!=' Rel
12 Rel = Add | Rel '<=' Add | Rel '>=' Add | Rel '<' Add | Rel '>' Add
13 Add = Mul | Add '+' Mul | Add '-' Mul
14 Mul = Term | Mul '*' Term | Mul '/' Term | Mul '%' Term
15 Term = '(' Expr ')' | '!' Term | decimal | 'n'
19 recursive descent expression evaluator with stack depth limit.
20 eval* functions return the value of the subexpression and set
21 the current string pointer to the next non-space char.
30 static const char *skipspace(const char *s)
32 while (isspace(*s)) s++;
36 static unsigned long fail(struct st *st)
42 static unsigned long evalexpr(struct st *st, int d);
44 static unsigned long evalterm(struct st *st, int d)
48 if (--d < 0) return fail(st);
49 st->s = skipspace(st->s);
50 if (isdigit(*st->s)) {
51 a = strtoul(st->s, &e, 10);
52 if (e == st->s || a == -1) return fail(st);
57 st->s = skipspace(st->s + 1);
63 if (*st->s != ')') return fail(st);
64 st->s = skipspace(st->s + 1);
69 return !evalterm(st, d);
74 static unsigned long evalmul(struct st *st, int d)
76 unsigned long b, a = evalterm(st, d);
80 if (op != '*' && op != '/' && op != '%')
88 } else if (op == '%') {
96 static unsigned long evaladd(struct st *st, int d)
101 a += (sub ? -1 : 1) * evalmul(st, d);
102 if (*st->s != '+' && *st->s != '-')
109 static unsigned long evalrel(struct st *st, int d)
111 unsigned long b, a = evaladd(st, d);
114 if (*st->s != '<' && *st->s != '>')
116 less = st->s[0] == '<';
117 eq = st->s[1] == '=';
120 a = (less ? a < b : a > b) || (eq && a == b);
124 static unsigned long evaleq(struct st *st, int d)
126 unsigned long a = evalrel(st, d);
130 if ((c != '=' && c != '!') || st->s[1] != '=')
133 a = (evalrel(st, d) == a) ^ (c == '!');
137 static unsigned long evaland(struct st *st, int d)
139 unsigned long a = evaleq(st, d);
141 if (st->s[0] != '&' || st->s[1] != '&')
144 a = evaleq(st, d) && a;
148 static unsigned long evalor(struct st *st, int d)
150 unsigned long a = evaland(st, d);
152 if (st->s[0] != '|' || st->s[1] != '|')
155 a = evaland(st, d) || a;
159 static unsigned long evalexpr(struct st *st, int d)
161 unsigned long a1, a2, a3;
164 a1 = evalor(st, d-6);
168 a2 = evalexpr(st, d);
172 a3 = evalexpr(st, d);
176 unsigned long __pleval(const char *s, unsigned long n)
183 a = evalexpr(&st, 100);
184 if (st.err || *st.s != ';')