Changeset 640ffe6 in mainline for uspace/app/sbi/src/stype.c
- Timestamp:
- 2010-05-08T08:15:57Z (15 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 4039c77
- Parents:
- 1317380 (diff), 051bc69a (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/sbi/src/stype.c
r1317380 r640ffe6 38 38 #include <stdlib.h> 39 39 #include <assert.h> 40 #include "cspan.h" 40 41 #include "debug.h" 41 42 #include "intmap.h" … … 52 53 53 54 static void stype_csi(stype_t *stype, stree_csi_t *csi); 55 static void stype_ctor(stype_t *stype, stree_ctor_t *ctor); 56 static void stype_ctor_body(stype_t *stype, stree_ctor_t *ctor); 54 57 static void stype_fun(stype_t *stype, stree_fun_t *fun); 55 58 static void stype_var(stype_t *stype, stree_var_t *var); … … 66 69 static void stype_for(stype_t *stype, stree_for_t *for_s); 67 70 static void stype_raise(stype_t *stype, stree_raise_t *raise_s); 71 static void stype_break(stype_t *stype, stree_break_t *break_s); 68 72 static void stype_return(stype_t *stype, stree_return_t *return_s); 69 73 static void stype_exps(stype_t *stype, stree_exps_t *exp_s, bool_t want_value); … … 80 84 static stree_expr_t *stype_convert_tdeleg(stype_t *stype, stree_expr_t *expr, 81 85 tdata_item_t *dest); 86 static stree_expr_t *stype_convert_tenum(stype_t *stype, stree_expr_t *expr, 87 tdata_item_t *dest); 82 88 static stree_expr_t *stype_convert_tfun_tdeleg(stype_t *stype, 83 89 stree_expr_t *expr, tdata_item_t *dest); 84 90 static stree_expr_t *stype_convert_tvref(stype_t *stype, stree_expr_t *expr, 85 91 tdata_item_t *dest); 86 static void stype_convert_failure(stype_t *stype, tdata_item_t *src,92 static void stype_convert_failure(stype_t *stype, stree_expr_t *expr, 87 93 tdata_item_t *dest); 88 94 … … 112 118 while (mbr_n != NULL) { 113 119 mbr = list_node_data(mbr_n, stree_modm_t *); 114 assert(mbr->mc == mc_csi); 115 116 stype_csi(stype, mbr->u.csi); 120 121 switch (mbr->mc) { 122 case mc_csi: 123 stype_csi(stype, mbr->u.csi); 124 break; 125 case mc_enum: 126 stype_enum(stype, mbr->u.enum_d); 127 break; 128 } 117 129 118 130 mbr_n = list_next(&module->members, mbr_n); … … 145 157 switch (csimbr->cc) { 146 158 case csimbr_csi: stype_csi(stype, csimbr->u.csi); break; 159 case csimbr_ctor: stype_ctor(stype, csimbr->u.ctor); break; 147 160 case csimbr_deleg: stype_deleg(stype, csimbr->u.deleg); break; 161 case csimbr_enum: stype_enum(stype, csimbr->u.enum_d); break; 148 162 case csimbr_fun: stype_fun(stype, csimbr->u.fun); break; 149 163 case csimbr_var: stype_var(stype, csimbr->u.var); break; … … 155 169 156 170 stype->current_csi = prev_ctx; 171 } 172 173 /** Type a constructor. 174 * 175 * @param stype Static typing object. 176 * @param ctor Constructor to type. 177 */ 178 static void stype_ctor(stype_t *stype, stree_ctor_t *ctor) 179 { 180 #ifdef DEBUG_TYPE_TRACE 181 printf("Type constructor '"); 182 symbol_print_fqn(ctor_to_symbol(ctor)); 183 printf("'.\n"); 184 #endif 185 if (ctor->titem == NULL) 186 stype_ctor_header(stype, ctor); 187 188 stype_ctor_body(stype, ctor); 189 } 190 191 /** Type constructor header. 192 * 193 * @param stype Static typing object. 194 * @param ctor Constructor to type. 195 */ 196 void stype_ctor_header(stype_t *stype, stree_ctor_t *ctor) 197 { 198 stree_symbol_t *ctor_sym; 199 tdata_item_t *ctor_ti; 200 tdata_fun_t *tfun; 201 tdata_fun_sig_t *tsig; 202 203 #ifdef DEBUG_TYPE_TRACE 204 printf("Type constructor '"); 205 symbol_print_fqn(ctor_to_symbol(ctor)); 206 printf("' header.\n"); 207 #endif 208 if (ctor->titem != NULL) 209 return; /* Constructor header has already been typed. */ 210 211 ctor_sym = ctor_to_symbol(ctor); 212 213 /* Type function signature. */ 214 stype_fun_sig(stype, ctor_sym->outer_csi, ctor->sig, &tsig); 215 216 ctor_ti = tdata_item_new(tic_tfun); 217 tfun = tdata_fun_new(); 218 ctor_ti->u.tfun = tfun; 219 tfun->tsig = tsig; 220 221 ctor->titem = ctor_ti; 222 } 223 224 /** Type constructor body. 225 * 226 * @param stype Static typing object 227 * @param ctor Constructor 228 */ 229 static void stype_ctor_body(stype_t *stype, stree_ctor_t *ctor) 230 { 231 #ifdef DEBUG_TYPE_TRACE 232 printf("Type constructor '"); 233 symbol_print_fqn(ctor_to_symbol(ctor)); 234 printf("' body.\n"); 235 #endif 236 assert(stype->proc_vr == NULL); 237 238 stype->proc_vr = stype_proc_vr_new(); 239 stype->proc_vr->proc = ctor->proc; 240 list_init(&stype->proc_vr->block_vr); 241 242 stype_block(stype, ctor->proc->body); 243 244 free(stype->proc_vr); 245 stype->proc_vr = NULL; 157 246 } 158 247 … … 197 286 } 198 287 288 /** Type enum. 289 * 290 * @param stype Static typing object 291 * @param enum_d Enum to type 292 */ 293 void stype_enum(stype_t *stype, stree_enum_t *enum_d) 294 { 295 tdata_item_t *titem; 296 tdata_enum_t *tenum; 297 298 (void) stype; 299 300 #ifdef DEBUG_TYPE_TRACE 301 printf("Type enum '"); 302 symbol_print_fqn(enum_to_symbol(enum_d)); 303 printf("'.\n"); 304 #endif 305 if (enum_d->titem == NULL) { 306 titem = tdata_item_new(tic_tenum); 307 tenum = tdata_enum_new(); 308 titem->u.tenum = tenum; 309 tenum->enum_d = enum_d; 310 311 enum_d->titem = titem; 312 } else { 313 titem = enum_d->titem; 314 } 315 } 316 199 317 /** Type function. 200 318 * … … 457 575 case st_for: stype_for(stype, stat->u.for_s); break; 458 576 case st_raise: stype_raise(stype, stat->u.raise_s); break; 577 case st_break: stype_break(stype, stat->u.break_s); break; 459 578 case st_return: stype_return(stype, stat->u.return_s); break; 460 579 case st_exps: stype_exps(stype, stat->u.exp_s, want_value); break; … … 506 625 { 507 626 stree_expr_t *ccond; 627 list_node_t *ifc_node; 628 stree_if_clause_t *ifc; 508 629 509 630 #ifdef DEBUG_TYPE_TRACE 510 631 printf("Type 'if' statement.\n"); 511 632 #endif 512 /* Convert condition to boolean type. */ 513 stype_expr(stype, if_s->cond); 514 ccond = stype_convert(stype, if_s->cond, stype_boolean_titem(stype)); 515 516 /* Patch code with augmented expression. */ 517 if_s->cond = ccond; 518 519 /* Type the @c if block */ 520 stype_block(stype, if_s->if_block); 633 ifc_node = list_first(&if_s->if_clauses); 634 635 /* Walk through all if/elif clauses. */ 636 637 while (ifc_node != NULL) { 638 /* Get if/elif clause */ 639 ifc = list_node_data(ifc_node, stree_if_clause_t *); 640 641 /* Convert condition to boolean type. */ 642 stype_expr(stype, ifc->cond); 643 ccond = stype_convert(stype, ifc->cond, 644 stype_boolean_titem(stype)); 645 646 /* Patch code with augmented expression. */ 647 ifc->cond = ccond; 648 649 /* Type the @c if/elif block */ 650 stype_block(stype, ifc->block); 651 652 ifc_node = list_next(&if_s->if_clauses, ifc_node); 653 } 521 654 522 655 /* Type the @c else block */ … … 545 678 while_s->cond = ccond; 546 679 680 /* While is a breakable statement. Increment counter. */ 681 stype->proc_vr->bstat_cnt += 1; 682 547 683 /* Type the body of the loop */ 548 684 stype_block(stype, while_s->body); 685 686 stype->proc_vr->bstat_cnt -= 1; 549 687 } 550 688 … … 559 697 printf("Type 'for' statement.\n"); 560 698 #endif 699 /* For is a breakable statement. Increment counter. */ 700 stype->proc_vr->bstat_cnt += 1; 701 561 702 stype_block(stype, for_s->body); 703 704 stype->proc_vr->bstat_cnt -= 1; 562 705 } 563 706 … … 573 716 #endif 574 717 stype_expr(stype, raise_s->expr); 718 } 719 720 /** Type @c break statement */ 721 static void stype_break(stype_t *stype, stree_break_t *break_s) 722 { 723 #ifdef DEBUG_TYPE_TRACE 724 printf("Type 'break' statement.\n"); 725 #endif 726 (void) break_s; 727 728 /* Check whether there is an active statement to break from. */ 729 if (stype->proc_vr->bstat_cnt == 0) { 730 printf("Error: Break statement outside of while or for.\n"); 731 stype_note_error(stype); 732 } 575 733 } 576 734 … … 588 746 printf("Type 'return' statement.\n"); 589 747 #endif 590 stype_expr(stype, return_s->expr); 748 if (return_s->expr != NULL) 749 stype_expr(stype, return_s->expr); 591 750 592 751 /* Determine the type we need to return. */ … … 599 758 600 759 /* XXX Memoize to avoid recomputing. */ 601 run_texpr(stype->program, outer_sym->outer_csi, 602 fun->sig->rtype, &dtype); 760 if (fun->sig->rtype != NULL) { 761 run_texpr(stype->program, outer_sym->outer_csi, 762 fun->sig->rtype, &dtype); 763 764 if (return_s->expr == NULL) { 765 printf("Error: Return without a value in " 766 "function returning value.\n"); 767 stype_note_error(stype); 768 } 769 } else { 770 dtype = NULL; 771 772 if (return_s->expr != NULL) { 773 printf("Error: Return with a value in " 774 "value-less function.\n"); 775 stype_note_error(stype); 776 } 777 } 603 778 break; 604 779 case sc_prop: … … 606 781 assert(prop != NULL); 607 782 608 if (stype->proc_vr->proc != prop->getter) { 609 printf("Error: Return statement in " 610 "setter.\n"); 611 stype_note_error(stype); 783 if (stype->proc_vr->proc == prop->getter) { 784 if (return_s->expr == NULL) { 785 printf("Error: Return without a value in " 786 "getter.\n"); 787 stype_note_error(stype); 788 } 789 } else { 790 if (return_s->expr == NULL) { 791 printf("Error: Return with a value in " 792 "setter.\n"); 793 stype_note_error(stype); 794 } 612 795 } 613 796 … … 620 803 } 621 804 622 /* Convert to the return type. */ 623 cexpr = stype_convert(stype, return_s->expr, dtype); 624 625 /* Patch code with the augmented expression. */ 626 return_s->expr = cexpr; 805 if (dtype != NULL && return_s->expr != NULL) { 806 /* Convert to the return type. */ 807 cexpr = stype_convert(stype, return_s->expr, dtype); 808 809 /* Patch code with the augmented expression. */ 810 return_s->expr = cexpr; 811 } 627 812 } 628 813 … … 714 899 715 900 if (src == NULL) { 716 printf("Error: Conversion source is not valid.\n"); 901 cspan_print(expr->cspan); 902 printf(" Error: Conversion source is not valid.\n"); 717 903 stype_note_error(stype); 718 904 return expr; … … 738 924 } 739 925 926 if (src->tic == tic_tebase) { 927 stype_convert_failure(stype, expr, dest); 928 printf("Invalid use of reference to enum type in " 929 "expression.\n"); 930 return expr; 931 } 932 740 933 if (src->tic != dest->tic) { 741 stype_convert_failure(stype, src, dest);934 stype_convert_failure(stype, expr, dest); 742 935 return expr; 743 936 } … … 756 949 expr = stype_convert_tdeleg(stype, expr, dest); 757 950 break; 951 case tic_tebase: 952 /* Conversion destination should never be enum-base */ 953 assert(b_false); 954 case tic_tenum: 955 expr = stype_convert_tenum(stype, expr, dest); 956 break; 758 957 case tic_tfun: 759 958 assert(b_false); … … 788 987 /* Check if both have the same tprimitive class. */ 789 988 if (src->u.tprimitive->tpc != dest->u.tprimitive->tpc) 790 stype_convert_failure(stype, src, dest);989 stype_convert_failure(stype, expr, dest); 791 990 792 991 return expr; … … 795 994 /** Convert expression of primitive type to object type. 796 995 * 797 * This function implements autoboxing. It modified the code. 996 * This function implements autoboxing. It modifies the code by inserting 997 * the boxing operation. 798 998 * 799 999 * @param stype Static typing object … … 828 1028 case tpc_string: bp_sym = bi->boxed_string; break; 829 1029 case tpc_resource: 830 stype_convert_failure(stype, src, dest);1030 stype_convert_failure(stype, expr, dest); 831 1031 return expr; 832 1032 } … … 834 1034 /* Target type must be boxed @a src or Object */ 835 1035 if (csi_sym != bp_sym && csi_sym != bi->gf_class) 836 stype_convert_failure(stype, src, dest);1036 stype_convert_failure(stype, expr, dest); 837 1037 838 1038 /* Patch the code to box the primitive value */ … … 841 1041 bexpr = stree_expr_new(ec_box); 842 1042 bexpr->u.box = box; 1043 bexpr->titem = dest; 843 1044 844 1045 /* No action needed to optionally convert boxed type to Object */ … … 901 1102 } else { 902 1103 /* No match */ 903 stype_convert_failure(stype, src, dest);1104 stype_convert_failure(stype, expr, dest); 904 1105 return expr; 905 1106 } … … 916 1117 if (tdata_item_equal(carg, darg) != b_true) { 917 1118 /* Diferent argument type */ 918 stype_convert_failure(stype, src, dest);1119 stype_convert_failure(stype, expr, dest); 919 1120 printf("Different argument type '"); 920 1121 tdata_item_print(carg); … … 931 1132 if (ca_n != NULL || da_n != NULL) { 932 1133 /* Diferent number of arguments */ 933 stype_convert_failure(stype, src, dest);1134 stype_convert_failure(stype, expr, dest); 934 1135 printf("Different number of arguments.\n"); 935 1136 return expr; … … 959 1160 /* Compare rank and base type. */ 960 1161 if (src->u.tarray->rank != dest->u.tarray->rank) { 961 stype_convert_failure(stype, src, dest);1162 stype_convert_failure(stype, expr, dest); 962 1163 return expr; 963 1164 } … … 966 1167 if (tdata_item_equal(src->u.tarray->base_ti, 967 1168 dest->u.tarray->base_ti) != b_true) { 968 stype_convert_failure(stype, src, dest);1169 stype_convert_failure(stype, expr, dest); 969 1170 } 970 1171 … … 1004 1205 /* Both must be the same delegate. */ 1005 1206 if (sdeleg->deleg != ddeleg->deleg) { 1006 stype_convert_failure(stype, src, dest); 1207 stype_convert_failure(stype, expr, dest); 1208 return expr; 1209 } 1210 1211 return expr; 1212 } 1213 1214 /** Convert expression of enum type to enum type. 1215 * 1216 * @param stype Static typing object 1217 * @param expr Expression 1218 * @param dest Destination type 1219 */ 1220 static stree_expr_t *stype_convert_tenum(stype_t *stype, stree_expr_t *expr, 1221 tdata_item_t *dest) 1222 { 1223 tdata_item_t *src; 1224 tdata_enum_t *senum, *denum; 1225 1226 #ifdef DEBUG_TYPE_TRACE 1227 printf("Convert enum type.\n"); 1228 #endif 1229 src = expr->titem; 1230 assert(src->tic == tic_tenum); 1231 assert(dest->tic == tic_tenum); 1232 1233 senum = src->u.tenum; 1234 denum = dest->u.tenum; 1235 1236 /* 1237 * XXX How should enum types interact with generics? 1238 */ 1239 1240 /* Both must be of the same enum type (with the same declaration). */ 1241 if (senum->enum_d != denum->enum_d) { 1242 stype_convert_failure(stype, expr, dest); 1007 1243 return expr; 1008 1244 } … … 1043 1279 1044 1280 if (!stype_fun_sig_equal(stype, ssig, dsig)) { 1045 stype_convert_failure(stype, src, dest);1281 stype_convert_failure(stype, expr, dest); 1046 1282 return expr; 1047 1283 } … … 1075 1311 /* Currently only allow if both types are the same. */ 1076 1312 if (src->u.tvref->targ != dest->u.tvref->targ) { 1077 stype_convert_failure(stype, src, dest);1313 stype_convert_failure(stype, expr, dest); 1078 1314 return expr; 1079 1315 } … … 1085 1321 * 1086 1322 * @param stype Static typing object 1087 * @param src Original type1323 * @param expr Original expression 1088 1324 * @param dest Destination type 1089 1325 */ 1090 static void stype_convert_failure(stype_t *stype, tdata_item_t *src,1326 static void stype_convert_failure(stype_t *stype, stree_expr_t *expr, 1091 1327 tdata_item_t *dest) 1092 1328 { 1093 printf("Error: Cannot convert "); 1094 tdata_item_print(src); 1329 cspan_print(expr->cspan); 1330 printf(" Error: Cannot convert "); 1331 tdata_item_print(expr->titem); 1095 1332 printf(" to "); 1096 1333 tdata_item_print(dest); … … 1099 1336 stype_note_error(stype); 1100 1337 } 1338 1339 /** Box value. 1340 * 1341 * This function implements implicit boxing. It modifies the code by inserting 1342 * the boxing operation. 1343 * 1344 * @param stype Static typing object 1345 * @param expr Expression 1346 * @return Modified expression. 1347 */ 1348 stree_expr_t *stype_box_expr(stype_t *stype, stree_expr_t *expr) 1349 { 1350 tdata_item_t *src; 1351 builtin_t *bi; 1352 stree_symbol_t *bp_sym; 1353 stree_box_t *box; 1354 stree_expr_t *bexpr; 1355 tdata_object_t *tobject; 1356 1357 #ifdef DEBUG_TYPE_TRACE 1358 printf("Boxing.\n"); 1359 #endif 1360 src = expr->titem; 1361 assert(src->tic == tic_tprimitive); 1362 1363 bi = stype->program->builtin; 1364 1365 /* Make compiler happy. */ 1366 bp_sym = NULL; 1367 1368 switch (src->u.tprimitive->tpc) { 1369 case tpc_bool: bp_sym = bi->boxed_bool; break; 1370 case tpc_char: bp_sym = bi->boxed_char; break; 1371 case tpc_int: bp_sym = bi->boxed_int; break; 1372 case tpc_nil: assert(b_false); 1373 case tpc_string: bp_sym = bi->boxed_string; break; 1374 case tpc_resource: 1375 cspan_print(expr->cspan); 1376 printf(" Error: Cannot use "); 1377 tdata_item_print(expr->titem); 1378 printf(" as an object.\n"); 1379 1380 stype_note_error(stype); 1381 return expr; 1382 } 1383 1384 /* Patch the code to box the primitive value */ 1385 box = stree_box_new(); 1386 box->arg = expr; 1387 bexpr = stree_expr_new(ec_box); 1388 bexpr->u.box = box; 1389 bexpr->titem = tdata_item_new(tic_tobject); 1390 tobject = tdata_object_new(); 1391 bexpr->titem->u.tobject = tobject; 1392 1393 tobject->csi = symbol_to_csi(bp_sym); 1394 assert(tobject->csi != NULL); 1395 1396 return bexpr; 1397 } 1398 1399 1101 1400 1102 1401 /** Determine if two type signatures are equal. … … 1296 1595 1297 1596 stree_symbol_t *outer_sym; 1597 stree_ctor_t *ctor; 1298 1598 stree_fun_t *fun; 1299 1599 stree_prop_t *prop; … … 1314 1614 #endif 1315 1615 1616 /* Make compiler happy. */ 1617 args = NULL; 1618 varg = NULL; 1619 1316 1620 switch (outer_sym->sc) { 1621 case sc_ctor: 1622 ctor = symbol_to_ctor(outer_sym); 1623 assert(ctor != NULL); 1624 args = &ctor->sig->args; 1625 varg = ctor->sig->varg; 1626 break; 1317 1627 case sc_fun: 1318 1628 fun = symbol_to_fun(outer_sym); … … 1331 1641 setter_arg = prop->setter_arg; 1332 1642 break; 1333 default: 1643 case sc_csi: 1644 case sc_deleg: 1645 case sc_enum: 1646 case sc_var: 1334 1647 assert(b_false); 1335 1648 }
Note:
See TracChangeset
for help on using the changeset viewer.