From 976b6d1b1a078bc3232a73ff8eead13a8a213484 Mon Sep 17 00:00:00 2001 From: Danila Fedorin Date: Tue, 27 Feb 2018 11:57:45 -0800 Subject: [PATCH] Add code to parse while loops. --- include/lexer.h | 1 + include/tree.h | 1 + src/debug.c | 1 + src/lexer.c | 4 +++- src/parser.c | 41 +++++++++++++++++++++++++++++++++++++++++ src/tree.c | 2 +- 6 files changed, 48 insertions(+), 2 deletions(-) diff --git a/include/lexer.h b/include/lexer.h index 0ebc1b1..2c3437f 100644 --- a/include/lexer.h +++ b/include/lexer.h @@ -60,6 +60,7 @@ enum libab_lexer_token_e { TOKEN_OP_POSTFIX, TOKEN_KW_IF, TOKEN_KW_ELSE, + TOKEN_KW_WHILE, TOKEN_LAST }; diff --git a/include/tree.h b/include/tree.h index fd30fc4..addd379 100644 --- a/include/tree.h +++ b/include/tree.h @@ -17,6 +17,7 @@ enum libab_tree_variant_e { BLOCK, VOID, IF, + WHILE, CALL }; diff --git a/src/debug.c b/src/debug.c index c3038b2..8532db4 100644 --- a/src/debug.c +++ b/src/debug.c @@ -13,6 +13,7 @@ const char* _debug_node_name(libab_tree_variant var) { "block", "void", "if", + "while", "call" }; return names[var]; diff --git a/src/lexer.c b/src/lexer.c index 5b6596b..7f65373 100644 --- a/src/lexer.c +++ b/src/lexer.c @@ -12,7 +12,8 @@ libab_result libab_lexer_init(libab_lexer* lexer) { "[a-zA-Z][a-zA-Z0-9_]*", "[0-9]+(\\.[0-9]*)?", "if", - "else" + "else", + "while", }; libab_lexer_token tokens[] = { TOKEN_CHAR, @@ -20,6 +21,7 @@ libab_result libab_lexer_init(libab_lexer* lexer) { TOKEN_NUM, TOKEN_KW_IF, TOKEN_KW_ELSE, + TOKEN_KW_WHILE, }; const size_t count = sizeof(tokens)/sizeof(libab_lexer_token); diff --git a/src/parser.c b/src/parser.c index 2dbfb2a..a1a1ccf 100644 --- a/src/parser.c +++ b/src/parser.c @@ -227,6 +227,45 @@ libab_result _parse_if(struct parser_state* state, libab_tree** store_into) { return result; } +libab_result _parse_while(struct parser_state* state, libab_tree** store_into) { + libab_result result = LIBAB_SUCCESS; + libab_tree* condition = NULL; + libab_tree* value = NULL; + + if(_parser_is_type(state, TOKEN_KW_WHILE)) { + result = _parser_construct_node_vec(state->current_match, store_into); + if(result == LIBAB_SUCCESS) { + (*store_into)->variant = WHILE; + _parser_state_step(state); + } + } else { + result = LIBAB_UNEXPECTED; + } + + if(result == LIBAB_SUCCESS) { + result = _parser_consume_char(state, '('); + } + + if(result == LIBAB_SUCCESS) { + PARSE_CHILD(result, state, _parse_expression, condition, &(*store_into)->children); + } + + if(result == LIBAB_SUCCESS) { + result = _parser_consume_char(state, ')'); + } + + if(result == LIBAB_SUCCESS) { + PARSE_CHILD(result, state, _parse_expression, value, &(*store_into)->children); + } + + if(result != LIBAB_SUCCESS) { + if(*store_into) libab_tree_free_recursive(*store_into); + *store_into = NULL; + } + + return result; +} + libab_result _parse_call(struct parser_state* state, libab_tree** store_into) { libab_result result = LIBAB_SUCCESS; libab_tree* temp; @@ -285,6 +324,8 @@ libab_result _parse_atom(struct parser_state* state, libab_tree** store_into) { _parser_state_step(state); } else if(_parser_is_type(state, TOKEN_KW_IF)) { result = _parse_if(state, store_into); + } else if(_parser_is_type(state, TOKEN_KW_WHILE)) { + result = _parse_while(state, store_into); } else if(_parser_is_char(state, '{')) { result = _parse_block(state, store_into, 1); } else { diff --git a/src/tree.c b/src/tree.c index 99c447e..e4bdbd1 100644 --- a/src/tree.c +++ b/src/tree.c @@ -4,7 +4,7 @@ int libab_tree_has_vector(libab_tree_variant variant) { return variant == BASE || variant == OP || variant == UNARY_OP || variant == BLOCK || - variant == IF || variant == CALL; + variant == IF || variant == CALL || variant == WHILE; } int libab_tree_has_string(libab_tree_variant variant) {