summaryrefslogtreecommitdiff
path: root/src/skaembutils/s6-expr.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/skaembutils/s6-expr.c')
-rw-r--r--src/skaembutils/s6-expr.c41
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") ;