source: mainline/uspace/app/sbi/src/p_expr.c@ fa36f29

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since fa36f29 was fa36f29, checked in by Jiri Svoboda <jiri@…>, 15 years ago

Update SBI to rev. 75.

  • Property mode set to 100644
File size: 8.4 KB
RevLine 
[09ababb7]1/*
2 * Copyright (c) 2010 Jiri Svoboda
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @file Parse arithmetic expressions. */
30
31#include <assert.h>
32#include <stdlib.h>
33#include "lex.h"
34#include "list.h"
35#include "mytypes.h"
[fa36f29]36#include "p_type.h"
[09ababb7]37#include "parse.h"
38#include "stree.h"
39
40#include "p_expr.h"
41
42static stree_expr_t *parse_assign(parse_t *parse);
43static stree_expr_t *parse_comparative(parse_t *parse);
44static stree_expr_t *parse_additive(parse_t *parse);
[fa36f29]45static stree_expr_t *parse_prefix(parse_t *parse);
46static stree_expr_t *parse_prefix_new(parse_t *parse);
[09ababb7]47static stree_expr_t *parse_postfix(parse_t *parse);
48static stree_expr_t *parse_pf_access(parse_t *parse, stree_expr_t *a);
49static stree_expr_t *parse_pf_call(parse_t *parse, stree_expr_t *a);
50static stree_expr_t *parse_primitive(parse_t *parse);
51static stree_expr_t *parse_nameref(parse_t *parse);
52static stree_expr_t *parse_lit_int(parse_t *parse);
[fa36f29]53static stree_expr_t *parse_lit_ref(parse_t *parse);
[09ababb7]54static stree_expr_t *parse_lit_string(parse_t *parse);
[fa36f29]55static stree_expr_t *parse_self_ref(parse_t *parse);
[09ababb7]56
57/** Parse expression. */
58stree_expr_t *parse_expr(parse_t *parse)
59{
60 return parse_assign(parse);
61}
62
63/** Parse assignment expression. */
64static stree_expr_t *parse_assign(parse_t *parse)
65{
66 stree_expr_t *a, *b, *tmp;
67 stree_assign_t *assign;
68
69 a = parse_comparative(parse);
70
71 switch (lcur_lc(parse)) {
72 case lc_assign:
73 assign = stree_assign_new(ac_set);
74 break;
75 case lc_increase:
76 assign = stree_assign_new(ac_increase);
77 break;
78 default:
79 return a;
80 }
81
82 lskip(parse);
83 b = parse_comparative(parse);
84
85 assign->dest = a;
86 assign->src = b;
87
88 tmp = stree_expr_new(ec_assign);
89 tmp->u.assign = assign;
90 return tmp;
91}
92
93/** Parse comparative expression. */
94static stree_expr_t *parse_comparative(parse_t *parse)
95{
96 stree_expr_t *a, *b, *tmp;
97 stree_binop_t *binop;
98 binop_class_t bc;
99
100 a = parse_additive(parse);
101
102 while (lcur_lc(parse) == lc_equal || lcur_lc(parse) == lc_notequal ||
103 lcur_lc(parse) == lc_lt || lcur_lc(parse) == lc_gt ||
104 lcur_lc(parse) == lc_lt_equal || lcur_lc(parse) == lc_gt_equal) {
105
106 switch (lcur_lc(parse)) {
107 case lc_equal: bc = bo_equal; break;
108 case lc_notequal: bc = bo_notequal; break;
109 case lc_lt: bc = bo_lt; break;
110 case lc_gt: bc = bo_gt; break;
111 case lc_lt_equal: bc = bo_lt_equal; break;
112 case lc_gt_equal: bc = bo_gt_equal; break;
113 default: assert(b_false);
114 }
115
116 lskip(parse);
117 b = parse_additive(parse);
118
119 binop = stree_binop_new(bc);
120 binop->arg1 = a;
121 binop->arg2 = b;
122
123 tmp = stree_expr_new(ec_binop);
124 tmp->u.binop = binop;
125 a = tmp;
126 }
127
128 return a;
129}
130
131/** Parse additive expression. */
132static stree_expr_t *parse_additive(parse_t *parse)
133{
134 stree_expr_t *a, *b, *tmp;
135 stree_binop_t *binop;
136
[fa36f29]137 a = parse_prefix(parse);
[09ababb7]138 while (lcur_lc(parse) == lc_plus) {
139 lskip(parse);
[fa36f29]140 b = parse_prefix(parse);
[09ababb7]141
142 binop = stree_binop_new(bo_plus);
143 binop->arg1 = a;
144 binop->arg2 = b;
145
146 tmp = stree_expr_new(ec_binop);
147 tmp->u.binop = binop;
148 a = tmp;
149 }
150
151 return a;
152}
153
[fa36f29]154/** Parse prefix expression. */
155static stree_expr_t *parse_prefix(parse_t *parse)
156{
157 stree_expr_t *a;
158
159 switch (lcur_lc(parse)) {
160 case lc_plus:
161 printf("Unimplemented: Unary plus.\n");
162 exit(1);
163 case lc_new:
164 a = parse_prefix_new(parse);
165 break;
166 default:
167 a = parse_postfix(parse);
168 break;
169 }
170
171 return a;
172}
173
174/** Parse @c new operator. */
175static stree_expr_t *parse_prefix_new(parse_t *parse)
176{
177 stree_texpr_t *texpr;
178 stree_new_t *new_op;
179 stree_expr_t *expr;
180
181 lmatch(parse, lc_new);
182 texpr = parse_texpr(parse);
183 lmatch(parse, lc_lparen);
184 lmatch(parse, lc_rparen);
185
186 new_op = stree_new_new();
187 new_op->texpr = texpr;
188 expr = stree_expr_new(ec_new);
189 expr->u.new_op = new_op;
190
191 return expr;
192}
193
[09ababb7]194/** Parse postfix expression. */
195static stree_expr_t *parse_postfix(parse_t *parse)
196{
197 stree_expr_t *a;
198 stree_expr_t *tmp;
199
200 a = parse_primitive(parse);
201
202 while (lcur_lc(parse) == lc_period || lcur_lc(parse) == lc_lparen) {
203
204 switch (lcur_lc(parse)) {
205 case lc_period:
206 tmp = parse_pf_access(parse, a);
207 break;
208 case lc_lparen:
209 tmp = parse_pf_call(parse, a);
210 break;
211 default:
212 assert(b_false);
213 }
214
215 a = tmp;
216 }
217
218 return a;
219}
220
221/** Parse member access expression */
222static stree_expr_t *parse_pf_access(parse_t *parse, stree_expr_t *a)
223{
224 stree_ident_t *ident;
225 stree_expr_t *expr;
226 stree_access_t *access;
227
228 lmatch(parse, lc_period);
229 ident = parse_ident(parse);
230
231 access = stree_access_new();
232 access->arg = a;
233 access->member_name = ident;
234
235 expr = stree_expr_new(ec_access);
236 expr->u.access = access;
237
238 return expr;
239}
240
241/** Parse function call expression. */
242static stree_expr_t *parse_pf_call(parse_t *parse, stree_expr_t *a)
243{
244 stree_expr_t *expr;
245 stree_call_t *call;
246 stree_expr_t *arg;
247
248 lmatch(parse, lc_lparen);
249
250 call = stree_call_new();
251 call->fun = a;
252 list_init(&call->args);
253
254 /* Parse function arguments */
255
256 if (lcur_lc(parse) != lc_rparen) {
257 while (b_true) {
258 arg = parse_expr(parse);
259 list_append(&call->args, arg);
260
261 if (lcur_lc(parse) == lc_rparen)
262 break;
263 lmatch(parse, lc_comma);
264 }
265 }
266
267 lmatch(parse, lc_rparen);
268
269 expr = stree_expr_new(ec_call);
270 expr->u.call = call;
271
272 return expr;
273}
274
275/** Parse primitive expression. */
276static stree_expr_t *parse_primitive(parse_t *parse)
277{
278 stree_expr_t *expr;
279
280 switch (lcur_lc(parse)) {
281 case lc_ident:
282 expr = parse_nameref(parse);
283 break;
284 case lc_lit_int:
285 expr = parse_lit_int(parse);
286 break;
[fa36f29]287 case lc_nil:
288 expr = parse_lit_ref(parse);
289 break;
[09ababb7]290 case lc_lit_string:
291 expr = parse_lit_string(parse);
292 break;
[fa36f29]293 case lc_self:
294 expr = parse_self_ref(parse);
295 break;
[09ababb7]296 default:
297 lunexpected_error(parse);
298 exit(1);
299 }
300
301 return expr;
302}
303
304/** Parse name reference. */
305static stree_expr_t *parse_nameref(parse_t *parse)
306{
307 stree_nameref_t *nameref;
308 stree_expr_t *expr;
309
310 nameref = stree_nameref_new();
311 nameref->name = parse_ident(parse);
312 expr = stree_expr_new(ec_nameref);
313 expr->u.nameref = nameref;
314
315 return expr;
316}
317
318/** Parse integer literal. */
319static stree_expr_t *parse_lit_int(parse_t *parse)
320{
321 stree_literal_t *literal;
322 stree_expr_t *expr;
323
324 lcheck(parse, lc_lit_int);
325
326 literal = stree_literal_new(ltc_int);
327 literal->u.lit_int.value = lcur(parse)->u.lit_int.value;
328
329 lskip(parse);
330
331 expr = stree_expr_new(ec_literal);
332 expr->u.literal = literal;
333
334 return expr;
335}
336
[fa36f29]337/** Parse reference literal (@c nil). */
338static stree_expr_t *parse_lit_ref(parse_t *parse)
339{
340 stree_literal_t *literal;
341 stree_expr_t *expr;
342
343 lmatch(parse, lc_nil);
344
345 literal = stree_literal_new(ltc_ref);
346
347 expr = stree_expr_new(ec_literal);
348 expr->u.literal = literal;
349
350 return expr;
351}
352
[09ababb7]353/** Parse string literal. */
354static stree_expr_t *parse_lit_string(parse_t *parse)
355{
356 stree_literal_t *literal;
357 stree_expr_t *expr;
358
359 lcheck(parse, lc_lit_string);
360
361 literal = stree_literal_new(ltc_string);
362 literal->u.lit_string.value = lcur(parse)->u.lit_string.value;
363
364 lskip(parse);
365
366 expr = stree_expr_new(ec_literal);
367 expr->u.literal = literal;
368
369 return expr;
370}
[fa36f29]371
372/** Parse @c self keyword. */
373static stree_expr_t *parse_self_ref(parse_t *parse)
374{
375 stree_self_ref_t *self_ref;
376 stree_expr_t *expr;
377
378 lmatch(parse, lc_self);
379
380 self_ref = stree_self_ref_new();
381
382 expr = stree_expr_new(ec_self_ref);
383 expr->u.self_ref = self_ref;
384
385 return expr;
386}
Note: See TracBrowser for help on using the repository browser.