コード例 #1
0
ファイル: reify.c プロジェクト: Theodus/ponyc
void deferred_reify_add_method_typeparams(deferred_reification_t* deferred,
  ast_t* typeparams, ast_t* typeargs, pass_opt_t* opt)
{
  pony_assert((deferred->method_typeparams == NULL) &&
    (deferred->method_typeargs == NULL));

  pony_assert(((typeparams != NULL) && (typeargs != NULL)) ||
    ((typeparams == NULL) && (typeargs == NULL)));

  if(typeparams == NULL)
    return;

  ast_t* r_typeparams = ast_dup(typeparams);
  deferred->method_typeargs = ast_dup(typeargs);

  // Must replace `this` before typeparam reification.
  if(deferred->thistype != NULL)
    r_typeparams = viewpoint_replacethis(r_typeparams, deferred->thistype,
      false);

  if(deferred->type_typeparams != NULL)
    r_typeparams = reify(r_typeparams, deferred->type_typeparams,
      deferred->type_typeargs, opt, false);

  deferred->method_typeparams = r_typeparams;
}
コード例 #2
0
ファイル: subtype.c プロジェクト: jersey99/ponyc
static bool push_assume(ast_t* sub, ast_t* super)
{
  // Returns true if we have already assumed sub is a subtype of super.
  if(subtype_assume != NULL)
  {
    ast_t* assumption = ast_child(subtype_assume);

    while(assumption != NULL)
    {
      AST_GET_CHILDREN(assumption, assume_sub, assume_super);

      if(exact_nominal(sub, assume_sub) &&
        exact_nominal(super, assume_super))
        return true;

      assumption = ast_sibling(assumption);
    }
  } else {
    subtype_assume = ast_from(sub, TK_NONE);
  }

  BUILD(assume, sub, NODE(TK_NONE, TREE(ast_dup(sub)) TREE(ast_dup(super))));
  ast_add(subtype_assume, assume);
  return false;
}
コード例 #3
0
ファイル: reach.c プロジェクト: DevL/ponyc
static void add_rmethod(reachable_method_stack_t** s,
  reachable_type_t* t, reachable_method_name_t* n, ast_t* typeargs)
{
  const char* name = genname_fun(NULL, n->name, typeargs);
  reachable_method_t* m = reach_method(n, name);

  if(m == NULL)
  {
    m = POOL_ALLOC(reachable_method_t);
    m->name = name;
    m->typeargs = ast_dup(typeargs);
    m->vtable_index = (uint32_t)-1;

    ast_t* fun = lookup(NULL, NULL, t->type, n->name);

    if(typeargs != NULL)
    {
      // Reify the method with its typeargs, if it has any.
      AST_GET_CHILDREN(fun, cap, id, typeparams, params, result, can_error,
        body);

      ast_t* r_fun = reify(fun, typeparams, typeargs);
      ast_free_unattached(fun);
      fun = r_fun;
    }

    m->r_fun = ast_dup(fun);
    ast_free_unattached(fun);

    reachable_methods_put(&n->r_methods, m);

    // Put on a stack of reachable methods to trace.
    *s = reachable_method_stack_push(*s, m);
  }
}
コード例 #4
0
ファイル: reach.c プロジェクト: Sendence/ponyc
static void add_rmethod_to_subtype(reach_t* r, reach_type_t* t,
  reach_method_name_t* n, reach_method_t* m, pass_opt_t* opt)
{
  // Add the method to the type if it isn't already there.
  reach_method_name_t* n2 = add_method_name(t, n->name);
  add_rmethod(r, t, n2, m->cap, m->typeargs, opt);

  // Add this mangling to the type if it isn't already there.
  reach_method_t* mangled = reach_mangled_get(&n2->r_mangled, m);

  if(mangled != NULL)
    return;

  mangled = POOL_ALLOC(reach_method_t);
  memset(mangled, 0, sizeof(reach_method_t));

  mangled->name = m->name;
  mangled->mangled_name = m->mangled_name;
  mangled->full_name = make_full_name(t, mangled);

  mangled->cap = m->cap;
  mangled->r_fun = ast_dup(m->r_fun);
  mangled->typeargs = ast_dup(m->typeargs);
  mangled->forwarding = true;

  mangled->param_count = m->param_count;
  mangled->params = (reach_param_t*)ponyint_pool_alloc_size(
    mangled->param_count * sizeof(reach_param_t));
  memcpy(mangled->params, m->params, m->param_count * sizeof(reach_param_t));
  mangled->result = m->result;

  // Add to the mangled table only.
  reach_mangled_put(&n2->r_mangled, mangled);
}
コード例 #5
0
ファイル: assemble.c プロジェクト: jonas-l/ponyc
ast_t* set_cap_and_ephemeral(ast_t* type, token_id cap, token_id ephemeral)
{
  switch(ast_id(type))
  {
    case TK_UNIONTYPE:
    case TK_ISECTTYPE:
    case TK_TUPLETYPE:
    {
      ast_t* child = ast_child(type);
      type = ast_from(type, ast_id(type));

      while(child != NULL)
      {
        ast_append(type, set_cap_and_ephemeral(child, cap, ephemeral));
        child = ast_sibling(child);
      }

      return type;
    }

    case TK_NOMINAL:
    {
      type = ast_dup(type);
      AST_GET_CHILDREN(type, package, id, typeargs, tcap, eph);

      if(cap != TK_NONE)
        ast_setid(tcap, cap);

      ast_setid(eph, ephemeral);
      return type;
    }

    case TK_TYPEPARAMREF:
    {
      type = ast_dup(type);
      AST_GET_CHILDREN(type, id, tcap, eph);

      if(cap != TK_NONE)
        ast_setid(tcap, cap);

      ast_setid(eph, ephemeral);
      return type;
    }

    case TK_ARROW:
      // Just use the lhs of the viewpoint type.
      return set_cap_and_ephemeral(ast_childidx(type, 1), cap, ephemeral);

    default: {}
  }

  assert(0);
  return NULL;
}
コード例 #6
0
ファイル: traits.c プロジェクト: abingham/ponyc
// Process the given list of provided methods (all of the same name) for the
// given entity
static bool process_method_name(ast_t* list, ast_t* entity)
{
  assert(list != NULL);
  assert(entity != NULL);

  const char* name = ast_name(list);
  assert(name != NULL);

  ast_t* existing = ast_get(entity, name, NULL);

  if(existing != NULL)
  {
    // Method is explicitly defined in entity
    if(!methods_compatible(list, existing, name, entity))
      return false;
  } else {
    // Method is not defined in entity
    existing = most_general_method(list, entity, name);

    if(existing == NULL)
      return false;

    // Add the most general method from the list to the entity
    existing = ast_dup(existing);
    ast_append(ast_childidx(entity, 4), existing);
    ast_set(entity, name, existing, SYM_NONE);
  }

  // Current body (if any) is not provided by this entity, get one from the
  // trait methods
  if(ast_data(existing) != (void*)entity)
    attach_body_from_list(list, existing);

  return true;
}
コード例 #7
0
ファイル: ast.c プロジェクト: awaidmann/ponyc
ast_t* ast_append(ast_t* parent, ast_t* child)
{
  assert(parent != NULL);
  assert(child != NULL);
  assert(parent != child);

  if(hasparent(child))
    child = ast_dup(child);

  set_scope_and_parent(child, parent);

  if(parent->child == NULL)
  {
    parent->child = child;
    return child;
  }

  ast_t* ast = parent->child;

  while(ast->sibling != NULL)
    ast = ast->sibling;

  ast->sibling = child;
  return child;
}
コード例 #8
0
ファイル: viewpoint.c プロジェクト: jonas-l/ponyc
static ast_t* make_single_arrow(ast_t* left, ast_t* right)
{
  switch(ast_id(left))
  {
    case TK_ARROW:
    {
      ast_t* arrow = ast_dup(left);
      ast_t* child = ast_childidx(arrow, 1);

      // Arrow is right associative.
      while(ast_id(child) == TK_ARROW)
        child = ast_childidx(child, 1);

      ast_t* view = viewpoint_type(child, right);

      if(view == NULL)
      {
        ast_free_unattached(arrow);
        return NULL;
      }

      ast_replace(&child, view);
      return arrow;
    }

    default: {}
  }

  ast_t* arrow = ast_from(left, TK_ARROW);
  ast_add(arrow, right);
  ast_add(arrow, left);
  return arrow;
}
コード例 #9
0
ファイル: viewpoint.c プロジェクト: jonas-l/ponyc
static ast_t* viewpoint_for_type(token_id view, token_id eph, ast_t* type,
  int cap_index)
{
  ast_t* cap = ast_childidx(type, cap_index);
  token_id tcap = ast_id(cap);
  token_id rcap = cap_viewpoint(view, tcap);

  if(rcap == TK_NONE)
    return NULL;

  if((tcap != rcap) || (eph == TK_EPHEMERAL))
  {
    type = ast_dup(type);
    cap = ast_childidx(type, cap_index);
    ast_setid(cap, rcap);

    if(eph == TK_EPHEMERAL && ((view == TK_ISO) || (view == TK_TRN)))
    {
      // If we're adapting from an ephemeral type, make this type ephemeral.
      // iso^->iso = iso^, previous views were iso, alias(iso^) ~ alias(iso)
      // iso^->trn = trn^, previous views were tag, alias(trn^) ~ alias(tag)
      // trn^->iso = iso^, previous views were iso, alias(iso^) ~ alias(iso)
      // trn^->trn = trn^, previous views were trn, alias(trn^) ~ alias(trn)
      // alias(iso)->x isn't alllowed
      // alias(trn)->x = box->x
      // alias(iso^) ~ alias(box->iso)
      // alias(trn^) ~ alias(box->trn)
      // Doesn't work for ref, isn't needed for val, box or tag.
      ast_t* ephemeral = ast_sibling(cap);
      ast_setid(ephemeral, eph);
    }
  }

  return type;
}
コード例 #10
0
ファイル: ast.c プロジェクト: awaidmann/ponyc
void ast_swap(ast_t* prev, ast_t* next)
{
  assert(prev != NULL);
  assert(prev != next);

  ast_t* parent = ast_parent(prev);
  assert(parent != NULL);

  if(hasparent(next))
    next = ast_dup(next);

  set_scope_and_parent(next, parent);

  if(parent->type == prev)
  {
    parent->type = next;
  } else {
    ast_t* last = ast_previous(prev);

    if(last != NULL)
      last->sibling = next;
    else
      parent->child = next;

    next->sibling = prev->sibling;
  }

  prev->sibling = NULL;
  make_orphan_leave_scope(prev);
}
コード例 #11
0
ファイル: reach.c プロジェクト: jersey99/ponyc
static reachable_type_t* add_tuple(reachable_method_stack_t** s,
  reachable_types_t* r, uint32_t* next_type_id, ast_t* type)
{
  if(contains_dontcare(type))
    return NULL;

  reachable_type_t* t = reach_type(r, type);

  if(t != NULL)
    return t;

  t = add_reachable_type(r, type);
  t->type_id = ++(*next_type_id);

  t->field_count = (uint32_t)ast_childcount(t->ast);
  t->fields = (reachable_field_t*)calloc(t->field_count,
    sizeof(reachable_field_t));
  size_t index = 0;

  ast_t* child = ast_child(type);

  while(child != NULL)
  {
    t->fields[index].ast = ast_dup(child);
    t->fields[index].type = add_type(s, r, next_type_id, child);;
    index++;

    child = ast_sibling(child);
  }

  return t;
}
コード例 #12
0
ファイル: reify.c プロジェクト: jonas-l/ponyc
static ast_t* reify_without_defaults(ast_t* ast, ast_t* typeparams,
  ast_t* typeargs, ast_t** lastparam, ast_t** lastarg)
{
  // Duplicate the node.
  ast_t* r_ast = ast_dup(ast);

  // Iterate pairwise through the params and the args.
  ast_t* typeparam = ast_child(typeparams);
  ast_t* typearg = ast_child(typeargs);

  while((typeparam != NULL) && (typearg != NULL))
  {
    // Reify the typeparam with the typearg.
    reify_one(&r_ast, typeparam, typearg);
    typeparam = ast_sibling(typeparam);
    typearg = ast_sibling(typearg);
  }

  if(lastparam != NULL)
    *lastparam = typeparam;

  if(lastarg != NULL)
    *lastarg = typearg;

  return r_ast;
}
コード例 #13
0
ファイル: reify.c プロジェクト: JamesLinus/ponyc
ast_t* reify(ast_t* ast, ast_t* typeparams, ast_t* typeargs, pass_opt_t* opt)
{
  (void)opt;
  assert(
    (ast_id(typeparams) == TK_TYPEPARAMS) ||
    (ast_id(typeparams) == TK_NONE)
    );
  assert(
    (ast_id(typeargs) == TK_TYPEARGS) ||
    (ast_id(typeargs) == TK_NONE)
    );

  // Duplicate the node.
  ast_t* r_ast = ast_dup(ast);

  // Iterate pairwise through the typeparams and typeargs.
  ast_t* typeparam = ast_child(typeparams);
  ast_t* typearg = ast_child(typeargs);

  while((typeparam != NULL) && (typearg != NULL))
  {
    reify_one(&r_ast, typeparam, typearg);
    typeparam = ast_sibling(typeparam);
    typearg = ast_sibling(typearg);
  }

  assert(typeparam == NULL);
  assert(typearg == NULL);
  return r_ast;
}
コード例 #14
0
ファイル: reify.c プロジェクト: Theodus/ponyc
deferred_reification_t* deferred_reify_dup(deferred_reification_t* deferred)
{
  if(deferred == NULL)
    return NULL;

  deferred_reification_t* copy = POOL_ALLOC(deferred_reification_t);

  copy->ast = deferred->ast;
  copy->type_typeparams = ast_dup(deferred->type_typeparams);
  copy->type_typeargs = ast_dup(deferred->type_typeargs);
  copy->method_typeparams = ast_dup(deferred->method_typeparams);
  copy->method_typeargs = ast_dup(deferred->method_typeargs);
  copy->thistype = ast_dup(deferred->thistype);

  return copy;
}
コード例 #15
0
ファイル: reify.c プロジェクト: Theodus/ponyc
deferred_reification_t* deferred_reify_new(ast_t* ast, ast_t* typeparams,
  ast_t* typeargs, ast_t* thistype)
{
  pony_assert(((typeparams != NULL) && (typeargs != NULL)) ||
    ((typeparams == NULL) && (typeargs == NULL)));

  deferred_reification_t* deferred = POOL_ALLOC(deferred_reification_t);

  deferred->ast = ast;
  deferred->type_typeparams = ast_dup(typeparams);
  deferred->type_typeargs = ast_dup(typeargs);
  deferred->thistype = ast_dup(thistype);
  deferred->method_typeparams = NULL;
  deferred->method_typeargs = NULL;

  return deferred;
}
コード例 #16
0
ファイル: sanitise.c プロジェクト: danielaRiesgo/ponyc
ast_t* sanitise_type(ast_t* type)
{
  assert(type != NULL);

  ast_t* new_type = ast_dup(type);
  sanitise(&new_type);
  return new_type;
}
コード例 #17
0
ファイル: viewpoint.c プロジェクト: JamesLinus/ponyc
ast_t* viewpoint_replace(ast_t* ast, ast_t* target, ast_t* with)
{
  // Target is thistype or a typeparamref. With is a type (when replacing
  // `this` in a reified method signature) or a single capability (when
  // typechecking arrow types).
  assert(
    (ast_id(target) == TK_THISTYPE) ||
    (ast_id(target) == TK_TYPEPARAMREF));

  ast_t* r_ast = ast_dup(ast);
  replace_type(&r_ast, target, with);
  return r_ast;
}
コード例 #18
0
ファイル: ast.c プロジェクト: awaidmann/ponyc
ast_t* ast_add(ast_t* parent, ast_t* child)
{
  assert(parent != NULL);
  assert(parent != child);
  assert(parent->child != child);

  if(hasparent(child))
    child = ast_dup(child);

  set_scope_and_parent(child, parent);
  child->sibling = parent->child;
  parent->child = child;
  return child;
}
コード例 #19
0
ファイル: ast.c プロジェクト: awaidmann/ponyc
void ast_replace(ast_t** prev, ast_t* next)
{
  if(*prev == next)
    return;

  if(hasparent(next))
    next = ast_dup(next);

  if(hasparent(*prev))
    ast_swap(*prev, next);

  ast_free(*prev);
  *prev = next;
}
コード例 #20
0
ファイル: viewpoint.c プロジェクト: jonas-l/ponyc
static ast_t* viewpoint_lower_for_type(ast_t* type, int cap_index)
{
  ast_t* cap = ast_childidx(type, cap_index);
  token_id tcap = ast_id(cap);

  // For any chain of arrows, return a capability that is a subtype of the
  // resulting capability.
  // ref->iso = iso, val->iso = val, box->iso = tag => iso
  // ref->trn = trn, val->trn = val, box->trn = box => trn
  // ref->ref = ref, val->ref = val, box->ref = box => trn
  // ref->val = val, val->val = val, box->val = val => val
  // ref->box = box, val->box = val, box->box = box => val
  // ref->tag = tag, val->tag = tag, box->tag = tag => tag
  // #read: ref = trn, val = val, box = val => trn
  // #send: iso = iso, val = val, tag = tag => iso
  // #share: val = val, tag = tag => val
  // #any: iso = iso => iso
  switch(tcap)
  {
    case TK_ISO:
    case TK_TRN:
    case TK_VAL:
    case TK_TAG:
      return type;

    case TK_REF:
    case TK_CAP_READ:
      tcap = TK_TRN;
      break;

    case TK_BOX:
    case TK_CAP_SHARE:
      tcap = TK_VAL;
      break;

    case TK_CAP_SEND:
    case TK_CAP_ANY:
      tcap = TK_ISO;
      break;

    default:
      assert(0);
      return NULL;
  }

  type = ast_dup(type);
  cap = ast_childidx(type, cap_index);
  ast_setid(cap, tcap);
  return type;
}
コード例 #21
0
ファイル: reach.c プロジェクト: Sendence/ponyc
static reach_method_t* add_rmethod(reach_t* r, reach_type_t* t,
  reach_method_name_t* n, token_id cap, ast_t* typeargs, pass_opt_t* opt)
{
  const char* name = genname_fun(cap, n->name, typeargs);
  reach_method_t* m = reach_rmethod(n, name);

  if(m != NULL)
    return m;

  m = POOL_ALLOC(reach_method_t);
  memset(m, 0, sizeof(reach_method_t));
  m->name = name;
  m->cap = cap;
  m->typeargs = ast_dup(typeargs);
  m->vtable_index = (uint32_t)-1;

  ast_t* r_ast = set_cap_and_ephemeral(t->ast, cap, TK_NONE);
  ast_t* fun = lookup(NULL, NULL, r_ast, n->name);
  ast_free_unattached(r_ast);

  if(typeargs != NULL)
  {
    // Reify the method with its typeargs, if it has any.
    AST_GET_CHILDREN(fun, cap, id, typeparams, params, result, can_error,
      body);

    fun = reify(fun, typeparams, typeargs, opt, false);
  }

  m->r_fun = fun;
  set_method_types(r, m, opt);
  m->mangled_name = make_mangled_name(m);
  m->full_name = make_full_name(t, m);

  // Add to both tables.
  reach_methods_put(&n->r_methods, m);
  reach_mangled_put(&n->r_mangled, m);

  // Put on a stack of reachable methods to trace.
  r->stack = reach_method_stack_push(r->stack, m);

  // Add the method to any subtypes.
  add_rmethod_to_subtypes(r, t, n, m, opt);

  return m;
}
コード例 #22
0
ファイル: reify.c プロジェクト: jonas-l/ponyc
static bool reify_one(ast_t** astp, ast_t* typeparam, ast_t* typearg)
{
  ast_t* ast = *astp;
  ast_t* type = ast_type(ast);

  if(type != NULL)
    reify_one(&type, typeparam, typearg);

  if(ast_id(ast) == TK_TYPEPARAMREF)
    return reify_typeparamref(astp, typeparam, typearg);

  ast_t* child = ast_child(ast);
  bool flatten = false;

  while(child != NULL)
  {
    flatten |= reify_one(&child, typeparam, typearg);
    child = ast_sibling(child);
  }

  // Flatten type expressions after reifying them.
  if(flatten)
  {
    switch(ast_id(ast))
    {
      case TK_ARROW:
      {
        AST_GET_CHILDREN(ast, left, right);
        ast = viewpoint_type(left, right);

        if(ast == NULL)
          return false;

        if(ast == right)
          ast = ast_dup(ast);

        ast_replace(astp, ast);
        return true;
      }

      default: {}
    }
  }

  return false;
}
コード例 #23
0
ファイル: ast.c プロジェクト: awaidmann/ponyc
ast_t* ast_add_sibling(ast_t* older_sibling, ast_t* new_sibling)
{
  assert(older_sibling != NULL);
  assert(new_sibling != NULL);
  assert(older_sibling != new_sibling);
  assert(hasparent(older_sibling));

  if(hasparent(new_sibling))
    new_sibling = ast_dup(new_sibling);

  assert(new_sibling->sibling == NULL);

  set_scope_and_parent(new_sibling, older_sibling->parent);
  new_sibling->sibling = older_sibling->sibling;
  older_sibling->sibling = new_sibling;
  return new_sibling;
}
コード例 #24
0
ファイル: reify.c プロジェクト: Theodus/ponyc
ast_t* deferred_reify(deferred_reification_t* deferred, ast_t* ast,
  pass_opt_t* opt)
{
  ast_t* r_ast = ast_dup(ast);

  // Must replace `this` before typeparam reification.
  if(deferred->thistype != NULL)
    r_ast = viewpoint_replacethis(r_ast, deferred->thistype, false);

  if(deferred->type_typeparams != NULL)
    r_ast = reify(r_ast, deferred->type_typeparams, deferred->type_typeargs,
      opt, false);

  if(deferred->method_typeparams != NULL)
    r_ast = reify(r_ast, deferred->method_typeparams, deferred->method_typeargs,
      opt, false);

  return r_ast;
}
コード例 #25
0
ファイル: assemble.c プロジェクト: jonas-l/ponyc
static ast_t* type_typeexpr(token_id t, ast_t* l_type, ast_t* r_type)
{
  bool is_union = t == TK_UNIONTYPE;

  if(l_type == NULL)
    return r_type;

  if(r_type == NULL)
    return l_type;

  if(is_subtype(l_type, r_type))
  {
    if(is_union)
      return r_type;
    else
      return l_type;
  }

  if(is_subtype(r_type, l_type))
  {
    if(is_union)
      return l_type;
    else
      return r_type;
  }

  ast_t* type = ast_from(l_type, t);
  append_to_typeexpr(type, l_type, is_union);
  append_to_typeexpr(type, r_type, is_union);

  // If there's only one element, remove the type expression node.
  ast_t* child = ast_child(type);

  if(ast_sibling(child) == NULL)
  {
    child = ast_dup(child);
    ast_free_unattached(type);
    type = child;
  }

  return type;
}
コード例 #26
0
ファイル: literal.c プロジェクト: abingham/ponyc
// Coerce a literal control block to be the specified target type
static bool coerce_control_block(ast_t** astp, ast_t* target_type,
  lit_chain_t* chain, pass_opt_t* options, bool report_errors)
{
  assert(astp != NULL);
  ast_t* literal_expr = *astp;
  assert(literal_expr != NULL);

  ast_t* lit_type = ast_type(literal_expr);
  assert(lit_type != NULL);
  assert(ast_id(lit_type) == TK_LITERAL);
  ast_t* block_type = ast_type(lit_type);

  for(ast_t* p = ast_child(lit_type); p != NULL; p = ast_sibling(p))
  {
    assert(ast_id(p) == TK_LITERALBRANCH);
    ast_t* branch = (ast_t*)ast_data(p);
    assert(branch != NULL);

    if(!coerce_literal_to_type(&branch, target_type, chain, options,
      report_errors))
    {
      ast_free_unattached(block_type);
      return false;
    }

    block_type = type_union(block_type, ast_type(branch));
  }

  if(is_typecheck_error(block_type))
    return false;

  // block_type may be a sub-tree of the current type of literal_expr.
  // This means we must copy it before setting it as the type since ast_settype
  // will first free the existing type of literal_expr, which may include
  // block_type.
  if(ast_parent(block_type) != NULL)
    block_type = ast_dup(block_type);

  ast_settype(literal_expr, block_type);
  return true;
}
コード例 #27
0
ファイル: viewpoint.c プロジェクト: volth/ponyc
static ast_t* viewpoint_lower_for_typeparam(ast_t* type)
{
  AST_GET_CHILDREN(type, id, cap, eph);
  token_id tcap = ast_id(cap);

  // ref->boxgen = trn, val->boxgen = val, box->boxgen = val => trn
  // ref->taggen = val, val->taggen = val, box->taggen = val => val
  // ref->anygen = iso, val->anygen = val, box->anygen = val => iso
  switch(tcap)
  {
    case TK_ISO:
    case TK_TRN:
    case TK_REF:
    case TK_VAL:
    case TK_TAG:
      return type;

    case TK_BOX_GENERIC:
      tcap = TK_TRN;
      break;

    case TK_TAG_GENERIC:
      tcap = TK_VAL;
      break;

    case TK_ANY_GENERIC:
      tcap = TK_ISO;
      break;

    default:
      assert(0);
      return NULL;
  }

  type = ast_dup(type);
  cap = ast_childidx(type, 1);
  ast_setid(cap, tcap);
  return type;
}
コード例 #28
0
ファイル: viewpoint.c プロジェクト: volth/ponyc
static ast_t* viewpoint_lower_for_nominal(ast_t* type)
{
  ast_t* cap = ast_childidx(type, 3);
  token_id tcap = ast_id(cap);

  // For any chain of arrows, return a capability that is a subtype of the
  // resulting capability.
  // ref->iso = iso, val->iso = val, box->iso = tag => iso
  // ref->trn = trn, val->trn = val, box->trn = box => trn
  // ref->ref = ref, val->ref = val, box->ref = box => trn
  // ref->val = val, val->val = val, box->val = val => val
  // ref->box = box, val->box = val, box->box = box => val
  // ref->tag = tag, val->tag = tag, box->tag = tag => tag
  switch(tcap)
  {
    case TK_ISO:
    case TK_TRN:
    case TK_VAL:
    case TK_TAG:
      return type;

    case TK_REF:
      tcap = TK_TRN;
      break;

    case TK_BOX:
      tcap = TK_VAL;
      break;

    default:
      assert(0);
      return NULL;
  }

  type = ast_dup(type);
  cap = ast_childidx(type, 3);
  ast_setid(cap, tcap);
  return type;
}
コード例 #29
0
ファイル: assemble.c プロジェクト: jonas-l/ponyc
ast_t* type_for_fun(ast_t* ast)
{
  AST_GET_CHILDREN(ast, cap, name, typeparams, params, result);
  token_id fcap = ast_id(cap);

  if(fcap == TK_NONE)
    fcap = TK_TAG;

  // The params may already have types attached. If we build the function type
  // directly from those we'll get nested types which can mess things up. To
  // avoid this make a clean version of the params without types.
  ast_t* clean_params = ast_dup(params);

  for(ast_t* p = ast_child(clean_params); p != NULL; p = ast_sibling(p))
    ast_settype(p, NULL);

  BUILD(fun, ast,
    NODE(TK_FUNTYPE,
      NODE(fcap) TREE(typeparams) TREE(clean_params) TREE(result)));

  return fun;
}
コード例 #30
0
ファイル: reach.c プロジェクト: Sendence/ponyc
static reach_type_t* add_tuple(reach_t* r, ast_t* type, pass_opt_t* opt)
{
  if(contains_dontcare(type))
    return NULL;

  reach_type_t* t = reach_type(r, type);

  if(t != NULL)
    return t;

  t = add_reach_type(r, type);
  t->underlying = TK_TUPLETYPE;
  t->type_id = r->next_type_id++;

  t->field_count = (uint32_t)ast_childcount(t->ast);
  t->fields = (reach_field_t*)calloc(t->field_count,
    sizeof(reach_field_t));

  printbuf_t* mangle = printbuf_new();
  printbuf(mangle, "%d", t->field_count);

  ast_t* child = ast_child(type);
  size_t index = 0;

  while(child != NULL)
  {
    t->fields[index].ast = ast_dup(child);
    t->fields[index].type = add_type(r, child, opt);
    printbuf(mangle, "%s", t->fields[index].type->mangle);
    index++;

    child = ast_sibling(child);
  }

  t->mangle = stringtab(mangle->m);
  printbuf_free(mangle);
  return t;
}