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
|
#include "env.h"
#include "ctx.h"
#include "eval.h"
static void init_result(lsp_env_t *e) {
e->result.is_value = true;
e->result.ctx = e->m->nil;
e->result.value = e->m->nil;
}
static void release_result(lsp_env_t *e) {
lsp_mem_dec_ref(e->m, e->result.ctx);
lsp_mem_dec_ref(e->m, e->result.value);
init_result(e);
}
void lsp_env_init(lsp_env_t *e, lsp_mem_t *m, lsp_in_stream_t *in,
lsp_out_stream_t *out) {
e->m = m;
e->in = in;
e->out = out;
init_result(e);
}
lsp_status_t lsp_env_set_result_value(lsp_env_t *e, lsp_addr_t value) {
release_result(e);
lsp_status_t status = lsp_mem_inc_ref(e->m, value);
if (status != LSP_SUCCESS)
return status;
e->result.is_value = true;
e->result.value = value;
return LSP_SUCCESS;
}
lsp_status_t lsp_env_set_result_eval(lsp_env_t *e, lsp_addr_t ctx,
lsp_addr_t value) {
release_result(e);
lsp_status_t status = lsp_mem_inc_ref(e->m, ctx);
if (status != LSP_SUCCESS)
return status;
status = lsp_mem_inc_ref(e->m, value);
if (status != LSP_SUCCESS) {
lsp_mem_dec_ref(e->m, ctx);
return status;
}
e->result.is_value = false;
e->result.ctx = ctx;
e->result.value = value;
return LSP_SUCCESS;
}
lsp_status_t lsp_env_resolve(lsp_env_t *e, lsp_addr_t ctx, lsp_addr_t value,
lsp_addr_t *result) {
lsp_status_t status = lsp_env_set_result_eval(e, ctx, value);
if (status != LSP_SUCCESS)
return status;
while (!e->result.is_value) {
lsp_addr_t eval_ctx = e->result.ctx;
lsp_addr_t eval_value = e->result.value;
init_result(e);
status = lsp_eval(e, eval_ctx, eval_value);
lsp_mem_dec_ref(e->m, eval_ctx);
lsp_mem_dec_ref(e->m, eval_value);
if (status != LSP_SUCCESS)
return status;
}
*result = e->result.value;
init_result(e);
return LSP_SUCCESS;
}
|