From 39dd07b1346b3fe202a133dc56cef0e1594faf43 Mon Sep 17 00:00:00 2001 From: Danila Fedorin Date: Tue, 12 Jun 2018 23:34:18 -0700 Subject: [PATCH] Add pseudo-refcounting to tree creation. --- include/lexer.h | 2 -- include/tree.h | 6 ++++++ src/lexer.c | 6 ++---- src/parser.c | 48 +----------------------------------------------- src/tree.c | 25 +++++++++++++++++++------ 5 files changed, 28 insertions(+), 59 deletions(-) diff --git a/include/lexer.h b/include/lexer.h index ca9779a..9a57655 100644 --- a/include/lexer.h +++ b/include/lexer.h @@ -67,8 +67,6 @@ enum libab_lexer_token_e { TOKEN_KW_ARROW, TOKEN_KW_FUN, TOKEN_KW_RETURN, - TOKEN_KW_LET, - TOKEN_KW_BE, TOKEN_LAST }; diff --git a/include/tree.h b/include/tree.h index 632413c..d6b1870 100644 --- a/include/tree.h +++ b/include/tree.h @@ -119,5 +119,11 @@ int libab_tree_has_vector(libab_tree_variant var); * @param tree the tree to free. */ void libab_tree_free_recursive(libab_tree* tree); +/** + * Frees the tree, taking into account reference-counted + * nodes. + * @param tree the tree to free. + */ +void libab_tree_refcount_free(libab_tree* tree); #endif diff --git a/src/lexer.c b/src/lexer.c index 1964d36..7ad154a 100644 --- a/src/lexer.c +++ b/src/lexer.c @@ -16,13 +16,11 @@ libab_result libab_lexer_init(libab_lexer* lexer) { "do", "->", "fun", - "return", - "let", - "be"}; + "return"}; libab_lexer_token tokens[] = { TOKEN_CHAR, TOKEN_ID, TOKEN_NUM, TOKEN_KW_IF, TOKEN_KW_ELSE, TOKEN_KW_WHILE, TOKEN_KW_DO, TOKEN_KW_ARROW, - TOKEN_KW_FUN, TOKEN_KW_RETURN, TOKEN_KW_LET, TOKEN_KW_BE}; + TOKEN_KW_FUN, TOKEN_KW_RETURN }; const size_t count = sizeof(tokens) / sizeof(libab_lexer_token); eval_config_init(&lexer->config); diff --git a/src/parser.c b/src/parser.c index cd46a14..ac5f8c8 100644 --- a/src/parser.c +++ b/src/parser.c @@ -489,51 +489,6 @@ libab_result _parse_fun_param(struct parser_state* state, return result; } -libab_result _parse_def_fun(struct parser_state* state, - libab_tree** store_into) { - libab_result result = LIBAB_SUCCESS; - libab_tree* temp; - if (_parser_is_type(state, TOKEN_KW_LET)) { - _parser_state_step(state); - if (!_parser_eof(state)) { - result = _parser_construct_node_both(state, state->current_match, - store_into); - } else { - result = LIBAB_UNEXPECTED; - } - } else { - result = LIBAB_UNEXPECTED; - } - - if (result == LIBAB_SUCCESS) { - _parser_state_step(state); - libab_ref_null(&(*store_into)->type); - (*store_into)->variant = TREE_FUN; - result = _parser_consume_char(state, ':'); - } - - if (result == LIBAB_SUCCESS) { - libab_ref_free(&(*store_into)->type); - result = _parse_type(state, &(*store_into)->type); - } - - if (result == LIBAB_SUCCESS) { - result = _parser_consume_type(state, TOKEN_KW_BE); - } - - if (result == LIBAB_SUCCESS) { - PARSE_CHILD(result, state, _parse_expression, temp, - &(*store_into)->children); - } - - if (result != LIBAB_SUCCESS && *store_into) { - libab_tree_free_recursive(*store_into); - *store_into = NULL; - } - - return result; -} - libab_result _parse_fun(struct parser_state* state, libab_tree** store_into) { libab_result result = LIBAB_SUCCESS; int is_parenth, is_comma; @@ -551,6 +506,7 @@ libab_result _parse_fun(struct parser_state* state, libab_tree** store_into) { _parser_state_step(state); libab_ref_null(&(*store_into)->type); (*store_into)->variant = TREE_FUN; + (*store_into)->int_value = 1; result = _parser_consume_char(state, '('); } while (result == LIBAB_SUCCESS && !_parser_eof(state) && @@ -778,8 +734,6 @@ libab_result _parse_atom(struct parser_state* state, libab_tree** store_into) { result = _parse_braced_block(state, store_into); } else if (_parser_is_type(state, TOKEN_KW_FUN)) { result = _parse_fun(state, store_into); - } else if (_parser_is_type(state, TOKEN_KW_LET)) { - result = _parse_def_fun(state, store_into); } else if (_parser_is_type(state, TOKEN_KW_RETURN)) { result = _parse_return(state, store_into); } else { diff --git a/src/tree.c b/src/tree.c index da0274a..e198672 100644 --- a/src/tree.c +++ b/src/tree.c @@ -47,10 +47,23 @@ int _tree_foreach_free(void* data, va_list args) { return 0; } -void libab_tree_free_recursive(libab_tree* tree) { - if (libab_tree_has_vector(tree->variant)) { - vec_foreach(&tree->children, NULL, compare_always, _tree_foreach_free); - } - libab_tree_free(tree); - free(tree); +int _tree_needs_free(libab_tree* tree) { + return ((tree->variant == TREE_FUN && --tree->int_value) | (tree->variant != TREE_FUN)); +} + +void libab_tree_free_recursive(libab_tree* tree) { + if(_tree_needs_free(tree)) { + if (libab_tree_has_vector(tree->variant)) { + vec_foreach(&tree->children, NULL, compare_always, _tree_foreach_free); + } + libab_tree_free(tree); + free(tree); + } +} + +void libab_tree_refcount_free(libab_tree* tree) { + if(_tree_needs_free(tree)) { + libab_tree_free(tree); + free(tree); + } }