blob: 09c84a30c01291b8e3ed42814b4637bc3bce02f3 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
|
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include "common.h"
#include "symbol-table.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static int hash(const char *str)
{
int idx = 0;
for (; *str; str++) {
idx = idx << 1;
idx += *str;
}
return (idx & (CCMMC_SYMBOL_SCOPE_HASH_TABLE_SIZE - 1));
}
void ccmmc_symbol_table_init(CcmmcSymbolTable *table)
{
table->all = NULL;
table->all_last = NULL;
table->this_scope = NULL;
table->current = NULL;
}
// push a scope on the stack
void ccmmc_symbol_table_open_scope(CcmmcSymbolTable *table)
{
CcmmcSymbolScope *scope = malloc(sizeof(CcmmcSymbolScope));
ERR_FATAL_CHECK(scope, malloc);
for (int i = 0; i < CCMMC_SYMBOL_SCOPE_HASH_TABLE_SIZE; i++)
scope->hash_table[i] = NULL;
if (table->all == NULL) {
table->all = scope;
table->all_last = scope;
} else {
table->all_last->all_next = scope;
table->all_last = scope;
}
scope->all_next = NULL;
scope->current_next = table->current;
table->current = scope;
}
// used by code-generation phase
void ccmmc_symbol_table_reopen_scope(CcmmcSymbolTable *table)
{
if (table->this_scope == NULL)
table->this_scope = table->all;
else
table->this_scope = table->this_scope->all_next;
table->current = table->this_scope;
}
// pop a scope from the stack
void ccmmc_symbol_table_close_scope(CcmmcSymbolTable *table)
{
CcmmcSymbolScope *closing = table->current;
table->current = closing->current_next;
}
void ccmmc_symbol_table_insert(CcmmcSymbolTable *table,
const char *name, CcmmcSymbolKind kind, CcmmcSymbolType type)
{
int key = hash(name);
CcmmcSymbol *symbol = malloc(sizeof(CcmmcSymbol));
ERR_FATAL_CHECK(symbol, malloc);
symbol->kind = kind;
symbol->type = type;
symbol->attr.addr = 0;
symbol->name = name;
symbol->next = table->current->hash_table[key];
table->current->hash_table[key] = symbol;
}
CcmmcSymbol *ccmmc_symbol_table_retrieve (
CcmmcSymbolTable *table, const char *name)
{
if (name == NULL)
return NULL;
int key = hash(name);
for (CcmmcSymbolScope *scope = table->current; scope; scope = scope->current_next) {
for (CcmmcSymbol *symbol = scope->hash_table[key]; symbol; symbol = symbol->next) {
if (strcmp(name, symbol->name) == 0)
return symbol;
}
}
return NULL;
}
bool ccmmc_symbol_scope_exist(CcmmcSymbolScope *scope, const char *name)
{
int key = hash(name);
for (CcmmcSymbol *symbol = scope->hash_table[key];
symbol != NULL; symbol = symbol->next) {
if (strcmp(name, symbol->name) == 0)
return true;
}
return false;
}
// vim: set sw=4 ts=4 sts=4 et:
|