Extract line reading logic to reader and remove REPL tests
Reading a line into the buffer was the only logic complex enough to be worth testing really, and exposing the necessary parts of it to test it effectively was a pain. Makes more sense to move read_line out and throw away most of the tests.
This commit is contained in:
@@ -3,6 +3,8 @@
|
||||
|
||||
#include "memory_pool.h"
|
||||
|
||||
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);
|
||||
|
||||
|
||||
@@ -3,23 +3,11 @@
|
||||
|
||||
#include "memory_pool.h"
|
||||
|
||||
#define REPL_LINE_BUFFER_SIZE 128
|
||||
#define REPL_RESULT_BUFFER_SIZE 128
|
||||
|
||||
typedef int (*get_byte_fn_t)(void);
|
||||
typedef const expression_t *(*read_fn_t)(
|
||||
memory_pool_t *pool, const char *input, int len);
|
||||
typedef int (*evaluate_fn_t)(const expression_t *expression);
|
||||
typedef void (*print_fn_t)(const char *output, int len);
|
||||
#define REPL_BUFFER_SIZE 128
|
||||
|
||||
typedef struct {
|
||||
get_byte_fn_t get_byte;
|
||||
read_fn_t read;
|
||||
evaluate_fn_t evaluate;
|
||||
print_fn_t print;
|
||||
memory_pool_t pool;
|
||||
char line_buffer[REPL_LINE_BUFFER_SIZE];
|
||||
char result_buffer[REPL_RESULT_BUFFER_SIZE];
|
||||
char buffer[REPL_BUFFER_SIZE];
|
||||
} repl_t;
|
||||
|
||||
bool step_repl(repl_t *repl);
|
||||
|
||||
14
lib/reader.c
14
lib/reader.c
@@ -2,6 +2,7 @@
|
||||
|
||||
#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);
|
||||
@@ -152,6 +153,19 @@ static int parse_expression(
|
||||
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)
|
||||
{
|
||||
|
||||
26
lib/repl.c
26
lib/repl.c
@@ -1,5 +1,8 @@
|
||||
#include "repl.h"
|
||||
|
||||
#include "evaluator.h"
|
||||
#include "reader.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
@@ -7,26 +10,17 @@ bool step_repl(repl_t *repl)
|
||||
{
|
||||
init_memory_pool(&repl->pool);
|
||||
|
||||
int len;
|
||||
for (len = 0; len < REPL_LINE_BUFFER_SIZE; ++len) {
|
||||
const int byte = repl->get_byte();
|
||||
if (EOF == byte)
|
||||
return false;
|
||||
else if ('\n' == byte)
|
||||
break;
|
||||
repl->line_buffer[len] = (char)byte;
|
||||
}
|
||||
const expression_t *e = repl->read(&repl->pool, repl->line_buffer, len);
|
||||
const int len = read_line(getchar, repl->buffer, REPL_BUFFER_SIZE);
|
||||
if (len < 0)
|
||||
return false;
|
||||
const expression_t *e = read_expression(&repl->pool, repl->buffer, len);
|
||||
if (NULL == e) {
|
||||
const char *msg = "Invalid expression\n";
|
||||
repl->print(msg, strlen(msg));
|
||||
puts("Invalid expression\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
const int result = repl->evaluate(e);
|
||||
const int result_len = snprintf(
|
||||
repl->result_buffer, REPL_RESULT_BUFFER_SIZE, "%d\n", result);
|
||||
repl->print(repl->result_buffer, result_len);
|
||||
const int result = evaluate(e);
|
||||
printf("%d\n", result);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user