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
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #include <assert.h>
00039 #include <stdint.h>
00040 #include <stdlib.h>
00041 #include <dirent.h>
00042 #include <fstream>
00043 #include <iostream>
00044 #include <string>
00045 #include <sstream>
00046
00047 #include <libsherpa/UExcept.hxx>
00048
00049 #include "UocInfo.hxx"
00050 #include "AST.hxx"
00051 #include "Type.hxx"
00052 #include "TypeInfer.hxx"
00053 #include "TypeScheme.hxx"
00054 #include "TypeMut.hxx"
00055 #include "Typeclass.hxx"
00056 #include "inter-pass.hxx"
00057 #include "Unify.hxx"
00058
00059 using namespace boost;
00060 using namespace sherpa;
00061 using namespace std;
00062
00063
00064 #define CHKEXP(itsExpansive, exp) do {\
00065 bool ans = (exp);\
00066 if (ans == true) \
00067 (itsExpansive) = true; \
00068 }while (0)
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086 bool
00087 isExpansive(std::ostream& errStream,
00088 shared_ptr<const TSEnvironment > gamma,
00089 shared_ptr<const AST> ast)
00090 {
00091 bool itsExpansive = false;
00092
00093 switch (ast->astType) {
00094 case at_intLiteral:
00095 case at_floatLiteral:
00096 case at_boolLiteral:
00097 case at_charLiteral:
00098 case at_stringLiteral:
00099 case at_lambda:
00100 case at_sizeof:
00101 case at_bitsizeof:
00102 {
00103 itsExpansive = false;
00104 break;
00105 }
00106
00107 case at_apply:
00108 {
00109 itsExpansive = true;
00110 break;
00111 }
00112 case at_setbang:
00113 {
00114 itsExpansive = true;
00115 break;
00116 }
00117
00118 case at_allocREF:
00119 case at_mkClosure:
00120 case at_ident:
00121 case at_fill:
00122 case at_usesel:
00123 case at_dup:
00124 case at_docString:
00125 {
00126 itsExpansive = false;
00127 break;
00128 }
00129
00130 case at_letStar:
00131 case at_let:
00132 case at_letrec:
00133 {
00134 CHKEXP(itsExpansive, isExpansive(errStream, gamma,
00135 ast->child(0)));
00136 CHKEXP(itsExpansive, isExpansive(errStream, gamma,
00137 ast->child(1)));
00138 break;
00139 }
00140
00141 case at_copyREF:
00142 case at_setClosure:
00143 case at_letbindings:
00144 case at_loopbindings:
00145 {
00146 for (size_t i=0; !itsExpansive && i < ast->children.size(); i++)
00147 CHKEXP(itsExpansive, isExpansive(errStream, gamma,
00148 ast->child(i)));
00149 break;
00150 }
00151
00152 case at_letbinding:
00153 {
00154 itsExpansive = isExpansive(errStream, gamma,
00155 ast->child(1));
00156 break;
00157 }
00158
00159 case at_loopbinding:
00160 {
00161 CHKEXP(itsExpansive, isExpansive(errStream, gamma,
00162 ast->child(1)));
00163 CHKEXP(itsExpansive, isExpansive(errStream, gamma,
00164 ast->child(2)));
00165 break;
00166 }
00167
00168 case at_try:
00169 case at_throw:
00170 case at_labeledBlock:
00171 case at_return_from:
00172 #if 0
00173 {
00174 itsExpansive = true;
00175 break;
00176 }
00177 #endif
00178 case at_loop:
00179 case at_looptest:
00180 case at_begin:
00181 {
00182 for (size_t i=0; !itsExpansive && i < ast->children.size(); i++)
00183 CHKEXP(itsExpansive, isExpansive(errStream, gamma,
00184 ast->child(i)));
00185 break;
00186 }
00187
00188 case at_suspend:
00189 {
00190 itsExpansive = isExpansive(errStream, gamma,
00191 ast->child(1));
00192 break;
00193 }
00194
00195 case at_typeAnnotation:
00196 {
00197 itsExpansive = isExpansive(errStream, gamma,
00198 ast->child(0));
00199 break;
00200 }
00201
00202 case at_if:
00203 {
00204 CHKEXP(itsExpansive, isExpansive(errStream, gamma,
00205 ast->child(0)));
00206 CHKEXP(itsExpansive, isExpansive(errStream, gamma,
00207 ast->child(1)));
00208 CHKEXP(itsExpansive, isExpansive(errStream, gamma,
00209 ast->child(2)));
00210 break;
00211 }
00212
00213 case at_when:
00214 case at_unless:
00215 {
00216 CHKEXP(itsExpansive, isExpansive(errStream, gamma,
00217 ast->child(0)));
00218 CHKEXP(itsExpansive, isExpansive(errStream, gamma,
00219 ast->child(1)));
00220 break;
00221 }
00222
00223 case at_cond:
00224 {
00225 CHKEXP(itsExpansive, isExpansive(errStream, gamma,
00226 ast->child(0)));
00227 CHKEXP(itsExpansive, isExpansive(errStream, gamma,
00228 ast->child(1)));
00229 break;
00230 }
00231
00232 case at_cond_legs:
00233 {
00234 for (size_t i=0; !itsExpansive && i < ast->children.size(); i++)
00235 CHKEXP(itsExpansive, isExpansive(errStream, gamma,
00236 ast->child(i)));
00237 break;
00238 }
00239
00240 case at_cond_leg:
00241 {
00242 CHKEXP(itsExpansive, isExpansive(errStream, gamma,
00243 ast->child(1)));
00244 break;
00245 }
00246
00247 case at_condelse:
00248 {
00249 CHKEXP(itsExpansive, isExpansive(errStream, gamma,
00250 ast->child(0)));
00251 break;
00252 }
00253
00254 case at_uswitch:
00255 {
00256 CHKEXP(itsExpansive, isExpansive(errStream, gamma,
00257 ast->child(2)));
00258 if (ast->child(3)->astType != at_Null)
00259 CHKEXP(itsExpansive, isExpansive(errStream, gamma,
00260 ast->child(3)));
00261 break;
00262 }
00263
00264 case at_otherwise:
00265 case at_usw_leg:
00266 {
00267
00268 CHKEXP(itsExpansive, isExpansive(errStream, gamma,
00269 ast->child(1)));
00270 break;
00271 }
00272
00273 case at_unit:
00274 break;
00275
00276 case at_MakeVector:
00277 {
00278
00279
00280
00281 itsExpansive = true;
00282 break;
00283 }
00284
00285 case at_letGather:
00286 case at_vector:
00287 case at_array:
00288 case at_mkArrayRef:
00289 #ifdef HAVE_INDEXABLE_LENGTH_OPS
00290 case at_array_length:
00291 case at_array_ref_length:
00292 case at_vector_length:
00293 #endif
00294 case at_array_nth:
00295 case at_array_ref_nth:
00296 case at_vector_nth:
00297 case at_inner_ref:
00298 case at_deref:
00299 case at_usw_legs:
00300 case at_and:
00301 case at_or:
00302 {
00303 for (size_t i=0; !itsExpansive && i < ast->children.size(); i++)
00304 CHKEXP(itsExpansive, isExpansive(errStream, gamma,
00305 ast->child(i)));
00306 break;
00307 }
00308 case at_nth:
00309
00310 assert(false);
00311 break;
00312
00313 case at_fqCtr:
00314 {
00315 itsExpansive = false;
00316 break;
00317 }
00318
00319 case at_select:
00320 case at_sel_ctr:
00321 {
00322 CHKEXP(itsExpansive, isExpansive(errStream, gamma,
00323 ast->child(0)));
00324 break;
00325 }
00326
00327 case at_struct_apply:
00328 case at_object_apply:
00329 case at_ucon_apply:
00330 {
00331 for (size_t i=1; !itsExpansive && i < ast->children.size(); i++)
00332 CHKEXP(itsExpansive, isExpansive(errStream, gamma,
00333 ast->child(i)));
00334 break;
00335 }
00336
00337 case at_container:
00338 {
00339 CHKEXP(itsExpansive, isExpansive(errStream, gamma,
00340 ast->child(1)));
00341 break;
00342 }
00343
00344 case at_tcapp:
00345 {
00346
00347
00348 itsExpansive = false;
00349 break;
00350 }
00351
00352 case at_unboxedCat:
00353 case at_boxedCat:
00354 case at_oc_closed:
00355 case at_oc_open:
00356 case at_opaqueCat:
00357 case agt_category:
00358 case at_module:
00359 case at_define:
00360 case at_recdef:
00361 case at_defrepr:
00362 case at_defstruct:
00363 case at_defunion:
00364 case at_declrepr:
00365 case at_declstruct:
00366 case at_declunion:
00367 case at_declares:
00368 case at_declare:
00369 case at_tvlist:
00370 case at_constructors:
00371 case at_constructor:
00372 case at_fields:
00373 case at_field:
00374 case at_fieldType:
00375 case at_methdecl:
00376 case at_bitfieldType:
00377 case at_arrayRefType:
00378 case at_byRefType:
00379 case at_boxedType:
00380 case at_exceptionType:
00381 case at_dummyType:
00382 case at_unboxedType:
00383 case at_fn:
00384 case at_primaryType:
00385 case at_arrayType:
00386 case at_vectorType:
00387 case at_mutableType:
00388 case at_constType:
00389 case at_typeapp:
00390 case at_qualType:
00391 case at_methType:
00392 case at_constraints:
00393 case at_identPattern:
00394 case at_Null:
00395 case at_AnyGroup:
00396 case agt_literal:
00397 case agt_tvar:
00398 case agt_var:
00399 case agt_definition:
00400 case agt_type_definition:
00401 case agt_value_definition:
00402 case agt_uselhs:
00403 case agt_type:
00404 case agt_openclosed:
00405
00406
00407
00408
00409
00410 case at_reprctrs:
00411 case at_reprctr:
00412 case at_reprrepr:
00413 case agt_expr:
00414 case agt_expr_or_define:
00415 case agt_eform:
00416 case at_proclaim:
00417 case at_interface:
00418 case at_importAs:
00419 case at_provide:
00420 case at_import:
00421 case at_ifsel:
00422 case agt_CompilationUnit:
00423 case at_defexception:
00424 case at_deftypeclass:
00425 case at_tcdecls:
00426 case at_tyfn:
00427 case at_method_decls:
00428 case at_method_decl:
00429 case at_definstance:
00430 case at_tcmethods:
00431 case at_tcmethod_binding:
00432 case agt_tc_definition:
00433 case agt_if_definition:
00434 case agt_ow:
00435 case agt_qtype:
00436 case agt_fielditem:
00437 case at_ifident:
00438 case at_argVec:
00439 case at_fnargVec:
00440 case at_localFrame:
00441 case at_frameBindings:
00442 case at_identList:
00443 case agt_ucon:
00444 {
00445 errStream << ast->loc << ": "
00446 << "Internal Compiler Error."
00447 << "Unexpected ast-type " << ast->tagName()
00448 << " obtained by isExpansive() routine."
00449 << std::endl;
00450 itsExpansive = true;
00451 break;
00452 }
00453 }
00454 return itsExpansive;
00455 }
00456
00457
00458
00459
00460
00461
00462
00463
00464 bool
00465 isAValue(shared_ptr<const AST> ast)
00466 {
00467 switch (ast->astType) {
00468 case at_unit:
00469 case at_boolLiteral:
00470 case at_charLiteral:
00471 case at_intLiteral:
00472 case at_floatLiteral:
00473 case at_stringLiteral:
00474 case at_lambda:
00475 case at_sizeof:
00476 case at_bitsizeof:
00477 case at_mkClosure:
00478 case at_ident:
00479 case at_usesel:
00480 return true;
00481
00482 case at_typeAnnotation:
00483 return isAValue(ast->child(0));
00484
00485 #ifdef HAVE_INDEXABLE_LENGTH_OPS
00486 case at_array_length:
00487
00488
00489 return isAValue(ast->child(0));
00490 #else
00491 case at_select:
00492 {
00493 shared_ptr<Type> t = ast->child(0)->symType->getBareType();
00494 if (t->typeTag == ty_array)
00495 return true;
00496 else
00497 return false;
00498 }
00499 #endif
00500
00501 default:
00502 return false;
00503 }
00504 }
00505
00506 bool
00507 isExpansive(std::ostream& errStream,
00508 shared_ptr<const TSEnvironment > gamma,
00509 shared_ptr<Type> typ)
00510 {
00511 bool itsExpansive = false;
00512 shared_ptr<Type> t = typ->getType();
00513
00514 if (t->mark & MARK_PREDICATE)
00515 return itsExpansive;
00516
00517 t->mark |= MARK_PREDICATE;
00518
00519 switch(t->typeTag) {
00520 case ty_unit:
00521 case ty_bool:
00522 case ty_char:
00523 case ty_string:
00524 case ty_int8:
00525 case ty_int16:
00526 case ty_int32:
00527 case ty_int64:
00528 case ty_uint8:
00529 case ty_uint16:
00530 case ty_uint32:
00531 case ty_uint64:
00532 case ty_word:
00533 case ty_float:
00534 case ty_double:
00535 case ty_quad:
00536 case ty_field:
00537
00538 case ty_tvar:
00539 case ty_dummy:
00540 case ty_kvar:
00541 case ty_kfix:
00542
00543 #ifdef KEEP_BF
00544 case ty_bitfield:
00545 #endif
00546 case ty_fn:
00547 case ty_method:
00548 case ty_typeclass:
00549 break;
00550
00551 case ty_tyfn:
00552 case ty_fnarg:
00553 case ty_byref:
00554 assert(false);
00555 break;
00556
00557 case ty_letGather:
00558 case ty_array:
00559 case ty_array_ref:
00560 case ty_vector:
00561 for (size_t i=0; i<t->components.size(); i++)
00562 CHKEXP(itsExpansive, isExpansive(errStream, gamma,
00563 t->CompType(i)));
00564 break;
00565
00566 case ty_structv:
00567 case ty_structr:
00568 case ty_unionv:
00569 case ty_unionr:
00570 case ty_uconv:
00571 case ty_uconr:
00572 case ty_uvalv:
00573 case ty_uvalr:
00574 case ty_mbFull:
00575 case ty_mbTop:
00576 case ty_pcst:
00577 case ty_ref:
00578 case ty_exn:
00579 {
00580 for (size_t i=0; i<t->typeArgs.size(); i++)
00581 CHKEXP(itsExpansive, isExpansive(errStream, gamma,
00582 t->TypeArg(i)));
00583
00584 for (size_t i=0; i<t->components.size(); i++)
00585 CHKEXP(itsExpansive, isExpansive(errStream, gamma,
00586 t->CompType(i)));
00587 break;
00588 }
00589
00590 case ty_const:
00591 {
00592 CHKEXP(itsExpansive, isExpansive(errStream, gamma,
00593 t->Base()->minimizeMutability()));
00594 break;
00595 }
00596
00597 case ty_mutable:
00598 {
00599 itsExpansive = true;
00600 break;
00601 }
00602 }
00603
00604 t->mark &= ~MARK_PREDICATE;
00605 return itsExpansive;
00606 }