Mercurial > hg > Members > kono > compiler-examples
annotate calc.c @ 26:8550260c18fa
fix aarch on mac and llvm
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Fri, 18 Oct 2024 16:06:51 +0900 |
parents | e5c8532ab38d |
children |
rev | line source |
---|---|
0 | 1 /* |
2 Simple Calculator | |
3 $Id$ | |
4 */ | |
5 | |
6 #include <stdio.h> | |
7 | |
8 char *ptr,*last_ptr; | |
9 int value,lvalue; | |
10 int last_token; | |
11 int variable[48]; | |
12 | |
13 static int expr(); | |
14 static int aexpr(); | |
15 static int mexpr(); | |
16 static int term(); | |
17 | |
18 | |
19 #define T_EQUAL (0x100|'=') | |
20 #define T_NEQUAL (0x100|'!') | |
21 #define T_LSHIFT (0x100|'<') | |
22 #define T_RSHIFT (0x100|'>') | |
23 | |
24 static void | |
25 line_skip() | |
26 { | |
27 while(*ptr++); | |
28 last_ptr = ptr; | |
29 last_token = EOF; | |
30 } | |
31 | |
32 static void | |
26
8550260c18fa
fix aarch on mac and llvm
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
17
diff
changeset
|
33 error(char *description) |
0 | 34 { |
35 fprintf(stderr,"%s on %s\n",description,last_ptr); | |
36 line_skip(); | |
37 } | |
38 | |
39 static int | |
40 token() | |
41 { | |
42 int c,d; | |
43 | |
44 last_ptr = ptr; /* for error position */ | |
45 c= *ptr; | |
46 while(c<=' ' && c) { | |
47 c = *++ptr; | |
48 } | |
49 if(!c) { | |
50 last_token = EOF; | |
51 return last_token; | |
52 } | |
53 ptr++; | |
54 if ('/'==c && ('/'== *ptr || '*'== *ptr)) { /* comment */ | |
55 line_skip(); | |
56 return EOF; | |
57 } | |
58 if('1'<=c && c<='9') { /* Decimal */ | |
59 d = c-'0'; | |
17 | 60 while((c= *ptr++)) { |
0 | 61 if('0'<=c && c<='9') { |
62 d = d*10 + (c - '0'); | |
63 } else { | |
64 break; | |
65 } | |
66 } | |
67 c && ptr--; | |
68 value = d; | |
69 last_token = '0'; | |
70 return last_token; | |
71 } else if ('0'==c && 'x'== *ptr) { /* Hex */ | |
72 ptr++; | |
73 d = 0; | |
17 | 74 while((c= *ptr++)) { |
0 | 75 if('0'<=c && c<='9') { |
76 d = d*16 + (c - '0'); | |
77 } else if('a'<=c && c<='f') { | |
78 d = d*16 + (c - 'a' + 10); | |
79 } else if('A'<=c && c<='F') { | |
80 d = d*16 + (c - 'a' + 10); | |
81 } else { | |
82 break; | |
83 } | |
84 } | |
85 c && ptr--; | |
86 value = d; | |
87 last_token = '0'; | |
88 return last_token; | |
89 } else if ('0'==c) { /* Octal */ | |
90 d = c-'0'; | |
17 | 91 while((c= *ptr++)) { |
0 | 92 if('0'<=c && c<='7') { |
93 d = d*8 + (c - '0'); | |
94 } else { | |
95 break; | |
96 } | |
97 } | |
98 c && ptr--; | |
99 value = d; | |
100 last_token = '0'; | |
101 return last_token; | |
102 } else if ('\''==c) { /* Ascii */ | |
103 d = 0; | |
17 | 104 while((c= *ptr++)) { |
0 | 105 if('\''!=c && c<=0x7f) { |
106 d = d*256 + c; | |
107 } else if(c>=0x80 && *ptr) { | |
108 d = d*256*256 + c*256 + *ptr++; | |
109 } else { | |
110 break; | |
111 } | |
112 } | |
113 c && ptr--; | |
114 value = d; | |
115 last_token = '0'; | |
116 return last_token; | |
117 } else if (('a'<=c && c<='z') || /* variable */ | |
118 ('A'<=c && c<='Z')) { | |
119 value = ((c>'Z')?c-'a'+'Z'-'A'+1:c-'A'); | |
120 last_token = 'v'; | |
121 return last_token; | |
122 } else if ('='==c && '='== *ptr) { /* equal */ | |
123 ptr++; | |
124 last_token = T_EQUAL; | |
125 return last_token; | |
126 } else if ('!'==c && '='== *ptr) { /* equal */ | |
127 ptr++; | |
128 last_token = T_NEQUAL; | |
17 | 129 return last_token; |
0 | 130 } else if ('<'==c && '<'== *ptr) { /* shift */ |
131 ptr++; | |
132 last_token = T_LSHIFT; | |
133 return last_token; | |
134 } else if ('>'==c && '>'== *ptr) { /* shift */ | |
135 ptr++; | |
136 last_token = T_RSHIFT; | |
137 return last_token; | |
138 } else { | |
139 last_token = c; | |
140 return last_token; | |
141 } | |
142 } | |
143 | |
144 static int | |
145 expr() | |
146 { | |
147 int d,assign; | |
148 | |
149 d = aexpr(); | |
150 assign = lvalue; | |
151 while(last_token!=EOF) { | |
152 switch(last_token) { | |
153 case '<': | |
154 d = (d < aexpr()); | |
155 break; | |
156 case '>': | |
157 d = (d > aexpr()); | |
158 break; | |
159 case T_EQUAL: | |
160 d = (d == aexpr()); | |
161 break; | |
162 case T_NEQUAL: | |
163 d = (d != aexpr()); | |
164 break; | |
165 case T_LSHIFT: | |
166 d <<= aexpr(); | |
167 break; | |
168 case T_RSHIFT: | |
169 d >>= aexpr(); | |
170 break; | |
171 case '?': | |
172 { | |
173 int true; | |
174 true = expr(); | |
175 if(last_token != ':') { | |
176 error("? expression not terminated with :"); | |
177 return true; | |
178 } | |
179 if(d) { | |
180 expr(); | |
181 return true; | |
182 } else { | |
183 return expr(); | |
184 } | |
185 } | |
186 break; | |
187 case '=': | |
188 if(assign>=0) { | |
189 d = expr(); | |
190 variable[assign] = d; | |
191 return d; | |
192 } else { | |
193 error("Bad assignment"); | |
194 return 0; | |
195 } | |
196 break; | |
197 case ':': | |
198 case ')': | |
199 return d; | |
200 default: | |
201 error("Bad expression"); | |
202 token(); | |
203 } | |
204 } | |
205 last_token = EOF; | |
206 return d; | |
207 } | |
208 | |
209 static int | |
210 aexpr() | |
211 { | |
212 int d; | |
213 | |
214 d = mexpr(); | |
215 while(last_token!=EOF) { | |
216 switch(last_token) { | |
217 case '^': | |
218 d ^= mexpr(); | |
219 break; | |
220 case '|': | |
221 d |= mexpr(); | |
222 break; | |
223 case '&': | |
224 d &= mexpr(); | |
225 break; | |
226 case '-': | |
227 d -= mexpr(); | |
228 break; | |
229 case '+': | |
230 d += mexpr(); | |
231 break; | |
232 default: | |
233 return d; | |
234 } | |
235 } | |
236 return d; | |
237 } | |
238 | |
239 static int | |
240 mexpr() | |
241 { | |
242 int d; | |
243 | |
244 d = term(); | |
245 while(last_token!=EOF) { | |
246 switch(last_token) { | |
247 case '*': | |
248 d *= term(); | |
249 break; | |
250 case '/': | |
251 d /= term(); | |
252 break; | |
253 case '%': | |
254 d %= term(); | |
255 break; | |
256 case '^': | |
257 d ^= term(); | |
258 break; | |
259 default: | |
260 return d; | |
261 } | |
262 } | |
263 return d; | |
264 } | |
265 | |
266 static int term() | |
267 { | |
268 int d; | |
269 | |
270 lvalue= -1; | |
271 token(); | |
272 if(last_token==EOF) { | |
273 error("Term expected"); | |
274 } | |
275 switch(last_token) { | |
276 case '0': | |
277 d = value; | |
278 token(); | |
279 return d; | |
280 case 'v': | |
281 d = lvalue = value; | |
282 token(); | |
283 return variable[d]; | |
284 case '-': | |
285 return - term(); | |
286 case '!': | |
287 return ! term(); | |
288 case '(': | |
289 d = expr(); | |
290 if(last_token != ')') { | |
291 error("Unbalanced parenthsis"); | |
292 } | |
293 token(); | |
294 return d; | |
295 default: | |
296 token(); | |
297 error("Unknown term"); | |
298 return 0; | |
299 } | |
300 } | |
301 | |
302 int | |
303 main(int ac,char *av[]) | |
304 { | |
305 int d; | |
306 char buf[BUFSIZ]; | |
307 | |
308 while (fgets(buf,BUFSIZ,stdin)) { | |
309 ptr = buf; | |
310 d = expr(); | |
311 printf("%s = 0x%08x = %d\n",buf,d,d); | |
312 fflush(stdout); | |
313 } | |
314 return 0; | |
315 } | |
316 | |
317 /* end */ |