1*68929Sbostic %token ARITH_NUM ARITH_LPAREN ARITH_RPAREN 254332Smarc 354332Smarc %left ARITH_OR 454332Smarc %left ARITH_AND 5*68929Sbostic %left ARITH_BOR 6*68929Sbostic %left ARITH_BXOR 7*68929Sbostic %left ARITH_BAND 8*68929Sbostic %left ARITH_EQ ARITH_NE 9*68929Sbostic %left ARITH_LT ARITH_GT ARITH_GE ARITH_LE 10*68929Sbostic %left ARITH_LSHIFT ARITH_RSHIFT 11*68929Sbostic %left ARITH_ADD ARITH_SUB 12*68929Sbostic %left ARITH_MUL ARITH_DIV ARITH_REM 13*68929Sbostic %left ARITH_UNARYMINUS ARITH_UNARYPLUS ARITH_NOT ARITH_BNOT 1454332Smarc %% 1554332Smarc 1654332Smarc exp: expr = { 1754332Smarc return ($1); 1854332Smarc } 1954332Smarc ; 2054332Smarc 2154332Smarc 2254332Smarc expr: ARITH_LPAREN expr ARITH_RPAREN = { $$ = $2; } 23*68929Sbostic | expr ARITH_OR expr = { $$ = $1 ? $1 : $3 ? $3 : 0; } 24*68929Sbostic | expr ARITH_AND expr = { $$ = $1 ? ( $3 ? $3 : 0 ) : 0; } 25*68929Sbostic | expr ARITH_BOR expr = { $$ = $1 | $3; } 26*68929Sbostic | expr ARITH_BXOR expr = { $$ = $1 ^ $3; } 27*68929Sbostic | expr ARITH_BAND expr = { $$ = $1 & $3; } 28*68929Sbostic | expr ARITH_EQ expr = { $$ = $1 == $3; } 29*68929Sbostic | expr ARITH_GT expr = { $$ = $1 > $3; } 30*68929Sbostic | expr ARITH_GE expr = { $$ = $1 >= $3; } 31*68929Sbostic | expr ARITH_LT expr = { $$ = $1 < $3; } 32*68929Sbostic | expr ARITH_LE expr = { $$ = $1 <= $3; } 33*68929Sbostic | expr ARITH_NE expr = { $$ = $1 != $3; } 34*68929Sbostic | expr ARITH_LSHIFT expr = { $$ = $1 << $3; } 35*68929Sbostic | expr ARITH_RSHIFT expr = { $$ = $1 >> $3; } 36*68929Sbostic | expr ARITH_ADD expr = { $$ = $1 + $3; } 37*68929Sbostic | expr ARITH_SUB expr = { $$ = $1 - $3; } 38*68929Sbostic | expr ARITH_MUL expr = { $$ = $1 * $3; } 39*68929Sbostic | expr ARITH_DIV expr = { 4054332Smarc if ($3 == 0) 4154332Smarc yyerror("division by zero"); 4254332Smarc $$ = $1 / $3; 4354332Smarc } 44*68929Sbostic | expr ARITH_REM expr = { 45*68929Sbostic if ($3 == 0) 46*68929Sbostic yyerror("division by zero"); 47*68929Sbostic $$ = $1 % $3; 48*68929Sbostic } 4954332Smarc | ARITH_NOT expr = { $$ = !($2); } 50*68929Sbostic | ARITH_BNOT expr = { $$ = ~($2); } 51*68929Sbostic | ARITH_SUB expr %prec ARITH_UNARYMINUS = { $$ = -($2); } 52*68929Sbostic | ARITH_ADD expr %prec ARITH_UNARYPLUS = { $$ = $2; } 5354332Smarc | ARITH_NUM 5454332Smarc ; 5554332Smarc %% 5660701Sbostic /*- 5760701Sbostic * Copyright (c) 1993 5860701Sbostic * The Regents of the University of California. All rights reserved. 5960701Sbostic * 6060701Sbostic * This code is derived from software contributed to Berkeley by 6160701Sbostic * Kenneth Almquist. 6260701Sbostic * 6360701Sbostic * %sccs.include.redist.c% 6460701Sbostic */ 6554332Smarc 6660701Sbostic #ifndef lint 67*68929Sbostic static char sccsid[] = "@(#)arith.y 8.2 (Berkeley) 04/27/95"; 6860701Sbostic #endif /* not lint */ 6960701Sbostic 7054332Smarc #include "shell.h" 7154332Smarc #include "error.h" 7254332Smarc #include "output.h" 7354332Smarc #include "memalloc.h" 7454332Smarc 7554332Smarc char *arith_buf, *arith_startbuf; 7654332Smarc 7754332Smarc arith(s) 7854332Smarc char *s; 7954332Smarc { 8054332Smarc long result; 8154332Smarc 8254332Smarc arith_buf = arith_startbuf = s; 8354332Smarc 8454332Smarc INTOFF; 8554332Smarc result = yyparse(); 8654332Smarc arith_lex_reset(); /* reprime lex */ 8754332Smarc INTON; 8854332Smarc 8954332Smarc return (result); 9054332Smarc } 9154332Smarc 9254332Smarc yyerror(s) 9354332Smarc char *s; 9454332Smarc { 9554332Smarc extern yytext, yylval; 9654332Smarc 9754332Smarc yyerrok; 9854332Smarc yyclearin; 9954332Smarc arith_lex_reset(); /* reprime lex */ 10054332Smarc error("arithmetic expression: %s: \"%s\"", s, arith_startbuf); 10154332Smarc } 10254332Smarc 10354332Smarc /* 10454332Smarc * The exp(1) builtin. 10554332Smarc */ 10654332Smarc expcmd(argc, argv) 10754332Smarc char **argv; 10854332Smarc { 10954332Smarc char *p; 11054332Smarc char *concat; 11154332Smarc char **ap; 11254332Smarc long i; 11354332Smarc 11454332Smarc if (argc > 1) { 11554332Smarc p = argv[1]; 11654332Smarc if (argc > 2) { 11754332Smarc /* 11854332Smarc * concatenate arguments 11954332Smarc */ 12054332Smarc STARTSTACKSTR(concat); 12154332Smarc ap = argv + 2; 12254332Smarc for (;;) { 12354332Smarc while (*p) 12454332Smarc STPUTC(*p++, concat); 12554332Smarc if ((p = *ap++) == NULL) 12654332Smarc break; 12754332Smarc STPUTC(' ', concat); 12854332Smarc } 12954332Smarc STPUTC('\0', concat); 13054332Smarc p = grabstackstr(concat); 13154332Smarc } 13254332Smarc } else 13354332Smarc p = ""; 13454332Smarc 13554332Smarc i = arith(p); 13654332Smarc 13754332Smarc out1fmt("%d\n", i); 13854332Smarc return (! i); 13954332Smarc } 14054332Smarc 14154332Smarc /*************************/ 14254332Smarc #ifdef TEST_ARITH 14354332Smarc #include <stdio.h> 14454332Smarc main(argc, argv) 14554332Smarc char *argv[]; 14654332Smarc { 14754332Smarc printf("%d\n", exp(argv[1])); 14854332Smarc } 14954332Smarc error(s) 15054332Smarc char *s; 15154332Smarc { 15254332Smarc fprintf(stderr, "exp: %s\n", s); 15354332Smarc exit(1); 15454332Smarc } 15554332Smarc #endif 156