Remove read_expression and use parse_expression directly

This commit is contained in:
Camden Dixie O'Brien 2024-10-24 22:28:12 +01:00
parent b44bd100ca
commit f591809d1f
4 changed files with 57 additions and 61 deletions

View File

@ -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;

View File

@ -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

View File

@ -1,11 +1,20 @@
#include "reader.h"
#include <ctype.h>
#include <stddef.h>
#include <stdio.h>
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;
}

View File

@ -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);