1*54332Smarc %token ARITH_OR ARITH_AND ARITH_ADD ARITH_SUBT ARITH_MULT ARITH_DIV ARITH_REM ARITH_EQ ARITH_GT ARITH_GEQ ARITH_LT ARITH_LEQ ARITH_NEQ 2*54332Smarc %token ARITH_NUM ARITH_LPAREN ARITH_RPAREN ARITH_NOT ARITH_UNARYMINUS 3*54332Smarc 4*54332Smarc %left ARITH_OR 5*54332Smarc %left ARITH_AND 6*54332Smarc %left ARITH_EQ ARITH_NEQ 7*54332Smarc %left ARITH_LT ARITH_GT ARITH_GEQ ARITH_LEQ 8*54332Smarc %left ARITH_ADD ARITH_SUBT 9*54332Smarc %left ARITH_MULT ARITH_DIV ARITH_REM 10*54332Smarc %left ARITH_UNARYMINUS ARITH_NOT 11*54332Smarc %% 12*54332Smarc 13*54332Smarc exp: expr = { 14*54332Smarc return ($1); 15*54332Smarc } 16*54332Smarc ; 17*54332Smarc 18*54332Smarc 19*54332Smarc expr: ARITH_LPAREN expr ARITH_RPAREN = { $$ = $2; } 20*54332Smarc | expr ARITH_OR expr = { $$ = $1 ? $1 : $3 ? $3 : 0; } 21*54332Smarc | expr ARITH_AND expr = { $$ = $1 ? ( $3 ? $3 : 0 ) : 0; } 22*54332Smarc | expr ARITH_EQ expr = { $$ = $1 == $3; } 23*54332Smarc | expr ARITH_GT expr = { $$ = $1 > $3; } 24*54332Smarc | expr ARITH_GEQ expr = { $$ = $1 >= $3; } 25*54332Smarc | expr ARITH_LT expr = { $$ = $1 < $3; } 26*54332Smarc | expr ARITH_LEQ expr = { $$ = $1 <= $3; } 27*54332Smarc | expr ARITH_NEQ expr = { $$ = $1 != $3; } 28*54332Smarc | expr ARITH_ADD expr = { $$ = $1 + $3; } 29*54332Smarc | expr ARITH_SUBT expr = { $$ = $1 - $3; } 30*54332Smarc | expr ARITH_MULT expr = { $$ = $1 * $3; } 31*54332Smarc | expr ARITH_DIV expr = { 32*54332Smarc if ($3 == 0) 33*54332Smarc yyerror("division by zero"); 34*54332Smarc $$ = $1 / $3; 35*54332Smarc } 36*54332Smarc | expr ARITH_REM expr = { $$ = $1 % $3; } 37*54332Smarc | ARITH_NOT expr = { $$ = !($2); } 38*54332Smarc | ARITH_UNARYMINUS expr = { $$ = -($2); } 39*54332Smarc | ARITH_NUM 40*54332Smarc ; 41*54332Smarc %% 42*54332Smarc 43*54332Smarc #include "shell.h" 44*54332Smarc #include "error.h" 45*54332Smarc #include "output.h" 46*54332Smarc #include "memalloc.h" 47*54332Smarc 48*54332Smarc char *arith_buf, *arith_startbuf; 49*54332Smarc 50*54332Smarc arith(s) 51*54332Smarc char *s; 52*54332Smarc { 53*54332Smarc extern arith_wasoper; 54*54332Smarc long result; 55*54332Smarc 56*54332Smarc arith_wasoper = 1; 57*54332Smarc arith_buf = arith_startbuf = s; 58*54332Smarc 59*54332Smarc INTOFF; 60*54332Smarc result = yyparse(); 61*54332Smarc arith_lex_reset(); /* reprime lex */ 62*54332Smarc INTON; 63*54332Smarc 64*54332Smarc return (result); 65*54332Smarc } 66*54332Smarc 67*54332Smarc yyerror(s) 68*54332Smarc char *s; 69*54332Smarc { 70*54332Smarc extern yytext, yylval; 71*54332Smarc 72*54332Smarc yyerrok; 73*54332Smarc yyclearin; 74*54332Smarc arith_lex_reset(); /* reprime lex */ 75*54332Smarc error("arithmetic expression: %s: \"%s\"", s, arith_startbuf); 76*54332Smarc } 77*54332Smarc 78*54332Smarc /* 79*54332Smarc * The exp(1) builtin. 80*54332Smarc */ 81*54332Smarc expcmd(argc, argv) 82*54332Smarc char **argv; 83*54332Smarc { 84*54332Smarc char *p; 85*54332Smarc char *concat; 86*54332Smarc char **ap; 87*54332Smarc long i; 88*54332Smarc 89*54332Smarc if (argc > 1) { 90*54332Smarc p = argv[1]; 91*54332Smarc if (argc > 2) { 92*54332Smarc /* 93*54332Smarc * concatenate arguments 94*54332Smarc */ 95*54332Smarc STARTSTACKSTR(concat); 96*54332Smarc ap = argv + 2; 97*54332Smarc for (;;) { 98*54332Smarc while (*p) 99*54332Smarc STPUTC(*p++, concat); 100*54332Smarc if ((p = *ap++) == NULL) 101*54332Smarc break; 102*54332Smarc STPUTC(' ', concat); 103*54332Smarc } 104*54332Smarc STPUTC('\0', concat); 105*54332Smarc p = grabstackstr(concat); 106*54332Smarc } 107*54332Smarc } else 108*54332Smarc p = ""; 109*54332Smarc 110*54332Smarc i = arith(p); 111*54332Smarc 112*54332Smarc out1fmt("%d\n", i); 113*54332Smarc return (! i); 114*54332Smarc } 115*54332Smarc 116*54332Smarc /*************************/ 117*54332Smarc #ifdef TEST_ARITH 118*54332Smarc #include <stdio.h> 119*54332Smarc main(argc, argv) 120*54332Smarc char *argv[]; 121*54332Smarc { 122*54332Smarc printf("%d\n", exp(argv[1])); 123*54332Smarc } 124*54332Smarc error(s) 125*54332Smarc char *s; 126*54332Smarc { 127*54332Smarc fprintf(stderr, "exp: %s\n", s); 128*54332Smarc exit(1); 129*54332Smarc } 130*54332Smarc #endif 131