From f591809d1f238a1c0edc34aa7f2a7e7d6f5d5d2a Mon Sep 17 00:00:00 2001 From: Camden Dixie O'Brien Date: Thu, 24 Oct 2024 22:28:12 +0100 Subject: [PATCH] Remove read_expression and use parse_expression directly --- app/main.c | 8 ++++-- lib/include/reader.h | 4 +-- lib/reader.c | 41 +++++++++------------------- tests/reader_tests.c | 65 +++++++++++++++++++++++++------------------- 4 files changed, 57 insertions(+), 61 deletions(-) diff --git a/app/main.c b/app/main.c index fa51531..eed3136 100644 --- a/app/main.c +++ b/app/main.c @@ -16,13 +16,15 @@ static bool step_repl(void) const int len = read_line(getchar, buffer, BUFFER_SIZE); if (len < 0) return false; - const expression_t *e = read_expression(&pool, buffer, len); - if (NULL == e) { + + expression_t *expression; + const int used = parse_expression(&pool, buffer, len, &expression); + if (used != len) { puts("Invalid expression\n"); return true; } - const int result = evaluate(e); + const int result = evaluate(expression); printf("%d\n", result); return true; diff --git a/lib/include/reader.h b/lib/include/reader.h index 5853d06..df8667d 100644 --- a/lib/include/reader.h +++ b/lib/include/reader.h @@ -5,7 +5,7 @@ int read_line(int (*get_byte)(void), char *buffer, int buffer_size); -const expression_t * -read_expression(memory_pool_t *pool, const char *input, int len); +int parse_expression( + memory_pool_t *pool, const char *input, int len, expression_t **out); #endif diff --git a/lib/reader.c b/lib/reader.c index 20cf78e..555afb2 100644 --- a/lib/reader.c +++ b/lib/reader.c @@ -1,11 +1,20 @@ #include "reader.h" #include -#include #include -static int parse_expression( - memory_pool_t *pool, const char *input, int len, expression_t **out); +int read_line(int (*get_byte)(void), char *buffer, int buffer_size) +{ + for (int len = 0; len < buffer_size; ++len) { + const int byte = get_byte(); + if (EOF == byte) + return -1; + if ('\n' == byte) + return len; + buffer[len] = (char)byte; + } + return buffer_size; +} static int parse_whitespace(const char *input, int len) { @@ -104,7 +113,7 @@ static int parse_term( return used; } -static int parse_expression( +int parse_expression( memory_pool_t *pool, const char *input, int len, expression_t **out) { int result, used = 0; @@ -152,27 +161,3 @@ static int parse_expression( *out = expr; return used; } - -int read_line(int (*get_byte)(void), char *buffer, int buffer_size) -{ - for (int len = 0; len < buffer_size; ++len) { - const int byte = get_byte(); - if (EOF == byte) - return -1; - if ('\n' == byte) - return len; - buffer[len] = (char)byte; - } - return buffer_size; -} - -const expression_t * -read_expression(memory_pool_t *pool, const char *input, int len) -{ - expression_t *expression; - const int used = parse_expression(pool, input, len, &expression); - if (used == len) - return expression; - else - return NULL; -} diff --git a/tests/reader_tests.c b/tests/reader_tests.c index 68240fe..bedaaf1 100644 --- a/tests/reader_tests.c +++ b/tests/reader_tests.c @@ -19,7 +19,8 @@ static int test_get_byte(void) static void input_1234_is_read_as_number_with_expected_value(void) { init_memory_pool(&pool); - const expression_t *result = read_expression(&pool, "1234", 4); + expression_t *result; + parse_expression(&pool, "1234", 4, &result); ASSERT_NOT_NULL(result); ASSERT_TRUE(result->is_number); ASSERT_EQUAL(1234, result->number); @@ -28,7 +29,8 @@ static void input_1234_is_read_as_number_with_expected_value(void) static void input_4321_is_read_as_number_with_expected_value(void) { init_memory_pool(&pool); - const expression_t *result = read_expression(&pool, "4321", 4); + expression_t *result; + parse_expression(&pool, "4321", 4, &result); ASSERT_NOT_NULL(result); ASSERT_TRUE(result->is_number); ASSERT_EQUAL(4321, result->number); @@ -37,7 +39,8 @@ static void input_4321_is_read_as_number_with_expected_value(void) static void input_1234_with_len_3_is_read_as_123(void) { init_memory_pool(&pool); - const expression_t *result = read_expression(&pool, "1234", 3); + expression_t *result; + parse_expression(&pool, "1234", 3, &result); ASSERT_NOT_NULL(result); ASSERT_TRUE(result->is_number); ASSERT_EQUAL(123, result->number); @@ -46,7 +49,8 @@ static void input_1234_with_len_3_is_read_as_123(void) static void input_1_plus_2_with_no_spaces_is_read_as_an_add_application(void) { init_memory_pool(&pool); - const expression_t *result = read_expression(&pool, "1+2", 3); + expression_t *result; + parse_expression(&pool, "1+2", 3, &result); ASSERT_NOT_NULL(result); ASSERT_FALSE(result->is_number); ASSERT_EQUAL(OPERATOR_ADD, result->application.operator); @@ -55,7 +59,8 @@ static void input_1_plus_2_with_no_spaces_is_read_as_an_add_application(void) static void operands_of_15_plus_54_are_read_as_numbers(void) { init_memory_pool(&pool); - const expression_t *result = read_expression(&pool, "15+54", 5); + expression_t *result; + parse_expression(&pool, "15+54", 5, &result); ASSERT_NOT_NULL(result); ASSERT_FALSE(result->is_number); ASSERT_NOT_NULL(result->application.operands[0]); @@ -70,7 +75,8 @@ static void input_6_minus_2_with_no_spaces_is_read_as_a_subtract_application(void) { init_memory_pool(&pool); - const expression_t *result = read_expression(&pool, "6-2", 3); + expression_t *result; + parse_expression(&pool, "6-2", 3, &result); ASSERT_NOT_NULL(result); ASSERT_FALSE(result->is_number); ASSERT_EQUAL(OPERATOR_SUBTRACT, result->application.operator); @@ -80,7 +86,8 @@ static void input_1_plus_2_plus_3_is_parsed_as_a_left_nested_application(void) { init_memory_pool(&pool); - const expression_t *result = read_expression(&pool, "1+2+3", 5); + expression_t *result; + parse_expression(&pool, "1+2+3", 5, &result); ASSERT_NOT_NULL(result); ASSERT_FALSE(result->is_number); ASSERT_EQUAL(OPERATOR_ADD, result->application.operator); @@ -106,7 +113,8 @@ static void input_1_times_2_times_3_is_parsed_as_a_left_nested_application(void) { init_memory_pool(&pool); - const expression_t *result = read_expression(&pool, "1*2*3", 5); + expression_t *result; + parse_expression(&pool, "1*2*3", 5, &result); ASSERT_NOT_NULL(result); ASSERT_FALSE(result->is_number); ASSERT_EQUAL(OPERATOR_MULTIPLY, result->application.operator); @@ -132,7 +140,8 @@ static void input_1_plus_2_times_3_is_parsed_as_a_right_nested_application(void) { init_memory_pool(&pool); - const expression_t *result = read_expression(&pool, "1+2*3", 5); + expression_t *result; + parse_expression(&pool, "1+2*3", 5, &result); ASSERT_NOT_NULL(result); ASSERT_FALSE(result->is_number); ASSERT_EQUAL(OPERATOR_ADD, result->application.operator); @@ -157,7 +166,8 @@ input_1_plus_2_times_3_is_parsed_as_a_right_nested_application(void) static void paren_1_plus_2_times_3_close_paren_parses_as_left_nested(void) { init_memory_pool(&pool); - const expression_t *result = read_expression(&pool, "(1+2)*3", 7); + expression_t *result; + parse_expression(&pool, "(1+2)*3", 7, &result); ASSERT_NOT_NULL(result); ASSERT_FALSE(result->is_number); ASSERT_EQUAL(OPERATOR_MULTIPLY, result->application.operator); @@ -179,24 +189,19 @@ static void paren_1_plus_2_times_3_close_paren_parses_as_left_nested(void) ASSERT_EQUAL(3, operand1->number); } -static void garbage_input_yeilds_null(void) +static void garbage_input_yeilds_error(void) { init_memory_pool(&pool); - const expression_t *result = read_expression(&pool, "arwizxhu", 8); - ASSERT_NULL(result); -} - -static void valid_expression_followed_by_garbage_yeilds_null(void) -{ - init_memory_pool(&pool); - const expression_t *result = read_expression(&pool, "5+2jvkre", 8); - ASSERT_NULL(result); + expression_t *result; + const int used = parse_expression(&pool, "arwizxhu", 8, &result); + ASSERT_EQUAL(0, used); } static void sum_with_single_spaces_around_plus_is_parsed_successfully(void) { init_memory_pool(&pool); - const expression_t *result = read_expression(&pool, "1 + 2", 5); + expression_t *result; + parse_expression(&pool, "1 + 2", 5, &result); ASSERT_NOT_NULL(result); ASSERT_FALSE(result->is_number); ASSERT_EQUAL(OPERATOR_ADD, result->application.operator); @@ -205,7 +210,8 @@ static void sum_with_single_spaces_around_plus_is_parsed_successfully(void) static void sum_with_multiple_spaces_around_plus_is_parsed_successfully(void) { init_memory_pool(&pool); - const expression_t *result = read_expression(&pool, "1 + 2", 7); + expression_t *result; + parse_expression(&pool, "1 + 2", 7, &result); ASSERT_NOT_NULL(result); ASSERT_FALSE(result->is_number); ASSERT_EQUAL(OPERATOR_ADD, result->application.operator); @@ -214,7 +220,8 @@ static void sum_with_multiple_spaces_around_plus_is_parsed_successfully(void) static void product_with_spaces_around_times_is_parsed_successfully(void) { init_memory_pool(&pool); - const expression_t *result = read_expression(&pool, "1 * 2", 6); + expression_t *result; + parse_expression(&pool, "1 * 2", 6, &result); ASSERT_NOT_NULL(result); ASSERT_FALSE(result->is_number); ASSERT_EQUAL(OPERATOR_MULTIPLY, result->application.operator); @@ -223,7 +230,8 @@ static void product_with_spaces_around_times_is_parsed_successfully(void) static void spaces_inside_parens_are_ignored(void) { init_memory_pool(&pool); - const expression_t *result = read_expression(&pool, "( 14 )", 6); + expression_t *result; + parse_expression(&pool, "( 14 )", 6, &result); ASSERT_NOT_NULL(result); ASSERT_TRUE(result->is_number); ASSERT_EQUAL(14, result->number); @@ -232,7 +240,8 @@ static void spaces_inside_parens_are_ignored(void) static void leading_spaces_are_ignored(void) { init_memory_pool(&pool); - const expression_t *result = read_expression(&pool, " 14", 5); + expression_t *result; + parse_expression(&pool, " 14", 5, &result); ASSERT_NOT_NULL(result); ASSERT_TRUE(result->is_number); ASSERT_EQUAL(14, result->number); @@ -241,7 +250,8 @@ static void leading_spaces_are_ignored(void) static void trailing_spaces_are_ignored(void) { init_memory_pool(&pool); - const expression_t *result = read_expression(&pool, "14 ", 5); + expression_t *result; + parse_expression(&pool, "14 ", 5, &result); ASSERT_NOT_NULL(result); ASSERT_TRUE(result->is_number); ASSERT_EQUAL(14, result->number); @@ -296,8 +306,7 @@ int main(void) RUN_TEST(input_1_times_2_times_3_is_parsed_as_a_left_nested_application); RUN_TEST(input_1_plus_2_times_3_is_parsed_as_a_right_nested_application); RUN_TEST(paren_1_plus_2_times_3_close_paren_parses_as_left_nested); - RUN_TEST(garbage_input_yeilds_null); - RUN_TEST(valid_expression_followed_by_garbage_yeilds_null); + RUN_TEST(garbage_input_yeilds_error); RUN_TEST(sum_with_single_spaces_around_plus_is_parsed_successfully); RUN_TEST(sum_with_multiple_spaces_around_plus_is_parsed_successfully); RUN_TEST(product_with_spaces_around_times_is_parsed_successfully);