Changeset 38aaacc2 in mainline for uspace/app/sbi/src/stype.c
- Timestamp:
- 2010-04-23T21:41:10Z (15 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- f4f866c
- Parents:
- 074444f
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/sbi/src/stype.c
r074444f r38aaacc2 30 30 * @file Implements a walk on the program that computes and checks static 31 31 * types. 'Types' the program. 32 * 33 * If a type error is encountered, stype_note_error() is called to set 34 * the typing error flag. 32 35 */ 33 36 … … 53 56 static void stype_prop(stype_t *stype, stree_prop_t *prop); 54 57 58 static void stype_fun_sig(stype_t *stype, stree_csi_t *outer_csi, 59 stree_fun_sig_t *sig, tdata_fun_sig_t **rtsig); 60 static void stype_fun_body(stype_t *stype, stree_fun_t *fun); 55 61 static void stype_block(stype_t *stype, stree_block_t *block); 56 62 … … 64 70 static void stype_wef(stype_t *stype, stree_wef_t *wef_s); 65 71 66 /** Type module */ 72 static stree_expr_t *stype_convert_tprimitive(stype_t *stype, 73 stree_expr_t *expr, tdata_item_t *dest); 74 static stree_expr_t *stype_convert_tprim_tobj(stype_t *stype, 75 stree_expr_t *expr, tdata_item_t *dest); 76 static stree_expr_t *stype_convert_tobject(stype_t *stype, stree_expr_t *expr, 77 tdata_item_t *dest); 78 static stree_expr_t *stype_convert_tarray(stype_t *stype, stree_expr_t *expr, 79 tdata_item_t *dest); 80 static stree_expr_t *stype_convert_tdeleg(stype_t *stype, stree_expr_t *expr, 81 tdata_item_t *dest); 82 static stree_expr_t *stype_convert_tfun_tdeleg(stype_t *stype, 83 stree_expr_t *expr, tdata_item_t *dest); 84 static stree_expr_t *stype_convert_tvref(stype_t *stype, stree_expr_t *expr, 85 tdata_item_t *dest); 86 static void stype_convert_failure(stype_t *stype, tdata_item_t *src, 87 tdata_item_t *dest); 88 89 static bool_t stype_fun_sig_equal(stype_t *stype, tdata_fun_sig_t *asig, 90 tdata_fun_sig_t *sdig); 91 92 /** Type module. 93 * 94 * If the module contains a type error, @a stype->error will be set 95 * when this function returns. 96 * 97 * @param stype Static typing object 98 * @param module Module to type 99 */ 67 100 void stype_module(stype_t *stype, stree_module_t *module) 68 101 { … … 87 120 } 88 121 89 /** Type CSI */ 122 /** Type CSI. 123 * 124 * @param stype Static typing object 125 * @param csi CSI to type 126 */ 90 127 static void stype_csi(stype_t *stype, stree_csi_t *csi) 91 128 { … … 108 145 switch (csimbr->cc) { 109 146 case csimbr_csi: stype_csi(stype, csimbr->u.csi); break; 147 case csimbr_deleg: stype_deleg(stype, csimbr->u.deleg); break; 110 148 case csimbr_fun: stype_fun(stype, csimbr->u.fun); break; 111 149 case csimbr_var: stype_var(stype, csimbr->u.var); break; … … 119 157 } 120 158 121 /** Type function */ 159 /** Type delegate. 160 * 161 * @param stype Static typing object. 162 * @param deleg Delegate to type. 163 */ 164 void stype_deleg(stype_t *stype, stree_deleg_t *deleg) 165 { 166 stree_symbol_t *deleg_sym; 167 tdata_item_t *deleg_ti; 168 tdata_deleg_t *tdeleg; 169 tdata_fun_sig_t *tsig; 170 171 #ifdef DEBUG_TYPE_TRACE 172 printf("Type delegate '"); 173 symbol_print_fqn(deleg_to_symbol(deleg)); 174 printf("'.\n"); 175 #endif 176 if (deleg->titem == NULL) { 177 deleg_ti = tdata_item_new(tic_tdeleg); 178 deleg->titem = deleg_ti; 179 tdeleg = tdata_deleg_new(); 180 deleg_ti->u.tdeleg = tdeleg; 181 } else { 182 deleg_ti = deleg->titem; 183 assert(deleg_ti->u.tdeleg != NULL); 184 tdeleg = deleg_ti->u.tdeleg; 185 } 186 187 if (tdeleg->tsig != NULL) 188 return; /* Delegate has already been typed. */ 189 190 deleg_sym = deleg_to_symbol(deleg); 191 192 /* Type function signature. Store result in deleg->titem. */ 193 stype_fun_sig(stype, deleg_sym->outer_csi, deleg->sig, &tsig); 194 195 tdeleg->deleg = deleg; 196 tdeleg->tsig = tsig; 197 } 198 199 /** Type function. 200 * 201 * We split typing of function header and body because at the point we 202 * are typing the body of some function we may encounter function calls. 203 * To type a function call we first need to type the header of the function 204 * being called. 205 * 206 * @param stype Static typing object. 207 * @param fun Function to type. 208 */ 122 209 static void stype_fun(stype_t *stype, stree_fun_t *fun) 123 210 { 124 list_node_t *arg_n;125 stree_proc_arg_t *arg;126 stree_symbol_t *fun_sym;127 tdata_item_t *titem;128 129 211 #ifdef DEBUG_TYPE_TRACE 130 212 printf("Type function '"); … … 132 214 printf("'.\n"); 133 215 #endif 216 if (fun->titem == NULL) 217 stype_fun_header(stype, fun); 218 219 stype_fun_body(stype, fun); 220 } 221 222 /** Type function header. 223 * 224 * Types the header of @a fun (but not its body). 225 * 226 * @param stype Static typing object 227 * @param fun Funtction 228 */ 229 void stype_fun_header(stype_t *stype, stree_fun_t *fun) 230 { 231 stree_symbol_t *fun_sym; 232 tdata_item_t *fun_ti; 233 tdata_fun_t *tfun; 234 tdata_fun_sig_t *tsig; 235 236 #ifdef DEBUG_TYPE_TRACE 237 printf("Type function '"); 238 symbol_print_fqn(fun_to_symbol(fun)); 239 printf("' header.\n"); 240 #endif 241 if (fun->titem != NULL) 242 return; /* Function header has already been typed. */ 243 134 244 fun_sym = fun_to_symbol(fun); 245 246 /* Type function signature. */ 247 stype_fun_sig(stype, fun_sym->outer_csi, fun->sig, &tsig); 248 249 fun_ti = tdata_item_new(tic_tfun); 250 tfun = tdata_fun_new(); 251 fun_ti->u.tfun = tfun; 252 tfun->tsig = tsig; 253 254 fun->titem = fun_ti; 255 } 256 257 /** Type function signature. 258 * 259 * Types the function signature @a sig. 260 * 261 * @param stype Static typing object 262 * @param outer_csi CSI within which the signature is defined. 263 * @param sig Function signature 264 */ 265 static void stype_fun_sig(stype_t *stype, stree_csi_t *outer_csi, 266 stree_fun_sig_t *sig, tdata_fun_sig_t **rtsig) 267 { 268 list_node_t *arg_n; 269 stree_proc_arg_t *arg; 270 tdata_item_t *titem; 271 tdata_fun_sig_t *tsig; 272 273 #ifdef DEBUG_TYPE_TRACE 274 printf("Type function signature.\n"); 275 #endif 276 tsig = tdata_fun_sig_new(); 277 278 list_init(&tsig->arg_ti); 135 279 136 280 /* 137 281 * Type formal arguments. 138 * XXX Save the results.139 282 */ 140 arg_n = list_first(& fun->args);283 arg_n = list_first(&sig->args); 141 284 while (arg_n != NULL) { 142 285 arg = list_node_data(arg_n, stree_proc_arg_t *); … … 144 287 /* XXX Because of overloaded builtin WriteLine. */ 145 288 if (arg->type == NULL) { 146 arg_n = list_next(&fun->args, arg_n); 289 list_append(&tsig->arg_ti, NULL); 290 arg_n = list_next(&sig->args, arg_n); 147 291 continue; 148 292 } 149 293 150 run_texpr(stype->program, fun_sym->outer_csi, arg->type,151 &titem);152 153 arg_n = list_next(& fun->args, arg_n);294 run_texpr(stype->program, outer_csi, arg->type, &titem); 295 list_append(&tsig->arg_ti, titem); 296 297 arg_n = list_next(&sig->args, arg_n); 154 298 } 155 299 156 300 /* Variadic argument */ 157 if ( fun->varg != NULL) {301 if (sig->varg != NULL) { 158 302 /* Check type and verify it is an array. */ 159 run_texpr(stype->program, fun_sym->outer_csi, fun->varg->type,160 &titem);303 run_texpr(stype->program, outer_csi, sig->varg->type, &titem); 304 tsig->varg_ti = titem; 161 305 162 306 if (titem->tic != tic_tarray && titem->tic != tic_ignore) { … … 166 310 } 167 311 168 /* 169 * Type function body. 170 */ 312 /* Return type */ 313 if (sig->rtype != NULL) { 314 run_texpr(stype->program, outer_csi, sig->rtype, &titem); 315 tsig->rtype = titem; 316 } 317 318 *rtsig = tsig; 319 } 320 321 /** Type function body. 322 * 323 * Types the body of function @a fun (if it has one). 324 * 325 * @param stype Static typing object 326 * @param fun Funtction 327 */ 328 static void stype_fun_body(stype_t *stype, stree_fun_t *fun) 329 { 330 #ifdef DEBUG_TYPE_TRACE 331 printf("Type function '"); 332 symbol_print_fqn(fun_to_symbol(fun)); 333 printf("' body.\n"); 334 #endif 335 assert(stype->proc_vr == NULL); 171 336 172 337 /* Builtin functions do not have a body. */ … … 184 349 } 185 350 186 /** Type member variable */ 351 /** Type member variable. 352 * 353 * @param stype Static typing object 354 * @param var Member variable 355 */ 187 356 static void stype_var(stype_t *stype, stree_var_t *var) 188 357 { … … 201 370 } 202 371 203 /** Type property */ 372 /** Type property. 373 * 374 * @param stype Static typing object 375 * @param prop Property 376 */ 204 377 static void stype_prop(stype_t *stype, stree_prop_t *prop) 205 378 { … … 226 399 } 227 400 228 /** Type statement block */ 401 /** Type statement block. 402 * 403 * @param stype Static typing object 404 * @param block Statement block 405 */ 229 406 static void stype_block(stype_t *stype, stree_block_t *block) 230 407 { … … 265 442 * for nested statemens). This is used in interactive mode. 266 443 * 267 * @param stype Static typ er object.268 * @param stat Statement to type .269 * @param want_value @c b_true to allow ignoring expression value .444 * @param stype Static typing object 445 * @param stat Statement to type 446 * @param want_value @c b_true to allow ignoring expression value 270 447 */ 271 448 void stype_stat(stype_t *stype, stree_stat_t *stat, bool_t want_value) … … 286 463 } 287 464 288 /** Type local variable declaration */ 465 /** Type local variable declaration statement. 466 * 467 * @param stype Static typing object 468 * @param vdecl_s Variable delcaration statement 469 */ 289 470 static void stype_vdecl(stype_t *stype, stree_vdecl_t *vdecl_s) 290 471 { … … 317 498 } 318 499 319 /** Type @c if statement */ 500 /** Type @c if statement. 501 * 502 * @param stype Static typing object 503 * @param if_s @c if statement 504 */ 320 505 static void stype_if(stype_t *stype, stree_if_t *if_s) 321 506 { … … 340 525 } 341 526 342 /** Type @c while statement */ 527 /** Type @c while statement 528 * 529 * @param stype Static typing object 530 * @param while_s @c while statement 531 */ 343 532 static void stype_while(stype_t *stype, stree_while_t *while_s) 344 533 { … … 360 549 } 361 550 362 /** Type @c for statement */ 551 /** Type @c for statement. 552 * 553 * @param stype Static typing object 554 * @param for_s @c for statement 555 */ 363 556 static void stype_for(stype_t *stype, stree_for_t *for_s) 364 557 { … … 369 562 } 370 563 371 /** Type @c raise statement */ 564 /** Type @c raise statement. 565 * 566 * @param stype Static typing object 567 * @param raise_s @c raise statement 568 */ 372 569 static void stype_raise(stype_t *stype, stree_raise_t *raise_s) 373 570 { … … 402 599 403 600 /* XXX Memoize to avoid recomputing. */ 404 run_texpr(stype->program, outer_sym->outer_csi, fun->rtype,405 &dtype);601 run_texpr(stype->program, outer_sym->outer_csi, 602 fun->sig->rtype, &dtype); 406 603 break; 407 604 case sc_prop: … … 430 627 } 431 628 432 /** Type expression statement */ 629 /** Type expression statement. 630 * 631 * @param stype Static typing object 632 * @param exp_s Expression statement 633 */ 433 634 static void stype_exps(stype_t *stype, stree_exps_t *exp_s, bool_t want_value) 434 635 { … … 442 643 } 443 644 444 /** Type With-Except-Finally statement */ 645 /** Type with-except-finally statement. 646 * 647 * @param stype Static typing object 648 * @param wef_s With-except-finally statement 649 */ 445 650 static void stype_wef(stype_t *stype, stree_wef_t *wef_s) 446 651 { … … 482 687 * Note: No conversion that would require modifying @a expr is implemented 483 688 * yet. 689 * 690 * @param stype Static typing object 691 * @param expr Expression 692 * @param dest Destination type 484 693 */ 485 694 stree_expr_t *stype_convert(stype_t *stype, stree_expr_t *expr, … … 488 697 tdata_item_t *src; 489 698 490 (void) stype;491 699 src = expr->titem; 700 701 #ifdef DEBUG_TYPE_TRACE 702 printf("Convert '"); 703 tdata_item_print(src); 704 printf("' to '"); 705 tdata_item_print(dest); 706 printf("'.\n"); 707 #endif 492 708 493 709 if (dest == NULL) { … … 514 730 } 515 731 516 if (src->tic != dest->tic) 517 goto failure; 732 if (src->tic == tic_tprimitive && dest->tic == tic_tobject) { 733 return stype_convert_tprim_tobj(stype, expr, dest); 734 } 735 736 if (src->tic == tic_tfun && dest->tic == tic_tdeleg) { 737 return stype_convert_tfun_tdeleg(stype, expr, dest); 738 } 739 740 if (src->tic != dest->tic) { 741 stype_convert_failure(stype, src, dest); 742 return expr; 743 } 518 744 519 745 switch (src->tic) { 520 746 case tic_tprimitive: 521 /* Check if both have the same tprimitive class. */ 522 if (src->u.tprimitive->tpc != dest->u.tprimitive->tpc) 523 goto failure; 747 expr = stype_convert_tprimitive(stype, expr, dest); 524 748 break; 525 749 case tic_tobject: 526 /* Check if @c src is derived from @c dest. */ 527 if (stree_is_csi_derived_from_csi(src->u.tobject->csi, 528 dest->u.tobject->csi) != b_true) { 529 goto failure; 530 } 750 expr = stype_convert_tobject(stype, expr, dest); 531 751 break; 532 752 case tic_tarray: 533 /* Compare rank and base type. */ 534 if (src->u.tarray->rank != dest->u.tarray->rank) 535 goto failure; 536 537 /* XXX Should we convert each element? */ 538 if (tdata_item_equal(src->u.tarray->base_ti, 539 dest->u.tarray->base_ti) != b_true) 540 goto failure; 753 expr = stype_convert_tarray(stype, expr, dest); 754 break; 755 case tic_tdeleg: 756 expr = stype_convert_tdeleg(stype, expr, dest); 541 757 break; 542 758 case tic_tfun: 543 printf("Error: Unimplemented: Converting '"); 544 tdata_item_print(src); 545 printf("' to '"); 546 tdata_item_print(dest); 547 printf("'.\n"); 548 stype_note_error(stype); 759 assert(b_false); 760 case tic_tvref: 761 expr = stype_convert_tvref(stype, expr, dest); 549 762 break; 550 763 case tic_ignore: … … 553 766 554 767 return expr; 555 556 failure: 768 } 769 770 /** Convert expression of primitive type to primitive type. 771 * 772 * @param stype Static typing object 773 * @param expr Expression 774 * @param dest Destination type 775 */ 776 static stree_expr_t *stype_convert_tprimitive(stype_t *stype, 777 stree_expr_t *expr, tdata_item_t *dest) 778 { 779 tdata_item_t *src; 780 781 #ifdef DEBUG_TYPE_TRACE 782 printf("Convert primitive type.\n"); 783 #endif 784 src = expr->titem; 785 assert(src->tic == tic_tprimitive); 786 assert(dest->tic == tic_tprimitive); 787 788 /* Check if both have the same tprimitive class. */ 789 if (src->u.tprimitive->tpc != dest->u.tprimitive->tpc) 790 stype_convert_failure(stype, src, dest); 791 792 return expr; 793 } 794 795 /** Convert expression of primitive type to object type. 796 * 797 * This function implements autoboxing. It modified the code. 798 * 799 * @param stype Static typing object 800 * @param expr Expression 801 * @param dest Destination type 802 */ 803 static stree_expr_t *stype_convert_tprim_tobj(stype_t *stype, 804 stree_expr_t *expr, tdata_item_t *dest) 805 { 806 tdata_item_t *src; 807 builtin_t *bi; 808 stree_symbol_t *csi_sym; 809 stree_symbol_t *bp_sym; 810 stree_box_t *box; 811 stree_expr_t *bexpr; 812 813 #ifdef DEBUG_TYPE_TRACE 814 printf("Convert primitive type to object.\n"); 815 #endif 816 src = expr->titem; 817 assert(src->tic == tic_tprimitive); 818 assert(dest->tic == tic_tobject); 819 820 bi = stype->program->builtin; 821 csi_sym = csi_to_symbol(dest->u.tobject->csi); 822 823 switch (src->u.tprimitive->tpc) { 824 case tpc_bool: bp_sym = bi->boxed_bool; break; 825 case tpc_char: bp_sym = bi->boxed_char; break; 826 case tpc_int: bp_sym = bi->boxed_int; break; 827 case tpc_nil: assert(b_false); 828 case tpc_string: bp_sym = bi->boxed_string; break; 829 case tpc_resource: 830 stype_convert_failure(stype, src, dest); 831 return expr; 832 } 833 834 /* Target type must be boxed @a src or Object */ 835 if (csi_sym != bp_sym && csi_sym != bi->gf_class) 836 stype_convert_failure(stype, src, dest); 837 838 /* Patch the code to box the primitive value */ 839 box = stree_box_new(); 840 box->arg = expr; 841 bexpr = stree_expr_new(ec_box); 842 bexpr->u.box = box; 843 844 /* No action needed to optionally convert boxed type to Object */ 845 846 return bexpr; 847 } 848 849 /** Convert expression of object type to object type. 850 * 851 * @param stype Static typing object 852 * @param expr Expression 853 * @param dest Destination type 854 */ 855 static stree_expr_t *stype_convert_tobject(stype_t *stype, stree_expr_t *expr, 856 tdata_item_t *dest) 857 { 858 tdata_item_t *src; 859 tdata_item_t *cur; 860 stree_csi_t *cur_csi; 861 tdata_tvv_t *tvv; 862 tdata_item_t *b_ti, *bs_ti; 863 864 #ifdef DEBUG_TYPE_TRACE 865 printf("Convert object type.\n"); 866 #endif 867 list_node_t *ca_n, *da_n; 868 tdata_item_t *carg, *darg; 869 870 src = expr->titem; 871 assert(src->tic == tic_tobject); 872 assert(dest->tic == tic_tobject); 873 874 cur = src; 875 876 while (cur->u.tobject->csi != dest->u.tobject->csi) { 877 878 cur_csi = cur->u.tobject->csi; 879 stype_titem_to_tvv(stype, cur, &tvv); 880 881 if (cur_csi->base_csi_ref != NULL) { 882 run_texpr(stype->program, cur_csi, cur_csi->base_csi_ref, &b_ti); 883 if (b_ti->tic == tic_ignore) { 884 /* An error occured. */ 885 stype_note_error(stype); 886 return expr; 887 } 888 889 tdata_item_subst(b_ti, tvv, &bs_ti); 890 cur = bs_ti; 891 assert(cur->tic == tic_tobject); 892 893 } else if (cur_csi->base_csi != NULL) { 894 /* No explicit reference. Use grandfather class. */ 895 cur = tdata_item_new(tic_tobject); 896 cur->u.tobject = tdata_object_new(); 897 cur->u.tobject->csi = cur_csi->base_csi; 898 cur->u.tobject->static_ref = b_false; 899 900 list_init(&cur->u.tobject->targs); 901 } else { 902 /* No match */ 903 stype_convert_failure(stype, src, dest); 904 return expr; 905 } 906 } 907 908 /* Verify that type arguments match */ 909 ca_n = list_first(&cur->u.tobject->targs); 910 da_n = list_first(&dest->u.tobject->targs); 911 912 while (ca_n != NULL && da_n != NULL) { 913 carg = list_node_data(ca_n, tdata_item_t *); 914 darg = list_node_data(da_n, tdata_item_t *); 915 916 if (tdata_item_equal(carg, darg) != b_true) { 917 /* Diferent argument type */ 918 stype_convert_failure(stype, src, dest); 919 printf("Different argument type '"); 920 tdata_item_print(carg); 921 printf("' vs. '"); 922 tdata_item_print(darg); 923 printf("'.\n"); 924 return expr; 925 } 926 927 ca_n = list_next(&cur->u.tobject->targs, ca_n); 928 da_n = list_next(&dest->u.tobject->targs, da_n); 929 } 930 931 if (ca_n != NULL || da_n != NULL) { 932 /* Diferent number of arguments */ 933 stype_convert_failure(stype, src, dest); 934 printf("Different number of arguments.\n"); 935 return expr; 936 } 937 938 return expr; 939 } 940 941 /** Convert expression of array type to array type. 942 * 943 * @param stype Static typing object 944 * @param expr Expression 945 * @param dest Destination type 946 */ 947 static stree_expr_t *stype_convert_tarray(stype_t *stype, stree_expr_t *expr, 948 tdata_item_t *dest) 949 { 950 tdata_item_t *src; 951 952 #ifdef DEBUG_TYPE_TRACE 953 printf("Convert array type.\n"); 954 #endif 955 src = expr->titem; 956 assert(src->tic == tic_tarray); 957 assert(dest->tic == tic_tarray); 958 959 /* Compare rank and base type. */ 960 if (src->u.tarray->rank != dest->u.tarray->rank) { 961 stype_convert_failure(stype, src, dest); 962 return expr; 963 } 964 965 /* XXX Should we convert each element? */ 966 if (tdata_item_equal(src->u.tarray->base_ti, 967 dest->u.tarray->base_ti) != b_true) { 968 stype_convert_failure(stype, src, dest); 969 } 970 971 return expr; 972 } 973 974 /** Convert expression of delegate type to delegate type. 975 * 976 * @param stype Static typing object 977 * @param expr Expression 978 * @param dest Destination type 979 */ 980 static stree_expr_t *stype_convert_tdeleg(stype_t *stype, stree_expr_t *expr, 981 tdata_item_t *dest) 982 { 983 tdata_item_t *src; 984 tdata_deleg_t *sdeleg, *ddeleg; 985 986 #ifdef DEBUG_TYPE_TRACE 987 printf("Convert delegate type.\n"); 988 #endif 989 src = expr->titem; 990 assert(src->tic == tic_tdeleg); 991 assert(dest->tic == tic_tdeleg); 992 993 sdeleg = src->u.tdeleg; 994 ddeleg = dest->u.tdeleg; 995 996 /* 997 * XXX We need to redesign handling of generic types to handle 998 * delegates in generic CSIs properly. 999 */ 1000 1001 /* Destination should never be anonymous delegate. */ 1002 assert(ddeleg->deleg != NULL); 1003 1004 /* Both must be the same delegate. */ 1005 if (sdeleg->deleg != ddeleg->deleg) { 1006 stype_convert_failure(stype, src, dest); 1007 return expr; 1008 } 1009 1010 return expr; 1011 } 1012 1013 /** Convert expression of function type to delegate type. 1014 * 1015 * @param stype Static typing object 1016 * @param expr Expression 1017 * @param dest Destination type 1018 */ 1019 static stree_expr_t *stype_convert_tfun_tdeleg(stype_t *stype, 1020 stree_expr_t *expr, tdata_item_t *dest) 1021 { 1022 tdata_item_t *src; 1023 tdata_fun_t *sfun; 1024 tdata_deleg_t *ddeleg; 1025 tdata_fun_sig_t *ssig, *dsig; 1026 1027 #ifdef DEBUG_TYPE_TRACE 1028 printf("Convert delegate type.\n"); 1029 #endif 1030 src = expr->titem; 1031 assert(src->tic == tic_tfun); 1032 assert(dest->tic == tic_tdeleg); 1033 1034 sfun = src->u.tfun; 1035 ddeleg = dest->u.tdeleg; 1036 1037 ssig = sfun->tsig; 1038 assert(ssig != NULL); 1039 dsig = stype_deleg_get_sig(stype, ddeleg); 1040 assert(dsig != NULL); 1041 1042 /* Signature type must match. */ 1043 1044 if (!stype_fun_sig_equal(stype, ssig, dsig)) { 1045 stype_convert_failure(stype, src, dest); 1046 return expr; 1047 } 1048 1049 /* 1050 * XXX We should also compare attributes. Either the 1051 * tdeleg should be extended or we should get them 1052 * from stree_deleg. 1053 */ 1054 1055 return expr; 1056 } 1057 1058 1059 /** Convert expression of variable type to variable type. 1060 * 1061 * @param stype Static typing object 1062 * @param expr Expression 1063 * @param dest Destination type 1064 */ 1065 static stree_expr_t *stype_convert_tvref(stype_t *stype, stree_expr_t *expr, 1066 tdata_item_t *dest) 1067 { 1068 tdata_item_t *src; 1069 1070 #ifdef DEBUG_TYPE_TRACE 1071 printf("Convert variable type.\n"); 1072 #endif 1073 src = expr->titem; 1074 1075 /* Currently only allow if both types are the same. */ 1076 if (src->u.tvref->targ != dest->u.tvref->targ) { 1077 stype_convert_failure(stype, src, dest); 1078 return expr; 1079 } 1080 1081 return expr; 1082 } 1083 1084 /** Display conversion error message and note error. 1085 * 1086 * @param stype Static typing object 1087 * @param src Original type 1088 * @param dest Destination type 1089 */ 1090 static void stype_convert_failure(stype_t *stype, tdata_item_t *src, 1091 tdata_item_t *dest) 1092 { 557 1093 printf("Error: Cannot convert "); 558 1094 tdata_item_print(src); … … 562 1098 563 1099 stype_note_error(stype); 564 return expr; 565 } 566 567 /** Return a boolean type item */ 1100 } 1101 1102 /** Determine if two type signatures are equal. 1103 * 1104 * XXX This does not compare the attributes, which are missing from 1105 * @c tdata_fun_sig_t. 1106 * 1107 * @param stype Static typing object 1108 * @param asig First function signature type 1109 * @param bsig Second function signature type 1110 */ 1111 static bool_t stype_fun_sig_equal(stype_t *stype, tdata_fun_sig_t *asig, 1112 tdata_fun_sig_t *bsig) 1113 { 1114 list_node_t *aarg_n, *barg_n; 1115 tdata_item_t *aarg_ti, *barg_ti; 1116 1117 (void) stype; 1118 1119 /* Compare types of arguments */ 1120 aarg_n = list_first(&asig->arg_ti); 1121 barg_n = list_first(&bsig->arg_ti); 1122 1123 while (aarg_n != NULL && barg_n != NULL) { 1124 aarg_ti = list_node_data(aarg_n, tdata_item_t *); 1125 barg_ti = list_node_data(barg_n, tdata_item_t *); 1126 1127 if (!tdata_item_equal(aarg_ti, barg_ti)) 1128 return b_false; 1129 1130 aarg_n = list_next(&asig->arg_ti, aarg_n); 1131 barg_n = list_next(&bsig->arg_ti, barg_n); 1132 } 1133 1134 if (aarg_n != NULL || barg_n != NULL) 1135 return b_false; 1136 1137 /* Compare variadic argument */ 1138 1139 if (asig->varg_ti != NULL || bsig->varg_ti != NULL) { 1140 if (asig->varg_ti == NULL || 1141 bsig->varg_ti == NULL) { 1142 return b_false; 1143 } 1144 1145 if (!tdata_item_equal(asig->varg_ti, bsig->varg_ti)) { 1146 return b_false; 1147 } 1148 } 1149 1150 /* Compare return type */ 1151 if (!tdata_item_equal(asig->rtype, bsig->rtype)) 1152 return b_false; 1153 1154 return b_true; 1155 } 1156 1157 /** Get function signature from delegate. 1158 * 1159 * Function signature can be missing if the delegate type is incomplete. 1160 * This is used to break circular dependency when typing delegates. 1161 * If this happens, we type the delegate, which gives us the signature. 1162 */ 1163 tdata_fun_sig_t *stype_deleg_get_sig(stype_t *stype, tdata_deleg_t *tdeleg) 1164 { 1165 if (tdeleg->tsig == NULL) 1166 stype_deleg(stype, tdeleg->deleg); 1167 1168 /* Now we should have a signature. */ 1169 assert(tdeleg->tsig != NULL); 1170 return tdeleg->tsig; 1171 } 1172 1173 /** Convert tic_tobject type item to TVV, 1174 * 1175 * We split generic type application into two steps. In the first step 1176 * we match argument names of @a ti->csi to argument values in @a ti 1177 * to produce a TVV (name to value map for type arguments). That is the 1178 * purpose of this function. 1179 * 1180 * In the second step we substitute variables in another type item 1181 * with their values using the TVV. This is performed by tdata_item_subst(). 1182 * 1183 * @param stype Static typing object. 1184 * @param ti Type item of class tic_tobject. 1185 * @param rtvv Place to store pointer to new TVV. 1186 */ 1187 void stype_titem_to_tvv(stype_t *stype, tdata_item_t *ti, tdata_tvv_t **rtvv) 1188 { 1189 tdata_tvv_t *tvv; 1190 stree_csi_t *csi; 1191 1192 list_node_t *formal_n; 1193 list_node_t *real_n; 1194 1195 stree_targ_t *formal_arg; 1196 tdata_item_t *real_arg; 1197 1198 assert(ti->tic == tic_tobject); 1199 1200 tvv = tdata_tvv_new(); 1201 intmap_init(&tvv->tvv); 1202 1203 csi = ti->u.tobject->csi; 1204 formal_n = list_first(&csi->targ); 1205 real_n = list_first(&ti->u.tobject->targs); 1206 1207 while (formal_n != NULL && real_n != NULL) { 1208 formal_arg = list_node_data(formal_n, stree_targ_t *); 1209 real_arg = list_node_data(real_n, tdata_item_t *); 1210 1211 /* Store argument value into valuation. */ 1212 tdata_tvv_set_val(tvv, formal_arg->name->sid, real_arg); 1213 1214 formal_n = list_next(&csi->targ, formal_n); 1215 real_n = list_next(&ti->u.tobject->targs, real_n); 1216 } 1217 1218 if (formal_n != NULL || real_n != NULL) { 1219 printf("Error: Incorrect number of type arguments.\n"); 1220 stype_note_error(stype); 1221 1222 /* Fill missing arguments with recovery type items. */ 1223 while (formal_n != NULL) { 1224 formal_arg = list_node_data(formal_n, stree_targ_t *); 1225 /* Store recovery value into valuation. */ 1226 tdata_tvv_set_val(tvv, formal_arg->name->sid, 1227 stype_recovery_titem(stype)); 1228 1229 formal_n = list_next(&csi->targ, formal_n); 1230 } 1231 } 1232 1233 *rtvv = tvv; 1234 } 1235 1236 /** Return a boolean type item. 1237 * 1238 * @param stype Static typing object 1239 * @return New boolean type item. 1240 */ 568 1241 tdata_item_t *stype_boolean_titem(stype_t *stype) 569 1242 { … … 580 1253 } 581 1254 582 /** Find a local variable in the current function. */ 1255 /** Find a local variable in the current function. 1256 * 1257 * @param stype Static typing object 1258 * @param name Name of variable (SID). 1259 * @return Pointer to variable declaration or @c NULL if not 1260 * found. 1261 */ 583 1262 stree_vdecl_t *stype_local_vars_lookup(stype_t *stype, sid_t name) 584 1263 { … … 605 1284 } 606 1285 607 /** Find argument of the current procedure. */ 1286 /** Find argument of the current procedure. 1287 * 1288 * @param stype Static typing object 1289 * @param name Name of argument (SID). 1290 * @return Pointer to argument declaration or @c NULL if not 1291 * found. 1292 */ 608 1293 stree_proc_arg_t *stype_proc_args_lookup(stype_t *stype, sid_t name) 609 1294 { … … 633 1318 fun = symbol_to_fun(outer_sym); 634 1319 assert(fun != NULL); 635 args = &fun-> args;636 varg = fun-> varg;1320 args = &fun->sig->args; 1321 varg = fun->sig->varg; 637 1322 break; 638 1323 case sc_prop: … … 688 1373 } 689 1374 690 /** Note a static typing error that has been immediately recovered. */ 1375 /** Note a static typing error that has been immediately recovered. 1376 * 1377 * @param stype Static typing object 1378 */ 691 1379 void stype_note_error(stype_t *stype) 692 1380 { … … 694 1382 } 695 1383 696 /** Construct a special type item for recovery. */ 1384 /** Construct a special type item for recovery. 1385 * 1386 * The recovery item is propagated towards the expression root and causes 1387 * any further typing errors in the expression to be supressed. 1388 * 1389 * @param stype Static typing object 1390 */ 697 1391 tdata_item_t *stype_recovery_titem(stype_t *stype) 698 1392 { … … 705 1399 } 706 1400 707 /** Get current block visit record. */ 1401 /** Get current block visit record. 1402 * 1403 * @param stype Static typing object 1404 */ 708 1405 stype_block_vr_t *stype_get_current_block_vr(stype_t *stype) 709 1406 { … … 714 1411 } 715 1412 1413 /** Allocate new procedure visit record. 1414 * 1415 * @return New procedure VR 1416 */ 716 1417 stype_proc_vr_t *stype_proc_vr_new(void) 717 1418 { … … 727 1428 } 728 1429 1430 /** Allocate new block visit record. 1431 * 1432 * @return New block VR 1433 */ 729 1434 stype_block_vr_t *stype_block_vr_new(void) 730 1435 {
Note:
See TracChangeset
for help on using the changeset viewer.