⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 scope.c

📁 一个编译器修改的例子
💻 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 + -