Skip to content

Commit f276023

Browse files
committed
feat(parser): add symbolic table for syntatic parsing
1 parent 4cf647b commit f276023

File tree

2 files changed

+287
-0
lines changed

2 files changed

+287
-0
lines changed

src/symbol_table.c

Lines changed: 235 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,235 @@
1+
#include "symbol_table.h"
2+
3+
#include <stdio.h>
4+
#include <stdlib.h>
5+
#include <string.h>
6+
7+
static char *dup_string(const char *src)
8+
{
9+
if (!src)
10+
{
11+
return NULL;
12+
}
13+
size_t len = strlen(src) + 1;
14+
char *copy = malloc(len);
15+
if (!copy)
16+
{
17+
fprintf(stderr, "out of memory\n");
18+
exit(EXIT_FAILURE);
19+
}
20+
memcpy(copy, src, len);
21+
return copy;
22+
}
23+
24+
static void ensure_capacity(void **buffer, size_t elem_size, size_t *capacity, size_t needed)
25+
{
26+
if (*capacity >= needed)
27+
{
28+
return;
29+
}
30+
size_t new_capacity = (*capacity == 0) ? 4 : (*capacity * 2);
31+
while (new_capacity < needed)
32+
{
33+
new_capacity *= 2;
34+
}
35+
void *new_buffer = realloc(*buffer, new_capacity * elem_size);
36+
if (!new_buffer)
37+
{
38+
fprintf(stderr, "out of memory\n");
39+
exit(EXIT_FAILURE);
40+
}
41+
*buffer = new_buffer;
42+
*capacity = new_capacity;
43+
}
44+
45+
void symbol_table_init(SymbolTable *table)
46+
{
47+
if (!table)
48+
{
49+
return;
50+
}
51+
table->scopes = NULL;
52+
table->depth = 0;
53+
table->capacity = 0;
54+
}
55+
56+
static void symbol_scope_free(SymbolScope *scope)
57+
{
58+
if (!scope)
59+
{
60+
return;
61+
}
62+
for (size_t i = 0; i < scope->count; ++i)
63+
{
64+
free(scope->items[i].name);
65+
}
66+
free(scope->items);
67+
scope->items = NULL;
68+
scope->count = 0;
69+
scope->capacity = 0;
70+
}
71+
72+
void symbol_table_free(SymbolTable *table)
73+
{
74+
if (!table)
75+
{
76+
return;
77+
}
78+
for (size_t i = 0; i < table->depth; ++i)
79+
{
80+
symbol_scope_free(&table->scopes[i]);
81+
}
82+
free(table->scopes);
83+
table->scopes = NULL;
84+
table->depth = 0;
85+
table->capacity = 0;
86+
}
87+
88+
void symbol_table_push_scope(SymbolTable *table)
89+
{
90+
if (!table)
91+
{
92+
return;
93+
}
94+
ensure_capacity((void **)&table->scopes, sizeof(SymbolScope), &table->capacity, table->depth + 1);
95+
SymbolScope *scope = &table->scopes[table->depth++];
96+
scope->items = NULL;
97+
scope->count = 0;
98+
scope->capacity = 0;
99+
}
100+
101+
void symbol_table_pop_scope(SymbolTable *table)
102+
{
103+
if (!table || table->depth == 0)
104+
{
105+
return;
106+
}
107+
SymbolScope *scope = &table->scopes[table->depth - 1];
108+
symbol_scope_free(scope);
109+
table->depth--;
110+
}
111+
112+
int symbol_table_add(SymbolTable *table, const char *name, TypeKind type)
113+
{
114+
if (!table || table->depth == 0 || !name)
115+
{
116+
return 0;
117+
}
118+
SymbolScope *scope = &table->scopes[table->depth - 1];
119+
for (size_t i = 0; i < scope->count; ++i)
120+
{
121+
if (strcmp(scope->items[i].name, name) == 0)
122+
{
123+
return 0;
124+
}
125+
}
126+
ensure_capacity((void **)&scope->items, sizeof(Symbol), &scope->capacity, scope->count + 1);
127+
scope->items[scope->count].name = dup_string(name);
128+
scope->items[scope->count].type = type;
129+
scope->count++;
130+
return 1;
131+
}
132+
133+
const Symbol *symbol_table_lookup(const SymbolTable *table, const char *name)
134+
{
135+
if (!table || !name)
136+
{
137+
return NULL;
138+
}
139+
for (size_t depth = table->depth; depth > 0; --depth)
140+
{
141+
const SymbolScope *scope = &table->scopes[depth - 1];
142+
for (size_t i = 0; i < scope->count; ++i)
143+
{
144+
if (strcmp(scope->items[i].name, name) == 0)
145+
{
146+
return &scope->items[i];
147+
}
148+
}
149+
}
150+
return NULL;
151+
}
152+
153+
void function_table_init(FunctionTable *table)
154+
{
155+
if (!table)
156+
{
157+
return;
158+
}
159+
table->items = NULL;
160+
table->count = 0;
161+
table->capacity = 0;
162+
}
163+
164+
static void function_signature_free(FunctionSignature *signature)
165+
{
166+
if (!signature)
167+
{
168+
return;
169+
}
170+
free(signature->name);
171+
ast_param_list_destroy(&signature->params);
172+
}
173+
174+
void function_table_free(FunctionTable *table)
175+
{
176+
if (!table)
177+
{
178+
return;
179+
}
180+
for (size_t i = 0; i < table->count; ++i)
181+
{
182+
function_signature_free(&table->items[i]);
183+
}
184+
free(table->items);
185+
table->items = NULL;
186+
table->count = 0;
187+
table->capacity = 0;
188+
}
189+
190+
FunctionSignature *function_table_add(FunctionTable *table, const char *name, TypeKind return_type, const AstParamList *params)
191+
{
192+
if (!table || !name)
193+
{
194+
return NULL;
195+
}
196+
for (size_t i = 0; i < table->count; ++i)
197+
{
198+
if (strcmp(table->items[i].name, name) == 0)
199+
{
200+
return NULL;
201+
}
202+
}
203+
ensure_capacity((void **)&table->items, sizeof(FunctionSignature), &table->capacity, table->count + 1);
204+
FunctionSignature *signature = &table->items[table->count++];
205+
signature->name = dup_string(name);
206+
signature->return_type = return_type;
207+
signature->params = ast_param_list_make();
208+
if (params)
209+
{
210+
for (size_t i = 0; i < params->count; ++i)
211+
{
212+
AstParam param;
213+
param.type = params->items[i].type;
214+
param.name = dup_string(params->items[i].name);
215+
ast_param_list_push(&signature->params, param);
216+
}
217+
}
218+
return signature;
219+
}
220+
221+
const FunctionSignature *function_table_find(const FunctionTable *table, const char *name)
222+
{
223+
if (!table || !name)
224+
{
225+
return NULL;
226+
}
227+
for (size_t i = 0; i < table->count; ++i)
228+
{
229+
if (strcmp(table->items[i].name, name) == 0)
230+
{
231+
return &table->items[i];
232+
}
233+
}
234+
return NULL;
235+
}

src/symbol_table.h

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
#ifndef SYMBOL_TABLE_H
2+
#define SYMBOL_TABLE_H
3+
4+
#include "ast.h"
5+
6+
typedef struct
7+
{
8+
char *name;
9+
TypeKind type;
10+
} Symbol;
11+
12+
typedef struct
13+
{
14+
Symbol *items;
15+
size_t count;
16+
size_t capacity;
17+
} SymbolScope;
18+
19+
typedef struct
20+
{
21+
SymbolScope *scopes;
22+
size_t depth;
23+
size_t capacity;
24+
} SymbolTable;
25+
26+
typedef struct
27+
{
28+
char *name;
29+
TypeKind return_type;
30+
AstParamList params;
31+
} FunctionSignature;
32+
33+
typedef struct
34+
{
35+
FunctionSignature *items;
36+
size_t count;
37+
size_t capacity;
38+
} FunctionTable;
39+
40+
void symbol_table_init(SymbolTable *table);
41+
void symbol_table_free(SymbolTable *table);
42+
void symbol_table_push_scope(SymbolTable *table);
43+
void symbol_table_pop_scope(SymbolTable *table);
44+
int symbol_table_add(SymbolTable *table, const char *name, TypeKind type);
45+
const Symbol *symbol_table_lookup(const SymbolTable *table, const char *name);
46+
47+
void function_table_init(FunctionTable *table);
48+
void function_table_free(FunctionTable *table);
49+
FunctionSignature *function_table_add(FunctionTable *table, const char *name, TypeKind return_type, const AstParamList *params);
50+
const FunctionSignature *function_table_find(const FunctionTable *table, const char *name);
51+
52+
#endif

0 commit comments

Comments
 (0)