source: mainline/uspace/app/sbi/src/run_texpr.c@ 6c1315b

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

Update SBI to rev. 291.

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