diff options
Diffstat (limited to 'src_c/repl.c')
| -rw-r--r-- | src_c/repl.c | 104 |
1 files changed, 104 insertions, 0 deletions
diff --git a/src_c/repl.c b/src_c/repl.c new file mode 100644 index 0000000..6563613 --- /dev/null +++ b/src_c/repl.c @@ -0,0 +1,104 @@ +#include "repl.h" +#include "ctx.h" +#include "write.h" +#include "read.h" +#include "eval.h" + + +static void log_status(lsp_out_stream_t *s, lsp_status_t status) { + if (status == LSP_SUCCESS) + return; + + lsp_out_stream_write_str(s, "error: "); + + if (status == LSP_ERR_MEM) { + lsp_out_stream_write_str(s, "no memory"); + + } else if (status == LSP_ERR_CTX) { + lsp_out_stream_write_str(s, "can't resolve symbol"); + + } else if (status == LSP_ERR_READ) { + lsp_out_stream_write_str(s, "reader error"); + + } else if (status == LSP_ERR_WRITE) { + lsp_out_stream_write_str(s, "writer error"); + + } else if (status == LSP_ERR_EVAL) { + lsp_out_stream_write_str(s, "evaluation error"); + + } else if (status == LSP_ERR_APPLY) { + lsp_out_stream_write_str(s, "application error"); + + } else if (status == LSP_ERR_ARG_COUNT) { + lsp_out_stream_write_str(s, "invalid argument count"); + + } else if (status == LSP_ERR_ARG_TYPE) { + lsp_out_stream_write_str(s, "invalid argument type"); + + } else if (status == LSP_ERR_ARG_VALUE) { + lsp_out_stream_write_str(s, "invalid argument value"); + + } else if (status >= LSP_ERR_USER) { + lsp_out_stream_write_str(s, "user error "); + lsp_out_stream_write_int(s, status - LSP_ERR_USER); + + } else { + lsp_out_stream_write_str(s, "other error"); + } + + lsp_out_stream_write(s, '\n'); +} + + +static lsp_status_t skip_line(lsp_in_stream_t *s) { + lsp_uint8_t c; + lsp_status_t status; + + do { + status = lsp_in_stream_read(s, &c); + } while (status == LSP_SUCCESS && c != '\n'); + + return status; +} + + +lsp_status_t lsp_repl(lsp_env_t *e, lsp_addr_t ctx) { + while (true) { + lsp_addr_t value; + lsp_status_t status = lsp_read(e->m, e->in, &value); + if (status == LSP_EOF) + return status; + if (status != LSP_SUCCESS) { + log_status(e->out, status); + + status = skip_line(e->in); + if (status != LSP_SUCCESS) + return status; + + continue; + } + + lsp_addr_t result; + status = lsp_env_resolve(e, ctx, value, &result); + lsp_mem_dec_ref(e->m, value); + if (status == LSP_EOF) + return status; + if (status != LSP_SUCCESS) { + log_status(e->out, status); + continue; + } + + if (result == e->m->nil) + continue; + + status = lsp_write(e->m, e->out, result); + lsp_mem_dec_ref(e->m, result); + if (status == LSP_EOF) + return status; + if (status != LSP_SUCCESS) { + log_status(e->out, status); + continue; + } + lsp_out_stream_write(e->out, '\n'); + } +} |
