This commit is contained in:
Krzosa Karol
2022-04-30 12:28:34 +02:00
parent a5a3acf3ef
commit 3a9b748fed
15 changed files with 296 additions and 746 deletions

190
parser.c
View File

@@ -11,13 +11,18 @@ global Intern_String keyword_union;
global Intern_String keyword_function;
global Intern_String keyword_global;
global AST_Node *type_s64;
global AST_Node *type_u64;
global AST_Node *type_void;
global AST_Node *type_sizeu;
function void
parser_init(Parser *p){
p->interns_count = 4096;
p->interns = arena_push_array(&p->intern_table_arena, Intern_String, p->interns_count);
p->symbols_count = 4096;
p->symbols = arena_push_array(&p->intern_table_arena, Intern_String, p->symbols_count);
p->symbols = arena_push_array(&p->symbol_table_arena, AST_Node, p->symbols_count);
keyword_s64 = intern_string(p, lit("S64"));
keyword_u64 = intern_string(p, lit("U64"));
@@ -33,10 +38,12 @@ parser_init(Parser *p){
p->first_keyword = keyword_s64.s.str;
p->last_keyword = keyword_global.s.str;
type_insert(p, type_s64, keyword_s64);
type_insert(p, type_u64, keyword_u64);
type_insert(p, type_sizeu, keyword_sizeu);
type_insert(p, type_void, keyword_void);
parser_push_scope(p); // Global scope
type_s64 = symbol_register_basic_type(p, keyword_s64, sizeof(S64));
type_u64 = symbol_register_basic_type(p, keyword_u64, sizeof(U64));
type_sizeu = symbol_register_basic_type(p, keyword_sizeu, sizeof(SizeU));
type_void = symbol_register_basic_type(p, keyword_void, sizeof(void));
}
function B32
@@ -46,6 +53,19 @@ intern_is_keyword(Parser *p, Intern_String intern){
return false;
}
function void
intern_tokens(Parser *p){
for(S64 i = 0; i < p->tokens.len; i++){
Token *t = p->tokens.tokens + i;
if(t->kind == TK_Identifier){
t->intern_val = intern_string(p, t->string);
if(intern_is_keyword(p, t->intern_val)){
t->kind = TK_Keyword;
}
}
}
}
function void
parser_push_error(Parser *p, Token *token, char *str, ...){
@@ -130,122 +150,100 @@ intern_string(Parser *p, String string){
return result;
}
function void
intern_tokens(Parser *p){
for(S64 i = 0; i < p->tokens.len; i++){
Token *t = p->tokens.tokens + i;
if(t->kind == TK_Identifier){
t->intern_val = intern_string(p, t->string);
if(intern_is_keyword(p, t->intern_val)){
t->kind = TK_Keyword;
}
}
}
}
function Symbol *
symbol_get_slot(Parser *p, Intern_String intern){
String string = intern.s;
Table_Index index = table_index_from_string(string, p->symbols_count);
//-----------------------------------------------------------------------------
// Symbols
//-----------------------------------------------------------------------------
function AST_Node *
symbol_alloc_slot(Parser *p, Intern_String string, B32 is_global){
Table_Index index = table_index_from_string(string.s, p->symbols_count);
for(;;){
Symbol *slot = p->symbols + index.iter;
if(slot->string.s.str == 0){
slot->string = intern;
AST_Node *symbol = p->symbols + index.iter;
if(symbol->name.s.str == 0){
/* @Note(Krzosa): Push on scope */ {
if(is_global){
SLLQueuePush(p->scope_stack->first, p->scope_stack->last, symbol);
}
else{
SLLQueuePush(p->global_scope->first, p->global_scope->last, symbol);
}
}
symbol->name = string;
p->symbols_inserted++;
return slot;
return symbol;
}
else if(slot->string.s.str == string.str){
return slot;
else if(intern_compare(symbol->name, string)){
return symbol;
}
if (table_index_advance(&index))
break;
}
parser_push_error(p, token_get(p), "Failed to find a spot for symbol");
return 0;
}
function Symbol *
symbol_get(Parser *p, Intern_String string){
function AST_Node *
symbol_lookup(Parser *p, Intern_String string){
Table_Index index = table_index_from_string(string.s, p->symbols_count);
for(;;){
Symbol *slot = p->symbols + index.iter;
if(slot->string.s.str == string.s.str){
return slot;
AST_Node *symbol = p->symbols + index.iter;
if(symbol->name.s.str == 0){
return 0;
}
else if(intern_compare(symbol->name, string)){
return symbol;
}
if (table_index_advance(&index))
break;
if (table_index_advance(&index))
return 0;
}
}
function AST_Node *
symbol_register_basic_type(Parser *p, Intern_String string, SizeU size){
AST_Node *node = symbol_alloc_slot(p, string, true);
node->kind = AK_BaseType;
node->base_type_size = size;
return node;
}
function AST_Node *
symbol_lookup_type(Parser *p, Intern_String string){
AST_Node *node = symbol_lookup(p, string);
if(node){
if(ast_is_type(node)){
return node;
}
}
return 0;
}
function B32
symbol_require_empty(Parser *p, Symbol *symbol){
assert(symbol);
B32 result = symbol->kind == SK_None;
if(!result){
// @Todo(Krzosa): Should send symbol name not token
parser_push_error(p, token_get(p), "This symbol name is already registered");
}
return result;
}
function void
const_val_insert(Parser *p, Token *token, Type *type, Intern_String string, Expr *expr){
Symbol *symbol = symbol_get_slot(p, string);
if(symbol_require_empty(p, symbol)){
symbol->kind = SK_Const;
symbol->token = token;
symbol->const_val.type = type;
symbol->const_val.expr = expr;
parser_push_scope(Parser *p){
Scope *scope = 0;
SLLStackPop(p->scope_free_list, scope);
if(!scope){
scope = arena_push_struct(&p->main_arena, Scope);
}
SLLStackPush(p->scope_stack, scope);
if(p->global_scope == 0){
p->global_scope = scope;
}
}
function void
variable_insert(Parser *p, Decl *decl){
Symbol *symbol = symbol_get_slot(p, decl->name);
if(symbol_require_empty(p, symbol)){
symbol->kind = SK_Decl;
symbol->decl = decl;
symbol->string = decl->name;
symbol->token = decl->token;
}
}
function void
type_insert(Parser *p, Type *type, Intern_String string){
Symbol *symbol = symbol_get_slot(p, string);
if(symbol_require_empty(p, symbol)){
symbol->kind = SK_Type;
symbol->type = type;
symbol->string = string;
}
}
function Type *
type_get(Parser *p, Intern_String string){
Type *result = 0;
Symbol *symbol = symbol_get(p, string);
if(symbol){
if(symbol->kind == SK_Type){
result = symbol->type;
}
else {
parser_push_error(p, token_get(p), "Symbol is not a type");
}
}
else{
parser_push_error(p, token_get(p), "Undefined type");
}
parser_pop_scope(Parser *p){
Scope *scope = 0;
SLLStackPop(p->scope_stack, scope);
assert(scope);
if(!result){
result = type_undefined;
for(AST_Node *s = scope->first; s; s=s->scope_next){
memory_zero(s, sizeof(AST_Node));
p->symbols_inserted--;
}
return result;
memory_zero(scope, sizeof(Scope));
SLLStackPush(p->scope_free_list, scope);
}