From 7a84babf1e6be3ad99e31d42a677d40d53b1cae5 Mon Sep 17 00:00:00 2001 From: Danila Fedorin Date: Sat, 24 Feb 2018 20:08:17 -0800 Subject: [PATCH] Add basic function call parsing. --- include/tree.h | 3 ++- src/libabacus.c | 4 ++++ src/parser.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 53 insertions(+), 1 deletion(-) diff --git a/include/tree.h b/include/tree.h index 3ffc3bf..5d83631 100644 --- a/include/tree.h +++ b/include/tree.h @@ -16,7 +16,8 @@ enum libab_tree_variant_e { UNARY_OP, BLOCK, VOID, - IF + IF, + CALL }; /** diff --git a/src/libabacus.c b/src/libabacus.c index 3c64e91..5780095 100644 --- a/src/libabacus.c +++ b/src/libabacus.c @@ -69,6 +69,10 @@ libab_result libab_register_function(libab* ab, const char* name, libab_function result = LIBAB_MALLOC; } + if(result == LIBAB_SUCCESS) { + result = libab_convert_lex_result(eval_config_add(&ab->lexer.config, name, TOKEN_FUN)); + } + if(result == LIBAB_SUCCESS) { result = libab_table_put(&ab->table, name, new_entry); } diff --git a/src/parser.c b/src/parser.c index 3440830..b8d4d39 100644 --- a/src/parser.c +++ b/src/parser.c @@ -219,6 +219,51 @@ libab_result _parse_if(struct parser_state* state, libab_tree** store_into) { return result; } +libab_result _parse_call(struct parser_state* state, libab_tree** store_into) { + libab_result result = LIBAB_SUCCESS; + libab_tree* temp; + + if(_parser_is_type(state, TOKEN_FUN)) { + result = _parser_construct_node_both(state, state->current_match, store_into); + if(result == LIBAB_SUCCESS) { + (*store_into)->variant = CALL; + } + _parser_state_step(state); + } else { + result = LIBAB_UNEXPECTED; + } + + if(result == LIBAB_SUCCESS) { + result = _parser_consume_char(state, '('); + } + + while(result == LIBAB_SUCCESS && !_parser_eof(state) && !_parser_is_char(state, ')')) { + result = _parse_expression(state, &temp); + if(result == LIBAB_SUCCESS) { + result = libab_convert_ds_result(vec_add(&(*store_into)->children, temp)); + if(result != LIBAB_SUCCESS) { + libab_tree_free_recursive(temp); + } + } + + if(result == LIBAB_SUCCESS && !(_parser_is_char(state, ')') || _parser_is_char(state, ','))) { + result = LIBAB_UNEXPECTED; + } else if(_parser_is_char(state, ',')) { + _parser_state_step(state); + } + } + if(result == LIBAB_SUCCESS) { + result = _parser_consume_char(state, ')'); + } + + if(result != LIBAB_SUCCESS) { + libab_tree_free_recursive(*store_into); + *store_into = NULL; + } + + return result; +} + libab_result _parse_atom(struct parser_state* state, libab_tree** store_into) { libab_result result; if(_parser_is_type(state, TOKEN_NUM) || _parser_is_type(state, TOKEN_ID)) { @@ -231,6 +276,8 @@ libab_result _parse_atom(struct parser_state* state, libab_tree** store_into) { result = _parse_if(state, store_into); } else if(_parser_is_char(state, '{')) { result = _parse_block(state, store_into, 1); + } else if(_parser_is_type(state, TOKEN_FUN)) { + result = _parse_call(state, store_into); } else { result = LIBAB_UNEXPECTED; }