Exemple #1
0
static void reify_one(ast_t** astp, ast_t* typeparam, ast_t* typearg)
{
  ast_t* ast = *astp;
  ast_t* child = ast_child(ast);

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

  ast_t* type = ast_type(ast);

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

  switch(ast_id(ast))
  {
    case TK_TYPEPARAMREF:
      reify_typeparamref(astp, typeparam, typearg);
      break;

    case TK_ARROW:
      reify_arrow(astp);
      break;

    default: {}
  }
}
Exemple #2
0
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;
}
Exemple #3
0
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;
}
Exemple #4
0
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;
}
Exemple #5
0
ast_t* reify(ast_t* orig, ast_t* ast, ast_t* typeparams, ast_t* typeargs)
{
  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* typeparam;
  ast_t* typearg;
  ast_t* r_ast = reify_without_defaults(ast, typeparams, typeargs, &typeparam,
    &typearg);

  if(typearg != NULL)
  {
    ast_error(orig, "too many type arguments");
    ast_error(typeparams, "definition is here");
    ast_free(r_ast);
    return NULL;
  }

  // Pick up default type arguments if they exist.
  while(typeparam != NULL)
  {
    typearg = ast_childidx(typeparam, 2);

    if(ast_id(typearg) == TK_NONE)
      break;

    // Reify the default typearg with the typeargs we have so far.
    ast_t* r_typearg = reify_without_defaults(typearg, typeparams, typeargs,
      NULL, NULL);

    ast_append(typeargs, r_typearg);
    reify_one(&r_ast, typeparam, r_typearg);
    typeparam = ast_sibling(typeparam);
  }

  if(typeparam != NULL)
  {
    ast_error(orig, "not enough type arguments");
    ast_error(typeparams, "definition is here");
    ast_free(r_ast);
    return NULL;
  }

  return r_ast;
}