-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy patheval.c
More file actions
86 lines (80 loc) · 2.32 KB
/
Copy patheval.c
File metadata and controls
86 lines (80 loc) · 2.32 KB
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
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "common_types.h"
#include "environment.h"
#include "operators.h"
#include "eval.h"
lval* eval_lval(env* e, lval* v){
if (v->type == LVAL_LIST){
if (v->list == NULL){
return copy_lval(e, v);
}
list* lc = copy_list(e, v->list);
lval* resp = eval(e, lc);
list_del(lc);
return resp;
}
if (v->type == LVAL_SYM){
return copy_lval(e, get_val(e, v->sym));
}
return copy_lval(e,v);
}
lval* eval(env* e, list* l){
if ( l == NULL ){
return lval_err("EVAL:Evaluating empty list");
}
if (l->expr == NULL){
return lval_err("EVAL: Operator expression NULL");
}
lval* first_expr = eval_lval(e, l->expr);
if (first_expr->type == LVAL_FUNC ){
lval* fn_resp = eval_func(e, l);
return fn_resp;
} if(first_expr->type == LVAL_LAMBDA){
lval* lmd_resp = eval_lambda(e, l);
return lmd_resp;
}
if (l->next == NULL){
return copy_lval(e, eval_lval(e, first_expr));
}
return lval_list(copy_list(e, l));
}
lval* eval_lambda(env* e, list * l){
lval* func_lval = eval_lval(e, l->expr);
list* operands = l->next;
// create fn env, with parent env to search for matching symbols if no matches
// found in lambda vars
env* fn_vars = init_env(e);
lval* env_set = build_scoped_env(
fn_vars, func_lval->lambda->var_expr, operands
);
if (env_set->type == LVAL_ERR){
del_env(fn_vars);
return env_set;
}
lval* lambda_eval = eval(fn_vars, func_lval->lambda->eval_expr);
// del will cascade through all lambda vars, but not parent env.
del_env(fn_vars);
lval_del(env_set);
return lambda_eval;
}
lval* eval_func(env* e, list * l){
lval* func_lval = eval_lval(e, l->expr);
bltn_ptr func_ptr = get_builtin(func_lval->sym);
return (func_ptr)(e, l->next);
}
lval* build_scoped_env(env* e, list* vars, list* vals){
if (vars == NULL){
if (vals != NULL){
return lval_err("Too many arguments for procedure");
}
return lval_nil();
}
if (vals == NULL){
return lval_err("Not enough arguments for procedure");
}
lval* val = eval_lval(e, vals->expr);
put_val(e, val, vars->expr->sym, ENV_SCOPED);
return build_scoped_env(e, vars->next, vals->next);
}