Remove read_expression and use parse_expression directly
This commit is contained in:
parent
b44bd100ca
commit
f591809d1f
@ -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;
|
||||
|
@ -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
|
||||
|
41
lib/reader.c
41
lib/reader.c
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user