From 90a32ac1a195578e9a3a9d642c34685fbca21b80 Mon Sep 17 00:00:00 2001 From: Max Wash Date: Tue, 19 Nov 2024 10:49:42 +0000 Subject: [PATCH] lang: lex: use a dictionary to lookup keywords --- lang/lex.c | 40 ++++++++++++++++++---------------------- 1 file changed, 18 insertions(+), 22 deletions(-) diff --git a/lang/lex.c b/lang/lex.c index 5c5f712..d2221ca 100644 --- a/lang/lex.c +++ b/lang/lex.c @@ -1,6 +1,8 @@ #include #include #include +#include +#include #include #include #include @@ -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); }