lang: lex: use a dictionary to lookup keywords
This commit is contained in:
40
lang/lex.c
40
lang/lex.c
@@ -1,6 +1,8 @@
|
||||
#include <blue/core/hash.h>
|
||||
#include <blue/core/queue.h>
|
||||
#include <blue/object/string.h>
|
||||
#include <blue/object/dict.h>
|
||||
#include <blue/object/number.h>
|
||||
#include <ctype.h>
|
||||
#include <ivy/lang/lex.h>
|
||||
#include <stdbool.h>
|
||||
@@ -18,7 +20,7 @@
|
||||
struct ivy_lexer {
|
||||
struct ivy_lexer_symbol_node *lex_sym_tree;
|
||||
struct ivy_line_source *lex_source;
|
||||
|
||||
b_dict *lex_keywords;
|
||||
enum ivy_status lex_status;
|
||||
|
||||
struct ivy_token *lex_queue;
|
||||
@@ -303,32 +305,22 @@ static void print_symbol_node(struct ivy_lexer_symbol_node *node, int depth)
|
||||
}
|
||||
}
|
||||
|
||||
static void init_keywords(void)
|
||||
static void init_keywords(b_dict *keyword_dict)
|
||||
{
|
||||
for (size_t i = 0; i < nr_keywords; i++) {
|
||||
keywords[i].name_hash = b_hash_string(keywords[i].name);
|
||||
struct lex_token_def *keyword = &keywords[i];
|
||||
b_dict_put(keyword_dict, keyword->name, B_RV_INT(keyword->id));
|
||||
}
|
||||
}
|
||||
|
||||
static enum ivy_keyword find_keyword_by_name(const char *s)
|
||||
static enum ivy_keyword find_keyword_by_name(struct ivy_lexer *lex, const char *s)
|
||||
{
|
||||
uint64_t s_hash = b_hash_string(s);
|
||||
|
||||
for (size_t i = 0; i < nr_keywords; i++) {
|
||||
struct lex_token_def *def = &keywords[i];
|
||||
|
||||
if (s_hash != def->name_hash) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strcmp(s, def->name) != 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
return def->id;
|
||||
b_number *id = b_dict_at(lex->lex_keywords, s);
|
||||
if (!id) {
|
||||
return IVY_KW_NONE;
|
||||
}
|
||||
|
||||
return IVY_KW_NONE;
|
||||
return b_number_get_int(id);
|
||||
}
|
||||
|
||||
enum ivy_status ivy_lexer_create(struct ivy_lexer **lexp)
|
||||
@@ -359,8 +351,8 @@ enum ivy_status ivy_lexer_create(struct ivy_lexer **lexp)
|
||||
|
||||
print_symbol_node(lex->lex_sym_tree, 0);
|
||||
|
||||
/* TODO only do keyword initialisation once */
|
||||
init_keywords();
|
||||
lex->lex_keywords = b_dict_create();
|
||||
init_keywords(lex->lex_keywords);
|
||||
*lexp = lex;
|
||||
|
||||
return IVY_OK;
|
||||
@@ -386,6 +378,10 @@ void ivy_lexer_destroy(struct ivy_lexer *lex)
|
||||
b_string_release(lex->lex_temp);
|
||||
}
|
||||
|
||||
if (lex->lex_keywords) {
|
||||
b_dict_release(lex->lex_keywords);
|
||||
}
|
||||
|
||||
destroy_state_stack(&lex->lex_state);
|
||||
|
||||
free(lex);
|
||||
@@ -967,7 +963,7 @@ static enum ivy_status read_ident(struct ivy_lexer *lex)
|
||||
}
|
||||
|
||||
enum ivy_keyword keyword = IVY_KW_NONE;
|
||||
if (!label && (keyword = find_keyword_by_name(s)) != IVY_KW_NONE) {
|
||||
if (!label && (keyword = find_keyword_by_name(lex, s)) != IVY_KW_NONE) {
|
||||
return push_keyword(lex, keyword);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user