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