Skip to content

Commit

Permalink
Store Symtab Symbols until Symtab destruction
Browse files Browse the repository at this point in the history
Previously, symbols were only stored until the end of scope. This is a
problem as the IL2 generator cannot access the symbols anymore. Now, the
symbols are stored until the symbol table itself is destructed.

As a result of how symbols are now stored - in one memory location
without moving - they no longer need to be referenced via an id, their
pointer can be directly returned
  • Loading branch information
jaihysc committed Apr 20, 2023
1 parent f3202f6 commit 0fa9758
Show file tree
Hide file tree
Showing 11 changed files with 113 additions and 146 deletions.
10 changes: 5 additions & 5 deletions src/cfg.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,16 @@ int block_lab_count(Block* blk) {
return vec_size(&blk->labels);
}

SymbolId block_lab(Block* blk, int i) {
Symbol* block_lab(Block* blk, int i) {
ASSERT(blk != NULL, "Block is null");
ASSERT(i >= 0, "Index out of range");
ASSERT(i < block_lab_count(blk), "Index out of range");
return vec_at(&blk->labels, i);
}

ErrorCode block_add_label(Block* blk, SymbolId lab_id) {
ErrorCode block_add_label(Block* blk, Symbol* lab) {
ASSERT(blk != NULL, "Block is null");
if (!vec_push_back(&blk->labels, lab_id)) return ec_badalloc;
if (!vec_push_back(&blk->labels, lab)) return ec_badalloc;
return ec_noerr;
}

Expand Down Expand Up @@ -104,11 +104,11 @@ ErrorCode cfg_new_block(Cfg* cfg, Block** block_ptr) {
return ec_noerr;
}

Block* cfg_find_labelled(Cfg* cfg, SymbolId lab_id) {
Block* cfg_find_labelled(Cfg* cfg, Symbol* lab) {
for (int i = 0; i < vec_size(&cfg->blocks); ++i) {
Block* blk = &vec_at(&cfg->blocks, i);
for (int j = 0; j < block_lab_count(blk); ++j) {
if (symid_equal(block_lab(blk, j), lab_id)) {
if (block_lab(blk, j) == lab) {
return blk;
}
}
Expand Down
8 changes: 4 additions & 4 deletions src/cfg.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
2. Control always leaves at the last statement or end of the block */
typedef struct {
/* Labels at the entry of this block */
vec_t(SymbolId) labels;
vec_t(Symbol*) labels;
vec_t(ILStatement) il_stats;

/* At most 2 options:
Expand All @@ -32,10 +32,10 @@ void block_destruct(Block* blk);
int block_lab_count(Block* blk);

/* Returns label at index in block */
SymbolId block_lab(Block* blk, int i);
Symbol* block_lab(Block* blk, int i);

/* Adds a new label at the entry of this block */
ErrorCode block_add_label(Block* blk, SymbolId lab_id);
ErrorCode block_add_label(Block* blk, Symbol* lab);

/* Returns number of IL statements in block */
int block_ilstat_count(Block* blk);
Expand Down Expand Up @@ -69,6 +69,6 @@ ErrorCode cfg_new_block(Cfg* cfg, Block** block_ptr);

/* Finds the first block which has the provided label
Returns null if not found */
Block* cfg_find_labelled(Cfg* cfg, SymbolId lab_id);
Block* cfg_find_labelled(Cfg* cfg, Symbol* lab);

#endif
2 changes: 1 addition & 1 deletion src/ilstatement.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ ILIns ilstat_ins(const ILStatement* stat) {
return stat->ins;
}

SymbolId ilstat_arg(const ILStatement* stat, int i) {
Symbol* ilstat_arg(const ILStatement* stat, int i) {
ASSERT(stat != NULL, "ILStatement is null");
ASSERT(i >= 0, "Index out of range");
ASSERT(i < stat->argc, "Index out of range");
Expand Down
4 changes: 2 additions & 2 deletions src/ilstatement.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,15 +53,15 @@ int il2_incfg(ILIns ins);

typedef struct {
ILIns ins;
SymbolId arg[MAX_IL2_ARGS];
Symbol* arg[MAX_IL2_ARGS];
int argc;
} ILStatement;

/* Returns ILIns for IL statement */
ILIns ilstat_ins(const ILStatement* stat);

/* Returns arg at index i for IL statement */
SymbolId ilstat_arg(const ILStatement* stat, int i);
Symbol* ilstat_arg(const ILStatement* stat, int i);

/* Returns the number of arguments in IL statement */
int ilstat_argc(const ILStatement* stat);
Expand Down
4 changes: 2 additions & 2 deletions src/parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -1387,9 +1387,9 @@ static ErrorCode parse_parameter_list(Parser* p, TNode* parent, int* matched) {
Type type;
type_construct(&type, declspec->ts, pointer->pointers);

SymbolId symid;
Symbol* sym;
if ((ecode = symtab_add(
p->symtab, &symid, identifier->token, type)) != ec_noerr) goto exit;
p->symtab, &sym, identifier->token, type)) != ec_noerr) goto exit;

/* Add to tree */
if ((ecode = tnode_attach(parent, node)) != ec_noerr) goto exit;
Expand Down
18 changes: 3 additions & 15 deletions src/symbol.c
Original file line number Diff line number Diff line change
@@ -1,19 +1,7 @@
#include "symbol.h"

#include <stddef.h>

#include "common.h"

SymbolId symid_invalid = {.index = -1};

int symid_valid(SymbolId sym_id) {
return sym_id.index != -1;
}

int symid_equal(SymbolId a, SymbolId b) {
return a.index == b.index && a.scope == b.scope;
}

ErrorCode symbol_construct(Symbol* sym, const char* token, Type type) {
sym->class = sl_normal;

Expand All @@ -34,7 +22,7 @@ ErrorCode symbol_construct(Symbol* sym, const char* token, Type type) {
return ec_noerr;
}

void symbol_sl_access(Symbol* sym, SymbolId ptr, SymbolId idx) {
void symbol_sl_access(Symbol* sym, Symbol* ptr, Symbol* idx) {
ASSERT(sym != NULL, "Symbol is null");
sym->class = sl_access;
sym->ptr = ptr;
Expand Down Expand Up @@ -70,12 +58,12 @@ void symbol_set_valcat(Symbol* sym, ValueCategory valcat) {
sym->valcat = valcat;
}

SymbolId symbol_ptr_sym(Symbol* sym) {
Symbol* symbol_ptr_sym(Symbol* sym) {
ASSERT(sym != NULL, "Symbol is null");
return sym->ptr;
}

SymbolId symbol_ptr_index(Symbol* sym) {
Symbol* symbol_ptr_index(Symbol* sym) {
ASSERT(sym != NULL, "Symbol is null");
return sym->ptr_idx;
}
Expand Down
29 changes: 8 additions & 21 deletions src/symbol.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,6 @@

#define MAX_SYMBOL_LEN 255 /* Max characters symbol name (exclude null terminator) */

typedef struct {
int scope; /* Index of scope */
int index; /* Index of symbol in scope */
} SymbolId;

/* Used to indicate invalid symbol */
extern SymbolId symid_invalid;

/* Return 1 if the SymbolId is valid, 0 otherwise */
int symid_valid(SymbolId sym_id);

/* Returns 1 if both symid are equal, 0 otherwise */
int symid_equal(SymbolId a, SymbolId b);

typedef enum {
sl_normal = 0,
sl_access /* Represents access to memory location */
Expand All @@ -32,16 +18,17 @@ typedef enum {
vc_nlval
} ValueCategory;

typedef struct {
typedef struct Symbol Symbol;
struct Symbol {
SymbolClass class;
char token[MAX_SYMBOL_LEN + 1];
Type type;
ValueCategory valcat;

/* Only for class sl_access */
SymbolId ptr;
SymbolId ptr_idx;
} Symbol;
Symbol* ptr;
Symbol* ptr_idx;
};

/* Creates symbol at given memory location */
ErrorCode symbol_construct(Symbol* sym, const char* token, Type type);
Expand All @@ -52,7 +39,7 @@ ErrorCode symbol_construct(Symbol* sym, const char* token, Type type);
symbol, leave as symid_invalid to default to 0
e.g., int* p; int a = p[2];
If this symbol is a, ptr is p, idx is 2 */
void symbol_sl_access(Symbol* sym, SymbolId ptr, SymbolId idx);
void symbol_sl_access(Symbol* sym, Symbol* ptr, Symbol* idx);

/* Returns SymbolClass for symbol */
SymbolClass symbol_class(Symbol* sym);
Expand All @@ -75,11 +62,11 @@ void symbol_set_valcat(Symbol* sym, ValueCategory valcat);
/* Returns the symbol for the pointer, which when indexed yields this symbol
e.g., int* p; int a = p[2];
If this symbol is a, the returned symbol is p */
SymbolId symbol_ptr_sym(Symbol* sym);
Symbol* symbol_ptr_sym(Symbol* sym);

/* Returns the symbol of the index, which when used to index symbol_ptr_sym
yields this symbol
The index is always in bytes */
SymbolId symbol_ptr_index(Symbol* sym);
Symbol* symbol_ptr_index(Symbol* sym);

#endif
94 changes: 35 additions & 59 deletions src/symtab.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
ErrorCode symtab_construct(Symtab* stab) {
ASSERT(stab != NULL, "Symtab is null");

hvec_construct(&stab->symbol);

stab->scopes = NULL;
stab->scopes_size = 0;
stab->scopes_capacity = 0;
Expand All @@ -30,9 +32,11 @@ void symtab_destruct(Symtab* stab) {
vec_destruct(&stab->scopes[i]);
}
cfree(stab->scopes);

hvec_destruct(&stab->symbol);
}

ErrorCode symtab_push_cat(Symtab* stab, SymbolCat cat, SymbolId sym) {
ErrorCode symtab_push_cat(Symtab* stab, SymbolCat cat, Symbol* sym) {
ASSERT(stab != NULL, "Symtab is null");

if (!vec_push_backu(&stab->cat[cat])) return ec_badalloc;
Expand All @@ -49,7 +53,7 @@ void symtab_pop_cat(Symtab* stab, SymbolCat cat) {
(void)vec_pop_back(&stab->cat[cat]);
}

SymbolId symtab_last_cat(Symtab* stab, SymbolCat cat) {
Symbol* symtab_last_cat(Symtab* stab, SymbolCat cat) {
ASSERT(stab != NULL, "Symtab is null");
ASSERTF(vec_size(&stab->cat[cat]) > 0,
"No symbol on symbol category %d stack", cat);
Expand Down Expand Up @@ -111,86 +115,58 @@ void symtab_pop_scope(Symtab* stab) {
}

/* Finds provided token within indicated scope
Returns symid_invalid if not found */
static SymbolId symtab_find_scoped(Symtab* stab, int i_scope, const char* token) {
Returns NULL if not found */
static Symbol* symtab_find_scoped(Symtab* stab, int i_scope, const char* token) {
ASSERT(stab != NULL, "Symtab is null");

for (int i = 0; i < vec_size(&stab->scopes[i_scope]); ++i) {
Symbol* sym = &vec_at(&stab->scopes[i_scope], i);
if (strequ(symbol_token(sym), token)) {
SymbolId id;
id.scope = i_scope;
id.index = i;
return id;
}
Symbol* sym = vec_at(&stab->scopes[i_scope], i);
if (strequ(symbol_token(sym), token)) return sym;
}
return symid_invalid;
return NULL;
}

SymbolId symtab_find(Symtab* stab, const char* token) {
Symbol* symtab_find(Symtab* stab, const char* token) {
ASSERT(stab != NULL, "Symtab is null");

for (int i_scope = stab->scopes_size - 1; i_scope >= 0; --i_scope) {
SymbolId found_id = symtab_find_scoped(stab, i_scope, token);
if (symid_valid(found_id)) {
return found_id;
}
Symbol* found = symtab_find_scoped(stab, i_scope, token);
if (found != NULL) return found;
}
return symid_invalid;
}

Symbol* symtab_get(Symtab* stab, SymbolId sym_id) {
ASSERT(stab != NULL, "Symtab is null");
ASSERT(symid_valid(sym_id), "Invalid symbol id");
ASSERT(sym_id.index < vec_size(&stab->scopes[sym_id.scope]), "Symbol id out of range");
return &vec_at(&stab->scopes[sym_id.scope], sym_id.index);
}

const char* symtab_get_token(Symtab* stab, SymbolId sym_id) {
ASSERT(stab != NULL, "Symtab is null");
return symbol_token(symtab_get(stab, sym_id));
}

Type symtab_get_type(Symtab* stab, SymbolId sym_id) {
ASSERT(stab != NULL, "Symtab is null");
return symbol_type(symtab_get(stab, sym_id));
}

ValueCategory symtab_get_valcat(Symtab* stab, SymbolId sym_id) {
ASSERT(stab != NULL, "Symtab is null");
return symbol_valcat(symtab_get(stab, sym_id));
return NULL;
}

/* Allocates storage for symbol in symbol table
Stores SymbolId of added symbol at pointer
Stores Symbol* of added symbol at pointer
or ec_symtab_dupname if it already exists */
static ErrorCode symtab_add_scoped(Symtab* stab, SymbolId* symid_ptr,
static ErrorCode symtab_add_scoped(Symtab* stab, Symbol** sym_ptr,
int i_scope, const char* token, Type type) {
ASSERT(stab != NULL, "Symtab is null");
ASSERT(stab->scopes_size > 0, "Invalid scope");

/* Add to vec of symbols */
if (!hvec_push_backu(&stab->symbol)) return ec_badalloc;
Symbol* sym = &hvec_back(&stab->symbol);

/* Add to vec of symbols in scope */
if (token != NULL) {
/* Normal symbols can not have duplicates in same scope */
if (symid_valid(symtab_find_scoped(stab, i_scope, token))) {
if (symtab_find_scoped(stab, i_scope, token) != NULL) {
ERRMSGF("Symbol already exists %s\n", token);
*symid_ptr = symid_invalid;
*sym_ptr = NULL;
return ec_symtab_dupname;
}
}

SymbolId id;
id.scope = i_scope;
id.index = vec_size(&stab->scopes[i_scope]);

if (!vec_push_backu(&stab->scopes[i_scope])) return ec_badalloc;
Symbol* sym = &vec_back(&stab->scopes[i_scope]);
vec_back(&stab->scopes[i_scope]) = sym;

symbol_construct(sym, token, type);
*symid_ptr = id;
*sym_ptr = sym;
return ec_noerr;
}

ErrorCode symtab_add(Symtab* stab, SymbolId* symid_ptr,
ErrorCode symtab_add(Symtab* stab, Symbol** sym_ptr,
const char* token, Type type) {
ASSERT(stab != NULL, "Symtab is null");
ASSERT(token != NULL, "token is null");
Expand All @@ -201,21 +177,21 @@ ErrorCode symtab_add(Symtab* stab, SymbolId* symid_ptr,
/* Add new symbol to current scope */
ASSERT(stab->scopes_size > 0, "No scope exists");
int curr_scope = stab->scopes_size - 1;
return symtab_add_scoped(stab, symid_ptr, curr_scope, token, type);
return symtab_add_scoped(stab, sym_ptr, curr_scope, token, type);
}

ErrorCode symtab_add_temporary(Symtab* stab, SymbolId* symid_ptr, Type type) {
ErrorCode symtab_add_temporary(Symtab* stab, Symbol** sym_ptr, Type type) {
ASSERT(stab != NULL, "Symtab is null");
AAPPENDI(token, "__t", stab->temp_num);
++stab->temp_num;

ErrorCode ecode;
if ((ecode = symtab_add(stab, symid_ptr, token, type)) != ec_noerr) return ecode;
symbol_set_valcat(symtab_get(stab, *symid_ptr), vc_nlval);
if ((ecode = symtab_add(stab, sym_ptr, token, type)) != ec_noerr) return ecode;
symbol_set_valcat(*sym_ptr, vc_nlval);
return ec_noerr;
}

ErrorCode symtab_add_label(Symtab* stab, SymbolId* symid_ptr) {
ErrorCode symtab_add_label(Symtab* stab, Symbol** sym_ptr) {
ASSERT(stab != NULL, "Symtab is null");
AAPPENDI(token, "__l", stab->label_num);
++stab->label_num;
Expand All @@ -224,8 +200,8 @@ ErrorCode symtab_add_label(Symtab* stab, SymbolId* symid_ptr) {
/* Scope at index 1 is function scope */
ErrorCode ecode;
if ((ecode = symtab_add_scoped(
stab, symid_ptr, 1, token, type_label)) != ec_noerr) return ecode;
symbol_set_valcat(symtab_get(stab, *symid_ptr), vc_nlval);
stab, sym_ptr, 1, token, type_label)) != ec_noerr) return ecode;
symbol_set_valcat(*sym_ptr, vc_nlval);
return ec_noerr;
}

Expand All @@ -240,7 +216,7 @@ void debug_print_symtab(Symtab* stab) {
LOGF(" %d [%d]\n", i, symbols_size);

for (int j = 0; j < symbols_size; ++j) {
Symbol* sym = &vec_at(&stab->scopes[i], j);
Symbol* sym = vec_at(&stab->scopes[i], j);
Type type = symbol_type(sym);
LOGF(" %d %s", j, ts_str(type.typespec));

Expand Down
Loading

0 comments on commit 0fa9758

Please sign in to comment.