00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00031 #include <assert.h>
00032 #include <stdlib.h>
00033 #include "cspan.h"
00034 #include "debug.h"
00035 #include "list.h"
00036 #include "mytypes.h"
00037 #include "stree.h"
00038 #include "strtab.h"
00039 #include "symbol.h"
00040 #include "tdata.h"
00041
00042 #include "run_texpr.h"
00043
00044 static void run_taccess(stree_program_t *prog, stree_csi_t *ctx,
00045 stree_taccess_t *taccess, tdata_item_t **res);
00046 static void run_tindex(stree_program_t *prog, stree_csi_t *ctx,
00047 stree_tindex_t *tindex, tdata_item_t **res);
00048 static void run_tliteral(stree_program_t *prog, stree_csi_t *ctx,
00049 stree_tliteral_t *tliteral, tdata_item_t **res);
00050 static void run_tnameref(stree_program_t *prog, stree_csi_t *ctx,
00051 stree_tnameref_t *tnameref, tdata_item_t **res);
00052 static void run_tapply(stree_program_t *prog, stree_csi_t *ctx,
00053 stree_tapply_t *tapply, tdata_item_t **res);
00054
00065 void run_texpr(stree_program_t *prog, stree_csi_t *ctx, stree_texpr_t *texpr,
00066 tdata_item_t **res)
00067 {
00068 switch (texpr->tc) {
00069 case tc_taccess:
00070 run_taccess(prog, ctx, texpr->u.taccess, res);
00071 break;
00072 case tc_tindex:
00073 run_tindex(prog, ctx, texpr->u.tindex, res);
00074 break;
00075 case tc_tliteral:
00076 run_tliteral(prog, ctx, texpr->u.tliteral, res);
00077 break;
00078 case tc_tnameref:
00079 run_tnameref(prog, ctx, texpr->u.tnameref, res);
00080 break;
00081 case tc_tapply:
00082 run_tapply(prog, ctx, texpr->u.tapply, res);
00083 break;
00084 }
00085 }
00086
00096 static void run_taccess(stree_program_t *prog, stree_csi_t *ctx,
00097 stree_taccess_t *taccess, tdata_item_t **res)
00098 {
00099 stree_symbol_t *sym;
00100 tdata_item_t *targ_i;
00101 tdata_item_t *titem;
00102 tdata_object_t *tobject;
00103 tdata_deleg_t *tdeleg;
00104 stree_csi_t *base_csi;
00105 stree_deleg_t *deleg;
00106 stree_enum_t *enum_d;
00107 tdata_enum_t *tenum;
00108
00109 #ifdef DEBUG_RUN_TRACE
00110 printf("Evaluating type access operation.\n");
00111 #endif
00112
00113 run_texpr(prog, ctx, taccess->arg, &targ_i);
00114
00115 if (targ_i->tic == tic_ignore) {
00116 *res = tdata_item_new(tic_ignore);
00117 return;
00118 }
00119
00120 if (targ_i->tic != tic_tobject) {
00121 cspan_print(taccess->texpr->cspan);
00122 printf(" Error: Using '.' with type which is not an "
00123 "object.\n");
00124 *res = tdata_item_new(tic_ignore);
00125 return;
00126 }
00127
00128
00129 base_csi = targ_i->u.tobject->csi;
00130
00131 sym = symbol_lookup_in_csi(prog, base_csi, taccess->member_name);
00132 if (sym == NULL) {
00133 cspan_print(taccess->member_name->cspan);
00134 printf(" Error: CSI '");
00135 symbol_print_fqn(csi_to_symbol(base_csi));
00136 printf("' has no member named '%s'.\n",
00137 strtab_get_str(taccess->member_name->sid));
00138 *res = tdata_item_new(tic_ignore);
00139 return;
00140 }
00141
00142
00143 titem = NULL;
00144
00145 switch (sym->sc) {
00146 case sc_csi:
00147
00148 titem = tdata_item_new(tic_tobject);
00149 tobject = tdata_object_new();
00150 titem->u.tobject = tobject;
00151
00152 tobject->static_ref = sn_nonstatic;
00153 tobject->csi = sym->u.csi;
00154 list_init(&tobject->targs);
00155 break;
00156 case sc_ctor:
00157
00158 assert(b_false);
00159 case sc_deleg:
00160
00161 deleg = symbol_to_deleg(sym);
00162 assert(deleg != NULL);
00163 if (deleg->titem == NULL) {
00164
00165
00166
00167
00168 titem = tdata_item_new(tic_tdeleg);
00169 tdeleg = tdata_deleg_new();
00170 titem->u.tdeleg = tdeleg;
00171 tdeleg->deleg = deleg;
00172 tdeleg->tsig = NULL;
00173
00174 deleg->titem = titem;
00175 } else {
00176 titem = deleg->titem;
00177 }
00178 break;
00179 case sc_enum:
00180
00181 enum_d = symbol_to_enum(sym);
00182 assert(enum_d != NULL);
00183 if (enum_d->titem == NULL) {
00184
00185
00186
00187
00188 titem = tdata_item_new(tic_tenum);
00189 tenum = tdata_enum_new();
00190 titem->u.tenum = tenum;
00191 tenum->enum_d = enum_d;
00192 } else {
00193 titem = enum_d->titem;
00194 }
00195 break;
00196 case sc_fun:
00197 case sc_var:
00198 case sc_prop:
00199 cspan_print(taccess->member_name->cspan);
00200 printf(" Error: Symbol '");
00201 symbol_print_fqn(sym);
00202 printf("' is not a type.\n");
00203 titem = tdata_item_new(tic_ignore);
00204 break;
00205 }
00206
00207 *res = titem;
00208 }
00209
00221 static void run_tindex(stree_program_t *prog, stree_csi_t *ctx,
00222 stree_tindex_t *tindex, tdata_item_t **res)
00223 {
00224 tdata_item_t *base_ti;
00225 tdata_item_t *titem;
00226 tdata_array_t *tarray;
00227 stree_expr_t *arg_expr;
00228 list_node_t *arg_node;
00229
00230 #ifdef DEBUG_RUN_TRACE
00231 printf("Evaluating type index operation.\n");
00232 #endif
00233
00234 run_texpr(prog, ctx, tindex->base_type, &base_ti);
00235
00236 if (base_ti->tic == tic_ignore) {
00237 *res = tdata_item_new(tic_ignore);
00238 return;
00239 }
00240
00241
00242 titem = tdata_item_new(tic_tarray);
00243 tarray = tdata_array_new();
00244 titem->u.tarray = tarray;
00245
00246 tarray->base_ti = base_ti;
00247 tarray->rank = tindex->n_args;
00248
00249
00250 list_init(&tarray->extents);
00251 arg_node = list_first(&tindex->args);
00252
00253 while (arg_node != NULL) {
00254 arg_expr = list_node_data(arg_node, stree_expr_t *);
00255 list_append(&tarray->extents, arg_expr);
00256 arg_node = list_next(&tindex->args, arg_node);
00257 }
00258
00259 *res = titem;
00260 }
00261
00269 static void run_tliteral(stree_program_t *prog, stree_csi_t *ctx,
00270 stree_tliteral_t *tliteral, tdata_item_t **res)
00271 {
00272 tdata_item_t *titem;
00273 tdata_primitive_t *tprimitive;
00274 tprimitive_class_t tpc;
00275
00276 #ifdef DEBUG_RUN_TRACE
00277 printf("Evaluating type literal.\n");
00278 #endif
00279 (void) prog;
00280 (void) ctx;
00281 (void) tliteral;
00282
00283
00284 tpc = 0;
00285
00286 switch (tliteral->tlc) {
00287 case tlc_bool: tpc = tpc_bool; break;
00288 case tlc_char: tpc = tpc_char; break;
00289 case tlc_int: tpc = tpc_int; break;
00290 case tlc_string: tpc = tpc_string; break;
00291 case tlc_resource: tpc = tpc_resource; break;
00292 }
00293
00294
00295 titem = tdata_item_new(tic_tprimitive);
00296 tprimitive = tdata_primitive_new(tpc);
00297 titem->u.tprimitive = tprimitive;
00298
00299 *res = titem;
00300 }
00301
00302 static void run_tnameref(stree_program_t *prog, stree_csi_t *ctx,
00303 stree_tnameref_t *tnameref, tdata_item_t **res)
00304 {
00305 stree_symbol_t *sym;
00306 tdata_item_t *titem;
00307 tdata_object_t *tobject;
00308 stree_targ_t *targ;
00309 tdata_vref_t *tvref;
00310 stree_deleg_t *deleg;
00311 tdata_deleg_t *tdeleg;
00312 stree_enum_t *enum_d;
00313 tdata_enum_t *tenum;
00314
00315 #ifdef DEBUG_RUN_TRACE
00316 printf("Evaluating type name reference.\n");
00317 printf("'%s'\n", strtab_get_str(tnameref->name->sid));
00318 #endif
00319
00320 if (ctx != NULL) {
00321
00322 targ = stree_csi_find_targ(ctx, tnameref->name);
00323
00324 if (targ != NULL) {
00325
00326 #ifdef DEBUG_RUN_TRACE
00327 printf("Found type argument '%s'.\n",
00328 strtab_get_str(tnameref->name->sid));
00329 #endif
00330 titem = tdata_item_new(tic_tvref);
00331 tvref = tdata_vref_new();
00332 titem->u.tvref = tvref;
00333 tvref->targ = targ;
00334
00335 *res = titem;
00336 return;
00337 }
00338 }
00339
00340
00341 sym = symbol_lookup_in_csi(prog, ctx, tnameref->name);
00342 if (sym == NULL) {
00343 cspan_print(tnameref->texpr->cspan);
00344 printf(" Error: Symbol '%s' not found.\n",
00345 strtab_get_str(tnameref->name->sid));
00346 *res = tdata_item_new(tic_ignore);
00347 return;
00348 }
00349
00350
00351 titem = NULL;
00352
00353 switch (sym->sc) {
00354 case sc_csi:
00355
00356 titem = tdata_item_new(tic_tobject);
00357 tobject = tdata_object_new();
00358 titem->u.tobject = tobject;
00359
00360 tobject->static_ref = sn_nonstatic;
00361 tobject->csi = sym->u.csi;
00362 list_init(&tobject->targs);
00363 break;
00364 case sc_ctor:
00365
00366 assert(b_false);
00367 case sc_deleg:
00368
00369 deleg = symbol_to_deleg(sym);
00370 assert(deleg != NULL);
00371 if (deleg->titem == NULL) {
00372
00373
00374
00375
00376 titem = tdata_item_new(tic_tdeleg);
00377 tdeleg = tdata_deleg_new();
00378 titem->u.tdeleg = tdeleg;
00379 tdeleg->deleg = deleg;
00380 tdeleg->tsig = NULL;
00381
00382 deleg->titem = titem;
00383 } else {
00384 titem = deleg->titem;
00385 }
00386 break;
00387 case sc_enum:
00388
00389 enum_d = symbol_to_enum(sym);
00390 assert(enum_d != NULL);
00391 if (enum_d->titem == NULL) {
00392
00393
00394
00395
00396 titem = tdata_item_new(tic_tenum);
00397 tenum = tdata_enum_new();
00398 titem->u.tenum = tenum;
00399 tenum->enum_d = enum_d;
00400 } else {
00401 titem = enum_d->titem;
00402 }
00403 break;
00404 case sc_fun:
00405 case sc_var:
00406 case sc_prop:
00407 cspan_print(tnameref->texpr->cspan);
00408 printf(" Error: Symbol '");
00409 symbol_print_fqn(sym);
00410 printf("' is not a type.\n");
00411 titem = tdata_item_new(tic_ignore);
00412 break;
00413 }
00414
00415 *res = titem;
00416 }
00417
00428 static void run_tapply(stree_program_t *prog, stree_csi_t *ctx,
00429 stree_tapply_t *tapply, tdata_item_t **res)
00430 {
00431 tdata_item_t *base_ti;
00432 tdata_item_t *arg_ti;
00433 tdata_item_t *titem;
00434 tdata_object_t *tobject;
00435
00436 list_node_t *arg_n;
00437 stree_texpr_t *arg;
00438
00439 list_node_t *farg_n;
00440
00441 #ifdef DEBUG_RUN_TRACE
00442 printf("Evaluating type apply operation.\n");
00443 #endif
00444
00445 titem = tdata_item_new(tic_tobject);
00446 tobject = tdata_object_new();
00447 titem->u.tobject = tobject;
00448
00449
00450 run_texpr(prog, ctx, tapply->gtype, &base_ti);
00451
00452 if (base_ti->tic != tic_tobject) {
00453 cspan_print(tapply->gtype->cspan);
00454 printf(" Error: Base type of generic application is not "
00455 "a CSI.\n");
00456 *res = tdata_item_new(tic_ignore);
00457 return;
00458 }
00459
00460 tobject->static_ref = sn_nonstatic;
00461 tobject->csi = base_ti->u.tobject->csi;
00462 list_init(&tobject->targs);
00463
00464
00465 farg_n = list_first(&tobject->csi->targ);
00466 arg_n = list_first(&tapply->targs);
00467 while (farg_n != NULL && arg_n != NULL) {
00468 arg = list_node_data(arg_n, stree_texpr_t *);
00469
00470 run_texpr(prog, ctx, arg, &arg_ti);
00471
00472 if (arg_ti->tic == tic_ignore) {
00473 *res = tdata_item_new(tic_ignore);
00474 return;
00475 }
00476
00477 list_append(&tobject->targs, arg_ti);
00478
00479 farg_n = list_next(&tobject->csi->targ, farg_n);
00480 arg_n = list_next(&tapply->targs, arg_n);
00481 }
00482
00483 if (farg_n != NULL || arg_n != NULL) {
00484 cspan_print(tapply->texpr->cspan);
00485 printf(" Error: Incorrect number of type arguments.\n");
00486 *res = tdata_item_new(tic_ignore);
00487 return;
00488 }
00489
00490 *res = titem;
00491 }