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
00037 #include <stdio.h>
00038 #include <stdlib.h>
00039 #include <assert.h>
00040 #include "cspan.h"
00041 #include "debug.h"
00042 #include "intmap.h"
00043 #include "list.h"
00044 #include "mytypes.h"
00045 #include "run_texpr.h"
00046 #include "stree.h"
00047 #include "strtab.h"
00048 #include "stype_expr.h"
00049 #include "symbol.h"
00050 #include "tdata.h"
00051
00052 #include "stype.h"
00053
00054 static void stype_csi(stype_t *stype, stree_csi_t *csi);
00055 static void stype_ctor(stype_t *stype, stree_ctor_t *ctor);
00056 static void stype_ctor_body(stype_t *stype, stree_ctor_t *ctor);
00057 static void stype_fun(stype_t *stype, stree_fun_t *fun);
00058 static void stype_var(stype_t *stype, stree_var_t *var);
00059 static void stype_prop(stype_t *stype, stree_prop_t *prop);
00060
00061 static void stype_fun_sig(stype_t *stype, stree_csi_t *outer_csi,
00062 stree_fun_sig_t *sig, tdata_fun_sig_t **rtsig);
00063 static void stype_fun_body(stype_t *stype, stree_fun_t *fun);
00064 static void stype_block(stype_t *stype, stree_block_t *block);
00065
00066 static void stype_class_impl_check(stype_t *stype, stree_csi_t *csi);
00067 static void stype_class_impl_check_if(stype_t *stype, stree_csi_t *csi,
00068 tdata_item_t *iface_ti);
00069 static void stype_class_impl_check_mbr(stype_t *stype, stree_csi_t *csi,
00070 tdata_tvv_t *if_tvv, stree_csimbr_t *ifmbr);
00071 static void stype_class_impl_check_fun(stype_t *stype,
00072 stree_symbol_t *cfun_sym, tdata_tvv_t *if_tvv, stree_symbol_t *ifun_sym);
00073 static void stype_class_impl_check_prop(stype_t *stype,
00074 stree_symbol_t *cprop_sym, tdata_tvv_t *if_tvv, stree_symbol_t *iprop_sym);
00075
00076 static void stype_vdecl(stype_t *stype, stree_vdecl_t *vdecl_s);
00077 static void stype_if(stype_t *stype, stree_if_t *if_s);
00078 static void stype_switch(stype_t *stype, stree_switch_t *switch_s);
00079 static void stype_while(stype_t *stype, stree_while_t *while_s);
00080 static void stype_for(stype_t *stype, stree_for_t *for_s);
00081 static void stype_raise(stype_t *stype, stree_raise_t *raise_s);
00082 static void stype_break(stype_t *stype, stree_break_t *break_s);
00083 static void stype_return(stype_t *stype, stree_return_t *return_s);
00084 static void stype_exps(stype_t *stype, stree_exps_t *exp_s, bool_t want_value);
00085 static void stype_wef(stype_t *stype, stree_wef_t *wef_s);
00086
00087 static stree_expr_t *stype_convert_tprimitive(stype_t *stype,
00088 stree_expr_t *expr, tdata_item_t *dest);
00089 static stree_expr_t *stype_convert_tprim_tobj(stype_t *stype,
00090 stree_expr_t *expr, tdata_item_t *dest);
00091 static stree_expr_t *stype_convert_tobject(stype_t *stype, stree_expr_t *expr,
00092 tdata_item_t *dest);
00093 static stree_expr_t *stype_convert_tarray(stype_t *stype, stree_expr_t *expr,
00094 tdata_item_t *dest);
00095 static stree_expr_t *stype_convert_tdeleg(stype_t *stype, stree_expr_t *expr,
00096 tdata_item_t *dest);
00097 static stree_expr_t *stype_convert_tenum(stype_t *stype, stree_expr_t *expr,
00098 tdata_item_t *dest);
00099 static stree_expr_t *stype_convert_tfun_tdeleg(stype_t *stype,
00100 stree_expr_t *expr, tdata_item_t *dest);
00101 static stree_expr_t *stype_convert_tvref(stype_t *stype, stree_expr_t *expr,
00102 tdata_item_t *dest);
00103
00104 static bool_t stype_fun_sig_equal(stype_t *stype, tdata_fun_sig_t *asig,
00105 tdata_fun_sig_t *sdig);
00106
00115 void stype_module(stype_t *stype, stree_module_t *module)
00116 {
00117 list_node_t *mbr_n;
00118 stree_modm_t *mbr;
00119
00120 #ifdef DEBUG_TYPE_TRACE
00121 printf("Type module.\n");
00122 #endif
00123 stype->current_csi = NULL;
00124 stype->proc_vr = NULL;
00125
00126 mbr_n = list_first(&module->members);
00127 while (mbr_n != NULL) {
00128 mbr = list_node_data(mbr_n, stree_modm_t *);
00129
00130 switch (mbr->mc) {
00131 case mc_csi:
00132 stype_csi(stype, mbr->u.csi);
00133 break;
00134 case mc_enum:
00135 stype_enum(stype, mbr->u.enum_d);
00136 break;
00137 }
00138
00139 mbr_n = list_next(&module->members, mbr_n);
00140 }
00141 }
00142
00148 static void stype_csi(stype_t *stype, stree_csi_t *csi)
00149 {
00150 list_node_t *csimbr_n;
00151 stree_csimbr_t *csimbr;
00152 stree_csi_t *prev_ctx;
00153
00154 #ifdef DEBUG_TYPE_TRACE
00155 printf("Type CSI '");
00156 symbol_print_fqn(csi_to_symbol(csi));
00157 printf("'.\n");
00158 #endif
00159 prev_ctx = stype->current_csi;
00160 stype->current_csi = csi;
00161
00162 csimbr_n = list_first(&csi->members);
00163 while (csimbr_n != NULL) {
00164 csimbr = list_node_data(csimbr_n, stree_csimbr_t *);
00165
00166 switch (csimbr->cc) {
00167 case csimbr_csi: stype_csi(stype, csimbr->u.csi); break;
00168 case csimbr_ctor: stype_ctor(stype, csimbr->u.ctor); break;
00169 case csimbr_deleg: stype_deleg(stype, csimbr->u.deleg); break;
00170 case csimbr_enum: stype_enum(stype, csimbr->u.enum_d); break;
00171 case csimbr_fun: stype_fun(stype, csimbr->u.fun); break;
00172 case csimbr_var: stype_var(stype, csimbr->u.var); break;
00173 case csimbr_prop: stype_prop(stype, csimbr->u.prop); break;
00174 }
00175
00176 csimbr_n = list_next(&csi->members, csimbr_n);
00177 }
00178
00179 if (csi->cc == csi_class)
00180 stype_class_impl_check(stype, csi);
00181
00182 stype->current_csi = prev_ctx;
00183 }
00184
00190 static void stype_ctor(stype_t *stype, stree_ctor_t *ctor)
00191 {
00192 #ifdef DEBUG_TYPE_TRACE
00193 printf("Type constructor '");
00194 symbol_print_fqn(ctor_to_symbol(ctor));
00195 printf("'.\n");
00196 #endif
00197 if (ctor->titem == NULL)
00198 stype_ctor_header(stype, ctor);
00199
00200 stype_ctor_body(stype, ctor);
00201 }
00202
00208 void stype_ctor_header(stype_t *stype, stree_ctor_t *ctor)
00209 {
00210 stree_symbol_t *ctor_sym;
00211 tdata_item_t *ctor_ti;
00212 tdata_fun_t *tfun;
00213 tdata_fun_sig_t *tsig;
00214
00215 #ifdef DEBUG_TYPE_TRACE
00216 printf("Type constructor '");
00217 symbol_print_fqn(ctor_to_symbol(ctor));
00218 printf("' header.\n");
00219 #endif
00220 if (ctor->titem != NULL)
00221 return;
00222
00223 ctor_sym = ctor_to_symbol(ctor);
00224
00225
00226 stype_fun_sig(stype, ctor_sym->outer_csi, ctor->sig, &tsig);
00227
00228 ctor_ti = tdata_item_new(tic_tfun);
00229 tfun = tdata_fun_new();
00230 ctor_ti->u.tfun = tfun;
00231 tfun->tsig = tsig;
00232
00233 ctor->titem = ctor_ti;
00234 }
00235
00241 static void stype_ctor_body(stype_t *stype, stree_ctor_t *ctor)
00242 {
00243 #ifdef DEBUG_TYPE_TRACE
00244 printf("Type constructor '");
00245 symbol_print_fqn(ctor_to_symbol(ctor));
00246 printf("' body.\n");
00247 #endif
00248 assert(stype->proc_vr == NULL);
00249
00250 stype->proc_vr = stype_proc_vr_new();
00251 stype->proc_vr->proc = ctor->proc;
00252 list_init(&stype->proc_vr->block_vr);
00253
00254 stype_block(stype, ctor->proc->body);
00255
00256 free(stype->proc_vr);
00257 stype->proc_vr = NULL;
00258 }
00259
00265 void stype_deleg(stype_t *stype, stree_deleg_t *deleg)
00266 {
00267 stree_symbol_t *deleg_sym;
00268 tdata_item_t *deleg_ti;
00269 tdata_deleg_t *tdeleg;
00270 tdata_fun_sig_t *tsig;
00271
00272 #ifdef DEBUG_TYPE_TRACE
00273 printf("Type delegate '");
00274 symbol_print_fqn(deleg_to_symbol(deleg));
00275 printf("'.\n");
00276 #endif
00277 if (deleg->titem == NULL) {
00278 deleg_ti = tdata_item_new(tic_tdeleg);
00279 deleg->titem = deleg_ti;
00280 tdeleg = tdata_deleg_new();
00281 deleg_ti->u.tdeleg = tdeleg;
00282 } else {
00283 deleg_ti = deleg->titem;
00284 assert(deleg_ti->u.tdeleg != NULL);
00285 tdeleg = deleg_ti->u.tdeleg;
00286 }
00287
00288 if (tdeleg->tsig != NULL)
00289 return;
00290
00291 deleg_sym = deleg_to_symbol(deleg);
00292
00293
00294 stype_fun_sig(stype, deleg_sym->outer_csi, deleg->sig, &tsig);
00295
00296 tdeleg->deleg = deleg;
00297 tdeleg->tsig = tsig;
00298 }
00299
00305 void stype_enum(stype_t *stype, stree_enum_t *enum_d)
00306 {
00307 tdata_item_t *titem;
00308 tdata_enum_t *tenum;
00309
00310 (void) stype;
00311
00312 #ifdef DEBUG_TYPE_TRACE
00313 printf("Type enum '");
00314 symbol_print_fqn(enum_to_symbol(enum_d));
00315 printf("'.\n");
00316 #endif
00317 if (enum_d->titem == NULL) {
00318 titem = tdata_item_new(tic_tenum);
00319 tenum = tdata_enum_new();
00320 titem->u.tenum = tenum;
00321 tenum->enum_d = enum_d;
00322
00323 enum_d->titem = titem;
00324 }
00325 }
00326
00337 static void stype_fun(stype_t *stype, stree_fun_t *fun)
00338 {
00339 #ifdef DEBUG_TYPE_TRACE
00340 printf("Type function '");
00341 symbol_print_fqn(fun_to_symbol(fun));
00342 printf("'.\n");
00343 #endif
00344 if (fun->titem == NULL)
00345 stype_fun_header(stype, fun);
00346
00347 stype_fun_body(stype, fun);
00348 }
00349
00357 void stype_fun_header(stype_t *stype, stree_fun_t *fun)
00358 {
00359 stree_symbol_t *fun_sym;
00360 tdata_item_t *fun_ti;
00361 tdata_fun_t *tfun;
00362 tdata_fun_sig_t *tsig;
00363
00364 #ifdef DEBUG_TYPE_TRACE
00365 printf("Type function '");
00366 symbol_print_fqn(fun_to_symbol(fun));
00367 printf("' header.\n");
00368 #endif
00369 if (fun->titem != NULL)
00370 return;
00371
00372 fun_sym = fun_to_symbol(fun);
00373
00374
00375 stype_fun_sig(stype, fun_sym->outer_csi, fun->sig, &tsig);
00376
00377 fun_ti = tdata_item_new(tic_tfun);
00378 tfun = tdata_fun_new();
00379 fun_ti->u.tfun = tfun;
00380 tfun->tsig = tsig;
00381
00382 fun->titem = fun_ti;
00383 }
00384
00393 static void stype_fun_sig(stype_t *stype, stree_csi_t *outer_csi,
00394 stree_fun_sig_t *sig, tdata_fun_sig_t **rtsig)
00395 {
00396 list_node_t *arg_n;
00397 stree_proc_arg_t *arg;
00398 tdata_item_t *titem;
00399 tdata_fun_sig_t *tsig;
00400
00401 #ifdef DEBUG_TYPE_TRACE
00402 printf("Type function signature.\n");
00403 #endif
00404 tsig = tdata_fun_sig_new();
00405
00406 list_init(&tsig->arg_ti);
00407
00408
00409
00410
00411 arg_n = list_first(&sig->args);
00412 while (arg_n != NULL) {
00413 arg = list_node_data(arg_n, stree_proc_arg_t *);
00414
00415
00416 if (arg->type == NULL) {
00417 list_append(&tsig->arg_ti, NULL);
00418 arg_n = list_next(&sig->args, arg_n);
00419 continue;
00420 }
00421
00422 run_texpr(stype->program, outer_csi, arg->type, &titem);
00423 list_append(&tsig->arg_ti, titem);
00424
00425 arg_n = list_next(&sig->args, arg_n);
00426 }
00427
00428
00429 if (sig->varg != NULL) {
00430
00431 run_texpr(stype->program, outer_csi, sig->varg->type, &titem);
00432 tsig->varg_ti = titem;
00433
00434 if (titem->tic != tic_tarray && titem->tic != tic_ignore) {
00435 printf("Error: Packed argument is not an array.\n");
00436 stype_note_error(stype);
00437 }
00438 }
00439
00440
00441 if (sig->rtype != NULL) {
00442 run_texpr(stype->program, outer_csi, sig->rtype, &titem);
00443 tsig->rtype = titem;
00444 }
00445
00446 *rtsig = tsig;
00447 }
00448
00456 static void stype_fun_body(stype_t *stype, stree_fun_t *fun)
00457 {
00458 #ifdef DEBUG_TYPE_TRACE
00459 printf("Type function '");
00460 symbol_print_fqn(fun_to_symbol(fun));
00461 printf("' body.\n");
00462 #endif
00463 assert(stype->proc_vr == NULL);
00464
00465
00466 if (fun->proc->body == NULL)
00467 return;
00468
00469 stype->proc_vr = stype_proc_vr_new();
00470 stype->proc_vr->proc = fun->proc;
00471 list_init(&stype->proc_vr->block_vr);
00472
00473 stype_block(stype, fun->proc->body);
00474
00475 free(stype->proc_vr);
00476 stype->proc_vr = NULL;
00477 }
00478
00484 static void stype_var(stype_t *stype, stree_var_t *var)
00485 {
00486 tdata_item_t *titem;
00487
00488 run_texpr(stype->program, stype->current_csi, var->type,
00489 &titem);
00490 if (titem->tic == tic_ignore) {
00491
00492 stype_note_error(stype);
00493 }
00494 }
00495
00501 static void stype_prop(stype_t *stype, stree_prop_t *prop)
00502 {
00503 #ifdef DEBUG_TYPE_TRACE
00504 printf("Type property '");
00505 symbol_print_fqn(prop_to_symbol(prop));
00506 printf("'.\n");
00507 #endif
00508 if (prop->titem == NULL)
00509 stype_prop_header(stype, prop);
00510
00511 stype->proc_vr = stype_proc_vr_new();
00512 list_init(&stype->proc_vr->block_vr);
00513
00514
00515 if (prop->getter != NULL && prop->getter->body != NULL) {
00516 stype->proc_vr->proc = prop->getter;
00517 stype_block(stype, prop->getter->body);
00518 }
00519
00520
00521 if (prop->setter != NULL && prop->setter->body != NULL) {
00522 stype->proc_vr->proc = prop->setter;
00523 stype_block(stype, prop->setter->body);
00524 }
00525
00526 free(stype->proc_vr);
00527 stype->proc_vr = NULL;
00528 }
00529
00535 void stype_prop_header(stype_t *stype, stree_prop_t *prop)
00536 {
00537 tdata_item_t *titem;
00538
00539 #ifdef DEBUG_TYPE_TRACE
00540 printf("Type property '");
00541 symbol_print_fqn(prop_to_symbol(prop));
00542 printf("' header.\n");
00543 #endif
00544 run_texpr(stype->program, stype->current_csi, prop->type,
00545 &titem);
00546 if (titem->tic == tic_ignore) {
00547
00548 stype_note_error(stype);
00549 return;
00550 }
00551
00552 prop->titem = titem;
00553 }
00554
00560 static void stype_block(stype_t *stype, stree_block_t *block)
00561 {
00562 stree_stat_t *stat;
00563 list_node_t *stat_n;
00564 stype_block_vr_t *block_vr;
00565 list_node_t *bvr_n;
00566
00567 #ifdef DEBUG_TYPE_TRACE
00568 printf("Type block.\n");
00569 #endif
00570
00571
00572 block_vr = stype_block_vr_new();
00573 intmap_init(&block_vr->vdecls);
00574
00575
00576 list_append(&stype->proc_vr->block_vr, block_vr);
00577
00578 stat_n = list_first(&block->stats);
00579 while (stat_n != NULL) {
00580 stat = list_node_data(stat_n, stree_stat_t *);
00581 stype_stat(stype, stat, b_false);
00582
00583 stat_n = list_next(&block->stats, stat_n);
00584 }
00585
00586
00587 bvr_n = list_last(&stype->proc_vr->block_vr);
00588 assert(list_node_data(bvr_n, stype_block_vr_t *) == block_vr);
00589 list_remove(&stype->proc_vr->block_vr, bvr_n);
00590 }
00591
00597 static void stype_class_impl_check(stype_t *stype, stree_csi_t *csi)
00598 {
00599 list_node_t *pred_n;
00600 stree_texpr_t *pred_te;
00601 tdata_item_t *pred_ti;
00602
00603 #ifdef DEBUG_TYPE_TRACE
00604 printf("Verify that class implements all interfaces.\n");
00605 #endif
00606 assert(csi->cc == csi_class);
00607
00608 pred_n = list_first(&csi->inherit);
00609 while (pred_n != NULL) {
00610 pred_te = list_node_data(pred_n, stree_texpr_t *);
00611 run_texpr(stype->program, csi, pred_te, &pred_ti);
00612
00613 assert(pred_ti->tic == tic_tobject);
00614 switch (pred_ti->u.tobject->csi->cc) {
00615 case csi_class:
00616 break;
00617 case csi_struct:
00618 assert(b_false);
00619 case csi_interface:
00620
00621 list_append(&csi->impl_if_ti, pred_ti);
00622
00623
00624 stype_class_impl_check_if(stype, csi, pred_ti);
00625 break;
00626 }
00627
00628 pred_n = list_next(&csi->inherit, pred_n);
00629 }
00630 }
00631
00638 static void stype_class_impl_check_if(stype_t *stype, stree_csi_t *csi,
00639 tdata_item_t *iface_ti)
00640 {
00641 tdata_tvv_t *iface_tvv;
00642 list_node_t *pred_n;
00643 tdata_item_t *pred_ti;
00644 tdata_item_t *pred_sti;
00645
00646 stree_csi_t *iface;
00647 list_node_t *ifmbr_n;
00648 stree_csimbr_t *ifmbr;
00649
00650 assert(csi->cc == csi_class);
00651
00652 assert(iface_ti->tic == tic_tobject);
00653 iface = iface_ti->u.tobject->csi;
00654 assert(iface->cc = csi_interface);
00655
00656 #ifdef DEBUG_TYPE_TRACE
00657 printf("Verify that class fully implements interface.\n");
00658 #endif
00659
00660 stype_titem_to_tvv(stype, iface_ti, &iface_tvv);
00661
00662
00663
00664
00665 pred_n = list_first(&iface->impl_if_ti);
00666 while (pred_n != NULL) {
00667 pred_ti = list_node_data(pred_n, tdata_item_t *);
00668 assert(pred_ti->tic == tic_tobject);
00669 assert(pred_ti->u.tobject->csi->cc == csi_interface);
00670
00671
00672 tdata_item_subst(pred_ti, iface_tvv, &pred_sti);
00673
00674
00675 stype_class_impl_check_if(stype, csi, pred_sti);
00676
00677 pred_n = list_next(&iface->impl_if_ti, pred_n);
00678 }
00679
00680
00681
00682
00683 ifmbr_n = list_first(&iface->members);
00684 while (ifmbr_n != NULL) {
00685 ifmbr = list_node_data(ifmbr_n, stree_csimbr_t *);
00686 stype_class_impl_check_mbr(stype, csi, iface_tvv, ifmbr);
00687
00688 ifmbr_n = list_next(&iface->members, ifmbr_n);
00689 }
00690 }
00691
00699 static void stype_class_impl_check_mbr(stype_t *stype, stree_csi_t *csi,
00700 tdata_tvv_t *if_tvv, stree_csimbr_t *ifmbr)
00701 {
00702 stree_symbol_t *cmbr_sym;
00703 stree_symbol_t *ifmbr_sym;
00704 stree_ident_t *ifmbr_name;
00705
00706 assert(csi->cc == csi_class);
00707
00708 #ifdef DEBUG_TYPE_TRACE
00709 printf("Verify that class implements interface member.\n");
00710 #endif
00711 ifmbr_name = stree_csimbr_get_name(ifmbr);
00712
00713 cmbr_sym = symbol_search_csi(stype->program, csi, ifmbr_name);
00714 if (cmbr_sym == NULL) {
00715 printf("Error: CSI '");
00716 symbol_print_fqn(csi_to_symbol(csi));
00717 printf("' should implement '");
00718 symbol_print_fqn(csimbr_to_symbol(ifmbr));
00719 printf("' but it does not.\n");
00720 stype_note_error(stype);
00721 return;
00722 }
00723
00724 ifmbr_sym = csimbr_to_symbol(ifmbr);
00725 if (cmbr_sym->sc != ifmbr_sym->sc) {
00726 printf("Error: CSI '");
00727 symbol_print_fqn(csi_to_symbol(csi));
00728 printf("' implements '");
00729 symbol_print_fqn(csimbr_to_symbol(ifmbr));
00730 printf("' as a different kind of symbol.\n");
00731 stype_note_error(stype);
00732 }
00733
00734 switch (cmbr_sym->sc) {
00735 case sc_csi:
00736 case sc_ctor:
00737 case sc_deleg:
00738 case sc_enum:
00739
00740
00741
00742
00743 assert(b_false);
00744 case sc_fun:
00745 stype_class_impl_check_fun(stype, cmbr_sym, if_tvv, ifmbr_sym);
00746 break;
00747 case sc_var:
00748
00749
00750
00751
00752 assert(b_false);
00753 case sc_prop:
00754 stype_class_impl_check_prop(stype, cmbr_sym, if_tvv, ifmbr_sym);
00755 break;
00756 }
00757 }
00758
00766 static void stype_class_impl_check_fun(stype_t *stype,
00767 stree_symbol_t *cfun_sym, tdata_tvv_t *if_tvv, stree_symbol_t *ifun_sym)
00768 {
00769 stree_fun_t *cfun;
00770 tdata_fun_t *tcfun;
00771 stree_fun_t *ifun;
00772 tdata_item_t *sifun_ti;
00773 tdata_fun_t *tifun;
00774
00775 #ifdef DEBUG_TYPE_TRACE
00776 printf("Verify that class '");
00777 symbol_print_fqn(csi_to_symbol(cfun_sym->outer_csi));
00778 printf("' implements function '");
00779 symbol_print_fqn(ifun_sym);
00780 printf("' properly.\n");
00781 #endif
00782 assert(cfun_sym->sc == sc_fun);
00783 cfun = cfun_sym->u.fun;
00784
00785 assert(ifun_sym->sc == sc_fun);
00786 ifun = ifun_sym->u.fun;
00787
00788 assert(cfun->titem->tic == tic_tfun);
00789 tcfun = cfun->titem->u.tfun;
00790
00791 tdata_item_subst(ifun->titem, if_tvv, &sifun_ti);
00792 assert(sifun_ti->tic == tic_tfun);
00793 tifun = sifun_ti->u.tfun;
00794
00795 if (!stype_fun_sig_equal(stype, tcfun->tsig, tifun->tsig)) {
00796 cspan_print(cfun->name->cspan);
00797 printf(" Error: Type of function '");
00798 symbol_print_fqn(cfun_sym);
00799 printf("' (");
00800 tdata_item_print(cfun->titem);
00801 printf(") does not match type of '");
00802 symbol_print_fqn(ifun_sym);
00803 printf("' (");
00804 tdata_item_print(sifun_ti);
00805 printf(") which it should implement.\n");
00806 stype_note_error(stype);
00807 }
00808 }
00809
00817 static void stype_class_impl_check_prop(stype_t *stype,
00818 stree_symbol_t *cprop_sym, tdata_tvv_t *if_tvv, stree_symbol_t *iprop_sym)
00819 {
00820 stree_prop_t *cprop;
00821 stree_prop_t *iprop;
00822 tdata_item_t *siprop_ti;
00823
00824 #ifdef DEBUG_TYPE_TRACE
00825 printf("Verify that class '");
00826 symbol_print_fqn(csi_to_symbol(cprop_sym->outer_csi));
00827 printf("' implements property '");
00828 symbol_print_fqn(iprop_sym);
00829 printf("' properly.\n");
00830 #endif
00831 assert(cprop_sym->sc == sc_prop);
00832 cprop = cprop_sym->u.prop;
00833
00834 assert(iprop_sym->sc == sc_prop);
00835 iprop = iprop_sym->u.prop;
00836
00837 tdata_item_subst(iprop->titem, if_tvv, &siprop_ti);
00838
00839 if (!tdata_item_equal(cprop->titem, siprop_ti)) {
00840 cspan_print(cprop->name->cspan);
00841 printf(" Error: Type of property '");
00842 symbol_print_fqn(cprop_sym);
00843 printf("' (");
00844 tdata_item_print(cprop->titem);
00845 printf(") does not match type of '");
00846 symbol_print_fqn(iprop_sym);
00847 printf("' (");
00848 tdata_item_print(siprop_ti);
00849 printf(") which it should implement.\n");
00850 stype_note_error(stype);
00851 }
00852
00853 if (iprop->getter != NULL && cprop->getter == NULL) {
00854 cspan_print(cprop->name->cspan);
00855 printf(" Error: Property '");
00856 symbol_print_fqn(cprop_sym);
00857 printf("' is missing a getter, which is required by '");
00858 symbol_print_fqn(iprop_sym);
00859 printf("'.\n");
00860 stype_note_error(stype);
00861 }
00862
00863 if (iprop->setter != NULL && cprop->setter == NULL) {
00864 cspan_print(cprop->name->cspan);
00865 printf(" Error: Property '");
00866 symbol_print_fqn(cprop_sym);
00867 printf("' is missing a setter, which is required by '");
00868 symbol_print_fqn(iprop_sym);
00869 printf("'.\n");
00870 stype_note_error(stype);
00871 }
00872 }
00873
00884 void stype_stat(stype_t *stype, stree_stat_t *stat, bool_t want_value)
00885 {
00886 #ifdef DEBUG_TYPE_TRACE
00887 printf("Type statement.\n");
00888 #endif
00889 switch (stat->sc) {
00890 case st_vdecl: stype_vdecl(stype, stat->u.vdecl_s); break;
00891 case st_if: stype_if(stype, stat->u.if_s); break;
00892 case st_switch: stype_switch(stype, stat->u.switch_s); break;
00893 case st_while: stype_while(stype, stat->u.while_s); break;
00894 case st_for: stype_for(stype, stat->u.for_s); break;
00895 case st_raise: stype_raise(stype, stat->u.raise_s); break;
00896 case st_break: stype_break(stype, stat->u.break_s); break;
00897 case st_return: stype_return(stype, stat->u.return_s); break;
00898 case st_exps: stype_exps(stype, stat->u.exp_s, want_value); break;
00899 case st_wef: stype_wef(stype, stat->u.wef_s); break;
00900 }
00901 }
00902
00908 static void stype_vdecl(stype_t *stype, stree_vdecl_t *vdecl_s)
00909 {
00910 stype_block_vr_t *block_vr;
00911 stree_vdecl_t *old_vdecl;
00912 tdata_item_t *titem;
00913
00914 #ifdef DEBUG_TYPE_TRACE
00915 printf("Type variable declaration statement.\n");
00916 #endif
00917 block_vr = stype_get_current_block_vr(stype);
00918 old_vdecl = (stree_vdecl_t *) intmap_get(&block_vr->vdecls,
00919 vdecl_s->name->sid);
00920
00921 if (old_vdecl != NULL) {
00922 printf("Error: Duplicate variable declaration '%s'.\n",
00923 strtab_get_str(vdecl_s->name->sid));
00924 stype_note_error(stype);
00925 }
00926
00927 run_texpr(stype->program, stype->current_csi, vdecl_s->type,
00928 &titem);
00929 if (titem->tic == tic_ignore) {
00930
00931 stype_note_error(stype);
00932 return;
00933 }
00934
00935
00936 vdecl_s->titem = titem;
00937
00938 intmap_set(&block_vr->vdecls, vdecl_s->name->sid, vdecl_s);
00939 }
00940
00946 static void stype_if(stype_t *stype, stree_if_t *if_s)
00947 {
00948 stree_expr_t *ccond;
00949 list_node_t *ifc_node;
00950 stree_if_clause_t *ifc;
00951
00952 #ifdef DEBUG_TYPE_TRACE
00953 printf("Type 'if' statement.\n");
00954 #endif
00955 ifc_node = list_first(&if_s->if_clauses);
00956
00957
00958
00959 while (ifc_node != NULL) {
00960
00961 ifc = list_node_data(ifc_node, stree_if_clause_t *);
00962
00963
00964 stype_expr(stype, ifc->cond);
00965 ccond = stype_convert(stype, ifc->cond,
00966 stype_boolean_titem(stype));
00967
00968
00969 ifc->cond = ccond;
00970
00971
00972 stype_block(stype, ifc->block);
00973
00974 ifc_node = list_next(&if_s->if_clauses, ifc_node);
00975 }
00976
00977
00978 if (if_s->else_block != NULL)
00979 stype_block(stype, if_s->else_block);
00980 }
00981
00987 static void stype_switch(stype_t *stype, stree_switch_t *switch_s)
00988 {
00989 stree_expr_t *expr, *cexpr;
00990 list_node_t *whenc_node;
00991 stree_when_t *whenc;
00992 list_node_t *expr_node;
00993 tdata_item_t *titem1, *titem2;
00994
00995 #ifdef DEBUG_TYPE_TRACE
00996 printf("Type 'switch' statement.\n");
00997 #endif
00998 stype_expr(stype, switch_s->expr);
00999
01000 titem1 = switch_s->expr->titem;
01001 if (titem1 == NULL) {
01002 cspan_print(switch_s->expr->cspan);
01003 printf(" Error: Switch expression has no value.\n");
01004 stype_note_error(stype);
01005 return;
01006 }
01007
01008
01009 whenc_node = list_first(&switch_s->when_clauses);
01010
01011 while (whenc_node != NULL) {
01012
01013 whenc = list_node_data(whenc_node, stree_when_t *);
01014
01015
01016 expr_node = list_first(&whenc->exprs);
01017 while (expr_node != NULL) {
01018 expr = list_node_data(expr_node, stree_expr_t *);
01019
01020 stype_expr(stype, expr);
01021 titem2 = expr->titem;
01022 if (titem2 == NULL) {
01023 cspan_print(expr->cspan);
01024 printf(" Error: When expression has no value.\n");
01025 stype_note_error(stype);
01026 return;
01027 }
01028
01029
01030 cexpr = stype_convert(stype, expr, titem1);
01031
01032
01033 list_node_setdata(expr_node, cexpr);
01034
01035 expr_node = list_next(&whenc->exprs, expr_node);
01036 }
01037
01038
01039 stype_block(stype, whenc->block);
01040
01041 whenc_node = list_next(&switch_s->when_clauses, whenc_node);
01042 }
01043
01044
01045 if (switch_s->else_block != NULL)
01046 stype_block(stype, switch_s->else_block);
01047 }
01048
01054 static void stype_while(stype_t *stype, stree_while_t *while_s)
01055 {
01056 stree_expr_t *ccond;
01057
01058 #ifdef DEBUG_TYPE_TRACE
01059 printf("Type 'while' statement.\n");
01060 #endif
01061
01062 stype_expr(stype, while_s->cond);
01063 ccond = stype_convert(stype, while_s->cond,
01064 stype_boolean_titem(stype));
01065
01066
01067 while_s->cond = ccond;
01068
01069
01070 stype->proc_vr->bstat_cnt += 1;
01071
01072
01073 stype_block(stype, while_s->body);
01074
01075 stype->proc_vr->bstat_cnt -= 1;
01076 }
01077
01083 static void stype_for(stype_t *stype, stree_for_t *for_s)
01084 {
01085 #ifdef DEBUG_TYPE_TRACE
01086 printf("Type 'for' statement.\n");
01087 #endif
01088
01089 stype->proc_vr->bstat_cnt += 1;
01090
01091 stype_block(stype, for_s->body);
01092
01093 stype->proc_vr->bstat_cnt -= 1;
01094 }
01095
01101 static void stype_raise(stype_t *stype, stree_raise_t *raise_s)
01102 {
01103 #ifdef DEBUG_TYPE_TRACE
01104 printf("Type 'raise' statement.\n");
01105 #endif
01106 stype_expr(stype, raise_s->expr);
01107 }
01108
01110 static void stype_break(stype_t *stype, stree_break_t *break_s)
01111 {
01112 #ifdef DEBUG_TYPE_TRACE
01113 printf("Type 'break' statement.\n");
01114 #endif
01115 (void) break_s;
01116
01117
01118 if (stype->proc_vr->bstat_cnt == 0) {
01119 printf("Error: Break statement outside of while or for.\n");
01120 stype_note_error(stype);
01121 }
01122 }
01123
01125 static void stype_return(stype_t *stype, stree_return_t *return_s)
01126 {
01127 stree_symbol_t *outer_sym;
01128 stree_fun_t *fun;
01129 stree_prop_t *prop;
01130
01131 stree_expr_t *cexpr;
01132 tdata_item_t *dtype;
01133
01134 #ifdef DEBUG_TYPE_TRACE
01135 printf("Type 'return' statement.\n");
01136 #endif
01137 if (return_s->expr != NULL)
01138 stype_expr(stype, return_s->expr);
01139
01140
01141
01142 outer_sym = stype->proc_vr->proc->outer_symbol;
01143 switch (outer_sym->sc) {
01144 case sc_fun:
01145 fun = symbol_to_fun(outer_sym);
01146 assert(fun != NULL);
01147
01148
01149 if (fun->sig->rtype != NULL) {
01150 run_texpr(stype->program, outer_sym->outer_csi,
01151 fun->sig->rtype, &dtype);
01152
01153 if (return_s->expr == NULL) {
01154 printf("Error: Return without a value in "
01155 "function returning value.\n");
01156 stype_note_error(stype);
01157 }
01158 } else {
01159 dtype = NULL;
01160
01161 if (return_s->expr != NULL) {
01162 printf("Error: Return with a value in "
01163 "value-less function.\n");
01164 stype_note_error(stype);
01165 }
01166 }
01167 break;
01168 case sc_prop:
01169 prop = symbol_to_prop(outer_sym);
01170 assert(prop != NULL);
01171
01172 if (stype->proc_vr->proc == prop->getter) {
01173 if (return_s->expr == NULL) {
01174 printf("Error: Return without a value in "
01175 "getter.\n");
01176 stype_note_error(stype);
01177 }
01178 } else {
01179 if (return_s->expr == NULL) {
01180 printf("Error: Return with a value in "
01181 "setter.\n");
01182 stype_note_error(stype);
01183 }
01184 }
01185
01186
01187 run_texpr(stype->program, outer_sym->outer_csi, prop->type,
01188 &dtype);
01189 break;
01190 default:
01191 assert(b_false);
01192 }
01193
01194 if (dtype != NULL && return_s->expr != NULL) {
01195
01196 cexpr = stype_convert(stype, return_s->expr, dtype);
01197
01198
01199 return_s->expr = cexpr;
01200 }
01201 }
01202
01208 static void stype_exps(stype_t *stype, stree_exps_t *exp_s, bool_t want_value)
01209 {
01210 #ifdef DEBUG_TYPE_TRACE
01211 printf("Type expression statement.\n");
01212 #endif
01213 stype_expr(stype, exp_s->expr);
01214
01215 if (want_value == b_false && exp_s->expr->titem != NULL) {
01216 cspan_print(exp_s->expr->cspan);
01217 printf(" Warning: Expression value ignored.\n");
01218 }
01219 }
01220
01226 static void stype_wef(stype_t *stype, stree_wef_t *wef_s)
01227 {
01228 list_node_t *ec_n;
01229 stree_except_t *ec;
01230
01231 #ifdef DEBUG_TYPE_TRACE
01232 printf("Type WEF statement.\n");
01233 #endif
01234
01235 if (wef_s->with_block != NULL)
01236 stype_block(stype, wef_s->with_block);
01237
01238
01239 ec_n = list_first(&wef_s->except_clauses);
01240 while (ec_n != NULL) {
01241 ec = list_node_data(ec_n, stree_except_t *);
01242 run_texpr(stype->program, stype->current_csi, ec->etype,
01243 &ec->titem);
01244 stype_block(stype, ec->block);
01245
01246 ec_n = list_next(&wef_s->except_clauses, ec_n);
01247 }
01248
01249
01250 if (wef_s->finally_block != NULL)
01251 stype_block(stype, wef_s->finally_block);
01252 }
01253
01272 stree_expr_t *stype_convert(stype_t *stype, stree_expr_t *expr,
01273 tdata_item_t *dest)
01274 {
01275 tdata_item_t *src;
01276
01277 src = expr->titem;
01278
01279 #ifdef DEBUG_TYPE_TRACE
01280 printf("Convert '");
01281 tdata_item_print(src);
01282 printf("' to '");
01283 tdata_item_print(dest);
01284 printf("'.\n");
01285 #endif
01286
01287 if (dest == NULL) {
01288 printf("Error: Conversion destination is not valid.\n");
01289 stype_note_error(stype);
01290 return expr;
01291 }
01292
01293 if (src == NULL) {
01294 cspan_print(expr->cspan);
01295 printf(" Error: Conversion source is not valid.\n");
01296 stype_note_error(stype);
01297 return expr;
01298 }
01299
01300 if (dest->tic == tic_ignore || src->tic == tic_ignore)
01301 return expr;
01302
01303
01304
01305
01306 if (src->tic == tic_tprimitive && src->u.tprimitive->tpc == tpc_nil) {
01307 if (dest->tic == tic_tobject)
01308 return expr;
01309 }
01310
01311 if (src->tic == tic_tprimitive && dest->tic == tic_tobject) {
01312 return stype_convert_tprim_tobj(stype, expr, dest);
01313 }
01314
01315 if (src->tic == tic_tfun && dest->tic == tic_tdeleg) {
01316 return stype_convert_tfun_tdeleg(stype, expr, dest);
01317 }
01318
01319 if (src->tic == tic_tebase) {
01320 stype_convert_failure(stype, convc_implicit, expr, dest);
01321 printf("Invalid use of reference to enum type in "
01322 "expression.\n");
01323 return expr;
01324 }
01325
01326 if (src->tic != dest->tic) {
01327 stype_convert_failure(stype, convc_implicit, expr, dest);
01328 return expr;
01329 }
01330
01331 switch (src->tic) {
01332 case tic_tprimitive:
01333 expr = stype_convert_tprimitive(stype, expr, dest);
01334 break;
01335 case tic_tobject:
01336 expr = stype_convert_tobject(stype, expr, dest);
01337 break;
01338 case tic_tarray:
01339 expr = stype_convert_tarray(stype, expr, dest);
01340 break;
01341 case tic_tdeleg:
01342 expr = stype_convert_tdeleg(stype, expr, dest);
01343 break;
01344 case tic_tebase:
01345
01346 assert(b_false);
01347 case tic_tenum:
01348 expr = stype_convert_tenum(stype, expr, dest);
01349 break;
01350 case tic_tfun:
01351 assert(b_false);
01352 case tic_tvref:
01353 expr = stype_convert_tvref(stype, expr, dest);
01354 break;
01355 case tic_ignore:
01356 assert(b_false);
01357 }
01358
01359 return expr;
01360 }
01361
01368 static stree_expr_t *stype_convert_tprimitive(stype_t *stype,
01369 stree_expr_t *expr, tdata_item_t *dest)
01370 {
01371 tdata_item_t *src;
01372
01373 #ifdef DEBUG_TYPE_TRACE
01374 printf("Convert primitive type.\n");
01375 #endif
01376 src = expr->titem;
01377 assert(src->tic == tic_tprimitive);
01378 assert(dest->tic == tic_tprimitive);
01379
01380
01381 if (src->u.tprimitive->tpc != dest->u.tprimitive->tpc)
01382 stype_convert_failure(stype, convc_implicit, expr, dest);
01383
01384 return expr;
01385 }
01386
01396 static stree_expr_t *stype_convert_tprim_tobj(stype_t *stype,
01397 stree_expr_t *expr, tdata_item_t *dest)
01398 {
01399 tdata_item_t *src;
01400 builtin_t *bi;
01401 stree_symbol_t *csi_sym;
01402 stree_symbol_t *bp_sym;
01403 stree_box_t *box;
01404 stree_expr_t *bexpr;
01405
01406 #ifdef DEBUG_TYPE_TRACE
01407 printf("Convert primitive type to object.\n");
01408 #endif
01409 src = expr->titem;
01410 assert(src->tic == tic_tprimitive);
01411 assert(dest->tic == tic_tobject);
01412
01413 bi = stype->program->builtin;
01414 csi_sym = csi_to_symbol(dest->u.tobject->csi);
01415
01416
01417 bp_sym = NULL;
01418
01419 switch (src->u.tprimitive->tpc) {
01420 case tpc_bool: bp_sym = bi->boxed_bool; break;
01421 case tpc_char: bp_sym = bi->boxed_char; break;
01422 case tpc_int: bp_sym = bi->boxed_int; break;
01423 case tpc_nil: assert(b_false);
01424 case tpc_string: bp_sym = bi->boxed_string; break;
01425 case tpc_resource:
01426 stype_convert_failure(stype, convc_implicit, expr, dest);
01427 return expr;
01428 }
01429
01430
01431 if (csi_sym != bp_sym && csi_sym != bi->gf_class)
01432 stype_convert_failure(stype, convc_implicit, expr, dest);
01433
01434
01435 box = stree_box_new();
01436 box->arg = expr;
01437 bexpr = stree_expr_new(ec_box);
01438 bexpr->u.box = box;
01439 bexpr->titem = dest;
01440
01441
01442
01443 return bexpr;
01444 }
01445
01452 static stree_expr_t *stype_convert_tobject(stype_t *stype, stree_expr_t *expr,
01453 tdata_item_t *dest)
01454 {
01455 tdata_item_t *src;
01456 tdata_item_t *pred_ti;
01457
01458 #ifdef DEBUG_TYPE_TRACE
01459 printf("Convert object type.\n");
01460 #endif
01461 src = expr->titem;
01462 assert(src->tic == tic_tobject);
01463 assert(dest->tic == tic_tobject);
01464
01465
01466
01467
01468
01469 pred_ti = stype_tobject_find_pred(stype, src, dest);
01470 if (pred_ti == NULL) {
01471 stype_convert_failure(stype, convc_implicit, expr, dest);
01472 printf("Not a base class or implemented or accumulated "
01473 "interface.\n");
01474 return expr;
01475 }
01476
01477
01478
01479
01480
01481 if (stype_targs_check_equal(stype, pred_ti, dest) != EOK) {
01482 stype_convert_failure(stype, convc_implicit, expr, dest);
01483 return expr;
01484 }
01485
01486 return expr;
01487 }
01488
01495 static stree_expr_t *stype_convert_tarray(stype_t *stype, stree_expr_t *expr,
01496 tdata_item_t *dest)
01497 {
01498 tdata_item_t *src;
01499
01500 #ifdef DEBUG_TYPE_TRACE
01501 printf("Convert array type.\n");
01502 #endif
01503 src = expr->titem;
01504 assert(src->tic == tic_tarray);
01505 assert(dest->tic == tic_tarray);
01506
01507
01508 if (src->u.tarray->rank != dest->u.tarray->rank) {
01509 stype_convert_failure(stype, convc_implicit, expr, dest);
01510 return expr;
01511 }
01512
01513
01514 if (tdata_item_equal(src->u.tarray->base_ti,
01515 dest->u.tarray->base_ti) != b_true) {
01516 stype_convert_failure(stype, convc_implicit, expr, dest);
01517 }
01518
01519 return expr;
01520 }
01521
01528 static stree_expr_t *stype_convert_tdeleg(stype_t *stype, stree_expr_t *expr,
01529 tdata_item_t *dest)
01530 {
01531 tdata_item_t *src;
01532 tdata_deleg_t *sdeleg, *ddeleg;
01533
01534 #ifdef DEBUG_TYPE_TRACE
01535 printf("Convert delegate type.\n");
01536 #endif
01537 src = expr->titem;
01538 assert(src->tic == tic_tdeleg);
01539 assert(dest->tic == tic_tdeleg);
01540
01541 sdeleg = src->u.tdeleg;
01542 ddeleg = dest->u.tdeleg;
01543
01544
01545
01546
01547
01548
01549
01550 assert(ddeleg->deleg != NULL);
01551
01552
01553 if (sdeleg->deleg != ddeleg->deleg) {
01554 stype_convert_failure(stype, convc_implicit, expr, dest);
01555 return expr;
01556 }
01557
01558 return expr;
01559 }
01560
01567 static stree_expr_t *stype_convert_tenum(stype_t *stype, stree_expr_t *expr,
01568 tdata_item_t *dest)
01569 {
01570 tdata_item_t *src;
01571 tdata_enum_t *senum, *denum;
01572
01573 #ifdef DEBUG_TYPE_TRACE
01574 printf("Convert enum type.\n");
01575 #endif
01576 src = expr->titem;
01577 assert(src->tic == tic_tenum);
01578 assert(dest->tic == tic_tenum);
01579
01580 senum = src->u.tenum;
01581 denum = dest->u.tenum;
01582
01583
01584
01585
01586
01587
01588 if (senum->enum_d != denum->enum_d) {
01589 stype_convert_failure(stype, convc_implicit, expr, dest);
01590 return expr;
01591 }
01592
01593 return expr;
01594 }
01595
01602 static stree_expr_t *stype_convert_tfun_tdeleg(stype_t *stype,
01603 stree_expr_t *expr, tdata_item_t *dest)
01604 {
01605 tdata_item_t *src;
01606 tdata_fun_t *sfun;
01607 tdata_deleg_t *ddeleg;
01608 tdata_fun_sig_t *ssig, *dsig;
01609
01610 #ifdef DEBUG_TYPE_TRACE
01611 printf("Convert delegate type.\n");
01612 #endif
01613 src = expr->titem;
01614 assert(src->tic == tic_tfun);
01615 assert(dest->tic == tic_tdeleg);
01616
01617 sfun = src->u.tfun;
01618 ddeleg = dest->u.tdeleg;
01619
01620 ssig = sfun->tsig;
01621 assert(ssig != NULL);
01622 dsig = stype_deleg_get_sig(stype, ddeleg);
01623 assert(dsig != NULL);
01624
01625
01626
01627 if (!stype_fun_sig_equal(stype, ssig, dsig)) {
01628 stype_convert_failure(stype, convc_implicit, expr, dest);
01629 return expr;
01630 }
01631
01632
01633
01634
01635
01636
01637
01638 return expr;
01639 }
01640
01641
01648 static stree_expr_t *stype_convert_tvref(stype_t *stype, stree_expr_t *expr,
01649 tdata_item_t *dest)
01650 {
01651 tdata_item_t *src;
01652
01653 #ifdef DEBUG_TYPE_TRACE
01654 printf("Convert variable type.\n");
01655 #endif
01656 src = expr->titem;
01657
01658
01659 if (src->u.tvref->targ != dest->u.tvref->targ) {
01660 stype_convert_failure(stype, convc_implicit, expr, dest);
01661 return expr;
01662 }
01663
01664 return expr;
01665 }
01666
01673 void stype_convert_failure(stype_t *stype, stype_conv_class_t convc,
01674 stree_expr_t *expr, tdata_item_t *dest)
01675 {
01676 cspan_print(expr->cspan);
01677 printf(" Error: ");
01678 switch (convc) {
01679 case convc_implicit: printf("Cannot implicitly convert '"); break;
01680 case convc_as: printf("Cannot use 'as' to convert '"); break;
01681 }
01682
01683 tdata_item_print(expr->titem);
01684 printf(" to ");
01685 tdata_item_print(dest);
01686 printf(".\n");
01687
01688 stype_note_error(stype);
01689 }
01690
01700 stree_expr_t *stype_box_expr(stype_t *stype, stree_expr_t *expr)
01701 {
01702 tdata_item_t *src;
01703 builtin_t *bi;
01704 stree_symbol_t *bp_sym;
01705 stree_box_t *box;
01706 stree_expr_t *bexpr;
01707 tdata_object_t *tobject;
01708
01709 #ifdef DEBUG_TYPE_TRACE
01710 printf("Boxing.\n");
01711 #endif
01712 src = expr->titem;
01713 assert(src->tic == tic_tprimitive);
01714
01715 bi = stype->program->builtin;
01716
01717
01718 bp_sym = NULL;
01719
01720 switch (src->u.tprimitive->tpc) {
01721 case tpc_bool: bp_sym = bi->boxed_bool; break;
01722 case tpc_char: bp_sym = bi->boxed_char; break;
01723 case tpc_int: bp_sym = bi->boxed_int; break;
01724 case tpc_nil: assert(b_false);
01725 case tpc_string: bp_sym = bi->boxed_string; break;
01726 case tpc_resource:
01727 cspan_print(expr->cspan);
01728 printf(" Error: Cannot use ");
01729 tdata_item_print(expr->titem);
01730 printf(" as an object.\n");
01731
01732 stype_note_error(stype);
01733 return expr;
01734 }
01735
01736
01737 box = stree_box_new();
01738 box->arg = expr;
01739 bexpr = stree_expr_new(ec_box);
01740 bexpr->u.box = box;
01741 bexpr->titem = tdata_item_new(tic_tobject);
01742 tobject = tdata_object_new();
01743 bexpr->titem->u.tobject = tobject;
01744
01745 tobject->csi = symbol_to_csi(bp_sym);
01746 assert(tobject->csi != NULL);
01747
01748 return bexpr;
01749 }
01750
01763 tdata_item_t *stype_tobject_find_pred(stype_t *stype, tdata_item_t *src,
01764 tdata_item_t *dest)
01765 {
01766 stree_csi_t *src_csi;
01767 tdata_tvv_t *tvv;
01768 tdata_item_t *b_ti, *bs_ti;
01769
01770 list_node_t *pred_n;
01771 stree_texpr_t *pred_te;
01772
01773 tdata_item_t *res_ti;
01774
01775 #ifdef DEBUG_TYPE_TRACE
01776 printf("Find CSI predecessor.\n");
01777 #endif
01778 assert(src->tic == tic_tobject);
01779 assert(dest->tic == tic_tobject);
01780
01781 if (src->u.tobject->csi == dest->u.tobject->csi)
01782 return src;
01783
01784 src_csi = src->u.tobject->csi;
01785 stype_titem_to_tvv(stype, src, &tvv);
01786
01787 res_ti = NULL;
01788
01789 switch (dest->u.tobject->csi->cc) {
01790 case csi_class:
01791
01792 pred_te = symbol_get_base_class_ref(stype->program,
01793 src_csi);
01794 if (pred_te != NULL) {
01795 run_texpr(stype->program, src_csi, pred_te,
01796 &b_ti);
01797 } else if (src_csi->base_csi != NULL &&
01798 src->u.tobject->csi->cc == csi_class) {
01799
01800 b_ti = tdata_item_new(tic_tobject);
01801 b_ti->u.tobject = tdata_object_new();
01802 b_ti->u.tobject->csi = src_csi->base_csi;
01803 b_ti->u.tobject->static_ref = sn_nonstatic;
01804
01805 list_init(&b_ti->u.tobject->targs);
01806 } else {
01807
01808 return NULL;
01809 }
01810
01811
01812 tdata_item_subst(b_ti, tvv, &bs_ti);
01813 assert(bs_ti->tic == tic_tobject);
01814
01815
01816 res_ti = stype_tobject_find_pred(stype, bs_ti, dest);
01817 if (b_ti->tic == tic_ignore) {
01818
01819 return NULL;
01820 }
01821 break;
01822 case csi_struct:
01823 assert(b_false);
01824 case csi_interface:
01825
01826
01827
01828
01829 pred_n = list_first(&src_csi->inherit);
01830 while (pred_n != NULL) {
01831 pred_te = list_node_data(pred_n, stree_texpr_t *);
01832 run_texpr(stype->program, src_csi, pred_te,
01833 &b_ti);
01834
01835
01836 tdata_item_subst(b_ti, tvv, &bs_ti);
01837 assert(bs_ti->tic == tic_tobject);
01838
01839
01840 res_ti = stype_tobject_find_pred(stype, bs_ti, dest);
01841 if (res_ti != NULL)
01842 break;
01843
01844 pred_n = list_next(&src_csi->inherit, pred_n);
01845 }
01846 break;
01847 }
01848
01849 return res_ti;
01850 }
01851
01866 int stype_targs_check_equal(stype_t *stype, tdata_item_t *a_ti,
01867 tdata_item_t *b_ti)
01868 {
01869 list_node_t *arg_a_n, *arg_b_n;
01870 tdata_item_t *arg_a, *arg_b;
01871
01872 (void) stype;
01873
01874 #ifdef DEBUG_TYPE_TRACE
01875 printf("Check if type arguments match.\n");
01876 #endif
01877 assert(a_ti->tic == tic_tobject);
01878 assert(b_ti->tic == tic_tobject);
01879
01880
01881
01882
01883
01884 arg_a_n = list_first(&a_ti->u.tobject->targs);
01885 arg_b_n = list_first(&b_ti->u.tobject->targs);
01886
01887 while (arg_a_n != NULL && arg_b_n != NULL) {
01888 arg_a = list_node_data(arg_a_n, tdata_item_t *);
01889 arg_b = list_node_data(arg_b_n, tdata_item_t *);
01890
01891 if (tdata_item_equal(arg_a, arg_b) != b_true) {
01892
01893 printf("Different argument type '");
01894 tdata_item_print(arg_a);
01895 printf("' vs. '");
01896 tdata_item_print(arg_b);
01897 printf("'.\n");
01898 return EINVAL;
01899 }
01900
01901 arg_a_n = list_next(&a_ti->u.tobject->targs, arg_a_n);
01902 arg_b_n = list_next(&b_ti->u.tobject->targs, arg_b_n);
01903 }
01904
01905 if (arg_a_n != NULL || arg_b_n != NULL) {
01906
01907 printf("Different number of arguments.\n");
01908 return EINVAL;
01909 }
01910
01911 return EOK;
01912 }
01913
01914
01924 static bool_t stype_fun_sig_equal(stype_t *stype, tdata_fun_sig_t *asig,
01925 tdata_fun_sig_t *bsig)
01926 {
01927 list_node_t *aarg_n, *barg_n;
01928 tdata_item_t *aarg_ti, *barg_ti;
01929
01930 (void) stype;
01931
01932
01933 aarg_n = list_first(&asig->arg_ti);
01934 barg_n = list_first(&bsig->arg_ti);
01935
01936 while (aarg_n != NULL && barg_n != NULL) {
01937 aarg_ti = list_node_data(aarg_n, tdata_item_t *);
01938 barg_ti = list_node_data(barg_n, tdata_item_t *);
01939
01940 if (!tdata_item_equal(aarg_ti, barg_ti))
01941 return b_false;
01942
01943 aarg_n = list_next(&asig->arg_ti, aarg_n);
01944 barg_n = list_next(&bsig->arg_ti, barg_n);
01945 }
01946
01947 if (aarg_n != NULL || barg_n != NULL)
01948 return b_false;
01949
01950
01951
01952 if (asig->varg_ti != NULL || bsig->varg_ti != NULL) {
01953 if (asig->varg_ti == NULL ||
01954 bsig->varg_ti == NULL) {
01955 return b_false;
01956 }
01957
01958 if (!tdata_item_equal(asig->varg_ti, bsig->varg_ti)) {
01959 return b_false;
01960 }
01961 }
01962
01963
01964
01965 if (asig->rtype != NULL || bsig->rtype != NULL) {
01966 if (asig->rtype == NULL ||
01967 bsig->rtype == NULL) {
01968 return b_false;
01969 }
01970
01971 if (!tdata_item_equal(asig->rtype, bsig->rtype)) {
01972 return b_false;
01973 }
01974 }
01975
01976 return b_true;
01977 }
01978
01985 tdata_fun_sig_t *stype_deleg_get_sig(stype_t *stype, tdata_deleg_t *tdeleg)
01986 {
01987 if (tdeleg->tsig == NULL)
01988 stype_deleg(stype, tdeleg->deleg);
01989
01990
01991 assert(tdeleg->tsig != NULL);
01992 return tdeleg->tsig;
01993 }
01994
02009 void stype_titem_to_tvv(stype_t *stype, tdata_item_t *ti, tdata_tvv_t **rtvv)
02010 {
02011 tdata_tvv_t *tvv;
02012 stree_csi_t *csi;
02013
02014 list_node_t *formal_n;
02015 list_node_t *real_n;
02016
02017 stree_targ_t *formal_arg;
02018 tdata_item_t *real_arg;
02019
02020 assert(ti->tic == tic_tobject);
02021
02022 tvv = tdata_tvv_new();
02023 intmap_init(&tvv->tvv);
02024
02025 csi = ti->u.tobject->csi;
02026 formal_n = list_first(&csi->targ);
02027 real_n = list_first(&ti->u.tobject->targs);
02028
02029 while (formal_n != NULL && real_n != NULL) {
02030 formal_arg = list_node_data(formal_n, stree_targ_t *);
02031 real_arg = list_node_data(real_n, tdata_item_t *);
02032
02033
02034 tdata_tvv_set_val(tvv, formal_arg->name->sid, real_arg);
02035
02036 formal_n = list_next(&csi->targ, formal_n);
02037 real_n = list_next(&ti->u.tobject->targs, real_n);
02038 }
02039
02040 if (formal_n != NULL || real_n != NULL) {
02041 printf("Error: Incorrect number of type arguments.\n");
02042 stype_note_error(stype);
02043
02044
02045 while (formal_n != NULL) {
02046 formal_arg = list_node_data(formal_n, stree_targ_t *);
02047
02048 tdata_tvv_set_val(tvv, formal_arg->name->sid,
02049 stype_recovery_titem(stype));
02050
02051 formal_n = list_next(&csi->targ, formal_n);
02052 }
02053 }
02054
02055 *rtvv = tvv;
02056 }
02057
02063 tdata_item_t *stype_boolean_titem(stype_t *stype)
02064 {
02065 tdata_item_t *titem;
02066 tdata_primitive_t *tprimitive;
02067
02068 (void) stype;
02069
02070 titem = tdata_item_new(tic_tprimitive);
02071 tprimitive = tdata_primitive_new(tpc_bool);
02072 titem->u.tprimitive = tprimitive;
02073
02074 return titem;
02075 }
02076
02084 stree_vdecl_t *stype_local_vars_lookup(stype_t *stype, sid_t name)
02085 {
02086 stype_proc_vr_t *proc_vr;
02087 stype_block_vr_t *block_vr;
02088 stree_vdecl_t *vdecl;
02089 list_node_t *node;
02090
02091 proc_vr = stype->proc_vr;
02092 node = list_last(&proc_vr->block_vr);
02093
02094
02095 while (node != NULL) {
02096 block_vr = list_node_data(node, stype_block_vr_t *);
02097 vdecl = intmap_get(&block_vr->vdecls, name);
02098 if (vdecl != NULL)
02099 return vdecl;
02100
02101 node = list_prev(&proc_vr->block_vr, node);
02102 }
02103
02104
02105 return NULL;
02106 }
02107
02115 stree_proc_arg_t *stype_proc_args_lookup(stype_t *stype, sid_t name)
02116 {
02117 stype_proc_vr_t *proc_vr;
02118
02119 stree_symbol_t *outer_sym;
02120 stree_ctor_t *ctor;
02121 stree_fun_t *fun;
02122 stree_prop_t *prop;
02123
02124 list_t *args;
02125 list_node_t *arg_node;
02126 stree_proc_arg_t *varg;
02127 stree_proc_arg_t *arg;
02128 stree_proc_arg_t *setter_arg;
02129
02130 proc_vr = stype->proc_vr;
02131 outer_sym = proc_vr->proc->outer_symbol;
02132
02133 setter_arg = NULL;
02134
02135 #ifdef DEBUG_TYPE_TRACE
02136 printf("Look for argument named '%s'.\n", strtab_get_str(name));
02137 #endif
02138
02139
02140 args = NULL;
02141 varg = NULL;
02142
02143 switch (outer_sym->sc) {
02144 case sc_ctor:
02145 ctor = symbol_to_ctor(outer_sym);
02146 assert(ctor != NULL);
02147 args = &ctor->sig->args;
02148 varg = ctor->sig->varg;
02149 break;
02150 case sc_fun:
02151 fun = symbol_to_fun(outer_sym);
02152 assert(fun != NULL);
02153 args = &fun->sig->args;
02154 varg = fun->sig->varg;
02155 break;
02156 case sc_prop:
02157 prop = symbol_to_prop(outer_sym);
02158 assert(prop != NULL);
02159 args = &prop->args;
02160 varg = prop->varg;
02161
02162
02163 if (prop->setter == proc_vr->proc)
02164 setter_arg = prop->setter_arg;
02165 break;
02166 case sc_csi:
02167 case sc_deleg:
02168 case sc_enum:
02169 case sc_var:
02170 assert(b_false);
02171 }
02172
02173 arg_node = list_first(args);
02174 while (arg_node != NULL) {
02175 arg = list_node_data(arg_node, stree_proc_arg_t *);
02176 if (arg->name->sid == name) {
02177
02178 #ifdef DEBUG_TYPE_TRACE
02179 printf("Found argument.\n");
02180 #endif
02181 return arg;
02182 }
02183
02184 arg_node = list_next(args, arg_node);
02185 }
02186
02187
02188 if (varg != NULL && varg->name->sid == name) {
02189 #ifdef DEBUG_TYPE_TRACE
02190 printf("Found variadic argument.\n");
02191 #endif
02192 return varg;
02193 }
02194
02195
02196 if (setter_arg != NULL && setter_arg->name->sid == name) {
02197 #ifdef DEBUG_TYPE_TRACE
02198 printf("Found setter argument.\n");
02199 #endif
02200 return setter_arg;
02201
02202 }
02203
02204 #ifdef DEBUG_TYPE_TRACE
02205 printf("Not found.\n");
02206 #endif
02207
02208 return NULL;
02209 }
02210
02215 void stype_note_error(stype_t *stype)
02216 {
02217 stype->error = b_true;
02218 }
02219
02227 tdata_item_t *stype_recovery_titem(stype_t *stype)
02228 {
02229 tdata_item_t *titem;
02230
02231 (void) stype;
02232
02233 titem = tdata_item_new(tic_ignore);
02234 return titem;
02235 }
02236
02241 stype_block_vr_t *stype_get_current_block_vr(stype_t *stype)
02242 {
02243 list_node_t *node;
02244
02245 node = list_last(&stype->proc_vr->block_vr);
02246 return list_node_data(node, stype_block_vr_t *);
02247 }
02248
02253 stype_proc_vr_t *stype_proc_vr_new(void)
02254 {
02255 stype_proc_vr_t *proc_vr;
02256
02257 proc_vr = calloc(1, sizeof(stype_proc_vr_t));
02258 if (proc_vr == NULL) {
02259 printf("Memory allocation failed.\n");
02260 exit(1);
02261 }
02262
02263 return proc_vr;
02264 }
02265
02270 stype_block_vr_t *stype_block_vr_new(void)
02271 {
02272 stype_block_vr_t *block_vr;
02273
02274 block_vr = calloc(1, sizeof(stype_block_vr_t));
02275 if (block_vr == NULL) {
02276 printf("Memory allocation failed.\n");
02277 exit(1);
02278 }
02279
02280 return block_vr;
02281 }