From 8ba4035afcc05080c7fec31b44e9da846b19b673 Mon Sep 17 00:00:00 2001 From: Camden Dixie O'Brien Date: Thu, 24 Oct 2024 14:39:44 +0100 Subject: [PATCH] Add basic sum parsing --- lib/reader.c | 79 ++++++++++++++++++++++++++++++++++++++------ tests/reader_tests.c | 20 +++++++++++ 2 files changed, 88 insertions(+), 11 deletions(-) diff --git a/lib/reader.c b/lib/reader.c index 9a2e20d..0900f66 100644 --- a/lib/reader.c +++ b/lib/reader.c @@ -3,19 +3,76 @@ #include #include +static int parse_number( + memory_pool_t *pool, const char *input, int remaining, expression_t *out) +{ + (void)pool; + + int value = 0, used = 0; + while (remaining > 0 && isdigit(*input)) { + value *= 10; + value += *input - '0'; + ++used; + --remaining; + ++input; + } + + out->is_number = true; + out->number = value; + return used; +} + +static int parse_application( + memory_pool_t *pool, const char *input, int remaining, expression_t *out) +{ + int result, used = 0; + + expression_t *operand0 = allocate_expression(pool); + result = parse_number(pool, input, remaining, operand0); + if (0 == result) + return 0; + used += result; + remaining -= result; + input += result; + + if (remaining <= 0 || *input != '+') + return 0; + ++used; + --remaining; + ++input; + + expression_t *operand1 = allocate_expression(pool); + result = parse_number(pool, input, remaining, operand1); + if (0 == result) + return 0; + used += result; + remaining -= result; + input += result; + + out->is_number = false; + out->application.operator = OPERATOR_ADD; + out->application.operands[0] = operand0; + out->application.operands[1] = operand1; + + return used; +} + +static int parse_expression( + memory_pool_t *pool, const char *input, int remaining, expression_t *out) +{ + int result = parse_application(pool, input, remaining, out); + if (0 != result) + return result; + else + return parse_number(pool, input, remaining, out); +} + const expression_t * read_expression(memory_pool_t *pool, const char *input, int len) { - expression_t *result = allocate_expression(pool); - if (NULL == result) + expression_t *expression = allocate_expression(pool); + if (NULL == expression) return NULL; - result->is_number = true; - result->number = 0; - while (isdigit(*input)) { - result->number *= 10; - result->number += *input - '0'; - ++input; - ++len; - } - return result; + parse_expression(pool, input, len, expression); + return expression; } diff --git a/tests/reader_tests.c b/tests/reader_tests.c index f50c091..f20538e 100644 --- a/tests/reader_tests.c +++ b/tests/reader_tests.c @@ -21,10 +21,30 @@ static void input_4321_is_read_as_number_with_expected_value(void) ASSERT_EQUAL(4321, result->number); } +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); + ASSERT_NOT_NULL(result); + ASSERT_TRUE(result->is_number); + ASSERT_EQUAL(123, result->number); +} + +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); + ASSERT_NOT_NULL(result); + ASSERT_FALSE(result->is_number); + ASSERT_EQUAL(OPERATOR_ADD, result->application.operator); +} + int main(void) { TESTING_BEGIN(); RUN_TEST(input_1234_is_read_as_number_with_expected_value); RUN_TEST(input_4321_is_read_as_number_with_expected_value); + RUN_TEST(input_1234_with_len_3_is_read_as_123); + RUN_TEST(input_1_plus_2_with_no_spaces_is_read_as_an_add_application); TESTING_END(); }