Make blocks expressions, and add implicit void expression at block ends.

This commit is contained in:
Danila Fedorin 2018-02-18 21:05:06 -08:00
parent 987027c4fc
commit 8ffcbb0ee2
2 changed files with 23 additions and 18 deletions

View File

@ -15,6 +15,7 @@ enum libab_tree_variant_e {
OP, OP,
UNARY_OP, UNARY_OP,
BLOCK, BLOCK,
VOID,
IF IF
}; };

View File

@ -110,6 +110,8 @@ libab_result _parse_atom(struct parser_state* state, libab_tree** store_into) {
(*store_into)->variant = (state->current_match->type == TOKEN_NUM) ? NUM : ID; (*store_into)->variant = (state->current_match->type == TOKEN_NUM) ? NUM : ID;
} }
_parser_state_step(state); _parser_state_step(state);
} else if(_parser_is_char(state, '{')) {
result = _parse_block(state, store_into, 1);
} else { } else {
result = LIBAB_UNEXPECTED; result = LIBAB_UNEXPECTED;
} }
@ -273,8 +275,8 @@ libab_result _parse_expression(struct parser_state* state, libab_tree** store_in
while(result == LIBAB_SUCCESS && !_parser_eof(state)) { while(result == LIBAB_SUCCESS && !_parser_eof(state)) {
enum parser_expression_type new_type = EXPR_NONE; enum parser_expression_type new_type = EXPR_NONE;
libab_lexer_match* new_token = state->current_match; libab_lexer_match* new_token = state->current_match;
if(_parser_is_type(state, TOKEN_CHAR)) {
char current_char = state->string[new_token->from]; char current_char = state->string[new_token->from];
if(_parser_is_type(state, TOKEN_CHAR) && current_char != '{') {
if(current_char == '(') { if(current_char == '(') {
result = libab_convert_ds_result(ll_append(&op_stack, new_token)); result = libab_convert_ds_result(ll_append(&op_stack, new_token));
if(result != LIBAB_SUCCESS) break; if(result != LIBAB_SUCCESS) break;
@ -348,21 +350,7 @@ libab_result _parse_expression(struct parser_state* state, libab_tree** store_in
ll_free(&op_stack); ll_free(&op_stack);
ll_foreach(&out_stack, NULL, compare_always, _parser_foreach_free_tree); ll_foreach(&out_stack, NULL, compare_always, _parser_foreach_free_tree);
ll_free(&out_stack);
return result;
}
libab_result _parse_statement(struct parser_state* state, libab_tree** store_into) {
libab_result result = LIBAB_SUCCESS;
if(_parser_is_char(state, '{')) result = _parse_block(state, store_into, 1);
else if(_parser_is_type(state, TOKEN_ID) ||
_parser_is_type(state, TOKEN_NUM) ||
_parser_is_char(state, '(') ||
_parser_is_type(state, TOKEN_OP_PREFIX)) {
result = _parse_expression(state, store_into);
if(result == LIBAB_SUCCESS) result = _parser_consume_char(state, ';');
}
return result; return result;
} }
@ -389,13 +377,29 @@ libab_result _parse_block(struct parser_state* state,
while(result == LIBAB_SUCCESS && while(result == LIBAB_SUCCESS &&
!_parser_eof(state) && !_parser_eof(state) &&
!(expect_braces && _parser_is_char(state, '}'))) { !(expect_braces && _parser_is_char(state, '}'))) {
result = _parse_statement(state, &temp); result = _parse_expression(state, &temp);
if(result == LIBAB_SUCCESS) { if(result == LIBAB_SUCCESS) {
result = libab_convert_ds_result(vec_add(&(*store_into)->children, temp)); result = libab_convert_ds_result(vec_add(&(*store_into)->children, temp));
if(result != LIBAB_SUCCESS) { if(result != LIBAB_SUCCESS) {
libab_tree_free_recursive(temp); libab_tree_free_recursive(temp);
} }
} }
if(_parser_is_char(state, ';')) {
temp = NULL;
_parser_state_step(state);
}
}
if(result == LIBAB_SUCCESS && temp == NULL) {
if((temp = malloc(sizeof(*temp)))) {
temp->variant = VOID;
result = libab_convert_ds_result(vec_add(&(*store_into)->children, temp));
if(result != LIBAB_SUCCESS) {
free(temp);
}
} else {
result = LIBAB_MALLOC;
}
} }
if(expect_braces && result == LIBAB_SUCCESS) result = _parser_consume_char(state, '}'); if(expect_braces && result == LIBAB_SUCCESS) result = _parser_consume_char(state, '}');