Ejemplo n.º 1
0
static void handle_stack(reachable_method_stack_t* s, reachable_types_t* r,
  uint32_t* next_type_id)
{
  while(s != NULL)
  {
    reachable_method_t* m;
    s = reachable_method_stack_pop(s, &m);

    AST_GET_CHILDREN(m->r_fun, cap, id, typeparams, params, result, can_error,
      body);

    m->param_count = ast_childcount(params);
    m->params = (reachable_type_t**)ponyint_pool_alloc_size(
      m->param_count * sizeof(reachable_type_t*));

    ast_t* param = ast_child(params);
    size_t i = 0;

    while(param != NULL)
    {
      AST_GET_CHILDREN(param, p_id, p_type);
      m->params[i++] = add_type(&s, r, next_type_id, p_type);
      param = ast_sibling(param);
    }

    m->result = add_type(&s, r, next_type_id, result);
    reachable_expr(&s, r, next_type_id, body);
  }
}
Ejemplo n.º 2
0
static void handle_stack(reach_t* r, pass_opt_t* opt)
{
  while(r->stack != NULL)
  {
    reach_method_t* m;
    r->stack = reach_method_stack_pop(r->stack, &m);

    ast_t* body = ast_childidx(m->r_fun, 6);
    reachable_expr(r, body, opt);
  }
}
Ejemplo n.º 3
0
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;
    }
  }
}
Ejemplo n.º 4
0
Archivo: reach.c Proyecto: DevL/ponyc
static void handle_stack(reachable_method_stack_t* s, reachable_types_t* r,
  uint32_t* next_type_id)
{
  while(s != NULL)
  {
    reachable_method_t* m;
    s = reachable_method_stack_pop(s, &m);

    AST_GET_CHILDREN(m->r_fun, cap, id, typeparams, params, result, can_error,
      body);

    ast_t* param = ast_child(params);

    while(param != NULL)
    {
      AST_GET_CHILDREN(param, p_id, p_type);
      add_type(&s, r, next_type_id, p_type);
      param = ast_sibling(param);
    }

    add_type(&s, r, next_type_id, result);
    reachable_expr(&s, r, next_type_id, body);
  }
}
Ejemplo n.º 5
0
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;
    }
  }
}
Ejemplo n.º 6
0
Archivo: reach.c Proyecto: 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);
  }
}
Ejemplo n.º 7
0
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);
  }
}