Create basic REPL module

This commit is contained in:
2024-10-24 16:29:28 +01:00
parent 810feee55e
commit 8d5f5e4ede
5 changed files with 179 additions and 1 deletions

35
lib/include/repl.h Normal file
View File

@@ -0,0 +1,35 @@
#ifndef REPL_H
#define REPL_H
#include "memory_pool.h"
#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);
typedef int (*evaluate_fn_t)(const expression_t *expression);
typedef void (*print_fn_t)(const char *output, int len);
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];
} repl_t;
void init_repl(repl_t *repl);
void step_repl(repl_t *repl);
void run_repl(repl_t *repl);
#endif

30
lib/repl.c Normal file
View File

@@ -0,0 +1,30 @@
#include "repl.h"
#include <stdio.h>
void init_repl(repl_t *repl)
{
init_memory_pool(&repl->pool);
}
void 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)
break;
repl->line_buffer[len] = (char)byte;
}
const expression_t *e = repl->read(&repl->pool, repl->line_buffer, len);
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);
}
void run_repl(repl_t *repl)
{
while (1)
step_repl(repl);
}