2 * Copyright (c) 2010 Jiri Svoboda
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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.
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.
29 /** @file Evaluate type expressions. */
42 #include "run_texpr.h"
44 static void run_taccess(stree_program_t
*prog
, stree_csi_t
*ctx
,
45 stree_taccess_t
*taccess
, tdata_item_t
**res
);
46 static void run_tindex(stree_program_t
*prog
, stree_csi_t
*ctx
,
47 stree_tindex_t
*tindex
, tdata_item_t
**res
);
48 static void run_tliteral(stree_program_t
*prog
, stree_csi_t
*ctx
,
49 stree_tliteral_t
*tliteral
, tdata_item_t
**res
);
50 static void run_tnameref(stree_program_t
*prog
, stree_csi_t
*ctx
,
51 stree_tnameref_t
*tnameref
, tdata_item_t
**res
);
52 static void run_tapply(stree_program_t
*prog
, stree_csi_t
*ctx
,
53 stree_tapply_t
*tapply
, tdata_item_t
**res
);
55 /** Evaluate type expression.
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.
61 * @param ctx Current CSI (context)
62 * @param texpr Type expression to evaluate
63 * @param res Place to store type result
65 void run_texpr(stree_program_t
*prog
, stree_csi_t
*ctx
, stree_texpr_t
*texpr
,
70 run_taccess(prog
, ctx
, texpr
->u
.taccess
, res
);
73 run_tindex(prog
, ctx
, texpr
->u
.tindex
, res
);
76 run_tliteral(prog
, ctx
, texpr
->u
.tliteral
, res
);
79 run_tnameref(prog
, ctx
, texpr
->u
.tnameref
, res
);
82 run_tapply(prog
, ctx
, texpr
->u
.tapply
, res
);
87 /** Evaluate type access expression.
89 * Evaluate operation per the type access ('.') operator.
92 * @param ctx Current CSI (context)
93 * @param taccess Type access expression to evaluate
94 * @param res Place to store type result
96 static void run_taccess(stree_program_t
*prog
, stree_csi_t
*ctx
,
97 stree_taccess_t
*taccess
, tdata_item_t
**res
)
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
;
109 #ifdef DEBUG_RUN_TRACE
110 printf("Evaluating type access operation.\n");
112 /* Evaluate base type. */
113 run_texpr(prog
, ctx
, taccess
->arg
, &targ_i
);
115 if (targ_i
->tic
== tic_ignore
) {
116 *res
= tdata_item_new(tic_ignore
);
120 if (targ_i
->tic
!= tic_tobject
) {
121 cspan_print(taccess
->texpr
->cspan
);
122 printf(" Error: Using '.' with type which is not an "
124 *res
= tdata_item_new(tic_ignore
);
129 base_csi
= targ_i
->u
.tobject
->csi
;
131 sym
= symbol_lookup_in_csi(prog
, base_csi
, taccess
->member_name
);
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
);
144 /* Construct type item. */
145 titem
= tdata_item_new(tic_tobject
);
146 tobject
= tdata_object_new();
147 titem
->u
.tobject
= tobject
;
149 tobject
->static_ref
= sn_nonstatic
;
150 tobject
->csi
= sym
->u
.csi
;
151 list_init(&tobject
->targs
);
154 /* It is not possible to reference a constructor explicitly. */
158 /* Fetch stored delegate type. */
159 deleg
= symbol_to_deleg(sym
);
160 assert(deleg
!= NULL
);
161 if (deleg
->titem
== NULL
) {
163 * Prepare a partial delegate which will be completed
166 titem
= tdata_item_new(tic_tdeleg
);
167 tdeleg
= tdata_deleg_new();
168 titem
->u
.tdeleg
= tdeleg
;
169 tdeleg
->deleg
= deleg
;
172 deleg
->titem
= titem
;
174 titem
= deleg
->titem
;
178 /* Fetch stored enum type. */
179 enum_d
= symbol_to_enum(sym
);
180 assert(enum_d
!= NULL
);
181 if (enum_d
->titem
== NULL
) {
183 * Prepare a partial enum whic will be completed
186 titem
= tdata_item_new(tic_tenum
);
187 tenum
= tdata_enum_new();
188 titem
->u
.tenum
= tenum
;
189 tenum
->enum_d
= enum_d
;
191 titem
= enum_d
->titem
;
197 cspan_print(taccess
->member_name
->cspan
);
198 printf(" Error: Symbol '");
199 symbol_print_fqn(sym
);
200 printf("' is not a type.\n");
201 titem
= tdata_item_new(tic_ignore
);
208 /** Evaluate type indexing expression.
210 * Evaluate operation per the type indexing ('[', ']') operator.
211 * A type indexing operation may have extents specified or only rank
214 * @param prog Program
215 * @param ctx Current CSI (context)
216 * @param tindex Type indexing expression to evaluate
217 * @param res Place to store type result
219 static void run_tindex(stree_program_t
*prog
, stree_csi_t
*ctx
,
220 stree_tindex_t
*tindex
, tdata_item_t
**res
)
222 tdata_item_t
*base_ti
= NULL
;
224 tdata_array_t
*tarray
;
225 stree_expr_t
*arg_expr
;
226 list_node_t
*arg_node
;
228 #ifdef DEBUG_RUN_TRACE
229 printf("Evaluating type index operation.\n");
231 /* Evaluate base type. */
232 run_texpr(prog
, ctx
, tindex
->base_type
, &base_ti
);
234 if (base_ti
->tic
== tic_ignore
) {
235 *res
= tdata_item_new(tic_ignore
);
239 /* Construct type item. */
240 titem
= tdata_item_new(tic_tarray
);
241 tarray
= tdata_array_new();
242 titem
->u
.tarray
= tarray
;
244 tarray
->base_ti
= base_ti
;
245 tarray
->rank
= tindex
->n_args
;
248 list_init(&tarray
->extents
);
249 arg_node
= list_first(&tindex
->args
);
251 while (arg_node
!= NULL
) {
252 arg_expr
= list_node_data(arg_node
, stree_expr_t
*);
253 list_append(&tarray
->extents
, arg_expr
);
254 arg_node
= list_next(&tindex
->args
, arg_node
);
260 /** Evaluate type literal expression.
262 * @param prog Program
263 * @param ctx Current CSI (context)
264 * @param tliteral Type literal
265 * @param res Place to store type result
267 static void run_tliteral(stree_program_t
*prog
, stree_csi_t
*ctx
,
268 stree_tliteral_t
*tliteral
, tdata_item_t
**res
)
271 tdata_primitive_t
*tprimitive
;
272 tprimitive_class_t tpc
;
274 #ifdef DEBUG_RUN_TRACE
275 printf("Evaluating type literal.\n");
281 /* Make compiler happy. */
284 switch (tliteral
->tlc
) {
302 /* Construct type item. */
303 titem
= tdata_item_new(tic_tprimitive
);
304 tprimitive
= tdata_primitive_new(tpc
);
305 titem
->u
.tprimitive
= tprimitive
;
310 static void run_tnameref(stree_program_t
*prog
, stree_csi_t
*ctx
,
311 stree_tnameref_t
*tnameref
, tdata_item_t
**res
)
315 tdata_object_t
*tobject
;
318 stree_deleg_t
*deleg
;
319 tdata_deleg_t
*tdeleg
;
320 stree_enum_t
*enum_d
;
323 #ifdef DEBUG_RUN_TRACE
324 printf("Evaluating type name reference.\n");
325 printf("'%s'\n", strtab_get_str(tnameref
->name
->sid
));
327 /* In interactive mode we are not in a class */
329 /* Look for type argument */
330 targ
= stree_csi_find_targ(ctx
, tnameref
->name
);
333 /* Found type argument */
334 #ifdef DEBUG_RUN_TRACE
335 printf("Found type argument '%s'.\n",
336 strtab_get_str(tnameref
->name
->sid
));
338 titem
= tdata_item_new(tic_tvref
);
339 tvref
= tdata_vref_new();
340 titem
->u
.tvref
= tvref
;
348 /* Look for symbol */
349 sym
= symbol_lookup_in_csi(prog
, ctx
, tnameref
->name
);
351 cspan_print(tnameref
->texpr
->cspan
);
352 printf(" Error: Symbol '%s' not found.\n",
353 strtab_get_str(tnameref
->name
->sid
));
354 *res
= tdata_item_new(tic_ignore
);
358 /* Make compiler happy. */
363 /* Construct type item. */
364 titem
= tdata_item_new(tic_tobject
);
365 tobject
= tdata_object_new();
366 titem
->u
.tobject
= tobject
;
368 tobject
->static_ref
= sn_nonstatic
;
369 tobject
->csi
= sym
->u
.csi
;
370 list_init(&tobject
->targs
);
373 /* It is not possible to reference a constructor explicitly. */
377 /* Fetch stored delegate type. */
378 deleg
= symbol_to_deleg(sym
);
379 assert(deleg
!= NULL
);
380 if (deleg
->titem
== NULL
) {
382 * Prepare a partial delegate which will be completed
385 titem
= tdata_item_new(tic_tdeleg
);
386 tdeleg
= tdata_deleg_new();
387 titem
->u
.tdeleg
= tdeleg
;
388 tdeleg
->deleg
= deleg
;
391 deleg
->titem
= titem
;
393 titem
= deleg
->titem
;
397 /* Fetch stored enum type. */
398 enum_d
= symbol_to_enum(sym
);
399 assert(enum_d
!= NULL
);
400 if (enum_d
->titem
== NULL
) {
402 * Prepare a partial enum whic will be completed
405 titem
= tdata_item_new(tic_tenum
);
406 tenum
= tdata_enum_new();
407 titem
->u
.tenum
= tenum
;
408 tenum
->enum_d
= enum_d
;
410 titem
= enum_d
->titem
;
416 cspan_print(tnameref
->texpr
->cspan
);
417 printf(" Error: Symbol '");
418 symbol_print_fqn(sym
);
419 printf("' is not a type.\n");
420 titem
= tdata_item_new(tic_ignore
);
427 /** Evaluate type application expression.
429 * In a type application expression type arguments are applied to a generic
432 * @param prog Program
433 * @param ctx Current CSI (context)
434 * @param tapply Type application expression
435 * @param res Place to store type result
437 static void run_tapply(stree_program_t
*prog
, stree_csi_t
*ctx
,
438 stree_tapply_t
*tapply
, tdata_item_t
**res
)
440 tdata_item_t
*base_ti
;
441 tdata_item_t
*arg_ti
;
443 tdata_object_t
*tobject
;
450 #ifdef DEBUG_RUN_TRACE
451 printf("Evaluating type apply operation.\n");
453 /* Construct type item. */
454 titem
= tdata_item_new(tic_tobject
);
455 tobject
= tdata_object_new();
456 titem
->u
.tobject
= tobject
;
458 /* Evaluate base (generic) type. */
459 run_texpr(prog
, ctx
, tapply
->gtype
, &base_ti
);
461 if (base_ti
->tic
!= tic_tobject
) {
462 cspan_print(tapply
->gtype
->cspan
);
463 printf(" Error: Base type of generic application is not "
465 *res
= tdata_item_new(tic_ignore
);
469 tobject
->static_ref
= sn_nonstatic
;
470 tobject
->csi
= base_ti
->u
.tobject
->csi
;
471 list_init(&tobject
->targs
);
473 /* Evaluate type arguments. */
474 farg_n
= list_first(&tobject
->csi
->targ
);
475 arg_n
= list_first(&tapply
->targs
);
476 while (farg_n
!= NULL
&& arg_n
!= NULL
) {
477 arg
= list_node_data(arg_n
, stree_texpr_t
*);
479 run_texpr(prog
, ctx
, arg
, &arg_ti
);
481 if (arg_ti
->tic
== tic_ignore
) {
482 *res
= tdata_item_new(tic_ignore
);
486 list_append(&tobject
->targs
, arg_ti
);
488 farg_n
= list_next(&tobject
->csi
->targ
, farg_n
);
489 arg_n
= list_next(&tapply
->targs
, arg_n
);
492 if (farg_n
!= NULL
|| arg_n
!= NULL
) {
493 cspan_print(tapply
->texpr
->cspan
);
494 printf(" Error: Incorrect number of type arguments.\n");
495 *res
= tdata_item_new(tic_ignore
);