Add basic EOF handling to REPL

This commit is contained in:
Camden Dixie O'Brien 2024-10-24 19:49:18 +01:00
parent 5ea066b75e
commit b491a1a782
3 changed files with 26 additions and 11 deletions

View File

@ -6,12 +6,6 @@
#define REPL_LINE_BUFFER_SIZE 128
#define REPL_RESULT_BUFFER_SIZE 128
typedef enum {
REPL_OK,
REPL_ERROR,
REPL_EXIT,
} repl_status_t;
typedef int (*get_byte_fn_t)(void);
typedef const expression_t *(*read_fn_t)(
memory_pool_t *pool, const char *input, int len);
@ -29,7 +23,7 @@ typedef struct {
} repl_t;
void init_repl(repl_t *repl);
void step_repl(repl_t *repl);
bool step_repl(repl_t *repl);
void run_repl(repl_t *repl);
#endif

View File

@ -7,12 +7,14 @@ void init_repl(repl_t *repl)
init_memory_pool(&repl->pool);
}
void step_repl(repl_t *repl)
bool step_repl(repl_t *repl)
{
int len;
for (len = 0; len < REPL_LINE_BUFFER_SIZE; ++len) {
const int byte = repl->get_byte();
if ('\n' == byte)
if (EOF == byte)
return false;
else if ('\n' == byte)
break;
repl->line_buffer[len] = (char)byte;
}
@ -21,10 +23,12 @@ void step_repl(repl_t *repl)
const int result_len = snprintf(
repl->result_buffer, REPL_RESULT_BUFFER_SIZE, "%d\n", result);
repl->print(repl->result_buffer, result_len);
return true;
}
void run_repl(repl_t *repl)
{
while (1)
step_repl(repl);
while (step_repl(repl))
;
}

View File

@ -97,11 +97,28 @@ static void result_of_evaluation_is_printed_with_a_newline(void)
ASSERT_MEM_EQUAL("4321\n", print_output, 5);
}
static void true_is_returned_on_successful_step(void)
{
set_up_valid_state();
const bool result = step_repl(&repl);
ASSERT_TRUE(result);
}
static void false_is_returned_on_end_of_input(void)
{
set_up_valid_state();
input_len = 0;
const bool result = step_repl(&repl);
ASSERT_FALSE(result);
}
int main(void)
{
TESTING_BEGIN();
RUN_TEST(read_is_called_on_first_line_line_in_input);
RUN_TEST(read_result_is_passed_to_evaluate);
RUN_TEST(result_of_evaluation_is_printed_with_a_newline);
RUN_TEST(true_is_returned_on_successful_step);
RUN_TEST(false_is_returned_on_end_of_input);
TESTING_END();
}