"Fossies" - the Fresh Open Source Software Archive

Member "ponyc-0.33.0/src/libponyc/type/cap.c" (1 Nov 2019, 17845 Bytes) of package /linux/misc/ponyc-0.33.0.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "cap.c" see the Fossies "Dox" file reference documentation.

    1 #include "cap.h"
    2 #include "../ast/token.h"
    3 #include "viewpoint.h"
    4 #include "ponyassert.h"
    5 
    6 // The resulting eph will always be TK_EPHEMERAL or TK_NONE.
    7 static void cap_aliasing(token_id* cap, token_id* eph)
    8 {
    9   switch(*eph)
   10   {
   11     case TK_EPHEMERAL:
   12       switch(*cap)
   13       {
   14         case TK_ISO:
   15         case TK_TRN:
   16         case TK_CAP_SEND:
   17         case TK_CAP_ANY:
   18           break;
   19 
   20         default:
   21           // Everything else unaliases as itself, so use TK_NONE.
   22           *eph = TK_NONE;
   23       }
   24       break;
   25 
   26     case TK_ALIASED:
   27       switch(*cap)
   28       {
   29         case TK_ISO:
   30           // Alias as tag.
   31           *cap = TK_TAG;
   32           break;
   33 
   34         case TK_TRN:
   35           // Alias as box.
   36           *cap = TK_BOX;
   37           break;
   38 
   39         case TK_CAP_SEND:
   40           // Alias as #share.
   41           *cap = TK_CAP_SHARE;
   42           break;
   43 
   44         case TK_CAP_ANY:
   45           // Alias as #alias.
   46           *cap = TK_CAP_ALIAS;
   47           break;
   48 
   49         default: {}
   50       }
   51 
   52       *eph = TK_NONE;
   53       break;
   54 
   55     default: {}
   56   }
   57 }
   58 
   59 bool is_cap_sub_cap(token_id sub, token_id subalias, token_id super,
   60   token_id supalias)
   61 {
   62   // Transform the cap based on the aliasing info.
   63   cap_aliasing(&sub, &subalias);
   64   cap_aliasing(&super, &supalias);
   65 
   66   if(supalias == TK_EPHEMERAL)
   67   {
   68     // Sub must be ephemeral.
   69     if(subalias != TK_EPHEMERAL)
   70       return false;
   71   }
   72 
   73   if(super == TK_TAG)
   74     return true;
   75 
   76   // Every possible instantiation of sub must be a subtype of every possible
   77   // instantiation of super.
   78   switch(sub)
   79   {
   80     case TK_ISO:
   81       switch(super)
   82       {
   83         case TK_ISO:
   84         case TK_TRN:
   85         case TK_REF:
   86         case TK_VAL:
   87         case TK_BOX:
   88         case TK_CAP_READ:  // {ref, val, box}
   89         case TK_CAP_SHARE: // {val, tag}
   90         case TK_CAP_SEND:  // {iso, val, tag}
   91         case TK_CAP_ALIAS: // {ref, val, box, tag}
   92         case TK_CAP_ANY:   // {iso, trn, ref, val, box, tag}
   93           return true;
   94 
   95         default: {}
   96       }
   97       break;
   98 
   99     case TK_TRN:
  100       switch(super)
  101       {
  102         case TK_TRN:
  103         case TK_REF:
  104         case TK_VAL:
  105         case TK_BOX:
  106         case TK_CAP_READ:  // {ref, val, box}
  107         case TK_CAP_SHARE: // {val, tag}
  108         case TK_CAP_ALIAS: // {ref, val, box, tag}
  109           return true;
  110 
  111         default: {}
  112       }
  113       break;
  114 
  115     case TK_REF:
  116       switch(super)
  117       {
  118         case TK_REF:
  119         case TK_BOX:
  120           return true;
  121 
  122         default: {}
  123       }
  124       break;
  125 
  126     case TK_VAL:
  127       switch(super)
  128       {
  129         case TK_VAL:
  130         case TK_BOX:
  131         case TK_CAP_SHARE: // {val, tag}
  132           return true;
  133 
  134         default: {}
  135       }
  136       break;
  137 
  138     case TK_BOX:
  139     case TK_CAP_READ: // {ref, val, box}
  140       switch(super)
  141       {
  142         case TK_BOX:
  143           return true;
  144 
  145         default: {}
  146       }
  147       break;
  148 
  149     default: {}
  150   }
  151 
  152   return false;
  153 }
  154 
  155 bool is_cap_sub_cap_constraint(token_id sub, token_id subalias, token_id super,
  156   token_id supalias)
  157 {
  158   // Transform the cap based on the aliasing info.
  159   cap_aliasing(&sub, &subalias);
  160   cap_aliasing(&super, &supalias);
  161 
  162   if(supalias == TK_EPHEMERAL)
  163   {
  164     // Sub must be ephemeral.
  165     if(subalias != TK_EPHEMERAL)
  166       return false;
  167   }
  168 
  169   if((sub == super) || (super == TK_CAP_ANY))
  170     return true;
  171 
  172   // Every possible instantiation of sub must be a member of the set of every
  173   // possible instantiation of super.
  174   switch(super)
  175   {
  176     case TK_CAP_READ: // {ref, val, box}
  177       switch(sub)
  178       {
  179         case TK_REF:
  180         case TK_VAL:
  181         case TK_BOX:
  182           return true;
  183 
  184         default: {}
  185       }
  186       break;
  187 
  188     case TK_CAP_SHARE: // {val, tag}
  189       switch(sub)
  190       {
  191         case TK_VAL:
  192         case TK_TAG:
  193           return true;
  194 
  195         default: {}
  196       }
  197       break;
  198 
  199     case TK_CAP_SEND: // {iso, val, tag}
  200       switch(sub)
  201       {
  202         case TK_ISO:
  203         case TK_VAL:
  204         case TK_TAG:
  205         case TK_CAP_SHARE: // {val, tag}
  206           return true;
  207 
  208         default: {}
  209       }
  210       break;
  211 
  212     case TK_CAP_ALIAS: // {ref, val, box, tag}
  213       switch(sub)
  214       {
  215         case TK_REF:
  216         case TK_VAL:
  217         case TK_BOX:
  218         case TK_TAG:
  219         case TK_CAP_READ:  // {ref, val, box}
  220         case TK_CAP_SHARE: // {val, tag}
  221           return true;
  222 
  223         default: {}
  224       }
  225       break;
  226 
  227     default: {}
  228   }
  229 
  230   return false;
  231 }
  232 
  233 bool is_cap_sub_cap_bound(token_id sub, token_id subalias, token_id super,
  234   token_id supalias)
  235 {
  236   // Transform the cap based on the aliasing info.
  237   cap_aliasing(&sub, &subalias);
  238   cap_aliasing(&super, &supalias);
  239 
  240   if(supalias == TK_EPHEMERAL)
  241   {
  242     // Sub must be ephemeral.
  243     if(subalias != TK_EPHEMERAL)
  244       return false;
  245   }
  246 
  247   if((sub == super) || (super == TK_TAG))
  248     return true;
  249 
  250   // Sub and super share the same initial bounds.
  251   //
  252   // If either rcap is a specific/singular capability, use the same rule
  253   // as in is_cap_sub_cap: every possible instantiation of sub must be a
  254   // subtype of every possible instantiation of super.
  255   //
  256   // If both rcaps are generic/set capabilities, use the following rule:
  257   // every instantiation of the super rcap must be a supertype of some
  258   // instantiation of the sub rcap (but not necessarily the same instantiation
  259   // of the sub rcap).
  260   switch(sub)
  261   {
  262     case TK_ISO:
  263       switch(super)
  264       {
  265         case TK_TRN:
  266         case TK_REF:
  267         case TK_VAL:
  268         case TK_BOX:
  269         case TK_CAP_READ:  // {ref, val, box}
  270         case TK_CAP_SHARE: // {val, tag}
  271         case TK_CAP_SEND:  // {iso, val, tag}
  272         case TK_CAP_ALIAS: // {ref, val, box, tag}
  273         case TK_CAP_ANY:   // {iso, trn, ref, val, box, tag}
  274           return true;
  275 
  276         default: {}
  277       }
  278       break;
  279 
  280     case TK_TRN:
  281       switch(super)
  282       {
  283         case TK_REF:
  284         case TK_VAL:
  285         case TK_BOX:
  286         case TK_CAP_READ:  // {ref, val, box}
  287         case TK_CAP_SHARE: // {val, tag}
  288         case TK_CAP_ALIAS: // {ref, val, box, tag}
  289           return true;
  290 
  291         default: {}
  292       }
  293       break;
  294 
  295     case TK_REF:
  296       switch(super)
  297       {
  298         case TK_BOX:
  299           return true;
  300 
  301         default: {}
  302       }
  303       break;
  304 
  305     case TK_VAL:
  306       switch(super)
  307       {
  308         case TK_BOX:
  309         case TK_CAP_SHARE: // {val, tag}
  310           return true;
  311 
  312         default: {}
  313       }
  314       break;
  315 
  316     case TK_CAP_READ: // {ref, val, box}
  317       switch(super)
  318       {
  319         case TK_BOX:
  320         case TK_CAP_SHARE: // {val, tag}
  321         case TK_CAP_ALIAS: // {ref, val, box, tag}
  322           return true;
  323 
  324         default: {}
  325       }
  326       break;
  327 
  328     case TK_CAP_SEND: // {iso, val, tag}
  329       switch(super)
  330       {
  331         case TK_CAP_READ:  // {ref, val, box}
  332         case TK_CAP_SHARE: // {val, tag}
  333         case TK_CAP_ALIAS: // {ref, val, box, tag}
  334         case TK_CAP_ANY:   // {iso, trn, ref, val, box, tag}
  335           return true;
  336 
  337         default: {}
  338       }
  339       break;
  340 
  341     case TK_CAP_ALIAS: // {ref, val, box, tag}
  342       switch(super)
  343       {
  344         case TK_CAP_READ:  // {ref, val, box}
  345         case TK_CAP_SHARE: // {val, tag}
  346           return true;
  347 
  348         default: {}
  349       }
  350       break;
  351 
  352     case TK_CAP_ANY: // {iso, trn, ref, val, box, tag}
  353       switch(super)
  354       {
  355         case TK_CAP_READ:  // {ref, val, box}
  356         case TK_CAP_SHARE: // {val, tag}
  357         case TK_CAP_SEND:  // {iso, val, tag}
  358         case TK_CAP_ALIAS: // {ref, val, box, tag}
  359           return true;
  360 
  361         default: {}
  362       }
  363       break;
  364 
  365     default: {}
  366   }
  367 
  368   return false;
  369 }
  370 
  371 bool is_cap_compat_cap(token_id left_cap, token_id left_eph,
  372   token_id right_cap, token_id right_eph)
  373 {
  374   // Transform the cap based on the aliasing info.
  375   cap_aliasing(&left_cap, &left_eph);
  376   cap_aliasing(&right_cap, &right_eph);
  377 
  378   if((left_cap == TK_TAG) || (right_cap == TK_TAG))
  379     return true;
  380 
  381   // Every possible instantiation of the left cap must be compatible with every
  382   // possible instantiation of right cap.
  383   switch(left_cap)
  384   {
  385     case TK_ISO:
  386       switch(right_cap)
  387       {
  388         case TK_ISO:
  389           return true;
  390 
  391         default: {}
  392       }
  393       break;
  394 
  395     case TK_TRN:
  396       switch(right_cap)
  397       {
  398         case TK_TRN:
  399         case TK_BOX:
  400           return true;
  401 
  402         default: {}
  403       }
  404       break;
  405 
  406     case TK_REF:
  407       switch(right_cap)
  408       {
  409         case TK_REF:
  410         case TK_BOX:
  411           return true;
  412 
  413         default: {}
  414       }
  415       break;
  416 
  417     case TK_VAL:
  418       switch(right_cap)
  419       {
  420         case TK_VAL:
  421         case TK_BOX:
  422         case TK_CAP_SHARE:
  423           return true;
  424 
  425         default: {}
  426       }
  427       break;
  428 
  429     case TK_BOX:
  430       switch(right_cap)
  431       {
  432         case TK_TRN:
  433         case TK_REF:
  434         case TK_VAL:
  435         case TK_BOX:
  436         case TK_CAP_READ:
  437         case TK_CAP_SHARE:
  438         case TK_CAP_ALIAS:
  439           return true;
  440 
  441         default: {}
  442       }
  443       break;
  444 
  445     case TK_CAP_READ:
  446     case TK_CAP_ALIAS:
  447       switch(right_cap)
  448       {
  449         case TK_BOX:
  450           return true;
  451 
  452         default: {}
  453       }
  454       break;
  455 
  456     case TK_CAP_SEND:
  457       break;
  458 
  459     case TK_CAP_SHARE:
  460       switch(right_cap)
  461       {
  462         case TK_VAL:
  463         case TK_BOX:
  464         case TK_CAP_SHARE:
  465           return true;
  466 
  467         default: {}
  468       }
  469       break;
  470 
  471     default: {}
  472   }
  473 
  474   return false;
  475 }
  476 
  477 ast_t* cap_fetch(ast_t* type)
  478 {
  479   switch(ast_id(type))
  480   {
  481     case TK_NOMINAL:
  482       return ast_childidx(type, 3);
  483 
  484     case TK_TYPEPARAMREF:
  485       return ast_childidx(type, 1);
  486 
  487     default: {}
  488   }
  489 
  490   pony_assert(0);
  491   return NULL;
  492 }
  493 
  494 token_id cap_single(ast_t* type)
  495 {
  496   ast_t* cap = cap_fetch(type);
  497   ast_t* eph = ast_sibling(cap);
  498 
  499   token_id tcap = ast_id(cap);
  500   token_id teph = ast_id(eph);
  501   cap_aliasing(&tcap, &teph);
  502 
  503   return tcap;
  504 }
  505 
  506 token_id cap_dispatch(ast_t* type)
  507 {
  508   switch(ast_id(type))
  509   {
  510     case TK_UNIONTYPE:
  511     {
  512       // Use the least specific capability.
  513       ast_t* child = ast_child(type);
  514       token_id cap = cap_dispatch(child);
  515       child = ast_sibling(child);
  516 
  517       while(child != NULL)
  518       {
  519         token_id child_cap = cap_dispatch(child);
  520 
  521         if(is_cap_sub_cap(cap, TK_NONE, child_cap, TK_NONE))
  522           cap = child_cap;
  523         else if(!is_cap_sub_cap(child_cap, TK_NONE, cap, TK_NONE))
  524           cap = TK_BOX;
  525 
  526         child = ast_sibling(child);
  527       }
  528 
  529       return cap;
  530     }
  531 
  532     case TK_ISECTTYPE:
  533     {
  534       // Use the most specific capability. Because all capabilities will be
  535       // locally compatible, there is a subtype relationship.
  536       ast_t* child = ast_child(type);
  537       token_id cap = cap_dispatch(child);
  538       child = ast_sibling(child);
  539 
  540       while(child != NULL)
  541       {
  542         token_id child_cap = cap_dispatch(child);
  543 
  544         if(is_cap_sub_cap(child_cap, TK_NONE, cap, TK_NONE))
  545           cap = child_cap;
  546 
  547         child = ast_sibling(child);
  548       }
  549 
  550       return cap;
  551     }
  552 
  553     case TK_NOMINAL:
  554       return cap_single(type);
  555 
  556     default: {}
  557   }
  558 
  559   pony_assert(0);
  560   return TK_NONE;
  561 }
  562 
  563 token_id cap_for_this(typecheck_t* t)
  564 {
  565   // If this is a primitive, it's a val.
  566   if(ast_id(t->frame->type) == TK_PRIMITIVE)
  567     return TK_VAL;
  568 
  569   // If we aren't in a method, we're in a field initialiser.
  570   if(t->frame->method == NULL)
  571     return TK_REF;
  572 
  573   // If it's a function, get the capability from the signature.
  574   if(ast_id(t->frame->method) == TK_FUN)
  575     return ast_id(ast_child(t->frame->method));
  576 
  577   // If it's a behaviour or a constructor, it's a ref.
  578   return TK_REF;
  579 }
  580 
  581 bool cap_view_upper(token_id left_cap, token_id left_eph,
  582   token_id* right_cap, token_id* right_eph)
  583 {
  584   cap_aliasing(&left_cap, &left_eph);
  585   cap_aliasing(right_cap, right_eph);
  586 
  587   // Can't see through these viewpoints.
  588   switch(left_cap)
  589   {
  590     case TK_TAG:
  591     case TK_CAP_SEND:
  592     case TK_CAP_SHARE:
  593     case TK_CAP_ALIAS:
  594     case TK_CAP_ANY:
  595       return false;
  596 
  597     default: {}
  598   }
  599 
  600   // A tag is always seen as a tag.
  601   if(*right_cap == TK_TAG)
  602     return true;
  603 
  604   switch(left_cap)
  605   {
  606     case TK_ISO:
  607     {
  608       switch(*right_cap)
  609       {
  610         case TK_ISO:
  611         case TK_CAP_SEND:
  612           if(left_eph == TK_EPHEMERAL)
  613             *right_eph = TK_EPHEMERAL;
  614           break;
  615 
  616         case TK_VAL:
  617         case TK_CAP_SHARE:
  618           break;
  619 
  620         default:
  621           *right_cap = TK_TAG;
  622           *right_eph = TK_NONE;
  623       }
  624       break;
  625     }
  626 
  627     case TK_TRN:
  628     {
  629       switch(*right_cap)
  630       {
  631         case TK_ISO:
  632         case TK_TRN:
  633         case TK_CAP_SEND:
  634           if(left_eph == TK_EPHEMERAL)
  635             *right_eph = TK_EPHEMERAL;
  636           break;
  637 
  638         case TK_VAL:
  639         case TK_CAP_SHARE:
  640           break;
  641 
  642         case TK_CAP_ALIAS:
  643         case TK_CAP_ANY:
  644           *right_cap = TK_TAG;
  645           *right_eph = TK_NONE;
  646           break;
  647 
  648         default:
  649           *right_cap = TK_BOX;
  650           *right_eph = TK_NONE;
  651       }
  652       break;
  653     }
  654 
  655     case TK_REF:
  656       break;
  657 
  658     case TK_VAL:
  659     {
  660       switch(*right_cap)
  661       {
  662         case TK_CAP_SEND:
  663         case TK_CAP_SHARE:
  664         case TK_CAP_ALIAS:
  665         case TK_CAP_ANY:
  666           *right_cap = TK_CAP_SHARE;
  667           break;
  668 
  669         default:
  670           *right_cap = TK_VAL;
  671       }
  672 
  673       *right_eph = TK_NONE;
  674       break;
  675     }
  676 
  677     case TK_BOX:
  678     case TK_CAP_READ:
  679     {
  680       switch(*right_cap)
  681       {
  682         case TK_ISO:
  683           *right_cap = TK_TAG;
  684           break;
  685 
  686         case TK_VAL:
  687         case TK_CAP_SHARE:
  688           break;
  689 
  690         case TK_CAP_SEND:
  691         case TK_CAP_ALIAS:
  692         case TK_CAP_ANY:
  693           *right_cap = TK_TAG;
  694           break;
  695 
  696         default:
  697           *right_cap = TK_BOX;
  698       }
  699 
  700       *right_eph = TK_NONE;
  701       break;
  702     }
  703 
  704     default:
  705       pony_assert(0);
  706       return false;
  707   }
  708 
  709   return true;
  710 }
  711 
  712 bool cap_view_lower(token_id left_cap, token_id left_eph,
  713   token_id* right_cap, token_id* right_eph)
  714 {
  715   cap_aliasing(&left_cap, &left_eph);
  716   cap_aliasing(right_cap, right_eph);
  717 
  718   // Can't see through these viewpoints.
  719   switch(left_cap)
  720   {
  721     case TK_TAG:
  722     case TK_CAP_SEND:
  723     case TK_CAP_SHARE:
  724     case TK_CAP_ALIAS:
  725     case TK_CAP_ANY:
  726       return false;
  727 
  728     default: {}
  729   }
  730 
  731   // A tag is always seen as a tag.
  732   if(*right_cap == TK_TAG)
  733     return true;
  734 
  735   switch(left_cap)
  736   {
  737     case TK_ISO:
  738     {
  739       switch(*right_cap)
  740       {
  741         case TK_ISO:
  742         case TK_CAP_SEND:
  743           if(left_eph == TK_EPHEMERAL)
  744             *right_eph = TK_EPHEMERAL;
  745           break;
  746 
  747         case TK_VAL:
  748         case TK_CAP_SHARE:
  749           break;
  750 
  751         case TK_CAP_READ:
  752         case TK_CAP_ALIAS:
  753         case TK_CAP_ANY:
  754           *right_cap = TK_CAP_SEND;
  755 
  756           if(left_eph == TK_EPHEMERAL)
  757             *right_eph = TK_EPHEMERAL;
  758           break;
  759 
  760         default:
  761           *right_cap = TK_TAG;
  762           *right_eph = TK_NONE;
  763       }
  764       break;
  765     }
  766 
  767     case TK_TRN:
  768     {
  769       switch(*right_cap)
  770       {
  771         case TK_ISO:
  772         case TK_TRN:
  773         case TK_CAP_SEND:
  774           if(left_eph == TK_EPHEMERAL)
  775             *right_eph = TK_EPHEMERAL;
  776           break;
  777 
  778         case TK_VAL:
  779         case TK_CAP_SHARE:
  780           break;
  781 
  782         case TK_CAP_READ:
  783         case TK_CAP_ALIAS:
  784           *right_cap = TK_VAL;
  785           *right_eph = TK_NONE;
  786           break;
  787 
  788         case TK_CAP_ANY:
  789           *right_cap = TK_ISO;
  790 
  791           if(left_eph == TK_EPHEMERAL)
  792             *right_eph = TK_EPHEMERAL;
  793           break;
  794 
  795         default:
  796           *right_cap = TK_BOX;
  797           *right_eph = TK_NONE;
  798       }
  799       break;
  800     }
  801 
  802     case TK_REF:
  803       break;
  804 
  805     case TK_VAL:
  806     {
  807       switch(*right_cap)
  808       {
  809         case TK_CAP_SEND:
  810         case TK_CAP_SHARE:
  811         case TK_CAP_ALIAS:
  812         case TK_CAP_ANY:
  813           *right_cap = TK_CAP_SHARE;
  814           break;
  815 
  816         default:
  817           *right_cap = TK_VAL;
  818       }
  819 
  820       *right_eph = TK_NONE;
  821       break;
  822     }
  823 
  824     case TK_BOX:
  825     {
  826       switch(*right_cap)
  827       {
  828         case TK_ISO:
  829           *right_cap = TK_TAG;
  830           break;
  831 
  832         case TK_VAL:
  833         case TK_CAP_SHARE:
  834           break;
  835 
  836         case TK_CAP_SEND:
  837           *right_cap = TK_CAP_SHARE;
  838           break;
  839 
  840         case TK_CAP_READ:
  841         case TK_CAP_ALIAS:
  842         case TK_CAP_ANY:
  843           *right_cap = TK_VAL;
  844           break;
  845 
  846         default:
  847           *right_cap = TK_BOX;
  848       }
  849 
  850       *right_eph = TK_NONE;
  851       break;
  852     }
  853 
  854     case TK_CAP_READ:
  855     {
  856       switch(*right_cap)
  857       {
  858         case TK_ISO:
  859           *right_cap = TK_CAP_SEND;
  860           break;
  861 
  862         case TK_REF:
  863           *right_cap = TK_CAP_READ;
  864           break;
  865 
  866         case TK_BOX:
  867           *right_cap = TK_VAL;
  868           break;
  869 
  870         default: {}
  871       }
  872       break;
  873     }
  874 
  875     default:
  876       pony_assert(0);
  877       return false;
  878   }
  879 
  880   return true;
  881 }
  882 
  883 bool cap_sendable(token_id cap)
  884 {
  885   switch(cap)
  886   {
  887     case TK_ISO:
  888     case TK_VAL:
  889     case TK_TAG:
  890     case TK_CAP_SEND:
  891     case TK_CAP_SHARE:
  892       return true;
  893 
  894     default: {}
  895   }
  896 
  897   return false;
  898 }
  899 
  900 bool cap_immutable_or_opaque(token_id cap)
  901 {
  902   switch(cap)
  903   {
  904     case TK_VAL:
  905     case TK_BOX:
  906     case TK_TAG:
  907     case TK_CAP_SHARE:
  908       return true;
  909 
  910     default: {}
  911   }
  912 
  913   return false;
  914 }
  915 
  916 bool cap_safetowrite(token_id into, token_id cap)
  917 {
  918   switch(into)
  919   {
  920     case TK_ISO:
  921       switch(cap)
  922       {
  923         case TK_ISO:
  924         case TK_VAL:
  925         case TK_TAG:
  926         case TK_CAP_SEND:
  927         case TK_CAP_SHARE:
  928           return true;
  929 
  930         default: {}
  931       }
  932       break;
  933 
  934     case TK_TRN:
  935       switch(cap)
  936       {
  937         case TK_ISO:
  938         case TK_TRN:
  939         case TK_VAL:
  940         case TK_TAG:
  941         case TK_CAP_SEND:
  942         case TK_CAP_SHARE:
  943           return true;
  944 
  945         default: {}
  946       }
  947       break;
  948 
  949     case TK_REF:
  950       return true;
  951 
  952     default: {}
  953   }
  954 
  955   return false;
  956 }