]> git.lizzy.rs Git - nothing.git/blob - src/script/interpreter.c
(#311) Implement eval_args
[nothing.git] / src / script / interpreter.c
1 #include <assert.h>
2 #include <math.h>
3 #include <string.h>
4
5 #include "./expr.h"
6 #include "./interpreter.h"
7
8 struct EvalResult eval_success(struct Expr expr)
9 {
10     struct EvalResult result = {
11         .is_error = false,
12         .expr = expr,
13         .error = NULL
14     };
15
16     return result;
17 }
18
19 struct EvalResult eval_failure(const char *error, struct Expr expr)
20 {
21     struct EvalResult result = {
22         .is_error = true,
23         .error = error,
24         .expr = expr
25     };
26
27     return result;
28 }
29
30 static struct EvalResult eval_atom(struct Expr scope, struct Atom *atom)
31 {
32     /* TODO: eval_atom is not implemented */
33     assert(atom);
34     (void) scope;
35     return eval_failure("not implemented", void_expr());
36 }
37
38 static struct EvalResult eval_args(struct Expr scope, struct Expr args)
39 {
40     (void) scope;
41     (void) args;
42
43     switch(args.type) {
44     case EXPR_ATOM:
45         return eval_atom(scope, args.atom);
46
47     case EXPR_CONS: {
48         struct EvalResult car = eval(scope, args.cons->car);
49         if (car.is_error) {
50             return car;
51         }
52
53         struct EvalResult cdr = eval_args(scope, args.cons->cdr);
54         if (cdr.is_error) {
55             return cdr;
56         }
57
58         /* TODO: memory leak */
59         return eval_success(cons_as_expr(create_cons(car.expr, cdr.expr)));
60     }
61
62     default: {}
63     }
64
65     return eval_failure("Unexpected expression", args);
66 }
67
68 static struct EvalResult plus_op(struct Expr scope, struct Expr args)
69 {
70     (void) scope;
71     (void) args;
72     /* TODO: plus_op is not implemented*/
73     return eval_failure("not implemnted", void_expr());
74 }
75
76 static struct EvalResult eval_funcall(struct Expr scope, struct Cons *cons)
77 {
78     assert(cons);
79     (void) scope;
80
81     if (cons->car.type != EXPR_ATOM && cons->car.atom->type != ATOM_SYMBOL) {
82         return eval_failure("Not a function", cons->car);
83     }
84
85     if (strcmp(cons->car.atom->sym, "+")) {
86         struct EvalResult args = eval_args(scope, cons->cdr);
87         if (args.is_error) {
88             return args;
89         }
90         return plus_op(scope, args.expr);
91     }
92
93     return eval_failure("Unknown function", cons->car);
94 }
95
96 struct EvalResult eval(struct Expr scope, struct Expr expr)
97 {
98     switch(expr.type) {
99     case EXPR_ATOM:
100         return eval_atom(scope, expr.atom);
101
102     case EXPR_CONS:
103         return eval_funcall(scope, expr.cons);
104
105     default: {}
106     }
107
108     return eval_failure("Unexpected expression", expr);
109 }