/
interpreter.c
125 lines (119 loc) · 3.32 KB
/
interpreter.c
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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include <setjmp.h>
#include <assert.h>
#include <sys/types.h>
#include <limits.h>
#include <errno.h>
#include <math.h>
#ifdef BOEHM_GC
#include <gc.h>
#endif
#include "llt.h"
#include "julia.h"
static jl_value_t *eval(jl_value_t *e);
jl_value_t *jl_interpret_toplevel_expr(jl_value_t *e)
{
return eval(e);
}
static jl_value_t *do_call(jl_function_t *f, jl_value_t **args, size_t nargs)
{
jl_value_t **argv = alloca(nargs * sizeof(jl_value_t*));
size_t i;
for(i=0; i < nargs; i++)
argv[i] = eval(args[i]);
return jl_apply(f, argv, nargs);
}
static jl_value_t *eval(jl_value_t *e)
{
if (jl_is_symbol(e)) {
jl_value_t **bp = jl_get_bindingp(jl_system_module, (jl_sym_t*)e);
if (*bp == NULL)
jl_errorf("%s not defined", ((jl_sym_t*)e)->name);
return *bp;
}
if (!jl_is_expr(e))
return e;
jl_expr_t *ex = (jl_expr_t*)e;
jl_value_t **args = &jl_tupleref(ex->args,0);
if (ex->head == call_sym) {
jl_function_t *f = (jl_function_t*)eval(args[0]);
if (!jl_is_func(f))
jl_error("apply: expected function");
return do_call(f, &args[1], ex->args->length-1);
}
else if (ex->head == assign_sym) {
jl_value_t **bp = jl_get_bindingp(jl_system_module, (jl_sym_t*)args[0]);
*bp = eval(args[1]);
return (jl_value_t*)jl_null;
}
else if (ex->head == top_sym) {
// we only do toplevel bindings
return eval(args[0]);
}
else if (ex->head == unbound_sym) {
jl_value_t **bp = jl_get_bindingp(jl_system_module, (jl_sym_t*)args[0]);
if (*bp == NULL)
return jl_true;
return jl_false;
}
else if (ex->head == quote_sym) {
return args[0];
}
else if (ex->head == null_sym) {
return (jl_value_t*)jl_null;
}
jl_error("not supported");
return (jl_value_t*)jl_null;
}
static int label_idx(jl_value_t *tgt, jl_tuple_t *stmts)
{
size_t j;
for(j=0; j < stmts->length; j++) {
jl_value_t *l = jl_tupleref(stmts,j);
if (jl_is_expr(l) && ((jl_expr_t*)l)->head==label_sym &&
jl_exprarg(l,0)==tgt)
break;
}
assert(j < stmts->length);
return j;
}
jl_value_t *jl_interpret_toplevel_thunk(jl_lambda_info_t *lam)
{
jl_expr_t *ast = (jl_expr_t*)lam->ast;
jl_tuple_t *stmts = jl_lam_body(ast);
size_t i=0;
while (1) {
jl_value_t *stmt = jl_tupleref(stmts,i);
if (jl_is_expr(stmt)) {
jl_sym_t *head = ((jl_expr_t*)stmt)->head;
if (head == label_sym) {
}
else if (head == goto_sym) {
i = label_idx(jl_exprarg(stmt,0), stmts);
continue;
}
else if (head == goto_ifnot_sym) {
jl_value_t *cond = eval(jl_exprarg(stmt,0));
if (cond == jl_false) {
i = label_idx(jl_exprarg(stmt,1), stmts);
continue;
}
}
else if (head == return_sym) {
return eval(jl_exprarg(stmt,0));
}
else {
eval(stmt);
}
}
else {
eval(stmt);
}
i++;
}
assert(0);
return (jl_value_t*)jl_null;
}