commit cec99cb
uint
·
2026-10-24 15:32:30 +0000 UTC
parent d3b7c08
Add eval, eval_call
1 files changed,
+53,
-12
M
expl.c
M
expl.c
+53,
-12
1@@ -197,34 +197,75 @@ value(parser* p, expl_type type)
2 static expl_value
3 eval(expl_node* n, environment** env)
4 {
5- char* end = NULL;
6+ expl_value result = { 0 };
7+ expl_value* v;
8+ char* end;
9
10 if (!n)
11- return NULL;
12+ return result;
13
14 switch (n->type) {
15 case EXPL_TYPE_STRING:
16- return n;
17+ result.type = EXPL_VALUE_STRING;
18+ result.as.string = n->value;
19+ return result;
20
21 case EXPL_TYPE_ATOM:
22- strtod(n->value, &end);
23- if (end != n->value && !*end)
24- return n;
25+ result.as.number = strtod(n->value, &end);
26+ if (end != n->value && !*end) {
27+ result.type = EXPL_VALUE_NUMBER;
28+ return result;
29+ }
30
31- return lookup(*env, n->value);
32+ v = lookup(*env, n->value);
33+ if (v)
34+ return *v;
35+ return result;
36
37 case EXPL_TYPE_LIST:
38- /* XXX */
39- return NULL;
40+ return eval_call(n, env);
41
42 default:
43- return NULL;
44+ return result;
45 }
46 }
47
48-static expl_node*
49-eval_let(expl_node* args, environment** env)
50+static expl_value
51+eval_call(expl_node* n, environment** env)
52 {
53+ expl_value result = { 0 };
54+ expl_value* fn = NULL;
55+ expl_value* argv = NULL;
56+ expl_node* arg = NULL;
57+ int argc = 0;
58+
59+ if (!n->child || n->child->type != EXPL_TYPE_ATOM)
60+ return result;
61+
62+ fn = lookup(*env, n->child->value);
63+ if (!fn || fn->type != EXPL_VALUE_FUNCTION)
64+ return result;
65+
66+ /* count args */
67+ for (arg = n->child->next; arg; arg = arg->next)
68+ argc++;
69+
70+ argv = argc ? malloc(argc * sizeof(*argv)) : NULL;
71+ if (argc && !argv)
72+ return result;
73+
74+ argc = 0;
75+ for (arg = n->child->next; arg; arg = arg->next)
76+ argv[argc++] = eval(arg, env);
77+
78+ /* call native fn if it exists */
79+ if (((function*)fn->as.function)->native)
80+ result = ((function*)fn->as.function)->native(argc, argv);
81+
82+ free(argv);
83+ return result;
84+}
85+
86 static int
87 register_native(environment** env, const char* name, expl_native fn)
88 {