Esempio n. 1
0
// Process the provides list for the given entity.
// Stage 1.
static bool provides_list(ast_t* entity, pass_opt_t* options)
{
  assert(entity != NULL);

  ast_t* provides = ast_childidx(entity, 3);
  assert(provides != NULL);

  bool r = true;

  for(ast_t* p = ast_child(provides); p != NULL; p = ast_sibling(p))
  {
    if(ast_id(p) != TK_NOMINAL)
    {
      ast_error(p, "provides list may only contain traits and interfaces");
      return false;
    }

    // Check type is a trait or interface
    ast_t* def = (ast_t*)ast_data(p);
    assert(def != NULL);

    if(ast_id(def) != TK_TRAIT && ast_id(def) != TK_INTERFACE)
    {
      ast_error(p, "can only provide traits and interfaces");
      return false;
    }

    // Now process provided type
    if(!trait_entity(def, options))
      r = false;
  }

  return r;
}
Esempio n. 2
0
ast_result_t pass_traits(ast_t** astp, pass_opt_t* options)
{
  ast_t* ast = *astp;

  switch(ast_id(ast))
  {
    case TK_PRIMITIVE:
    case TK_CLASS:
    case TK_ACTOR:
    case TK_INTERFACE:
    case TK_TRAIT:
      if(!trait_entity(ast, options))
        return AST_ERROR;

      break;

    case TK_LET:
    case TK_VAR:
      local_types(ast);
      break;

    default:
      break;
  }

  return AST_OK;
}
Esempio n. 3
0
// Process the methods provided to the given entity from all traits in its
// provides list.
static bool provided_methods(ast_t* entity, pass_opt_t* opt)
{
  assert(entity != NULL);

  ast_t* provides = ast_childidx(entity, 3);
  bool r = true;

  // Run through our provides list
  for(ast_t* trait_ref = ast_child(provides); trait_ref != NULL;
    trait_ref = ast_sibling(trait_ref))
  {
    ast_t* trait = (ast_t*)ast_data(trait_ref);
    assert(trait != NULL);

    if(!trait_entity(trait, opt))
      return false;

    ast_t* members = ast_childidx(trait, 4);

    // Run through the methods of each provided type.
    for(ast_t* method = ast_child(members); method != NULL;
      method = ast_sibling(method))
    {
      assert(is_method(method));

      ast_t* reified = reify_provides_type(method, trait_ref, opt);

      if(reified == NULL)
      {
        // Reification error, already reported.
        r = false;
      }
      else
      {
        if(!add_method_from_trait(entity, reified, trait_ref, opt))
          r = false;

        ast_free_unattached(reified);
      }
    }
  }

  return r;
}
Esempio n. 4
0
// Process the methods required for delegation to all the fields in the given
// entity.
static bool delegated_methods(ast_t* entity, pass_opt_t* opt)
{
  assert(entity != NULL);

  bool r = true;

  // Check all fields.
  for(ast_t* field = ast_child(ast_childidx(entity, 4)); field != NULL;
    field = ast_sibling(field))
  {
    if(is_field(field))
    {
      AST_GET_CHILDREN(field, id, f_type, value, delegates);

      // Check all delegates for field.
      for(ast_t* trait_ref = ast_child(delegates); trait_ref != NULL;
        trait_ref = ast_sibling(trait_ref))
      {
        ast_t* trait = (ast_t*)ast_data(trait_ref);
        assert(trait != NULL);

        if(!trait_entity(trait, opt))
          return false;

        // Run through the methods of each delegated type.
        for(ast_t* method = ast_child(ast_childidx(trait, 4));
          method != NULL; method = ast_sibling(method))
        {
          if(!delegated_method(entity, method, field, trait_ref, opt))
            r = false;
        }
      }
    }
  }

  return r;
}