source: mainline/uspace/app/sbi/src/run_texpr.c@ 23b7c02

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 23b7c02 was aaa77ba0, checked in by Martin Decky <martin@…>, 13 years ago

silence compiler warnings

  • Property mode set to 100644
File size: 12.5 KB
Line 
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 Evaluate type expressions. */
30
31#include <assert.h>
32#include <stdlib.h>
33#include "cspan.h"
34#include "debug.h"
35#include "list.h"
36#include "mytypes.h"
37#include "stree.h"
38#include "strtab.h"
39#include "symbol.h"
40#include "tdata.h"
41
42#include "run_texpr.h"
43
44static void run_taccess(stree_program_t *prog, stree_csi_t *ctx,
45 stree_taccess_t *taccess, tdata_item_t **res);
46static void run_tindex(stree_program_t *prog, stree_csi_t *ctx,
47 stree_tindex_t *tindex, tdata_item_t **res);
48static void run_tliteral(stree_program_t *prog, stree_csi_t *ctx,
49 stree_tliteral_t *tliteral, tdata_item_t **res);
50static void run_tnameref(stree_program_t *prog, stree_csi_t *ctx,
51 stree_tnameref_t *tnameref, tdata_item_t **res);
52static void run_tapply(stree_program_t *prog, stree_csi_t *ctx,
53 stree_tapply_t *tapply, tdata_item_t **res);
54
55/** Evaluate type expression.
56 *
57 * Evaluate type expression (this produces a type item). If a type error
58 * occurs, the resulting type item is of class @c tic_ignore.
59 *
60 * @param prog Program
61 * @param ctx Current CSI (context)
62 * @param texpr Type expression to evaluate
63 * @param res Place to store type result
64 */
65void run_texpr(stree_program_t *prog, stree_csi_t *ctx, stree_texpr_t *texpr,
66 tdata_item_t **res)
67{
68 switch (texpr->tc) {
69 case tc_taccess:
70 run_taccess(prog, ctx, texpr->u.taccess, res);
71 break;
72 case tc_tindex:
73 run_tindex(prog, ctx, texpr->u.tindex, res);
74 break;
75 case tc_tliteral:
76 run_tliteral(prog, ctx, texpr->u.tliteral, res);
77 break;
78 case tc_tnameref:
79 run_tnameref(prog, ctx, texpr->u.tnameref, res);
80 break;
81 case tc_tapply:
82 run_tapply(prog, ctx, texpr->u.tapply, res);
83 break;
84 }
85}
86
87/** Evaluate type access expression.
88 *
89 * Evaluate operation per the type access ('.') operator.
90 *
91 * @param prog Program
92 * @param ctx Current CSI (context)
93 * @param taccess Type access expression to evaluate
94 * @param res Place to store type result
95 */
96static void run_taccess(stree_program_t *prog, stree_csi_t *ctx,
97 stree_taccess_t *taccess, tdata_item_t **res)
98{
99 stree_symbol_t *sym;
100 tdata_item_t *targ_i = NULL;
101 tdata_item_t *titem = NULL;;
102 tdata_object_t *tobject;
103 tdata_deleg_t *tdeleg;
104 stree_csi_t *base_csi;
105 stree_deleg_t *deleg;
106 stree_enum_t *enum_d;
107 tdata_enum_t *tenum;
108
109#ifdef DEBUG_RUN_TRACE
110 printf("Evaluating type access operation.\n");
111#endif
112 /* Evaluate base type. */
113 run_texpr(prog, ctx, taccess->arg, &targ_i);
114
115 if (targ_i->tic == tic_ignore) {
116 *res = tdata_item_new(tic_ignore);
117 return;
118 }
119
120 if (targ_i->tic != tic_tobject) {
121 cspan_print(taccess->texpr->cspan);
122 printf(" Error: Using '.' with type which is not an "
123 "object.\n");
124 *res = tdata_item_new(tic_ignore);
125 return;
126 }
127
128 /* Get base CSI. */
129 base_csi = targ_i->u.tobject->csi;
130
131 sym = symbol_lookup_in_csi(prog, base_csi, taccess->member_name);
132 if (sym == NULL) {
133 cspan_print(taccess->member_name->cspan);
134 printf(" Error: CSI '");
135 symbol_print_fqn(csi_to_symbol(base_csi));
136 printf("' has no member named '%s'.\n",
137 strtab_get_str(taccess->member_name->sid));
138 *res = tdata_item_new(tic_ignore);
139 return;
140 }
141
142 switch (sym->sc) {
143 case sc_csi:
144 /* Construct type item. */
145 titem = tdata_item_new(tic_tobject);
146 tobject = tdata_object_new();
147 titem->u.tobject = tobject;
148
149 tobject->static_ref = sn_nonstatic;
150 tobject->csi = sym->u.csi;
151 list_init(&tobject->targs);
152 break;
153 case sc_ctor:
154 /* It is not possible to reference a constructor explicitly. */
155 assert(b_false);
156 case sc_deleg:
157 /* Fetch stored delegate type. */
158 deleg = symbol_to_deleg(sym);
159 assert(deleg != NULL);
160 if (deleg->titem == NULL) {
161 /*
162 * Prepare a partial delegate which will be completed
163 * later.
164 */
165 titem = tdata_item_new(tic_tdeleg);
166 tdeleg = tdata_deleg_new();
167 titem->u.tdeleg = tdeleg;
168 tdeleg->deleg = deleg;
169 tdeleg->tsig = NULL;
170
171 deleg->titem = titem;
172 } else {
173 titem = deleg->titem;
174 }
175 break;
176 case sc_enum:
177 /* Fetch stored enum type. */
178 enum_d = symbol_to_enum(sym);
179 assert(enum_d != NULL);
180 if (enum_d->titem == NULL) {
181 /*
182 * Prepare a partial enum whic will be completed
183 * later.
184 */
185 titem = tdata_item_new(tic_tenum);
186 tenum = tdata_enum_new();
187 titem->u.tenum = tenum;
188 tenum->enum_d = enum_d;
189 } else {
190 titem = enum_d->titem;
191 }
192 break;
193 case sc_fun:
194 case sc_var:
195 case sc_prop:
196 cspan_print(taccess->member_name->cspan);
197 printf(" Error: Symbol '");
198 symbol_print_fqn(sym);
199 printf("' is not a type.\n");
200 titem = tdata_item_new(tic_ignore);
201 break;
202 }
203
204 *res = titem;
205}
206
207/** Evaluate type indexing expression.
208 *
209 * Evaluate operation per the type indexing ('[', ']') operator.
210 * A type indexing operation may have extents specified or only rank
211 * specified.
212 *
213 * @param prog Program
214 * @param ctx Current CSI (context)
215 * @param tindex Type indexing expression to evaluate
216 * @param res Place to store type result
217 */
218static void run_tindex(stree_program_t *prog, stree_csi_t *ctx,
219 stree_tindex_t *tindex, tdata_item_t **res)
220{
221 tdata_item_t *base_ti = NULL;
222 tdata_item_t *titem;
223 tdata_array_t *tarray;
224 stree_expr_t *arg_expr;
225 list_node_t *arg_node;
226
227#ifdef DEBUG_RUN_TRACE
228 printf("Evaluating type index operation.\n");
229#endif
230 /* Evaluate base type. */
231 run_texpr(prog, ctx, tindex->base_type, &base_ti);
232
233 if (base_ti->tic == tic_ignore) {
234 *res = tdata_item_new(tic_ignore);
235 return;
236 }
237
238 /* Construct type item. */
239 titem = tdata_item_new(tic_tarray);
240 tarray = tdata_array_new();
241 titem->u.tarray = tarray;
242
243 tarray->base_ti = base_ti;
244 tarray->rank = tindex->n_args;
245
246 /* Copy extents. */
247 list_init(&tarray->extents);
248 arg_node = list_first(&tindex->args);
249
250 while (arg_node != NULL) {
251 arg_expr = list_node_data(arg_node, stree_expr_t *);
252 list_append(&tarray->extents, arg_expr);
253 arg_node = list_next(&tindex->args, arg_node);
254 }
255
256 *res = titem;
257}
258
259/** Evaluate type literal expression.
260 *
261 * @param prog Program
262 * @param ctx Current CSI (context)
263 * @param tliteral Type literal
264 * @param res Place to store type result
265 */
266static void run_tliteral(stree_program_t *prog, stree_csi_t *ctx,
267 stree_tliteral_t *tliteral, tdata_item_t **res)
268{
269 tdata_item_t *titem;
270 tdata_primitive_t *tprimitive;
271 tprimitive_class_t tpc;
272
273#ifdef DEBUG_RUN_TRACE
274 printf("Evaluating type literal.\n");
275#endif
276 (void) prog;
277 (void) ctx;
278 (void) tliteral;
279
280 /* Make compiler happy. */
281 tpc = 0;
282
283 switch (tliteral->tlc) {
284 case tlc_bool: tpc = tpc_bool; break;
285 case tlc_char: tpc = tpc_char; break;
286 case tlc_int: tpc = tpc_int; break;
287 case tlc_string: tpc = tpc_string; break;
288 case tlc_resource: tpc = tpc_resource; break;
289 }
290
291 /* Construct type item. */
292 titem = tdata_item_new(tic_tprimitive);
293 tprimitive = tdata_primitive_new(tpc);
294 titem->u.tprimitive = tprimitive;
295
296 *res = titem;
297}
298
299static void run_tnameref(stree_program_t *prog, stree_csi_t *ctx,
300 stree_tnameref_t *tnameref, tdata_item_t **res)
301{
302 stree_symbol_t *sym;
303 tdata_item_t *titem;
304 tdata_object_t *tobject;
305 stree_targ_t *targ;
306 tdata_vref_t *tvref;
307 stree_deleg_t *deleg;
308 tdata_deleg_t *tdeleg;
309 stree_enum_t *enum_d;
310 tdata_enum_t *tenum;
311
312#ifdef DEBUG_RUN_TRACE
313 printf("Evaluating type name reference.\n");
314 printf("'%s'\n", strtab_get_str(tnameref->name->sid));
315#endif
316 /* In interactive mode we are not in a class */
317 if (ctx != NULL) {
318 /* Look for type argument */
319 targ = stree_csi_find_targ(ctx, tnameref->name);
320
321 if (targ != NULL) {
322 /* Found type argument */
323#ifdef DEBUG_RUN_TRACE
324 printf("Found type argument '%s'.\n",
325 strtab_get_str(tnameref->name->sid));
326#endif
327 titem = tdata_item_new(tic_tvref);
328 tvref = tdata_vref_new();
329 titem->u.tvref = tvref;
330 tvref->targ = targ;
331
332 *res = titem;
333 return;
334 }
335 }
336
337 /* Look for symbol */
338 sym = symbol_lookup_in_csi(prog, ctx, tnameref->name);
339 if (sym == NULL) {
340 cspan_print(tnameref->texpr->cspan);
341 printf(" Error: Symbol '%s' not found.\n",
342 strtab_get_str(tnameref->name->sid));
343 *res = tdata_item_new(tic_ignore);
344 return;
345 }
346
347 /* Make compiler happy. */
348 titem = NULL;
349
350 switch (sym->sc) {
351 case sc_csi:
352 /* Construct type item. */
353 titem = tdata_item_new(tic_tobject);
354 tobject = tdata_object_new();
355 titem->u.tobject = tobject;
356
357 tobject->static_ref = sn_nonstatic;
358 tobject->csi = sym->u.csi;
359 list_init(&tobject->targs);
360 break;
361 case sc_ctor:
362 /* It is not possible to reference a constructor explicitly. */
363 assert(b_false);
364 case sc_deleg:
365 /* Fetch stored delegate type. */
366 deleg = symbol_to_deleg(sym);
367 assert(deleg != NULL);
368 if (deleg->titem == NULL) {
369 /*
370 * Prepare a partial delegate which will be completed
371 * later.
372 */
373 titem = tdata_item_new(tic_tdeleg);
374 tdeleg = tdata_deleg_new();
375 titem->u.tdeleg = tdeleg;
376 tdeleg->deleg = deleg;
377 tdeleg->tsig = NULL;
378
379 deleg->titem = titem;
380 } else {
381 titem = deleg->titem;
382 }
383 break;
384 case sc_enum:
385 /* Fetch stored enum type. */
386 enum_d = symbol_to_enum(sym);
387 assert(enum_d != NULL);
388 if (enum_d->titem == NULL) {
389 /*
390 * Prepare a partial enum whic will be completed
391 * later.
392 */
393 titem = tdata_item_new(tic_tenum);
394 tenum = tdata_enum_new();
395 titem->u.tenum = tenum;
396 tenum->enum_d = enum_d;
397 } else {
398 titem = enum_d->titem;
399 }
400 break;
401 case sc_fun:
402 case sc_var:
403 case sc_prop:
404 cspan_print(tnameref->texpr->cspan);
405 printf(" Error: Symbol '");
406 symbol_print_fqn(sym);
407 printf("' is not a type.\n");
408 titem = tdata_item_new(tic_ignore);
409 break;
410 }
411
412 *res = titem;
413}
414
415/** Evaluate type application expression.
416 *
417 * In a type application expression type arguments are applied to a generic
418 * CSI.
419 *
420 * @param prog Program
421 * @param ctx Current CSI (context)
422 * @param tapply Type application expression
423 * @param res Place to store type result
424 */
425static void run_tapply(stree_program_t *prog, stree_csi_t *ctx,
426 stree_tapply_t *tapply, tdata_item_t **res)
427{
428 tdata_item_t *base_ti;
429 tdata_item_t *arg_ti;
430 tdata_item_t *titem;
431 tdata_object_t *tobject;
432
433 list_node_t *arg_n;
434 stree_texpr_t *arg;
435
436 list_node_t *farg_n;
437
438#ifdef DEBUG_RUN_TRACE
439 printf("Evaluating type apply operation.\n");
440#endif
441 /* Construct type item. */
442 titem = tdata_item_new(tic_tobject);
443 tobject = tdata_object_new();
444 titem->u.tobject = tobject;
445
446 /* Evaluate base (generic) type. */
447 run_texpr(prog, ctx, tapply->gtype, &base_ti);
448
449 if (base_ti->tic != tic_tobject) {
450 cspan_print(tapply->gtype->cspan);
451 printf(" Error: Base type of generic application is not "
452 "a CSI.\n");
453 *res = tdata_item_new(tic_ignore);
454 return;
455 }
456
457 tobject->static_ref = sn_nonstatic;
458 tobject->csi = base_ti->u.tobject->csi;
459 list_init(&tobject->targs);
460
461 /* Evaluate type arguments. */
462 farg_n = list_first(&tobject->csi->targ);
463 arg_n = list_first(&tapply->targs);
464 while (farg_n != NULL && arg_n != NULL) {
465 arg = list_node_data(arg_n, stree_texpr_t *);
466
467 run_texpr(prog, ctx, arg, &arg_ti);
468
469 if (arg_ti->tic == tic_ignore) {
470 *res = tdata_item_new(tic_ignore);
471 return;
472 }
473
474 list_append(&tobject->targs, arg_ti);
475
476 farg_n = list_next(&tobject->csi->targ, farg_n);
477 arg_n = list_next(&tapply->targs, arg_n);
478 }
479
480 if (farg_n != NULL || arg_n != NULL) {
481 cspan_print(tapply->texpr->cspan);
482 printf(" Error: Incorrect number of type arguments.\n");
483 *res = tdata_item_new(tic_ignore);
484 return;
485 }
486
487 *res = titem;
488}
Note: See TracBrowser for help on using the repository browser.