コード例 #1
0
ファイル: reach.c プロジェクト: DevL/ponyc
void reach(reachable_types_t* r, uint32_t* next_type_id, ast_t* type,
  const char* name, ast_t* typeargs)
{
  reachable_method_stack_t* s = NULL;
  reachable_method(&s, r, next_type_id, type, name, typeargs);
  handle_stack(s, r, next_type_id);
}
コード例 #2
0
ファイル: reach.c プロジェクト: DevL/ponyc
static void reachable_fun(reachable_method_stack_t** s, reachable_types_t* r,
  uint32_t* next_type_id, ast_t* ast)
{
  AST_GET_CHILDREN(ast, receiver, method);
  ast_t* typeargs = NULL;

  // Dig through function qualification.
  switch(ast_id(receiver))
  {
    case TK_NEWREF:
    case TK_NEWBEREF:
    case TK_BEREF:
    case TK_FUNREF:
      typeargs = method;
      AST_GET_CHILDREN_NO_DECL(receiver, receiver, method);
      break;

    default: {}
  }

  ast_t* type = ast_type(receiver);
  const char* method_name = ast_name(method);

  reachable_method(s, r, next_type_id, type, method_name, typeargs);
}
コード例 #3
0
ファイル: reach.c プロジェクト: DevL/ponyc
static void reachable_method(reachable_method_stack_t** s,
  reachable_types_t* r, uint32_t* next_type_id, ast_t* type,
  const char* name, ast_t* typeargs)
{
  switch(ast_id(type))
  {
    case TK_NOMINAL:
    {
      reachable_type_t* t = add_type(s, r, next_type_id, type);
      add_method(s, t, name, typeargs);
      break;
    }

    case TK_UNIONTYPE:
    case TK_ISECTTYPE:
    {
      ast_t* child = ast_child(type);

      while(child != NULL)
      {
        ast_t* find = lookup_try(NULL, NULL, child, name);

        if(find != NULL)
          reachable_method(s, r, next_type_id, child, name, typeargs);

        child = ast_sibling(child);
      }

      break;
    }

    default:
      assert(0);
  }
}
コード例 #4
0
ファイル: reach.c プロジェクト: lukecheeseman/ponyc
static void reachable_pattern(reachable_method_stack_t** s,
  reachable_types_t* r, uint32_t* next_type_id, ast_t* ast)
{
  switch(ast_id(ast))
  {
    case TK_DONTCARE:
    case TK_NONE:
      break;

    case TK_VAR:
    case TK_LET:
    {
      AST_GET_CHILDREN(ast, idseq, type);
      add_type(s, r, next_type_id, type);
      break;
    }

    case TK_TUPLE:
    case TK_SEQ:
    {
      ast_t* child = ast_child(ast);

      while(child != NULL)
      {
        reachable_pattern(s, r, next_type_id, child);
        child = ast_sibling(child);
      }
      break;
    }

    default:
    {
      reachable_method(s, r, next_type_id, ast_type(ast), stringtab("eq"),
        NULL);
      reachable_expr(s, r, next_type_id, ast);
      break;
    }
  }
}
コード例 #5
0
ファイル: reach.c プロジェクト: Sendence/ponyc
static void add_special(reach_t* r, reach_type_t* t, ast_t* type,
  const char* special, pass_opt_t* opt)
{
  special = stringtab(special);
  ast_t* find = lookup_try(NULL, NULL, type, special);

  if(find != NULL)
  {
    switch(ast_id(find))
    {
      case TK_NEW:
      case TK_FUN:
      case TK_BE:
      {
        reachable_method(r, t->ast, special, NULL, opt);
        ast_free_unattached(find);
        break;
      }

      default: {}
    }
  }
}
コード例 #6
0
ファイル: reach.c プロジェクト: Sendence/ponyc
static void reachable_fun(reach_t* r, ast_t* ast, pass_opt_t* opt)
{
  AST_GET_CHILDREN(ast, receiver, method);
  ast_t* typeargs = NULL;

  // Dig through function qualification.
  switch(ast_id(receiver))
  {
    case TK_NEWREF:
    case TK_NEWBEREF:
    case TK_BEREF:
    case TK_FUNREF:
      typeargs = method;
      AST_GET_CHILDREN_NO_DECL(receiver, receiver, method);
      break;

    default: {}
  }

  ast_t* type = ast_type(receiver);
  const char* method_name = ast_name(method);

  reachable_method(r, type, method_name, typeargs, opt);
}
コード例 #7
0
ファイル: reach.c プロジェクト: Sendence/ponyc
static void reachable_pattern(reach_t* r, ast_t* ast, pass_opt_t* opt)
{
  switch(ast_id(ast))
  {
    case TK_DONTCARE:
    case TK_NONE:
      break;

    case TK_MATCH_CAPTURE:
    {
      AST_GET_CHILDREN(ast, idseq, type);
      add_type(r, type, opt);
      break;
    }

    case TK_TUPLE:
    case TK_SEQ:
    {
      ast_t* child = ast_child(ast);

      while(child != NULL)
      {
        reachable_pattern(r, child, opt);
        child = ast_sibling(child);
      }
      break;
    }

    default:
    {
      reachable_method(r, ast_type(ast), stringtab("eq"), NULL, opt);
      reachable_expr(r, ast, opt);
      break;
    }
  }
}
コード例 #8
0
ファイル: reach.c プロジェクト: DevL/ponyc
static void reachable_expr(reachable_method_stack_t** s, reachable_types_t* r,
  uint32_t* next_type_id, ast_t* ast)
{
  // If this is a method call, mark the method as reachable.
  switch(ast_id(ast))
  {
    case TK_TRUE:
    case TK_FALSE:
    case TK_INT:
    case TK_FLOAT:
    case TK_STRING:
    {
      ast_t* type = ast_type(ast);

      if(type != NULL)
        reachable_method(s, r, next_type_id, type, stringtab("create"), NULL);
      break;
    }

    case TK_TUPLE:
    {
      ast_t* type = ast_type(ast);
      add_type(s, r, next_type_id, type);
      break;
    }

    case TK_CASE:
    {
      AST_GET_CHILDREN(ast, pattern, guard, body);
      reachable_pattern(s, r, next_type_id, pattern);
      reachable_expr(s, r, next_type_id, guard);
      reachable_expr(s, r, next_type_id, body);
      break;
    }

    case TK_CALL:
      reachable_call(s, r, next_type_id, ast);
      break;

    case TK_FFICALL:
      reachable_ffi(s, r, next_type_id, ast);
      break;

    case TK_ADDRESS:
      reachable_addressof(s, r, next_type_id, ast);
      break;

    case TK_IF:
    {
      AST_GET_CHILDREN(ast, cond, then_clause, else_clause);
      assert(ast_id(cond) == TK_SEQ);
      cond = ast_child(cond);

      if(ast_sibling(cond) == NULL)
      {
        if(ast_id(cond) == TK_TRUE)
        {
          reachable_expr(s, r, next_type_id, then_clause);
          return;
        } else if(ast_id(cond) == TK_FALSE) {
          reachable_expr(s, r, next_type_id, else_clause);
          return;
        }
      }
      break;
    }

    default: {}
  }

  // Traverse all child expressions looking for calls.
  ast_t* child = ast_child(ast);

  while(child != NULL)
  {
    reachable_expr(s, r, next_type_id, child);
    child = ast_sibling(child);
  }
}
コード例 #9
0
ファイル: reach.c プロジェクト: Sendence/ponyc
static void reachable_expr(reach_t* r, ast_t* ast, pass_opt_t* opt)
{
  // If this is a method call, mark the method as reachable.
  switch(ast_id(ast))
  {
    case TK_TRUE:
    case TK_FALSE:
    case TK_INT:
    case TK_FLOAT:
    case TK_STRING:
    {
      ast_t* type = ast_type(ast);

      if(type != NULL)
        reachable_method(r, type, stringtab("create"), NULL, opt);
      break;
    }

    case TK_LET:
    case TK_VAR:
    case TK_TUPLE:
    {
      ast_t* type = ast_type(ast);
      add_type(r, type, opt);
      break;
    }

    case TK_CASE:
    {
      AST_GET_CHILDREN(ast, pattern, guard, body);
      reachable_pattern(r, pattern, opt);
      reachable_expr(r, guard, opt);
      reachable_expr(r, body, opt);
      break;
    }

    case TK_CALL:
      reachable_call(r, ast, opt);
      break;

    case TK_FFICALL:
      reachable_ffi(r, ast, opt);
      break;

    case TK_ADDRESS:
      reachable_addressof(r, ast, opt);
      break;

    case TK_IF:
    {
      AST_GET_CHILDREN(ast, cond, then_clause, else_clause);
      assert(ast_id(cond) == TK_SEQ);
      cond = ast_child(cond);

      ast_t* type = ast_type(ast);

      if(is_result_needed(ast) && !is_control_type(type))
        add_type(r, type, opt);

      if(ast_sibling(cond) == NULL)
      {
        if(ast_id(cond) == TK_TRUE)
        {
          reachable_expr(r, then_clause, opt);
          return;
        } else if(ast_id(cond) == TK_FALSE) {
          reachable_expr(r, else_clause, opt);
          return;
        }
      }
      break;
    }

    case TK_MATCH:
    case TK_WHILE:
    case TK_REPEAT:
    case TK_TRY:
    {
      ast_t* type = ast_type(ast);

      if(is_result_needed(ast) && !is_control_type(type))
        add_type(r, type, opt);

      break;
    }

    default: {}
  }

  // Traverse all child expressions looking for calls.
  ast_t* child = ast_child(ast);

  while(child != NULL)
  {
    reachable_expr(r, child, opt);
    child = ast_sibling(child);
  }
}
コード例 #10
0
ファイル: reach.c プロジェクト: Sendence/ponyc
void reach(reach_t* r, ast_t* type, const char* name, ast_t* typeargs,
  pass_opt_t* opt)
{
  reachable_method(r, type, name, typeargs, opt);
  handle_stack(r, opt);
}