示例#1
0
文件: ifdef.c 项目: Theodus/ponyc
bool ffi_get_decl(typecheck_t* t, ast_t* ast, ast_t** out_decl,
  pass_opt_t* opt)
{
  pony_assert(t != NULL);
  pony_assert(ast != NULL);
  pony_assert(out_decl != NULL);

  const char* ffi_name = ast_name(ast_child(ast));

  // Get the symbol table for our containing ifdef (if any) directly. We can't
  // just search up through scopes as normal since FFI declarations in outer
  // scopes may not be valid within our ifdef.
  ast_t* ifdef = t->frame->ifdef_clause;
  pony_assert(ifdef != NULL);

  symtab_t* symtab = ast_get_symtab(ifdef);
  sym_status_t status;
  ast_t* decl = symtab_find(symtab, ffi_name, &status);

  if(status == SYM_ERROR)
    // We've already found an error with that FFI name in this context.
    return false;

  if(status == SYM_NONE)
  {
    // We've not looked that up yet.
    pony_assert(decl == NULL);
    if(!find_ffi_decl(ast, t->frame->package, t->frame->ifdef_cond, &decl, opt))
    {
      // That went wrong. Record that so we don't try again.
      symtab_add(symtab, ffi_name, NULL, SYM_ERROR);
      return false;
    }

    // Store declaration found for next time, including if we found nothing.
    symtab_add(symtab, ffi_name, decl, SYM_FFIDECL);
  }

  *out_decl = decl;
  return true;
}
示例#2
0
文件: builder.c 项目: Potpourri/ponyc
// Process all our sub-tree references
static bool process_refs(build_parser_t* builder)
{
  assert(builder != NULL);
  assert(builder->defs != NULL);

  for(builder_ref_t* p = builder->refs; p != NULL; p = p->next)
  {
    assert(p->name != NULL);
    assert(p->node != NULL);

    ast_t* subtree = (ast_t*)symtab_find(builder->defs, p->name, NULL);

    if(subtree == NULL)
    {
      build_error(builder, "Attribute {def %s} not found", p->name);
      return false;
    }

    if(p->symtab == NULL)
    {
      // Set node data
      ast_setdata(p->node, subtree);
    }
    else
    {
      // Add subtree to node's symtab
      symtab_t* symtab = ast_get_symtab(p->node);
      assert(symtab != NULL);
      if(!symtab_add(symtab, p->symtab, subtree, SYM_NONE))
      {
        build_error(builder, "Duplicate name %s in symbol table", p->name);
        return false;
      }
    }
  }

  return true;
}
示例#3
0
文件: expr.c 项目: Potpourri/ponyc
ast_result_t pass_expr(ast_t** astp, pass_opt_t* options)
{
  typecheck_t* t = &options->check;
  ast_t* ast = *astp;
  bool r = true;

  switch(ast_id(ast))
  {
    case TK_NOMINAL:    r = expr_nominal(options, astp); break;
    case TK_FVAR:
    case TK_FLET:
    case TK_PARAM:      r = expr_field(options, ast); break;
    case TK_NEW:
    case TK_BE:
    case TK_FUN:        r = expr_fun(options, ast); break;
    case TK_SEQ:        r = expr_seq(ast); break;
    case TK_VAR:
    case TK_LET:        r = expr_local(t, ast); break;
    case TK_BREAK:      r = expr_break(t, ast); break;
    case TK_CONTINUE:   r = expr_continue(t, ast); break;
    case TK_RETURN:     r = expr_return(options, ast); break;
    case TK_IS:
    case TK_ISNT:       r = expr_identity(options, ast); break;
    case TK_ASSIGN:     r = expr_assign(options, ast); break;
    case TK_CONSUME:    r = expr_consume(t, ast); break;
    case TK_RECOVER:    r = expr_recover(ast); break;
    case TK_DOT:        r = expr_dot(options, astp); break;
    case TK_TILDE:      r = expr_tilde(options, astp); break;
    case TK_QUALIFY:    r = expr_qualify(options, astp); break;
    case TK_CALL:       r = expr_call(options, astp); break;
    case TK_IF:         r = expr_if(options, ast); break;
    case TK_WHILE:      r = expr_while(options, ast); break;
    case TK_REPEAT:     r = expr_repeat(options, ast); break;
    case TK_TRY_NO_CHECK:
    case TK_TRY:        r = expr_try(options, ast); break;
    case TK_MATCH:      r = expr_match(options, ast); break;
    case TK_CASES:      r = expr_cases(ast); break;
    case TK_CASE:       r = expr_case(options, ast); break;
    case TK_TUPLE:      r = expr_tuple(ast); break;
    case TK_ARRAY:      r = expr_array(options, astp); break;
    case TK_REFERENCE:  r = expr_reference(options, astp); break;
    case TK_THIS:       r = expr_this(options, ast); break;
    case TK_TRUE:
    case TK_FALSE:      r = expr_literal(options, ast, "Bool"); break;
    case TK_ERROR:      r = expr_error(ast); break;
    case TK_COMPILER_INTRINSIC:
                        r = expr_compiler_intrinsic(t, ast); break;
    case TK_POSITIONALARGS:
    case TK_NAMEDARGS:
    case TK_NAMEDARG:
    case TK_UPDATEARG:  ast_inheritflags(ast); break;
    case TK_AMP:        r = expr_addressof(options, ast); break;
    case TK_DONTCARE:   r = expr_dontcare(ast); break;

    case TK_INT:
      // Integer literals can be integers or floats
      make_literal_type(ast);
      break;

    case TK_FLOAT:
      make_literal_type(ast);
      break;

    case TK_STRING:
      if(ast_id(ast_parent(ast)) == TK_PACKAGE)
        return AST_OK;

      r = expr_literal(options, ast, "String");
      break;

    case TK_FFICALL:
      return expr_ffi(options, ast);

    default: {}
  }

  if(!r)
  {
    assert(get_error_count() > 0);
    return AST_ERROR;
  }

  // Can't use ast here, it might have changed
  symtab_t* symtab = ast_get_symtab(*astp);

  if(symtab != NULL && !symtab_check_all_defined(symtab))
    return AST_ERROR;

  return AST_OK;
}