X-Git-Url: https://git.kernel.dk/?p=fio.git;a=blobdiff_plain;f=exp%2Fexpression-parser.y;h=6ab6408874b829d2dffbf0ed6fa82ebc9558414d;hp=dbd8b6c27c40bf58c598564a8ca2d9283edde74e;hb=65641c1ef3a7e31c606e53f1fd61e65e998ab098;hpb=b470a02cade02049509d22442addfbc88d10116e diff --git a/exp/expression-parser.y b/exp/expression-parser.y index dbd8b6c2..6ab64088 100644 --- a/exp/expression-parser.y +++ b/exp/expression-parser.y @@ -20,7 +20,7 @@ #include #include - +#include struct parser_value_type { double dval; long long ival; @@ -55,8 +55,12 @@ extern void yyrestart(FILE *file); %token NUMBER %token BYE +%token SUFFIX %left '-' '+' +%right SUFFIX %left '*' '/' +%right '^' +%left '%' %nonassoc UMINUS %parse-param { long long *result } %parse-param { double *dresult } @@ -119,6 +123,59 @@ expression: expression '+' expression { $$.has_error = $2.has_error; } | '(' expression ')' { $$ = $2; } + | expression SUFFIX { + if (!$1.has_dval && !$2.has_dval) + $$.ival = $1.ival * $2.ival; + else + $$.ival = (long long) $1.dval * $2.dval; + if ($1.has_dval || $2.has_dval) + $$.dval = $1.dval * $2.dval; + else + $$.dval = $1.ival * $2.ival; + $$.has_error = $1.has_error || $2.has_error; + } + | expression '%' expression { + if ($1.has_dval || $3.has_dval) + yyerror(0, 0, 0, 0, "modulo on floats"); + if ($3.ival == 0) + yyerror(0, 0, 0, 0, "divide by zero"); + else { + $$.ival = $1.ival % $3.ival; + $$.dval = $$.ival; + } + $$.has_error = $1.has_error || $3.has_error; + } + | expression '^' expression { + $$.has_error = $1.has_error || $3.has_error; + if (!$1.has_dval && !$3.has_dval) { + int i; + + if ($3.ival == 0) { + $$.ival = 1; + } else if ($3.ival > 0) { + long long tmp = $1.ival; + $$.ival = 1.0; + for (i = 0; i < $3.ival; i++) + $$.ival *= tmp; + } else { + /* integers, 2^-3, ok, we now have doubles */ + double tmp; + if ($1.ival == 0 && $3.ival == 0) { + tmp = 1.0; + $$.has_error = 1; + } else { + double x = (double) $1.ival; + double y = (double) $3.ival; + tmp = pow(x, y); + } + $$.ival = (long long) tmp; + } + $$.dval = pow($1.dval, $3.dval); + } else { + $$.dval = pow($1.dval, $3.dval); + $$.ival = (long long) $$.dval; + } + } | NUMBER { $$ = $1; } | BYE { $$ = $1; *bye = 1; }; %%