1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
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');
}
}
|