xref: /original-bsd/bin/sh/arith.y (revision c6ddb5f9)
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