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 {