Exemplo n.º 1
0
ast_t* symtab_find_case(symtab_t* symtab, const char* name,
  sym_status_t* status)
{
  // Same as symtab_get, but is partially case insensitive. That is, type names
  // are compared as uppercase and other symbols are compared as lowercase.
  symbol_t s1 = {name, NULL, SYM_NONE, 0};
  symbol_t* s2 = symtab_get(symtab, &s1);

  if(s2 != NULL)
  {
    if(status != NULL)
      *status = s2->status;

    return s2->def;
  }

  const char* no_case = name_without_case(name);

  if(no_case != name)
    return symtab_find_case(symtab, no_case, status);

  if(status != NULL)
    *status = SYM_NONE;

  return NULL;
}
Exemplo n.º 2
0
ast_t* ast_get_case(ast_t* ast, const char* name, sym_status_t* status)
{
  // Same as ast_get, but is partially case insensitive. That is, type names
  // are compared as uppercase and other symbols are compared as lowercase.
  if(status != NULL)
    *status = SYM_NONE;

  do
  {
    if(ast->symtab != NULL)
    {
      sym_status_t status2;
      ast_t* value = (ast_t*)symtab_find_case(ast->symtab, name, &status2);

      if((status != NULL) && (*status == SYM_NONE))
        *status = status2;

      if(value != NULL)
        return value;
    }

    ast = ast->parent;
  } while((ast != NULL) && (token_get_id(ast->t) != TK_PROGRAM));

  return NULL;
}
Exemplo n.º 3
0
bool symtab_can_merge_public(symtab_t* dst, symtab_t* src)
{
  size_t i = HASHMAP_BEGIN;
  symbol_t* sym;

  while((sym = symtab_next(src, &i)) != NULL)
  {
    if(is_name_private(sym->name) ||
      (sym->status == SYM_NOCASE) ||
      !strcmp(sym->name, "Main"))
      continue;

    if(symtab_find_case(dst, sym->name, NULL) != NULL)
      return false;
  }

  return true;
}
Exemplo n.º 4
0
// Add the given method to the relevant name list in the given symbol table
static bool add_method_to_list(ast_t* method, methods_t* method_info,
  const char *entity_name)
{
  assert(method != NULL);
  assert(method_info != NULL);
  assert(entity_name != NULL);

  const char* name = ast_name(ast_childidx(method, 1));
  assert(name != NULL);

  symtab_t* symtab = method_info->symtab;
  assert(symtab != NULL);

  // Entity doesn't yet have method, add it to our list for later
  ast_t* list = (ast_t*)symtab_find(symtab, name, NULL);

  if(list == NULL)
  {
    ast_t* case_clash = (ast_t*)symtab_find_case(symtab, name, NULL);

    if(case_clash != NULL)
    {
      ast_error(case_clash, "in %s method name differs only in case",
        entity_name);
      ast_error(method, "previous definition is here");
      return false;
    }

    // First instance of this name
    list = ast_blank(TK_ID);
    ast_set_name(list, name);
    symtab_add(symtab, name, (void*)list, SYM_NONE);

    if(method_info->last_list == NULL)
      ast_add(method_info->name_lists, list);
    else
      ast_add_sibling(method_info->last_list, list);

    method_info->last_list = list;
  }

  ast_add(list, method);
  return true;
}
Exemplo n.º 5
0
bool ast_set(ast_t* ast, const char* name, ast_t* value, sym_status_t status,
  bool allow_shadowing)
{
  while(ast->symtab == NULL)
    ast = ast->parent;

  if(allow_shadowing)
  {
    // Only check the local scope.
    if(symtab_find_case(ast->symtab, name, NULL) != NULL)
      return false;
  } else {
    // Check the local scope and all parent scopes.
    if(ast_get_case(ast, name, NULL) != NULL)
      return false;
  }

  return symtab_add(ast->symtab, name, value, status);
}