コード例 #1
0
ファイル: sugar.c プロジェクト: shepheb/ponyc
static ast_result_t sugar_semi(pass_opt_t* options, ast_t** astp)
{
  ast_t* ast = *astp;
  assert(ast_id(ast) == TK_SEMI);

  // Semis are pointless, discard them
  assert(ast_child(ast) == NULL);
  *astp = ast_sibling(ast);
  ast_remove(ast);

  // Since we've effectively replaced ast with its successor we need to process
  // that too
  return pass_sugar(astp, options);
}
コード例 #2
0
ファイル: control.c プロジェクト: jersey99/ponyc
// Determine which branch of the given ifdef to use and convert the ifdef into
// an if.
static bool resolve_ifdef(pass_opt_t* opt, ast_t* ast)
{
  assert(ast != NULL);

  // We turn the ifdef node into an if so that codegen doesn't need to know
  // about ifdefs at all.
  // We need to determine which branch to take. Note that since normalisation
  // adds the conditions of outer ifdefs (if any) it may be that BOTH our then
  // and else conditions fail. In this case we can pick either one, since an
  // outer ifdef will throw away the whole branch this ifdef is in anyway.
  AST_GET_CHILDREN(ast, cond, then_clause, else_clause, else_cond);
  bool then_value = ifdef_cond_eval(cond, opt);

  ast_setid(ast, TK_IF);
  REPLACE(&cond, NODE(TK_SEQ, NODE(then_value ? TK_TRUE : TK_FALSE)));
  // Don't need to set condition type since we've finished type checking it.

  // Don't need else condition any more.
  ast_remove(else_cond);
  return true;
}
コード例 #3
0
ファイル: assemble.c プロジェクト: jonas-l/ponyc
static void append_one_to_isect(ast_t* ast, ast_t* append)
{
  ast_t* child = ast_child(ast);

  while(child != NULL)
  {
    ast_t* next = ast_sibling(child);

    if(is_subtype(child, append))
    {
      // If the incoming type is a supertype of a type that is already in the
      // intersection, then do not bother to append it.
      return;
    } else if(is_subtype(append, child)) {
      // If a type in the intersection is a supertype of the incoming type,
      // then remove it from the intersection.
      ast_remove(child);
    }

    child = next;
  }

  ast_append(ast, append);
}
コード例 #4
0
ファイル: sugar.c プロジェクト: shepheb/ponyc
static ast_result_t sugar_module(ast_t* ast)
{
  ast_t* docstring = ast_child(ast);

  ast_t* package = ast_parent(ast);
  assert(ast_id(package) == TK_PACKAGE);

  if(strcmp(package_name(package), "$0") != 0)
  {
    // Every module not in builtin has an implicit use builtin command.
    // Since builtin is always the first package processed it is $0.
    BUILD(builtin, ast,
      NODE(TK_USE,
      NONE
      STRING(stringtab("builtin"))
      NONE));

    ast_add(ast, builtin);
  }

  if((docstring == NULL) || (ast_id(docstring) != TK_STRING))
    return AST_OK;

  ast_t* package_docstring = ast_childlast(package);

  if(ast_id(package_docstring) == TK_STRING)
  {
    ast_error(docstring, "the package already has a docstring");
    ast_error(package_docstring, "the existing docstring is here");
    return AST_ERROR;
  }

  ast_append(package, docstring);
  ast_remove(docstring);
  return AST_OK;
}
コード例 #5
0
ファイル: ifdef.c プロジェクト: Theodus/ponyc
// Normalise the given ifdef condition.
static void cond_normalise(ast_t** astp)
{
  pony_assert(astp != NULL);

  ast_t* ast = *astp;
  pony_assert(ast != NULL);

  switch(ast_id(ast))
  {
    case TK_AND:
    {
      ast_setid(ast, TK_IFDEFAND);

      AST_GET_CHILDREN(ast, left, right, question);
      pony_assert(ast_id(question) == TK_NONE);
      ast_remove(question);
      cond_normalise(&left);
      cond_normalise(&right);
      break;
    }

    case TK_OR:
    {
      ast_setid(ast, TK_IFDEFOR);

      AST_GET_CHILDREN(ast, left, right, question);
      pony_assert(ast_id(question) == TK_NONE);
      ast_remove(question);
      cond_normalise(&left);
      cond_normalise(&right);
      break;
    }

    case TK_NOT:
    {
      ast_setid(ast, TK_IFDEFNOT);

      AST_GET_CHILDREN(ast, child);
      cond_normalise(&child);
      break;
    }

    case TK_STRING:
    {
      ast_setid(ast, TK_ID);

      REPLACE(astp,
        NODE(TK_IFDEFFLAG,
          TREE(*astp)));

      break;
    }

    case TK_REFERENCE:
    {
      const char* name = ast_name(ast_child(ast));
      if(strcmp(name, OS_POSIX_NAME) == 0)
      {
        REPLACE(astp,
          NODE(TK_IFDEFOR,
            NODE(TK_IFDEFOR,
              NODE(TK_IFDEFFLAG, ID(OS_LINUX_NAME))
              NODE(TK_IFDEFFLAG, ID(OS_MACOSX_NAME)))
            NODE(TK_IFDEFFLAG, ID(OS_BSD_NAME))));
        break;
      }

      ast_setid(ast, TK_IFDEFFLAG);
      break;
    }

    case TK_SEQ:
    {
      // Remove the sequence node.
      pony_assert(ast_childcount(ast) == 1);
      ast_t* child = ast_pop(ast);
      pony_assert(child != NULL);

      cond_normalise(&child);
      ast_replace(astp, child);
      break;
    }

    case TK_IFDEFAND:
    case TK_IFDEFOR:
    case TK_IFDEFNOT:
    case TK_IFDEFFLAG:
      // Already normalised.
      break;

    default:
      pony_assert(0);
      break;
  }
}