diff options
Diffstat (limited to 'src/skaembutils/s6-expr.c')
-rw-r--r-- | src/skaembutils/s6-expr.c | 41 |
1 files changed, 19 insertions, 22 deletions
diff --git a/src/skaembutils/s6-expr.c b/src/skaembutils/s6-expr.c index 4404d44..accb0e6 100644 --- a/src/skaembutils/s6-expr.c +++ b/src/skaembutils/s6-expr.c @@ -1,13 +1,15 @@ /* ISC license. */ +#include <sys/types.h> #include <unistd.h> #include <skalibs/allreadwrite.h> #include <skalibs/bytestr.h> -#include <skalibs/uint.h> +#include <skalibs/ulong.h> #include <skalibs/fmtscan.h> #include <skalibs/strerr2.h> #define USAGE "s6-expr arithmetic expression" +#define bail() strerr_dief1x(2, "invalid expression") enum opnum { @@ -42,7 +44,7 @@ struct node unsigned int type ; unsigned int arg1 ; unsigned int arg2 ; - int data ; + long data ; } ; static unsigned int lex (struct node *tree, char const *const *argv) @@ -82,8 +84,7 @@ static unsigned int lex (struct node *tree, char const *const *argv) { tree[pos].op = T_DATA ; tree[pos].type = 0 ; - if (!int_scan(argv[pos], &tree[pos].data)) - strerr_dief1x(2, "invalid expression") ; + if (!long_scan(argv[pos], &tree[pos].data)) bail() ; } } return pos ; @@ -125,32 +126,28 @@ static unsigned int parse (struct node *tree, unsigned int n) { switch (table[tree[pos].type][tree[stack[sp]].type]) { - case 'x' : _exit(2) ; + case 'x' : bail() ; case '!' : cont = 0 ; break ; case 's' : stack[++sp] = pos++ ; break ; + case 'M' : + if (tree[stack[sp-2]].type != 7) bail() ; + stack[sp-2] = stack[sp-1] ; + sp -= 2 ; case 'm' : reduce(tree, stack, &sp, 2) ; break ; case 'a' : reduce(tree, stack, &sp, 3) ; break ; case 'c' : reduce(tree, stack, &sp, 4) ; break ; case 'A' : reduce(tree, stack, &sp, 5) ; break ; case 'O' : reduce(tree, stack, &sp, 6) ; break ; case 'E' : tree[stack[sp]].type = 14 ; break ; - case 'M' : - { - if (tree[stack[sp-2]].type != 7) _exit(2) ; - stack[sp-2] = stack[sp-1] ; - sp -= 2 ; - reduce(tree, stack, &sp, 2) ; - break ; - } case 'z' : default : strerr_dief1x(101, "internal error in parse, please submit a bug-report.") ; /* can't happen */ } } - if (sp != 2) strerr_dief1x(2, "invalid expression") ; + if (sp != 2) bail() ; return stack[1] ; } -static int run (struct node const *tree, unsigned int root) +static long run (struct node const *tree, unsigned int root) { switch (tree[root].op) { @@ -158,12 +155,12 @@ static int run (struct node const *tree, unsigned int root) return tree[root].data ; case T_OR : { - int r = run(tree, tree[root].arg1) ; + long r = run(tree, tree[root].arg1) ; return r ? r : run(tree, tree[root].arg2) ; } case T_AND : { - int r = run(tree, tree[root].arg1) ; + long r = run(tree, tree[root].arg1) ; return r ? run(tree, tree[root].arg2) ? r : 0 : 0 ; } case T_EQUAL : @@ -188,22 +185,22 @@ static int run (struct node const *tree, unsigned int root) return run(tree, tree[root].arg1) / run(tree, tree[root].arg2) ; case T_MOD : return run(tree, tree[root].arg1) % run(tree, tree[root].arg2) ; - default: strerr_dief1x(101, "internal error in run, please submit a bug-report") ; + default : strerr_dief1x(101, "internal error in run, please submit a bug-report") ; } } int main (int argc, char const *const *argv) { - char fmt[UINT_FMT+1] ; - int val ; - unsigned int len ; + char fmt[ULONG_FMT+1] ; + long val ; + size_t len ; PROG = "s6-expr" ; if (argc <= 1) return 2 ; { struct node tree[argc + 1] ; val = run(tree, parse(tree, lex(tree, argv+1))) ; } - len = int_fmt(fmt, val) ; + len = long_fmt(fmt, val) ; fmt[len++] = '\n' ; if (allwrite(1, fmt, len) < len) strerr_diefu1sys(111, "write to stdout") ; |