]> git.lizzy.rs Git - nothing.git/blob - src/script/scope.c
(#328) Make scope more typesafe
[nothing.git] / src / script / scope.c
1 #include "./scope.h"
2
3 static struct Expr get_scope_value_impl(struct Expr scope, struct Expr name)
4 {
5     if (cons_p(scope)) {
6         struct Expr value = assoc(name, scope.cons->car);
7         return nil_p(value) ? get_scope_value_impl(scope.cons->cdr, name) : value;
8     }
9
10     return scope;
11 }
12
13 struct Expr get_scope_value(const struct Scope *scope, struct Expr name)
14 {
15     return get_scope_value_impl(scope->expr, name);
16 }
17
18 static struct Expr set_scope_value_impl(Gc *gc, struct Expr scope, struct Expr name, struct Expr value)
19 {
20     if (cons_p(scope)) {
21         if (!nil_p(assoc(name, scope.cons->car)) || nil_p(scope.cons->cdr)) {
22             return CONS(gc,
23                         CONS(gc, CONS(gc, name, value), scope.cons->car),
24                         scope.cons->cdr);
25         } else {
26             return CONS(gc,
27                         scope.cons->car,
28                         set_scope_value_impl(gc, scope.cons->cdr, name, value));
29         }
30     } else {
31         return CONS(gc,
32                     CONS(gc, CONS(gc, name, value), NIL(gc)),
33                     scope);
34     }
35 }
36
37 void set_scope_value(Gc *gc, struct Scope *scope, struct Expr name, struct Expr value)
38 {
39     scope->expr = set_scope_value_impl(gc, scope->expr, name, value);
40 }