Compare commits
2 Commits
b5b4d7816a
...
3fc90383a9
Author | SHA1 | Date |
---|---|---|
Danila Fedorin | 3fc90383a9 | |
Danila Fedorin | 39dd07b134 |
|
@ -67,8 +67,6 @@ enum libab_lexer_token_e {
|
||||||
TOKEN_KW_ARROW,
|
TOKEN_KW_ARROW,
|
||||||
TOKEN_KW_FUN,
|
TOKEN_KW_FUN,
|
||||||
TOKEN_KW_RETURN,
|
TOKEN_KW_RETURN,
|
||||||
TOKEN_KW_LET,
|
|
||||||
TOKEN_KW_BE,
|
|
||||||
TOKEN_LAST
|
TOKEN_LAST
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -119,5 +119,11 @@ int libab_tree_has_vector(libab_tree_variant var);
|
||||||
* @param tree the tree to free.
|
* @param tree the tree to free.
|
||||||
*/
|
*/
|
||||||
void libab_tree_free_recursive(libab_tree* tree);
|
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
|
#endif
|
||||||
|
|
10
src/custom.c
10
src/custom.c
|
@ -9,6 +9,7 @@ void libab_behavior_init_internal(libab_behavior* behavior,
|
||||||
void libab_behavior_init_tree(libab_behavior* behavior, libab_tree* tree) {
|
void libab_behavior_init_tree(libab_behavior* behavior, libab_tree* tree) {
|
||||||
behavior->variant = BIMPL_TREE;
|
behavior->variant = BIMPL_TREE;
|
||||||
behavior->data_u.tree = tree;
|
behavior->data_u.tree = tree;
|
||||||
|
tree->int_value++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void libab_behavior_copy(libab_behavior* behavior, libab_behavior* into) {
|
void libab_behavior_copy(libab_behavior* behavior, libab_behavior* into) {
|
||||||
|
@ -42,21 +43,24 @@ libab_result libab_function_init_internal(libab_function* function,
|
||||||
libab_function_ptr fun,
|
libab_function_ptr fun,
|
||||||
libab_ref* scope) {
|
libab_ref* scope) {
|
||||||
libab_result result = _function_init(function, scope);
|
libab_result result = _function_init(function, scope);
|
||||||
libab_behavior_init_internal(&function->behavior, fun);
|
if(result == LIBAB_SUCCESS)
|
||||||
|
libab_behavior_init_internal(&function->behavior, fun);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
libab_result libab_function_init_tree(libab_function* function,
|
libab_result libab_function_init_tree(libab_function* function,
|
||||||
libab_tree* tree,
|
libab_tree* tree,
|
||||||
libab_ref* scope) {
|
libab_ref* scope) {
|
||||||
libab_result result = _function_init(function, scope);
|
libab_result result = _function_init(function, scope);
|
||||||
libab_behavior_init_tree(&function->behavior, tree);
|
if(result == LIBAB_SUCCESS)
|
||||||
|
libab_behavior_init_tree(&function->behavior, tree);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
libab_result libab_function_init_behavior(libab_function* function,
|
libab_result libab_function_init_behavior(libab_function* function,
|
||||||
libab_behavior* behavior,
|
libab_behavior* behavior,
|
||||||
libab_ref* scope) {
|
libab_ref* scope) {
|
||||||
libab_result result = _function_init(function, scope);
|
libab_result result = _function_init(function, scope);
|
||||||
libab_behavior_copy(behavior, &function->behavior);
|
if(result == LIBAB_SUCCESS)
|
||||||
|
libab_behavior_copy(behavior, &function->behavior);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
void libab_function_free(libab_function* fun) {
|
void libab_function_free(libab_function* fun) {
|
||||||
|
|
|
@ -16,13 +16,11 @@ libab_result libab_lexer_init(libab_lexer* lexer) {
|
||||||
"do",
|
"do",
|
||||||
"->",
|
"->",
|
||||||
"fun",
|
"fun",
|
||||||
"return",
|
"return"};
|
||||||
"let",
|
|
||||||
"be"};
|
|
||||||
libab_lexer_token tokens[] = {
|
libab_lexer_token tokens[] = {
|
||||||
TOKEN_CHAR, TOKEN_ID, TOKEN_NUM, TOKEN_KW_IF,
|
TOKEN_CHAR, TOKEN_ID, TOKEN_NUM, TOKEN_KW_IF,
|
||||||
TOKEN_KW_ELSE, TOKEN_KW_WHILE, TOKEN_KW_DO, TOKEN_KW_ARROW,
|
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);
|
const size_t count = sizeof(tokens) / sizeof(libab_lexer_token);
|
||||||
|
|
||||||
eval_config_init(&lexer->config);
|
eval_config_init(&lexer->config);
|
||||||
|
|
48
src/parser.c
48
src/parser.c
|
@ -489,51 +489,6 @@ libab_result _parse_fun_param(struct parser_state* state,
|
||||||
return result;
|
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 _parse_fun(struct parser_state* state, libab_tree** store_into) {
|
||||||
libab_result result = LIBAB_SUCCESS;
|
libab_result result = LIBAB_SUCCESS;
|
||||||
int is_parenth, is_comma;
|
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);
|
_parser_state_step(state);
|
||||||
libab_ref_null(&(*store_into)->type);
|
libab_ref_null(&(*store_into)->type);
|
||||||
(*store_into)->variant = TREE_FUN;
|
(*store_into)->variant = TREE_FUN;
|
||||||
|
(*store_into)->int_value = 1;
|
||||||
result = _parser_consume_char(state, '(');
|
result = _parser_consume_char(state, '(');
|
||||||
}
|
}
|
||||||
while (result == LIBAB_SUCCESS && !_parser_eof(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);
|
result = _parse_braced_block(state, store_into);
|
||||||
} else if (_parser_is_type(state, TOKEN_KW_FUN)) {
|
} else if (_parser_is_type(state, TOKEN_KW_FUN)) {
|
||||||
result = _parse_fun(state, store_into);
|
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)) {
|
} else if (_parser_is_type(state, TOKEN_KW_RETURN)) {
|
||||||
result = _parse_return(state, store_into);
|
result = _parse_return(state, store_into);
|
||||||
} else {
|
} else {
|
||||||
|
|
25
src/tree.c
25
src/tree.c
|
@ -47,10 +47,23 @@ int _tree_foreach_free(void* data, va_list args) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void libab_tree_free_recursive(libab_tree* tree) {
|
int _tree_needs_free(libab_tree* tree) {
|
||||||
if (libab_tree_has_vector(tree->variant)) {
|
return ((tree->variant == TREE_FUN && --tree->int_value) | (tree->variant != TREE_FUN));
|
||||||
vec_foreach(&tree->children, NULL, compare_always, _tree_foreach_free);
|
}
|
||||||
}
|
|
||||||
libab_tree_free(tree);
|
void libab_tree_free_recursive(libab_tree* tree) {
|
||||||
free(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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue