From ac8e2ff4186975666527b78c98dc4959a30ec17d Mon Sep 17 00:00:00 2001 From: Danila Fedorin Date: Tue, 27 Feb 2018 12:30:37 -0800 Subject: [PATCH] Implement the do-while loop. --- include/lexer.h | 1 + include/tree.h | 1 + src/debug.c | 1 + src/lexer.c | 2 ++ src/parser.c | 40 ++++++++++++++++++++++++++++++++++++++++ src/tree.c | 3 ++- 6 files changed, 47 insertions(+), 1 deletion(-) diff --git a/include/lexer.h b/include/lexer.h index 2c3437f..1c667e6 100644 --- a/include/lexer.h +++ b/include/lexer.h @@ -61,6 +61,7 @@ enum libab_lexer_token_e { TOKEN_KW_IF, TOKEN_KW_ELSE, TOKEN_KW_WHILE, + TOKEN_KW_DO, TOKEN_LAST }; diff --git a/include/tree.h b/include/tree.h index addd379..8a5f744 100644 --- a/include/tree.h +++ b/include/tree.h @@ -18,6 +18,7 @@ enum libab_tree_variant_e { VOID, IF, WHILE, + DOWHILE, CALL }; diff --git a/src/debug.c b/src/debug.c index 8532db4..028023e 100644 --- a/src/debug.c +++ b/src/debug.c @@ -14,6 +14,7 @@ const char* _debug_node_name(libab_tree_variant var) { "void", "if", "while", + "dowhile", "call" }; return names[var]; diff --git a/src/lexer.c b/src/lexer.c index 7f65373..d479e58 100644 --- a/src/lexer.c +++ b/src/lexer.c @@ -14,6 +14,7 @@ libab_result libab_lexer_init(libab_lexer* lexer) { "if", "else", "while", + "do" }; libab_lexer_token tokens[] = { TOKEN_CHAR, @@ -22,6 +23,7 @@ libab_result libab_lexer_init(libab_lexer* lexer) { TOKEN_KW_IF, TOKEN_KW_ELSE, TOKEN_KW_WHILE, + TOKEN_KW_DO }; const size_t count = sizeof(tokens)/sizeof(libab_lexer_token); diff --git a/src/parser.c b/src/parser.c index a1a1ccf..fd8d7ca 100644 --- a/src/parser.c +++ b/src/parser.c @@ -266,6 +266,44 @@ libab_result _parse_while(struct parser_state* state, libab_tree** store_into) { return result; } +libab_result _parse_dowhile(struct parser_state* state, libab_tree** store_into) { + libab_result result = LIBAB_SUCCESS; + libab_tree* value = NULL; + libab_tree* condition = NULL; + + if(_parser_is_type(state, TOKEN_KW_DO)) { + result = _parser_construct_node_vec(state->current_match, store_into); + if(result == LIBAB_SUCCESS) { + (*store_into)->variant = DOWHILE; + _parser_state_step(state); + } + } else { + result = LIBAB_UNEXPECTED; + } + + if(result == LIBAB_SUCCESS) { + PARSE_CHILD(result, state, _parse_expression, value, &(*store_into)->children); + } + + if(result == LIBAB_SUCCESS) { + result = _parser_consume_type(state, TOKEN_KW_WHILE); + } + + 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, ')'); + } + + return result; +} + libab_result _parse_call(struct parser_state* state, libab_tree** store_into) { libab_result result = LIBAB_SUCCESS; libab_tree* temp; @@ -326,6 +364,8 @@ libab_result _parse_atom(struct parser_state* state, libab_tree** store_into) { 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_type(state, TOKEN_KW_DO)) { + result = _parse_dowhile(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 e4bdbd1..df3c114 100644 --- a/src/tree.c +++ b/src/tree.c @@ -4,7 +4,8 @@ int libab_tree_has_vector(libab_tree_variant variant) { return variant == BASE || variant == OP || variant == UNARY_OP || variant == BLOCK || - variant == IF || variant == CALL || variant == WHILE; + variant == IF || variant == CALL || variant == WHILE || + variant == DOWHILE; } int libab_tree_has_string(libab_tree_variant variant) {