diff --git a/lib/include/expression.h b/lib/include/expression.h index e31a448..75d6f05 100644 --- a/lib/include/expression.h +++ b/lib/include/expression.h @@ -4,10 +4,10 @@ #include typedef enum { - OPERATOR_ADD, - OPERATOR_SUBTRACT, - OPERATOR_MULTIPLY, - OPERATOR_DIVIDE, + OPERATOR_ADD = 0, + OPERATOR_SUBTRACT = 1, + OPERATOR_MULTIPLY = 2, + OPERATOR_DIVIDE = 3, } operator_t; struct _expression_t; diff --git a/lib/reader.c b/lib/reader.c index 0900f66..026f2f7 100644 --- a/lib/reader.c +++ b/lib/reader.c @@ -3,6 +3,10 @@ #include #include +static int parse_expression( + memory_pool_t *pool, const char *input, int remaining, + expression_t *out); + static int parse_number( memory_pool_t *pool, const char *input, int remaining, expression_t *out) { @@ -35,14 +39,25 @@ static int parse_application( remaining -= result; input += result; - if (remaining <= 0 || *input != '+') + if (remaining <= 0) return 0; + operator_t operator; + switch (*input) { + case '+': + operator= OPERATOR_ADD; + break; + case '-': + operator= OPERATOR_SUBTRACT; + break; + default: + return 0; + } ++used; --remaining; ++input; expression_t *operand1 = allocate_expression(pool); - result = parse_number(pool, input, remaining, operand1); + result = parse_expression(pool, input, remaining, operand1); if (0 == result) return 0; used += result; @@ -50,7 +65,7 @@ static int parse_application( input += result; out->is_number = false; - out->application.operator = OPERATOR_ADD; + out->application.operator= operator; out->application.operands[0] = operand0; out->application.operands[1] = operand1; diff --git a/tests/reader_tests.c b/tests/reader_tests.c index f20538e..344c998 100644 --- a/tests/reader_tests.c +++ b/tests/reader_tests.c @@ -39,12 +39,66 @@ static void input_1_plus_2_with_no_spaces_is_read_as_an_add_application(void) ASSERT_EQUAL(OPERATOR_ADD, result->application.operator); } +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); + ASSERT_NOT_NULL(result); + ASSERT_FALSE(result->is_number); + ASSERT_NOT_NULL(result->application.operands[0]); + ASSERT_TRUE(result->application.operands[0]->is_number); + ASSERT_EQUAL(15, result->application.operands[0]->number); + ASSERT_NOT_NULL(result->application.operands[1]); + ASSERT_TRUE(result->application.operands[1]->is_number); + ASSERT_EQUAL(54, result->application.operands[1]->number); +} + +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); + ASSERT_NOT_NULL(result); + ASSERT_FALSE(result->is_number); + ASSERT_EQUAL(OPERATOR_SUBTRACT, result->application.operator); +} + +static void +input_1_plus_2_plus_3_is_parsed_as_a_right_nested_application(void) +{ + init_memory_pool(&pool); + const expression_t *result = read_expression(&pool, "1+2+3", 5); + ASSERT_NOT_NULL(result); + ASSERT_FALSE(result->is_number); + ASSERT_EQUAL(OPERATOR_ADD, result->application.operator); + + const expression_t *operand0 = result->application.operands[0]; + ASSERT_NOT_NULL(operand0); + ASSERT_TRUE(operand0->is_number); + ASSERT_EQUAL(1, operand0->number); + + const expression_t *operand1 = result->application.operands[1]; + ASSERT_NOT_NULL(operand1); + ASSERT_FALSE(operand1->is_number); + ASSERT_EQUAL(OPERATOR_ADD, operand1->application.operator); + ASSERT_NOT_NULL(operand1->application.operands[0]); + ASSERT_TRUE(operand1->application.operands[0]->is_number); + ASSERT_EQUAL(2, operand1->application.operands[0]->number); + ASSERT_NOT_NULL(operand1->application.operands[1]); + ASSERT_TRUE(operand1->application.operands[1]->is_number); + ASSERT_EQUAL(3, operand1->application.operands[1]->number); +} + 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(operands_of_15_plus_54_are_read_as_numbers); RUN_TEST(input_1_plus_2_with_no_spaces_is_read_as_an_add_application); + RUN_TEST( + input_6_minus_2_with_no_spaces_is_read_as_a_subtract_application); + RUN_TEST(input_1_plus_2_plus_3_is_parsed_as_a_right_nested_application); TESTING_END(); }