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
00045 #include <stdio.h>
00046 #include <stdlib.h>
00047 #include <assert.h>
00048 #include "cspan.h"
00049 #include "debug.h"
00050 #include "list.h"
00051 #include "mytypes.h"
00052 #include "run_texpr.h"
00053 #include "stree.h"
00054 #include "strtab.h"
00055 #include "stype.h"
00056 #include "symbol.h"
00057 #include "tdata.h"
00058
00059 #include "stype_expr.h"
00060
00061 static void stype_nameref(stype_t *stype, stree_nameref_t *nameref,
00062 tdata_item_t **rtitem);
00063 static void stype_literal(stype_t *stype, stree_literal_t *literal,
00064 tdata_item_t **rtitem);
00065 static void stype_self_ref(stype_t *stype, stree_self_ref_t *self_ref,
00066 tdata_item_t **rtitem);
00067
00068 static void stype_binop(stype_t *stype, stree_binop_t *binop,
00069 tdata_item_t **rtitem);
00070
00071 static void stype_binop_tprimitive(stype_t *stype, stree_binop_t *binop,
00072 tdata_item_t *ta, tdata_item_t *tb, tdata_item_t **rtitem);
00073 static void stype_binop_bool(stype_t *stype, stree_binop_t *binop,
00074 tdata_item_t **rtitem);
00075 static void stype_binop_char(stype_t *stype, stree_binop_t *binop,
00076 tdata_item_t **rtitem);
00077 static void stype_binop_int(stype_t *stype, stree_binop_t *binop,
00078 tdata_item_t **rtitem);
00079 static void stype_binop_nil(stype_t *stype, stree_binop_t *binop,
00080 tdata_item_t **rtitem);
00081 static void stype_binop_string(stype_t *stype, stree_binop_t *binop,
00082 tdata_item_t **rtitem);
00083 static void stype_binop_resource(stype_t *stype, stree_binop_t *binop,
00084 tdata_item_t **rtitem);
00085
00086 static void stype_binop_tobject(stype_t *stype, stree_binop_t *binop,
00087 tdata_item_t *ta, tdata_item_t *tb, tdata_item_t **rtitem);
00088 static void stype_binop_tenum(stype_t *stype, stree_binop_t *binop,
00089 tdata_item_t *ta, tdata_item_t *tb, tdata_item_t **rtitem);
00090 static void stype_binop_tvref(stype_t *stype, stree_binop_t *binop,
00091 tdata_item_t *ta, tdata_item_t *tb, tdata_item_t **rtitem);
00092
00093 static void stype_unop(stype_t *stype, stree_unop_t *unop,
00094 tdata_item_t **rtitem);
00095 static void stype_unop_tprimitive(stype_t *stype, stree_unop_t *unop,
00096 tdata_item_t *ta, tdata_item_t **rtitem);
00097 static void stype_new(stype_t *stype, stree_new_t *new,
00098 tdata_item_t **rtitem);
00099 static void stype_new_object(stype_t *stype, stree_new_t *new_op,
00100 tdata_item_t *obj_ti);
00101
00102 static void stype_access(stype_t *stype, stree_access_t *access,
00103 tdata_item_t **rtitem);
00104 static void stype_access_tprimitive(stype_t *stype, stree_access_t *access,
00105 tdata_item_t *arg_ti, tdata_item_t **rtitem);
00106 static void stype_access_tobject(stype_t *stype, stree_access_t *access,
00107 tdata_item_t *arg_ti, tdata_item_t **rtitem);
00108 static void stype_access_tarray(stype_t *stype, stree_access_t *access,
00109 tdata_item_t *arg_ti, tdata_item_t **rtitem);
00110 static void stype_access_tebase(stype_t *stype, stree_access_t *access,
00111 tdata_item_t *arg_ti, tdata_item_t **rtitem);
00112
00113 static void stype_call(stype_t *stype, stree_call_t *call,
00114 tdata_item_t **rtitem);
00115 static void stype_call_args(stype_t *stype, cspan_t *cspan, list_t *farg_tis,
00116 tdata_item_t *fvarg_ti, list_t *args);
00117
00118 static void stype_index(stype_t *stype, stree_index_t *index,
00119 tdata_item_t **rtitem);
00120 static void stype_index_tprimitive(stype_t *stype, stree_index_t *index,
00121 tdata_item_t *base_ti, tdata_item_t **rtitem);
00122 static void stype_index_tobject(stype_t *stype, stree_index_t *index,
00123 tdata_item_t *base_ti, tdata_item_t **rtitem);
00124 static void stype_index_tarray(stype_t *stype, stree_index_t *index,
00125 tdata_item_t *base_ti, tdata_item_t **rtitem);
00126
00127 static void stype_assign(stype_t *stype, stree_assign_t *assign,
00128 tdata_item_t **rtitem);
00129 static void stype_as(stype_t *stype, stree_as_t *as_op, tdata_item_t **rtitem);
00130 static void stype_box(stype_t *stype, stree_box_t *box, tdata_item_t **rtitem);
00131
00132
00141 void stype_expr(stype_t *stype, stree_expr_t *expr)
00142 {
00143 tdata_item_t *et;
00144
00145 #ifdef DEBUG_TYPE_TRACE
00146 cspan_print(expr->cspan);
00147 printf(" Type expression.\n");
00148 #endif
00149
00150 et = NULL;
00151
00152 switch (expr->ec) {
00153 case ec_nameref: stype_nameref(stype, expr->u.nameref, &et); break;
00154 case ec_literal: stype_literal(stype, expr->u.literal, &et); break;
00155 case ec_self_ref: stype_self_ref(stype, expr->u.self_ref, &et); break;
00156 case ec_binop: stype_binop(stype, expr->u.binop, &et); break;
00157 case ec_unop: stype_unop(stype, expr->u.unop, &et); break;
00158 case ec_new: stype_new(stype, expr->u.new_op, &et); break;
00159 case ec_access: stype_access(stype, expr->u.access, &et); break;
00160 case ec_call: stype_call(stype, expr->u.call, &et); break;
00161 case ec_index: stype_index(stype, expr->u.index, &et); break;
00162 case ec_assign: stype_assign(stype, expr->u.assign, &et); break;
00163 case ec_as: stype_as(stype, expr->u.as_op, &et); break;
00164 case ec_box: stype_box(stype, expr->u.box, &et); break;
00165 }
00166
00167 expr->titem = et;
00168
00169 #ifdef DEBUG_TYPE_TRACE
00170 cspan_print(expr->cspan);
00171 printf(" Expression type is '");
00172 tdata_item_print(et);
00173 printf("'.\n");
00174 #endif
00175 }
00176
00183 static void stype_nameref(stype_t *stype, stree_nameref_t *nameref,
00184 tdata_item_t **rtitem)
00185 {
00186 stree_symbol_t *sym;
00187 stree_vdecl_t *vdecl;
00188 stree_proc_arg_t *proc_arg;
00189 tdata_item_t *titem;
00190 tdata_object_t *tobject;
00191 stree_csi_t *csi;
00192 stree_deleg_t *deleg;
00193 stree_enum_t *enum_d;
00194 tdata_ebase_t *tebase;
00195 stree_fun_t *fun;
00196 bool_t static_ctx;
00197
00198 #ifdef DEBUG_TYPE_TRACE
00199 cspan_print(nameref->expr->cspan);
00200 printf(" Evaluate type of name reference '%s'.\n",
00201 strtab_get_str(nameref->name->sid));
00202 #endif
00203
00204
00205
00206
00207 vdecl = stype_local_vars_lookup(stype, nameref->name->sid);
00208 if (vdecl != NULL) {
00209
00210 #ifdef DEBUG_RUN_TRACE
00211 printf("Found local variable declaration.\n");
00212 #endif
00213 run_texpr(stype->program, stype->current_csi, vdecl->type,
00214 &titem);
00215 *rtitem = titem;
00216 return;
00217 }
00218
00219
00220
00221
00222
00223 proc_arg = stype_proc_args_lookup(stype, nameref->name->sid);
00224 if (proc_arg != NULL) {
00225
00226 #ifdef DEBUG_RUN_TRACE
00227 printf("Found procedure argument.\n");
00228 #endif
00229 run_texpr(stype->program, stype->current_csi, proc_arg->type,
00230 &titem);
00231 *rtitem = titem;
00232 return;
00233 }
00234
00235
00236
00237
00238
00239 sym = symbol_lookup_in_csi(stype->program, stype->current_csi,
00240 nameref->name);
00241
00242 if (sym == NULL) {
00243
00244 if (stype->current_csi != NULL) {
00245 cspan_print(nameref->expr->cspan);
00246 printf(" Error: Symbol '%s' not found in '",
00247 strtab_get_str(nameref->name->sid));
00248 symbol_print_fqn(csi_to_symbol(stype->current_csi));
00249 printf("'.\n");
00250 } else {
00251 cspan_print(nameref->expr->cspan);
00252 printf(" Error: Symbol '%s' not found.\n",
00253 strtab_get_str(nameref->name->sid));
00254 }
00255 stype_note_error(stype);
00256 *rtitem = stype_recovery_titem(stype);
00257 return;
00258 }
00259
00260
00261 static_ctx = stree_symbol_is_static(stype->proc_vr->proc->outer_symbol);
00262
00263
00264
00265
00266
00267 if (sym->outer_csi != stype->current_csi)
00268 static_ctx = b_true;
00269
00270
00271 if (static_ctx && !stree_symbol_is_static(sym)) {
00272 cspan_print(nameref->expr->cspan);
00273 printf(" Error: Referencing non-static symbol '");
00274 symbol_print_fqn(sym);
00275 printf("' in static context.\n");
00276 stype_note_error(stype);
00277 *rtitem = stype_recovery_titem(stype);
00278 return;
00279 }
00280
00281
00282
00283
00284 titem = NULL;
00285
00286 switch (sym->sc) {
00287 case sc_var:
00288 run_texpr(stype->program, stype->current_csi,
00289 sym->u.var->type, &titem);
00290 break;
00291 case sc_prop:
00292
00293 stype_prop_header(stype, sym->u.prop);
00294 titem = sym->u.prop->titem;
00295 break;
00296 case sc_csi:
00297 csi = symbol_to_csi(sym);
00298 assert(csi != NULL);
00299
00300 titem = tdata_item_new(tic_tobject);
00301 tobject = tdata_object_new();
00302 titem->u.tobject = tobject;
00303
00304 tobject->static_ref = sn_static;
00305 tobject->csi = csi;
00306 break;
00307 case sc_ctor:
00308
00309 assert(b_false);
00310 case sc_deleg:
00311 deleg = symbol_to_deleg(sym);
00312 assert(deleg != NULL);
00313
00314 stype_deleg(stype, deleg);
00315 titem = deleg->titem;
00316 break;
00317 case sc_enum:
00318 enum_d = symbol_to_enum(sym);
00319 assert(enum_d != NULL);
00320
00321 titem = tdata_item_new(tic_tebase);
00322 tebase = tdata_ebase_new();
00323 titem->u.tebase = tebase;
00324
00325
00326 tebase->enum_d = enum_d;
00327 break;
00328 case sc_fun:
00329 fun = symbol_to_fun(sym);
00330 assert(fun != NULL);
00331
00332 stype_fun_header(stype, fun);
00333 titem = fun->titem;
00334 break;
00335 }
00336
00337 *rtitem = titem;
00338 }
00339
00346 static void stype_literal(stype_t *stype, stree_literal_t *literal,
00347 tdata_item_t **rtitem)
00348 {
00349 tdata_item_t *titem;
00350 tdata_primitive_t *tprimitive;
00351 tprimitive_class_t tpc;
00352
00353 #ifdef DEBUG_TYPE_TRACE
00354 cspan_print(literal->expr->cspan);
00355 printf(" Evaluate type of literal.\n");
00356 #endif
00357 (void) stype;
00358
00359
00360 tpc = 0;
00361
00362 switch (literal->ltc) {
00363 case ltc_bool: tpc = tpc_bool; break;
00364 case ltc_char: tpc = tpc_char; break;
00365 case ltc_int: tpc = tpc_int; break;
00366 case ltc_ref: tpc = tpc_nil; break;
00367 case ltc_string: tpc = tpc_string; break;
00368 }
00369
00370 titem = tdata_item_new(tic_tprimitive);
00371 tprimitive = tdata_primitive_new(tpc);
00372 titem->u.tprimitive = tprimitive;
00373
00374 *rtitem = titem;
00375 }
00376
00383 static void stype_self_ref(stype_t *stype, stree_self_ref_t *self_ref,
00384 tdata_item_t **rtitem)
00385 {
00386 stree_csi_t *cur_csi;
00387 tdata_item_t *titem;
00388 tdata_object_t *tobject;
00389
00390 #ifdef DEBUG_TYPE_TRACE
00391 cspan_print(self_ref->expr->cspan);
00392 printf(" Evaluate type of self reference.\n");
00393 #endif
00394 (void) stype;
00395 (void) self_ref;
00396
00397 cur_csi = stype->proc_vr->proc->outer_symbol->outer_csi;
00398
00399
00400 assert(cur_csi != NULL);
00401
00402
00403 titem = tdata_item_new(tic_tobject);
00404 tobject = tdata_object_new();
00405 titem->u.tobject = tobject;
00406
00407 tobject->static_ref = sn_nonstatic;
00408 tobject->csi = cur_csi;
00409 list_init(&tobject->targs);
00410
00411 *rtitem = titem;
00412 }
00413
00420 static void stype_binop(stype_t *stype, stree_binop_t *binop,
00421 tdata_item_t **rtitem)
00422 {
00423 bool_t equal;
00424 tdata_item_t *titem1, *titem2;
00425
00426 #ifdef DEBUG_TYPE_TRACE
00427 cspan_print(binop->expr->cspan);
00428 printf(" Evaluate type of binary operation.\n");
00429 #endif
00430 stype_expr(stype, binop->arg1);
00431 stype_expr(stype, binop->arg2);
00432
00433 titem1 = binop->arg1->titem;
00434 titem2 = binop->arg2->titem;
00435
00436 if (titem1 == NULL) {
00437 cspan_print(binop->arg1->cspan);
00438 printf(" Error: Binary operand has no value.\n");
00439 stype_note_error(stype);
00440 *rtitem = stype_recovery_titem(stype);
00441 return;
00442 }
00443
00444 if (titem2 == NULL) {
00445 cspan_print(binop->arg2->cspan);
00446 printf(" Error: Binary operand has no value.\n");
00447 stype_note_error(stype);
00448 *rtitem = stype_recovery_titem(stype);
00449 return;
00450 }
00451
00452 if (titem1->tic == tic_ignore || titem2->tic == tic_ignore) {
00453 *rtitem = stype_recovery_titem(stype);
00454 return;
00455 }
00456
00457 equal = tdata_item_equal(titem1, titem2);
00458 if (equal != b_true) {
00459 cspan_print(binop->expr->cspan);
00460 printf(" Error: Binary operation arguments "
00461 "have different types ('");
00462 tdata_item_print(titem1);
00463 printf("' and '");
00464 tdata_item_print(titem2);
00465 printf("').\n");
00466 stype_note_error(stype);
00467 *rtitem = stype_recovery_titem(stype);
00468 return;
00469 }
00470
00471 switch (titem1->tic) {
00472 case tic_tprimitive:
00473 stype_binop_tprimitive(stype, binop, titem1, titem2, rtitem);
00474 break;
00475 case tic_tobject:
00476 stype_binop_tobject(stype, binop, titem1, titem2, rtitem);
00477 break;
00478 case tic_tenum:
00479 stype_binop_tenum(stype, binop, titem1, titem2, rtitem);
00480 break;
00481 case tic_tvref:
00482 stype_binop_tvref(stype, binop, titem1, titem2, rtitem);
00483 break;
00484 default:
00485 cspan_print(binop->expr->cspan);
00486 printf(" Error: Binary operation on value which is not of a "
00487 "supported type (found '");
00488 tdata_item_print(titem1);
00489 printf("').\n");
00490 stype_note_error(stype);
00491 *rtitem = stype_recovery_titem(stype);
00492 break;
00493 }
00494
00495 }
00496
00505 static void stype_binop_tprimitive(stype_t *stype, stree_binop_t *binop,
00506 tdata_item_t *ta, tdata_item_t *tb, tdata_item_t **rtitem)
00507 {
00508 assert(ta->tic == tic_tprimitive);
00509 assert(tb->tic == tic_tprimitive);
00510
00511 switch (ta->u.tprimitive->tpc) {
00512 case tpc_bool:
00513 stype_binop_bool(stype, binop, rtitem);
00514 break;
00515 case tpc_char:
00516 stype_binop_char(stype, binop, rtitem);
00517 break;
00518 case tpc_int:
00519 stype_binop_int(stype, binop, rtitem);
00520 break;
00521 case tpc_nil:
00522 stype_binop_nil(stype, binop, rtitem);
00523 break;
00524 case tpc_string:
00525 stype_binop_string(stype, binop, rtitem);
00526 break;
00527 case tpc_resource:
00528 stype_binop_resource(stype, binop, rtitem);
00529 break;
00530 }
00531 }
00532
00539 static void stype_binop_bool(stype_t *stype, stree_binop_t *binop,
00540 tdata_item_t **rtitem)
00541 {
00542 tprimitive_class_t rtpc;
00543 tdata_item_t *res_ti;
00544
00545
00546 rtpc = 0;
00547
00548 switch (binop->bc) {
00549 case bo_equal:
00550 case bo_notequal:
00551 case bo_lt:
00552 case bo_gt:
00553 case bo_lt_equal:
00554 case bo_gt_equal:
00555
00556 rtpc = tpc_bool;
00557 break;
00558 case bo_plus:
00559 case bo_minus:
00560 case bo_mult:
00561
00562 cspan_print(binop->expr->cspan);
00563 printf(" Error: Binary operation (%d) on booleans.\n",
00564 binop->bc);
00565 stype_note_error(stype);
00566 *rtitem = stype_recovery_titem(stype);
00567 return;
00568 case bo_and:
00569 case bo_or:
00570
00571 rtpc = tpc_bool;
00572 break;
00573 }
00574
00575 res_ti = tdata_item_new(tic_tprimitive);
00576 res_ti->u.tprimitive = tdata_primitive_new(rtpc);
00577
00578 *rtitem = res_ti;
00579 }
00580
00587 static void stype_binop_char(stype_t *stype, stree_binop_t *binop,
00588 tdata_item_t **rtitem)
00589 {
00590 tprimitive_class_t rtpc;
00591 tdata_item_t *res_ti;
00592
00593 (void) stype;
00594
00595
00596 rtpc = 0;
00597
00598 switch (binop->bc) {
00599 case bo_equal:
00600 case bo_notequal:
00601 case bo_lt:
00602 case bo_gt:
00603 case bo_lt_equal:
00604 case bo_gt_equal:
00605
00606 rtpc = tpc_bool;
00607 break;
00608 case bo_plus:
00609 case bo_minus:
00610 case bo_mult:
00611 case bo_and:
00612 case bo_or:
00613
00614 cspan_print(binop->expr->cspan);
00615 printf(" Error: Binary operation (%d) on characters.\n",
00616 binop->bc);
00617 stype_note_error(stype);
00618 rtpc = tpc_char;
00619 break;
00620 }
00621
00622 res_ti = tdata_item_new(tic_tprimitive);
00623 res_ti->u.tprimitive = tdata_primitive_new(rtpc);
00624
00625 *rtitem = res_ti;
00626 }
00627
00634 static void stype_binop_int(stype_t *stype, stree_binop_t *binop,
00635 tdata_item_t **rtitem)
00636 {
00637 tprimitive_class_t rtpc;
00638 tdata_item_t *res_ti;
00639
00640 (void) stype;
00641
00642
00643 rtpc = 0;
00644
00645 switch (binop->bc) {
00646 case bo_equal:
00647 case bo_notequal:
00648 case bo_lt:
00649 case bo_gt:
00650 case bo_lt_equal:
00651 case bo_gt_equal:
00652
00653 rtpc = tpc_bool;
00654 break;
00655 case bo_plus:
00656 case bo_minus:
00657 case bo_mult:
00658
00659 rtpc = tpc_int;
00660 break;
00661 case bo_and:
00662 case bo_or:
00663
00664 cspan_print(binop->expr->cspan);
00665 printf(" Error: Binary operation (%d) on integers.\n",
00666 binop->bc);
00667 stype_note_error(stype);
00668 rtpc = tpc_char;
00669 break;
00670 }
00671
00672 res_ti = tdata_item_new(tic_tprimitive);
00673 res_ti->u.tprimitive = tdata_primitive_new(rtpc);
00674
00675 *rtitem = res_ti;
00676 }
00677
00684 static void stype_binop_nil(stype_t *stype, stree_binop_t *binop,
00685 tdata_item_t **rtitem)
00686 {
00687 (void) binop;
00688
00689 cspan_print(binop->expr->cspan);
00690 printf(" Unimplemented: Binary operation on nil.\n");
00691 stype_note_error(stype);
00692 *rtitem = stype_recovery_titem(stype);
00693 }
00694
00701 static void stype_binop_string(stype_t *stype, stree_binop_t *binop,
00702 tdata_item_t **rtitem)
00703 {
00704 tprimitive_class_t rtpc;
00705 tdata_item_t *res_ti;
00706
00707
00708 rtpc = 0;
00709
00710 switch (binop->bc) {
00711 case bo_equal:
00712 case bo_notequal:
00713
00714 rtpc = tpc_bool;
00715 break;
00716 case bo_plus:
00717
00718 rtpc = tpc_string;
00719 break;
00720
00721 case bo_lt:
00722 case bo_gt:
00723 case bo_lt_equal:
00724 case bo_gt_equal:
00725
00726 case bo_minus:
00727 case bo_mult:
00728 case bo_and:
00729 case bo_or:
00730
00731 cspan_print(binop->expr->cspan);
00732 printf(" Error: Binary operation (%d) on strings.\n",
00733 binop->bc);
00734 stype_note_error(stype);
00735 rtpc = tpc_char;
00736 break;
00737 }
00738
00739 res_ti = tdata_item_new(tic_tprimitive);
00740 res_ti->u.tprimitive = tdata_primitive_new(rtpc);
00741
00742 *rtitem = res_ti;
00743 }
00744
00751 static void stype_binop_resource(stype_t *stype, stree_binop_t *binop,
00752 tdata_item_t **rtitem)
00753 {
00754 tprimitive_class_t rtpc;
00755 tdata_item_t *res_ti;
00756
00757 (void) binop;
00758
00759 cspan_print(binop->expr->cspan);
00760 printf(" Error: Cannot apply operator to resource type.\n");
00761 stype_note_error(stype);
00762 rtpc = tpc_resource;
00763
00764 res_ti = tdata_item_new(tic_tprimitive);
00765 res_ti->u.tprimitive = tdata_primitive_new(rtpc);
00766
00767 *rtitem = res_ti;
00768 }
00769
00778 static void stype_binop_tobject(stype_t *stype, stree_binop_t *binop,
00779 tdata_item_t *ta, tdata_item_t *tb, tdata_item_t **rtitem)
00780 {
00781 tdata_item_t *res_ti;
00782
00783 (void) stype;
00784
00785 assert(ta->tic == tic_tobject || (ta->tic == tic_tprimitive &&
00786 ta->u.tprimitive->tpc == tpc_nil));
00787 assert(tb->tic == tic_tobject || (tb->tic == tic_tprimitive &&
00788 tb->u.tprimitive->tpc == tpc_nil));
00789
00790 switch (binop->bc) {
00791 case bo_equal:
00792 case bo_notequal:
00793
00794 res_ti = stype_boolean_titem(stype);
00795 break;
00796 default:
00797 cspan_print(binop->expr->cspan);
00798 printf(" Error: Binary operation (%d) on objects.\n",
00799 binop->bc);
00800 stype_note_error(stype);
00801 *rtitem = stype_recovery_titem(stype);
00802 return;
00803 }
00804
00805 *rtitem = res_ti;
00806 }
00807
00816 static void stype_binop_tenum(stype_t *stype, stree_binop_t *binop,
00817 tdata_item_t *ta, tdata_item_t *tb, tdata_item_t **rtitem)
00818 {
00819 tdata_item_t *res_ti;
00820
00821 assert(ta->tic == tic_tenum);
00822 assert(tb->tic == tic_tenum);
00823
00824 switch (binop->bc) {
00825 case bo_equal:
00826 case bo_notequal:
00827
00828 res_ti = stype_boolean_titem(stype);
00829 break;
00830 default:
00831 cspan_print(binop->expr->cspan);
00832 printf(" Error: Binary operation (%d) on values of enum "
00833 "type.\n", binop->bc);
00834 stype_note_error(stype);
00835 *rtitem = stype_recovery_titem(stype);
00836 return;
00837 }
00838
00839 *rtitem = res_ti;
00840 }
00841
00850 static void stype_binop_tvref(stype_t *stype, stree_binop_t *binop,
00851 tdata_item_t *ta, tdata_item_t *tb, tdata_item_t **rtitem)
00852 {
00853 tdata_item_t *res_ti;
00854
00855 assert(ta->tic == tic_tvref || (ta->tic == tic_tprimitive &&
00856 ta->u.tprimitive->tpc == tpc_nil));
00857 assert(tb->tic == tic_tvref || (tb->tic == tic_tprimitive &&
00858 tb->u.tprimitive->tpc == tpc_nil));
00859
00860 switch (binop->bc) {
00861 case bo_equal:
00862 case bo_notequal:
00863
00864 res_ti = stype_boolean_titem(stype);
00865 break;
00866 default:
00867 cspan_print(binop->expr->cspan);
00868 printf(" Error: Binary operation (%d) on variable types.\n",
00869 binop->bc);
00870 stype_note_error(stype);
00871 *rtitem = stype_recovery_titem(stype);
00872 return;
00873 }
00874
00875 *rtitem = res_ti;
00876 }
00877
00884 static void stype_unop(stype_t *stype, stree_unop_t *unop,
00885 tdata_item_t **rtitem)
00886 {
00887 tdata_item_t *titem;
00888
00889 #ifdef DEBUG_TYPE_TRACE
00890 cspan_print(unop->expr->cspan);
00891 printf(" Evaluate type of unary operation.\n");
00892 #endif
00893 stype_expr(stype, unop->arg);
00894
00895 titem = unop->arg->titem;
00896 if (titem == NULL) {
00897 cspan_print(unop->arg->cspan);
00898 printf(" Error: Argument of unary operation has no value.\n");
00899 stype_note_error(stype);
00900 *rtitem = stype_recovery_titem(stype);
00901 return;
00902 }
00903
00904 if (titem->tic == tic_ignore) {
00905 *rtitem = stype_recovery_titem(stype);
00906 return;
00907 }
00908
00909 switch (titem->tic) {
00910 case tic_tprimitive:
00911 stype_unop_tprimitive(stype, unop, titem, rtitem);
00912 break;
00913 default:
00914 cspan_print(unop->arg->cspan);
00915 printf(" Error: Unary operation on value which is not of a "
00916 "supported type (found '");
00917 tdata_item_print(titem);
00918 printf("').\n");
00919 stype_note_error(stype);
00920 *rtitem = stype_recovery_titem(stype);
00921 break;
00922 }
00923 }
00924
00932 static void stype_unop_tprimitive(stype_t *stype, stree_unop_t *unop,
00933 tdata_item_t *ta, tdata_item_t **rtitem)
00934 {
00935 tprimitive_class_t rtpc;
00936 tdata_item_t *res_ti;
00937
00938 (void) stype;
00939 (void) unop;
00940
00941 assert(ta->tic == tic_tprimitive);
00942
00943 switch (ta->u.tprimitive->tpc) {
00944 case tpc_bool:
00945 rtpc = tpc_bool;
00946 break;
00947 case tpc_int:
00948 rtpc = tpc_int;
00949 break;
00950 default:
00951 cspan_print(unop->arg->cspan);
00952 printf(" Error: Unary operator applied on unsupported "
00953 "primitive type %d.\n", ta->u.tprimitive->tpc);
00954 stype_note_error(stype);
00955 *rtitem = stype_recovery_titem(stype);
00956 return;
00957 }
00958
00959 res_ti = tdata_item_new(tic_tprimitive);
00960 res_ti->u.tprimitive = tdata_primitive_new(rtpc);
00961
00962 *rtitem = res_ti;
00963 }
00964
00971 static void stype_new(stype_t *stype, stree_new_t *new_op,
00972 tdata_item_t **rtitem)
00973 {
00974 #ifdef DEBUG_TYPE_TRACE
00975 cspan_print(new_op->expr->cspan);
00976 printf("Evaluate type of 'new' operation.\n");
00977 #endif
00978
00979
00980
00981
00982 run_texpr(stype->program, stype->current_csi, new_op->texpr, rtitem);
00983
00984 if ((*rtitem)->tic == tic_ignore) {
00985
00986 stype_note_error(stype);
00987 *rtitem = stype_recovery_titem(stype);
00988 return;
00989 }
00990
00991 if ((*rtitem)->tic == tic_tobject)
00992 stype_new_object(stype, new_op, *rtitem);
00993 }
00994
01000 static void stype_new_object(stype_t *stype, stree_new_t *new_op,
01001 tdata_item_t *obj_ti)
01002 {
01003 stree_csi_t *csi;
01004 stree_ctor_t *ctor;
01005 stree_symbol_t *ctor_sym;
01006 stree_ident_t *ctor_ident;
01007 tdata_fun_sig_t *tsig;
01008 tdata_tvv_t *obj_tvv;
01009 tdata_item_t *ctor_sti;
01010
01011 assert(obj_ti->tic == tic_tobject);
01012 csi = obj_ti->u.tobject->csi;
01013
01014 if (csi->cc == csi_interface) {
01015 cspan_print(new_op->expr->cspan);
01016 printf(" Error: Cannot instantiate an interface.\n");
01017 stype_note_error(stype);
01018 return;
01019 }
01020
01021 ctor_ident = stree_ident_new();
01022 ctor_ident->sid = strtab_get_sid(CTOR_IDENT);
01023
01024
01025 ctor_sym = symbol_search_csi_no_base(stype->program, csi,
01026 ctor_ident);
01027
01028 if (ctor_sym == NULL && !list_is_empty(&new_op->ctor_args)) {
01029 cspan_print(new_op->expr->cspan);
01030 printf(" Error: Passing arguments to 'new' but no "
01031 "constructor found.\n");
01032 stype_note_error(stype);
01033 return;
01034 }
01035
01036 if (ctor_sym == NULL)
01037 return;
01038
01039 ctor = symbol_to_ctor(ctor_sym);
01040 assert(ctor != NULL);
01041
01042
01043 stype_ctor_header(stype, ctor);
01044 if (ctor->titem->tic == tic_ignore)
01045 return;
01046
01047
01048 stype_titem_to_tvv(stype, obj_ti, &obj_tvv);
01049 tdata_item_subst(ctor->titem, obj_tvv, &ctor_sti);
01050
01051
01052 assert(ctor_sti->tic == tic_tfun);
01053 tsig = ctor_sti->u.tfun->tsig;
01054
01055 stype_call_args(stype, new_op->expr->cspan, &tsig->arg_ti,
01056 tsig->varg_ti, &new_op->ctor_args);
01057 }
01058
01065 static void stype_access(stype_t *stype, stree_access_t *access,
01066 tdata_item_t **rtitem)
01067 {
01068 tdata_item_t *arg_ti;
01069
01070 #ifdef DEBUG_TYPE_TRACE
01071 cspan_print(access->expr->cspan);
01072 printf(" Evaluate type of access operation.\n");
01073 #endif
01074 stype_expr(stype, access->arg);
01075 arg_ti = access->arg->titem;
01076
01077 if (arg_ti == NULL) {
01078 cspan_print(access->arg->cspan);
01079 printf(" Error: Argument of access operation has no value.\n");
01080 stype_note_error(stype);
01081 *rtitem = stype_recovery_titem(stype);
01082 return;
01083 }
01084
01085 switch (arg_ti->tic) {
01086 case tic_tprimitive:
01087 stype_access_tprimitive(stype, access, arg_ti, rtitem);
01088 break;
01089 case tic_tobject:
01090 stype_access_tobject(stype, access, arg_ti, rtitem);
01091 break;
01092 case tic_tarray:
01093 stype_access_tarray(stype, access, arg_ti, rtitem);
01094 break;
01095 case tic_tdeleg:
01096 cspan_print(access->arg->cspan);
01097 printf(" Error: Using '.' operator on a delegate.\n");
01098 stype_note_error(stype);
01099 *rtitem = stype_recovery_titem(stype);
01100 break;
01101 case tic_tebase:
01102 stype_access_tebase(stype, access, arg_ti, rtitem);
01103 break;
01104 case tic_tenum:
01105 cspan_print(access->arg->cspan);
01106 printf(" Error: Using '.' operator on expression of enum "
01107 "type.\n");
01108 stype_note_error(stype);
01109 *rtitem = stype_recovery_titem(stype);
01110 break;
01111 case tic_tfun:
01112 cspan_print(access->arg->cspan);
01113 printf(" Error: Using '.' operator on a function.\n");
01114 stype_note_error(stype);
01115 *rtitem = stype_recovery_titem(stype);
01116 break;
01117 case tic_tvref:
01118
01119 cspan_print(access->arg->cspan);
01120 printf(" Error: Using '.' operator on generic data.\n");
01121 *rtitem = stype_recovery_titem(stype);
01122 break;
01123 case tic_ignore:
01124 *rtitem = stype_recovery_titem(stype);
01125 break;
01126 }
01127 }
01128
01136 static void stype_access_tprimitive(stype_t *stype, stree_access_t *access,
01137 tdata_item_t *arg_ti, tdata_item_t **rtitem)
01138 {
01139 (void) arg_ti;
01140
01141
01142 access->arg = stype_box_expr(stype, access->arg);
01143 if (access->arg->titem->tic == tic_ignore) {
01144 *rtitem = stype_recovery_titem(stype);
01145 return;
01146 }
01147
01148
01149 stype_access_tobject(stype, access, access->arg->titem, rtitem);
01150 }
01151
01159 static void stype_access_tobject(stype_t *stype, stree_access_t *access,
01160 tdata_item_t *arg_ti, tdata_item_t **rtitem)
01161 {
01162 stree_symbol_t *member_sym;
01163 stree_var_t *var;
01164 stree_enum_t *enum_d;
01165 stree_fun_t *fun;
01166 stree_prop_t *prop;
01167 tdata_object_t *tobject;
01168 tdata_item_t *mtitem;
01169 tdata_tvv_t *tvv;
01170 stree_csi_t *member_csi;
01171
01172 #ifdef DEBUG_TYPE_TRACE
01173 printf("Type a CSI access operation.\n");
01174 #endif
01175 assert(arg_ti->tic == tic_tobject);
01176 tobject = arg_ti->u.tobject;
01177
01178
01179 member_sym = symbol_search_csi(stype->program, tobject->csi,
01180 access->member_name);
01181
01182 if (member_sym == NULL) {
01183
01184 cspan_print(access->member_name->cspan);
01185 printf(" Error: CSI '");
01186 symbol_print_fqn(csi_to_symbol(tobject->csi));
01187 printf("' has no member named '%s'.\n",
01188 strtab_get_str(access->member_name->sid));
01189 stype_note_error(stype);
01190 *rtitem = stype_recovery_titem(stype);
01191 return;
01192 }
01193
01194 #ifdef DEBUG_RUN_TRACE
01195 printf("Found member '%s'.\n",
01196 strtab_get_str(access->member_name->sid));
01197 #endif
01198
01199 if (tobject->static_ref == sn_static &&
01200 !stree_symbol_is_static(member_sym)) {
01201 cspan_print(access->member_name->cspan);
01202 printf(" Error: Accessing non-static member '");
01203 symbol_print_fqn(member_sym);
01204 printf("' in static context.\n");
01205 stype_note_error(stype);
01206 *rtitem = stype_recovery_titem(stype);
01207 return;
01208 }
01209
01210
01211 if (tobject->static_ref != sn_static &&
01212 stree_symbol_is_static(member_sym)) {
01213 cspan_print(access->member_name->cspan);
01214 printf(" Error: Accessing static member '");
01215 symbol_print_fqn(member_sym);
01216 printf("' in non-static context.\n");
01217 stype_note_error(stype);
01218 *rtitem = stype_recovery_titem(stype);
01219 return;
01220 }
01221
01222
01223 mtitem = NULL;
01224
01225 switch (member_sym->sc) {
01226 case sc_csi:
01227 member_csi = symbol_to_csi(member_sym);
01228 assert(member_csi != NULL);
01229
01230 mtitem = tdata_item_new(tic_tobject);
01231 tobject = tdata_object_new();
01232 mtitem->u.tobject = tobject;
01233
01234 tobject->static_ref = sn_static;
01235 tobject->csi = member_csi;
01236 break;
01237 case sc_ctor:
01238
01239 assert(b_false);
01240 case sc_deleg:
01241 cspan_print(access->member_name->cspan);
01242 printf(" Error: Accessing object member which is a "
01243 "delegate.\n");
01244 stype_note_error(stype);
01245 *rtitem = stype_recovery_titem(stype);
01246 return;
01247 case sc_enum:
01248 enum_d = symbol_to_enum(member_sym);
01249 assert(enum_d != NULL);
01250
01251 stype_enum(stype, enum_d);
01252 mtitem = enum_d->titem;
01253 break;
01254 case sc_fun:
01255 fun = symbol_to_fun(member_sym);
01256 assert(fun != NULL);
01257
01258 stype_fun_header(stype, fun);
01259 mtitem = fun->titem;
01260 break;
01261 case sc_var:
01262 var = symbol_to_var(member_sym);
01263 assert(var != NULL);
01264 run_texpr(stype->program, member_sym->outer_csi,
01265 var->type, &mtitem);
01266 break;
01267 case sc_prop:
01268 prop = symbol_to_prop(member_sym);
01269 assert(prop != NULL);
01270 run_texpr(stype->program, member_sym->outer_csi,
01271 prop->type, &mtitem);
01272 break;
01273 }
01274
01275
01276
01277
01278
01279
01280
01281
01282
01283 stype_titem_to_tvv(stype, arg_ti, &tvv);
01284 tdata_item_subst(mtitem, tvv, rtitem);
01285 }
01286
01294 static void stype_access_tarray(stype_t *stype, stree_access_t *access,
01295 tdata_item_t *arg_ti, tdata_item_t **rtitem)
01296 {
01297 (void) stype;
01298 (void) access;
01299 (void) rtitem;
01300
01301 cspan_print(access->arg->cspan);
01302 printf(" Error: Unimplemented: Accessing array type '");
01303 tdata_item_print(arg_ti);
01304 printf("'.\n");
01305 stype_note_error(stype);
01306 *rtitem = stype_recovery_titem(stype);
01307 }
01308
01316 static void stype_access_tebase(stype_t *stype, stree_access_t *access,
01317 tdata_item_t *arg_ti, tdata_item_t **rtitem)
01318 {
01319 tdata_ebase_t *tebase;
01320 tdata_enum_t *tenum;
01321 tdata_item_t *mtitem;
01322 stree_embr_t *embr;
01323
01324 #ifdef DEBUG_TYPE_TRACE
01325 printf("Type an ebase access operation.\n");
01326 #endif
01327 assert(arg_ti->tic == tic_tebase);
01328 tebase = arg_ti->u.tebase;
01329
01330
01331 embr = stree_enum_find_mbr(tebase->enum_d, access->member_name);
01332
01333 if (embr == NULL) {
01334
01335 cspan_print(access->member_name->cspan);
01336 printf(" Error: Enum type '");
01337 symbol_print_fqn(enum_to_symbol(tebase->enum_d));
01338 printf("' has no member named '%s'.\n",
01339 strtab_get_str(access->member_name->sid));
01340 stype_note_error(stype);
01341 *rtitem = stype_recovery_titem(stype);
01342 return;
01343 }
01344
01345 #ifdef DEBUG_RUN_TRACE
01346 printf("Found member '%s'.\n",
01347 strtab_get_str(access->member_name->sid));
01348 #endif
01349
01350 mtitem = tdata_item_new(tic_tenum);
01351 tenum = tdata_enum_new();
01352 mtitem->u.tenum = tenum;
01353 tenum->enum_d = tebase->enum_d;
01354
01355 *rtitem = mtitem;
01356 }
01357
01358
01365 static void stype_call(stype_t *stype, stree_call_t *call,
01366 tdata_item_t **rtitem)
01367 {
01368 tdata_item_t *fun_ti;
01369 tdata_fun_sig_t *tsig;
01370
01371 #ifdef DEBUG_TYPE_TRACE
01372 cspan_print(call->expr->cspan);
01373 printf(" Evaluate type of call operation.\n");
01374 #endif
01375
01376 stype_expr(stype, call->fun);
01377
01378
01379 fun_ti = call->fun->titem;
01380 switch (fun_ti->tic) {
01381 case tic_tdeleg:
01382 tsig = stype_deleg_get_sig(stype, fun_ti->u.tdeleg);
01383 assert(tsig != NULL);
01384 break;
01385 case tic_tfun:
01386 tsig = fun_ti->u.tfun->tsig;
01387 break;
01388 case tic_ignore:
01389 *rtitem = stype_recovery_titem(stype);
01390 return;
01391 default:
01392 cspan_print(call->fun->cspan);
01393 printf(" Error: Calling something which is not a function ");
01394 printf("(found '");
01395 tdata_item_print(fun_ti);
01396 printf("').\n");
01397 stype_note_error(stype);
01398 *rtitem = stype_recovery_titem(stype);
01399 return;
01400 }
01401
01402
01403 stype_call_args(stype, call->expr->cspan, &tsig->arg_ti, tsig->varg_ti,
01404 &call->args);
01405
01406 if (tsig->rtype != NULL) {
01407
01408 *rtitem = tsig->rtype;
01409 } else {
01410 *rtitem = NULL;
01411 }
01412 }
01413
01423 static void stype_call_args(stype_t *stype, cspan_t *cspan, list_t *farg_tis,
01424 tdata_item_t *fvarg_ti, list_t *args)
01425 {
01426 list_node_t *fargt_n;
01427 tdata_item_t *farg_ti;
01428 tdata_item_t *varg_ti;
01429
01430 list_node_t *arg_n;
01431 stree_expr_t *arg;
01432 stree_expr_t *carg;
01433
01434
01435 fargt_n = list_first(farg_tis);
01436 arg_n = list_first(args);
01437
01438 while (fargt_n != NULL && arg_n != NULL) {
01439 farg_ti = list_node_data(fargt_n, tdata_item_t *);
01440 arg = list_node_data(arg_n, stree_expr_t *);
01441 stype_expr(stype, arg);
01442
01443
01444 if (farg_ti == NULL) {
01445
01446 fargt_n = list_next(farg_tis, fargt_n);
01447 arg_n = list_next(args, arg_n);
01448 continue;
01449 }
01450
01451
01452 carg = stype_convert(stype, arg, farg_ti);
01453
01454
01455 list_node_setdata(arg_n, carg);
01456
01457 fargt_n = list_next(farg_tis, fargt_n);
01458 arg_n = list_next(args, arg_n);
01459 }
01460
01461
01462 if (fvarg_ti != NULL) {
01463
01464 farg_ti = fvarg_ti;
01465
01466
01467 assert(farg_ti->tic == tic_tarray);
01468 varg_ti = farg_ti->u.tarray->base_ti;
01469
01470 while (arg_n != NULL) {
01471 arg = list_node_data(arg_n, stree_expr_t *);
01472 stype_expr(stype, arg);
01473
01474
01475 carg = stype_convert(stype, arg, varg_ti);
01476
01477
01478 list_node_setdata(arg_n, carg);
01479
01480 arg_n = list_next(args, arg_n);
01481 }
01482 }
01483
01484 if (fargt_n != NULL) {
01485 cspan_print(cspan);
01486 printf(" Error: Too few arguments.\n");
01487 stype_note_error(stype);
01488 }
01489
01490 if (arg_n != NULL) {
01491 cspan_print(cspan);
01492 printf(" Error: Too many arguments.\n");
01493 stype_note_error(stype);
01494 }
01495 }
01496
01503 static void stype_index(stype_t *stype, stree_index_t *index,
01504 tdata_item_t **rtitem)
01505 {
01506 tdata_item_t *base_ti;
01507 list_node_t *arg_n;
01508 stree_expr_t *arg;
01509
01510 #ifdef DEBUG_TYPE_TRACE
01511 cspan_print(index->expr->cspan);
01512 printf(" Evaluate type of index operation.\n");
01513 #endif
01514 stype_expr(stype, index->base);
01515 base_ti = index->base->titem;
01516
01517
01518 arg_n = list_first(&index->args);
01519 while (arg_n != NULL) {
01520 arg = list_node_data(arg_n, stree_expr_t *);
01521 stype_expr(stype, arg);
01522
01523 arg_n = list_next(&index->args, arg_n);
01524 }
01525
01526 switch (base_ti->tic) {
01527 case tic_tprimitive:
01528 stype_index_tprimitive(stype, index, base_ti, rtitem);
01529 break;
01530 case tic_tobject:
01531 stype_index_tobject(stype, index, base_ti, rtitem);
01532 break;
01533 case tic_tarray:
01534 stype_index_tarray(stype, index, base_ti, rtitem);
01535 break;
01536 case tic_tdeleg:
01537 cspan_print(index->base->cspan);
01538 printf(" Error: Indexing a delegate.\n");
01539 stype_note_error(stype);
01540 *rtitem = stype_recovery_titem(stype);
01541 break;
01542 case tic_tebase:
01543 cspan_print(index->base->cspan);
01544 printf(" Error: Indexing an enum declaration.\n");
01545 stype_note_error(stype);
01546 *rtitem = stype_recovery_titem(stype);
01547 break;
01548 case tic_tenum:
01549 cspan_print(index->base->cspan);
01550 printf(" Error: Indexing an enum value.\n");
01551 stype_note_error(stype);
01552 *rtitem = stype_recovery_titem(stype);
01553 break;
01554 case tic_tfun:
01555 cspan_print(index->base->cspan);
01556 printf(" Error: Indexing a function.\n");
01557 stype_note_error(stype);
01558 *rtitem = stype_recovery_titem(stype);
01559 break;
01560 case tic_tvref:
01561
01562 cspan_print(index->base->cspan);
01563 printf(" Error: Indexing generic data.\n");
01564 *rtitem = stype_recovery_titem(stype);
01565 break;
01566 case tic_ignore:
01567 *rtitem = stype_recovery_titem(stype);
01568 break;
01569 }
01570 }
01571
01579 static void stype_index_tprimitive(stype_t *stype, stree_index_t *index,
01580 tdata_item_t *base_ti, tdata_item_t **rtitem)
01581 {
01582 tdata_primitive_t *tprimitive;
01583 tdata_item_t *titem;
01584
01585 (void) stype;
01586 (void) index;
01587
01588 assert(base_ti->tic == tic_tprimitive);
01589 tprimitive = base_ti->u.tprimitive;
01590
01591 if (tprimitive->tpc == tpc_string) {
01592 titem = tdata_item_new(tic_tprimitive);
01593 titem->u.tprimitive = tdata_primitive_new(tpc_char);
01594 *rtitem = titem;
01595 return;
01596 }
01597
01598 cspan_print(index->base->cspan);
01599 printf(" Error: Indexing primitive type '");
01600 tdata_item_print(base_ti);
01601 printf("'.\n");
01602 stype_note_error(stype);
01603 *rtitem = stype_recovery_titem(stype);
01604 }
01605
01613 static void stype_index_tobject(stype_t *stype, stree_index_t *index,
01614 tdata_item_t *base_ti, tdata_item_t **rtitem)
01615 {
01616 tdata_object_t *tobject;
01617 stree_symbol_t *idx_sym;
01618 stree_prop_t *idx;
01619 stree_ident_t *idx_ident;
01620 tdata_item_t *mtitem;
01621 tdata_tvv_t *tvv;
01622
01623 (void) index;
01624
01625 #ifdef DEBUG_TYPE_TRACE
01626 cspan_print(index->expr->cspan);
01627 printf(" Indexing object type '");
01628 tdata_item_print(base_ti);
01629 printf("'.\n");
01630 #endif
01631
01632 assert(base_ti->tic == tic_tobject);
01633 tobject = base_ti->u.tobject;
01634
01635
01636 idx_ident = stree_ident_new();
01637 idx_ident->sid = strtab_get_sid(INDEXER_IDENT);
01638 idx_sym = symbol_search_csi(stype->program, tobject->csi, idx_ident);
01639
01640 if (idx_sym == NULL) {
01641 cspan_print(index->base->cspan);
01642 printf(" Error: Indexing object of type '");
01643 tdata_item_print(base_ti);
01644 printf("' which does not have an indexer.\n");
01645 stype_note_error(stype);
01646 *rtitem = stype_recovery_titem(stype);
01647 return;
01648 }
01649
01650 idx = symbol_to_prop(idx_sym);
01651 assert(idx != NULL);
01652
01653
01654 run_texpr(stype->program, idx_sym->outer_csi, idx->type, &mtitem);
01655
01656
01657
01658
01659
01660
01661
01662
01663
01664 stype_titem_to_tvv(stype, base_ti, &tvv);
01665 tdata_item_subst(mtitem, tvv, rtitem);
01666 }
01667
01675 static void stype_index_tarray(stype_t *stype, stree_index_t *index,
01676 tdata_item_t *base_ti, tdata_item_t **rtitem)
01677 {
01678 list_node_t *arg_n;
01679 stree_expr_t *arg;
01680 int arg_count;
01681
01682 (void) stype;
01683 assert(base_ti->tic == tic_tarray);
01684
01685
01686
01687
01688
01689 arg_count = 0;
01690 arg_n = list_first(&index->args);
01691 while (arg_n != NULL) {
01692 ++arg_count;
01693
01694 arg = list_node_data(arg_n, stree_expr_t *);
01695 if (arg->titem->tic != tic_tprimitive ||
01696 arg->titem->u.tprimitive->tpc != tpc_int) {
01697
01698 cspan_print(arg->cspan);
01699 printf(" Error: Array index is not an integer.\n");
01700 stype_note_error(stype);
01701 }
01702
01703 arg_n = list_next(&index->args, arg_n);
01704 }
01705
01706 if (arg_count != base_ti->u.tarray->rank) {
01707 cspan_print(index->expr->cspan);
01708 printf(" Error: Using %d indices with array of rank %d.\n",
01709 arg_count, base_ti->u.tarray->rank);
01710 stype_note_error(stype);
01711 }
01712
01713 *rtitem = base_ti->u.tarray->base_ti;
01714 }
01715
01722 static void stype_assign(stype_t *stype, stree_assign_t *assign,
01723 tdata_item_t **rtitem)
01724 {
01725 stree_expr_t *csrc;
01726
01727 #ifdef DEBUG_TYPE_TRACE
01728 cspan_print(assign->expr->cspan);
01729 printf(" Evaluate type of assignment.\n");
01730 #endif
01731 stype_expr(stype, assign->dest);
01732 stype_expr(stype, assign->src);
01733
01734 csrc = stype_convert(stype, assign->src, assign->dest->titem);
01735
01736
01737 assign->src = csrc;
01738 *rtitem = NULL;
01739 }
01740
01747 static void stype_as(stype_t *stype, stree_as_t *as_op, tdata_item_t **rtitem)
01748 {
01749 tdata_item_t *titem;
01750 tdata_item_t *pred_ti;
01751
01752 #ifdef DEBUG_TYPE_TRACE
01753 cspan_print(as_op->expr->cspan);
01754 printf(" Evaluate type of @c as conversion.\n");
01755 #endif
01756 stype_expr(stype, as_op->arg);
01757 run_texpr(stype->program, stype->current_csi, as_op->dtype, &titem);
01758
01759 pred_ti = stype_tobject_find_pred(stype, titem, as_op->arg->titem);
01760 if (pred_ti == NULL) {
01761
01762 stype_convert_failure(stype, convc_as, as_op->arg, titem);
01763 *rtitem = titem;
01764 return;
01765 }
01766
01767
01768
01769
01770
01771 if (stype_targs_check_equal(stype, pred_ti, as_op->arg->titem)
01772 != EOK) {
01773 stype_convert_failure(stype, convc_as, as_op->arg, titem);
01774 *rtitem = titem;
01775 return;
01776 }
01777
01778 *rtitem = titem;
01779 }
01780
01790 static void stype_box(stype_t *stype, stree_box_t *box, tdata_item_t **rtitem)
01791 {
01792 tdata_item_t *ptitem, *btitem;
01793 tdata_object_t *tobject;
01794 stree_symbol_t *csi_sym;
01795 builtin_t *bi;
01796
01797 #ifdef DEBUG_TYPE_TRACE
01798 cspan_print(box->expr->cspan);
01799 printf(" Evaluate type of boxing operation.\n");
01800 #endif
01801 bi = stype->program->builtin;
01802
01803 stype_expr(stype, box->arg);
01804 ptitem = box->arg->titem;
01805
01806
01807 csi_sym = NULL;
01808
01809 assert(ptitem->tic == tic_tprimitive);
01810 switch (ptitem->u.tprimitive->tpc) {
01811 case tpc_bool: csi_sym = bi->boxed_bool; break;
01812 case tpc_char: csi_sym = bi->boxed_char; break;
01813 case tpc_int: csi_sym = bi->boxed_int; break;
01814 case tpc_nil: assert(b_false);
01815 case tpc_string: csi_sym = bi->boxed_string; break;
01816 case tpc_resource: assert(b_false);
01817 }
01818
01819 btitem = tdata_item_new(tic_tobject);
01820 tobject = tdata_object_new();
01821
01822 btitem->u.tobject = tobject;
01823 tobject->static_ref = sn_nonstatic;
01824 tobject->csi = symbol_to_csi(csi_sym);
01825 assert(tobject->csi != NULL);
01826 list_init(&tobject->targs);
01827
01828 *rtitem = btitem;
01829 }