Esempio n. 1
0
File: cap.c Progetto: jonas-l/ponyc
token_id cap_single(ast_t* type)
{
  size_t i;

  switch(ast_id(type))
  {
    case TK_NOMINAL:
      i = 3;
      break;

    case TK_TYPEPARAMREF:
      i = 1;
      break;

    default:
      assert(0);
      return TK_NONE;
  }

  ast_t* cap = ast_childidx(type, i);
  ast_t* eph = ast_sibling(cap);

  token_id tcap = ast_id(cap);
  token_id teph = ast_id(eph);
  cap_aliasing(&tcap, &teph);

  return tcap;
}
Esempio n. 2
0
File: cap.c Progetto: DevL/ponyc
token_id cap_single(ast_t* type)
{
  ast_t* cap = cap_fetch(type);
  ast_t* eph = ast_sibling(cap);

  token_id tcap = ast_id(cap);
  token_id teph = ast_id(eph);
  cap_aliasing(&tcap, &teph);

  return tcap;
}
Esempio n. 3
0
File: cap.c Progetto: DevL/ponyc
bool cap_view_lower(token_id left_cap, token_id left_eph,
  token_id* right_cap, token_id* right_eph)
{
  left_cap = cap_unbind(left_cap);
  *right_cap = cap_unbind(*right_cap);

  cap_aliasing(&left_cap, &left_eph);
  cap_aliasing(right_cap, right_eph);

  // Can't see through these viewpoints.
  switch(left_cap)
  {
    case TK_TAG:
    case TK_CAP_SEND:
    case TK_CAP_SHARE:
    case TK_CAP_ANY:
      return false;

    default: {}
  }

  // A tag is always seen as a tag.
  if(*right_cap == TK_TAG)
    return true;

  switch(left_cap)
  {
    case TK_ISO:
    {
      switch(*right_cap)
      {
        case TK_ISO:
        case TK_CAP_SEND:
          if(left_eph == TK_EPHEMERAL)
            *right_eph = TK_EPHEMERAL;
          break;

        case TK_VAL:
        case TK_CAP_SHARE:
          break;

        case TK_CAP_READ:
        case TK_CAP_ANY:
          *right_cap = TK_CAP_SEND;

          if(left_eph == TK_EPHEMERAL)
            *right_eph = TK_EPHEMERAL;
          break;

        default:
          *right_cap = TK_TAG;
          *right_eph = TK_NONE;
      }
      break;
    }

    case TK_TRN:
    {
      switch(*right_cap)
      {
        case TK_ISO:
        case TK_TRN:
        case TK_CAP_SEND:
          if(left_eph == TK_EPHEMERAL)
            *right_eph = TK_EPHEMERAL;
          break;

        case TK_VAL:
        case TK_CAP_SHARE:
          break;

        case TK_CAP_READ:
          *right_cap = TK_VAL;
          *right_eph = TK_NONE;
          break;

        case TK_CAP_ANY:
          *right_cap = TK_ISO;

          if(left_eph == TK_EPHEMERAL)
            *right_eph = TK_EPHEMERAL;
          break;

        default:
          *right_cap = TK_BOX;
          *right_eph = TK_NONE;
      }
      break;
    }

    case TK_REF:
      break;

    case TK_VAL:
    {
      switch(*right_cap)
      {
        case TK_CAP_SEND:
        case TK_CAP_SHARE:
        case TK_CAP_ANY:
          *right_cap = TK_CAP_SHARE;
          break;

        default:
          *right_cap = TK_VAL;
      }

      *right_eph = TK_NONE;
      break;
    }

    case TK_BOX:
    {
      switch(*right_cap)
      {
        case TK_ISO:
          *right_cap = TK_TAG;
          break;

        case TK_VAL:
        case TK_CAP_SHARE:
          break;

        case TK_CAP_SEND:
          *right_cap = TK_CAP_SHARE;
          break;

        case TK_CAP_READ:
        case TK_CAP_ANY:
          *right_cap = TK_VAL;
          break;

        default:
          *right_cap = TK_BOX;
      }

      *right_eph = TK_NONE;
      break;
    }

    case TK_CAP_READ:
    {
      switch(*right_cap)
      {
        case TK_ISO:
          *right_cap = TK_CAP_SEND;
          break;

        case TK_REF:
          *right_cap = TK_CAP_READ;
          break;

        case TK_BOX:
          *right_cap = TK_VAL;
          break;

        default: {}
      }
      break;
    }

    default:
      assert(0);
      return false;
  }

  return true;
}
Esempio n. 4
0
File: cap.c Progetto: DevL/ponyc
bool is_cap_sub_cap(token_id sub, token_id subalias, token_id super,
  token_id supalias)
{
  // Transform the cap based on the aliasing info.
  cap_aliasing(&sub, &subalias);
  cap_aliasing(&super, &supalias);

  if(supalias == TK_EPHEMERAL)
  {
    // Sub must be ephemeral.
    if(subalias != TK_EPHEMERAL)
      return false;
  }

  if((sub == super) || (super == TK_TAG) || (super == TK_CAP_ANY_BIND))
    return true;

  // Every possible value of sub must be a subtype of every possible value of
  // super.
  switch(sub)
  {
    case TK_ISO:
      switch(super)
      {
        case TK_ISO:
        case TK_TRN:
        case TK_REF:
        case TK_VAL:
        case TK_BOX:
        case TK_CAP_READ:
        case TK_CAP_SHARE:
        case TK_CAP_SEND:
        case TK_CAP_ANY:

        case TK_ISO_BIND:
        case TK_CAP_SEND_BIND:
          return true;

        default: {}
      }
      break;

    case TK_TRN:
      switch(super)
      {
        case TK_REF:
        case TK_VAL:
        case TK_BOX:
        case TK_CAP_READ:
        case TK_CAP_SHARE:

        case TK_TRN_BIND:
          return true;

        default: {}
      }
      break;

    case TK_REF:
      switch(super)
      {
        case TK_BOX:

        case TK_REF_BIND:
        case TK_CAP_READ_BIND:
          return true;

        default: {}
      }
      break;

    case TK_VAL:
      switch(super)
      {
        case TK_BOX:
        case TK_CAP_SHARE:

        case TK_VAL_BIND:
        case TK_CAP_READ_BIND:
        case TK_CAP_SEND_BIND:
        case TK_CAP_SHARE_BIND:
          return true;

        default: {}
      }
      break;

    case TK_BOX:
      switch(super)
      {
        case TK_BOX_BIND:
        case TK_CAP_READ_BIND:
          return true;

        default: {}
      }
      break;

    case TK_TAG:
      switch(super)
      {
        case TK_TAG_BIND:
        case TK_CAP_SEND_BIND:
        case TK_CAP_SHARE_BIND:
          return true;

        default: {}
      }
      break;

    case TK_CAP_READ:
      switch(super)
      {
        case TK_BOX:
        case TK_CAP_READ_BIND:
          return true;

        default: {}
      }
      break;

    case TK_CAP_SEND:
      switch(super)
      {
        case TK_CAP_SEND_BIND:
          return true;

        default: {}
      }
      break;

    case TK_CAP_SHARE:
      switch(super)
      {
        case TK_CAP_SHARE_BIND:
          return true;

        default: {}
      }
      break;

    default: {}
  }

  return false;
}
Esempio n. 5
0
File: cap.c Progetto: DevL/ponyc
bool is_cap_compat_cap(token_id left_cap, token_id left_eph,
  token_id right_cap, token_id right_eph)
{
  // Transform the cap based on the aliasing info.
  cap_aliasing(&left_cap, &left_eph);
  cap_aliasing(&right_cap, &right_eph);

  // Ignore compatibility for bind caps.
  if((cap_unbind(left_cap) != left_cap) ||
    (cap_unbind(right_cap) != right_cap))
    return true;

  if((left_cap == TK_TAG) || (right_cap == TK_TAG))
    return true;

  // Every possible value of left must be compatible with every possible value
  // of right.
  switch(left_cap)
  {
    case TK_ISO:
      switch(right_cap)
      {
        case TK_ISO:
          return true;

        default: {}
      }
      break;

    case TK_TRN:
      switch(right_cap)
      {
        case TK_TRN:
        case TK_BOX:
          return true;

        default: {}
      }
      break;

    case TK_REF:
      switch(right_cap)
      {
        case TK_REF:
        case TK_BOX:
          return true;

        default: {}
      }
      break;

    case TK_VAL:
      switch(right_cap)
      {
        case TK_VAL:
        case TK_BOX:
        case TK_CAP_SHARE:
          return true;

        default: {}
      }
      break;

    case TK_BOX:
      switch(right_cap)
      {
        case TK_TRN:
        case TK_REF:
        case TK_VAL:
        case TK_BOX:
        case TK_CAP_READ:
          return true;

        default: {}
      }
      break;

    case TK_CAP_READ:
      switch(right_cap)
      {
        case TK_BOX:
          return true;

        default: {}
      }
      break;

    case TK_CAP_SEND:
      break;

    case TK_CAP_SHARE:
      switch(right_cap)
      {
        case TK_VAL:
        case TK_BOX:
        case TK_CAP_SHARE:
          return true;

        default: {}
      }
      break;

    default: {}
  }

  return false;
}
Esempio n. 6
0
File: cap.c Progetto: DevL/ponyc
bool is_cap_match_cap(token_id operand_cap, token_id operand_eph,
  token_id pattern_cap, token_id pattern_eph)
{
  // Transform the cap based on the aliasing info.
  cap_aliasing(&operand_cap, &operand_eph);
  cap_aliasing(&pattern_cap, &pattern_eph);

  if(pattern_eph == TK_EPHEMERAL)
  {
    // Operand must be ephemeral.
    if(operand_eph != TK_EPHEMERAL)
      return false;
  }

  operand_cap = cap_unbind(operand_cap);
  pattern_cap = cap_unbind(pattern_cap);

  if((operand_cap == pattern_cap) || (pattern_cap == TK_TAG))
    return true;

  // Some instantiaion of the operand refcap must be a subtype of some
  // instantiation of the pattern refcap.
  switch(operand_cap)
  {
    case TK_ISO:
    case TK_CAP_SEND:
    case TK_CAP_ANY:
      switch(pattern_cap)
      {
        case TK_ISO:
        case TK_TRN:
        case TK_REF:
        case TK_VAL:
        case TK_BOX:
        case TK_CAP_READ:
        case TK_CAP_SHARE:
        case TK_CAP_SEND:
        case TK_CAP_ANY:
          return true;

        default: {}
      }
      break;

    case TK_TRN:
      switch(pattern_cap)
      {
        case TK_REF:
        case TK_VAL:
        case TK_BOX:
        case TK_CAP_READ:
        case TK_CAP_SHARE:
        case TK_CAP_SEND:
        case TK_CAP_ANY:
          return true;

        default: {}
      }
      break;

    case TK_REF:
      switch(pattern_cap)
      {
        case TK_BOX:
        case TK_CAP_READ:
        case TK_CAP_SHARE:
        case TK_CAP_SEND:
        case TK_CAP_ANY:
          return true;

        default: {}
      }
      break;

    case TK_VAL:
    case TK_CAP_SHARE:
      switch(pattern_cap)
      {
        case TK_BOX:
        case TK_CAP_READ:
        case TK_CAP_SHARE:
        case TK_CAP_SEND:
        case TK_CAP_ANY:
          return true;

        default: {}
      }
      break;

    case TK_BOX:
      switch(pattern_cap)
      {
        case TK_CAP_READ:
        case TK_CAP_SHARE:
        case TK_CAP_SEND:
        case TK_CAP_ANY:
          return true;

        default: {}
      }
      break;

    case TK_TAG:
      switch(pattern_cap)
      {
        case TK_CAP_SHARE:
        case TK_CAP_SEND:
        case TK_CAP_ANY:
          return true;

        default: {}
      }
      break;

    case TK_CAP_READ:
      switch(pattern_cap)
      {
        case TK_REF:
        case TK_VAL:
        case TK_BOX:
        case TK_CAP_SHARE:
        case TK_CAP_SEND:
        case TK_CAP_ANY:
          return true;

        default: {}
      }
      break;

    default: {}
  }

  return false;
}