📄 scope.c
字号:
#include "error.h"
#include "scope.h"
#include "salloc.h"
#include <string.h>
typedef struct tuple
{
char *key;
Declaration *decl;
struct tuple *next;
}
Tuple;
#define HASH_ENTRIES 32
struct scope
{
Scope *parent_scope;
Tuple *hash_table [HASH_ENTRIES];
};
static unsigned hash_index(const char *string)
{
unsigned index = 0;
if (string == NULL) /* Koen: idiot proof */
return 0;
while (*string != '\0')
index += *string++; /* Koen: using |= will often lead to the same index */
return index % HASH_ENTRIES;
}
static Declaration *search(const Scope *scope, const char *key, unsigned index)
{
Tuple *tuple;
for (tuple = scope->hash_table [index]; tuple != 0; tuple = tuple->next)
if (strcmp(tuple->key, key) == 0)
return tuple->decl;
return 0;
}
static void add_tuple(Scope *scope, const char *key, Declaration *decl,
unsigned index)
{
Tuple *tuple = safe_malloc(sizeof(Tuple));
tuple->key = safe_strdup(key);
tuple->decl = decl;
tuple->next = scope->hash_table [index];
scope->hash_table [index] = tuple;
}
static void delete_tuple(Tuple *tuple)
{
free(tuple->key);
free(tuple);
}
Scope *current_scope = 0, *global_scope;
Scope *new_scope(void)
{
Scope *scope = safe_malloc(sizeof(Scope));
unsigned i;
scope->parent_scope = current_scope;
current_scope = scope;
for (i = 0; i < HASH_ENTRIES; i ++)
scope->hash_table [i] = 0;
return scope;
}
void leave_scope(void)
{
current_scope = current_scope->parent_scope;
}
void delete_scope(Scope *scope)
{
if (scope != 0)
{
unsigned i;
Tuple *tuple, *next_tuple;
for (i = 0; i < HASH_ENTRIES; i ++)
for (tuple = scope->hash_table [i]; tuple != 0; tuple = next_tuple)
{
next_tuple = tuple->next;
delete_tuple(tuple);
}
free(scope);
}
}
void declare(const char *key, Declaration *decl)
{
unsigned index = hash_index(key);
if (search(current_scope, key, index) != 0)
error(0, "%s already declared in this scope", key);
else
add_tuple(current_scope, key, decl, index);
}
Declaration *lookup(const Scope *scope, const char *key)
{
unsigned index = hash_index(key);
Declaration *decl;
do
if ((decl = search(scope, key, index)) != 0)
return decl;
while ((scope = scope->parent_scope) != 0);
return 0;
}
Declaration *lookup_in_this_scope(const Scope *scope, const char *key)
{
return search(scope, key, hash_index(key));
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -