-
Notifications
You must be signed in to change notification settings - Fork 0
/
vars.c
152 lines (123 loc) · 3.53 KB
/
vars.c
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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
#include "vars.h"
lval* lval_fun(lbuiltin func, short op) {
lval* v = malloc(sizeof(lval));
v->type = LVAL_FUN;
v->builtin = func;
v->function_opcode = op;
add_to_gc(lisp_gc, v);
return v;
}
lval* lval_copy(lval* v) {
lval* x = malloc(sizeof(lval));
x->type = v->type;
//add the new lval to
add_to_gc(lisp_gc, x);
switch (v->type) {
/* Copy Functions and Numbers Directly */
case LVAL_FUN:
if (v->builtin){
x->builtin = v->builtin;
x->function_opcode = v->function_opcode;
}
else{
x->builtin = NULL;
x->env = lenv_copy(v->env);
x->formals = lval_copy(v->formals);
x->body = lval_copy(v->body);
}
break;
case LVAL_NUM: x->num = v->num; break;
/* Copy Strings using malloc and strcpy */
case LVAL_ERR:
x->err = malloc(strlen(v->err) + 1);
strcpy(x->err, v->err); break;
case LVAL_SYM:
x->sym = malloc(strlen(v->sym) + 1);
strcpy(x->sym, v->sym); break;
case LVAL_STR:
x->str = malloc(strlen(v->str) + 1);
strcpy(x->str, v->str);
break;
/* Copy Lists by copying each sub-expression */
case LVAL_S_EXPR:
case LVAL_Q_EXPR:
x->count = v->count;
x->cell = malloc(sizeof(lval*) * x->count);
for (int i = 0; i < x->count; i++) {
x->cell[i] = lval_copy(v->cell[i]);
}
break;
}
return x;
}
lenv* lenv_create(void) {
lenv* e = malloc(sizeof(lenv));
e->parent = NULL;
e->count = 0;
e->syms = NULL;
e->vals = NULL;
return e;
}
void lenv_del(lenv* e) {
for (int i = 0; i < e->count; i++) {
free(e->syms[i]);
//free_lval(e->vals[i]);
decrement_counter(e->vals[i]);
}
free(e->syms);
free(e->vals);
free(e);
}
lval* lenv_get(lenv* e, lval* k) {
/* Iterate over all items in environment */
for (int i = 0; i < e->count; i++) {
/* Check if the stored string matches the symbol string */
/* If it does, return a copy of the value */
if (strcmp(e->syms[i], k->sym) == 0) {
return lval_copy(e->vals[i]);
}
}
//look at the symbols in the parent environment
if (e->parent) {
return lenv_get(e->parent, k);
}
/* If no symbol found return error */
return lval_err("unbound symbol during lenv_get, with symbol: %s", k->sym);
}
void lenv_put(lenv* e, lval* k, lval* v) {
/* Iterate over all items in environment */
/* This is to see if variable already exists */
for (int i = 0; i < e->count; i++) {
/* If variable is found delete item at that position */
/* And replace with variable supplied by user */
if (strcmp(e->syms[i], k->sym) == 0) {
//free_lval(e->vals[i]);
decrement_counter(e->vals[i]);
assign_lval(&e->vals[i], v);
//e->vals[i] = lval_copy(v);
return;
}
}
/* If no existing entry found allocate space for new entry */
e->count++;
e->vals = realloc(e->vals, sizeof(lval*) * e->count);
e->syms = realloc(e->syms, sizeof(char*) * e->count);
/* Copy contents of lval and symbol string into new location */
//e->vals[e->count-1] = lval_copy(v);
assign_lval(&e->vals[e->count-1], v);
e->syms[e->count-1] = malloc(strlen(k->sym)+1);
strcpy(e->syms[e->count-1], k->sym);
}
lenv* lenv_copy(lenv* e) {
lenv* n = malloc(sizeof(lenv));
n->parent = e->parent;
n->count = e->count;
n->syms = malloc(sizeof(char*) * n->count);
n->vals = malloc(sizeof(lval*) * n->count);
for (int i = 0; i < e->count; i++) {
n->syms[i] = malloc(strlen(e->syms[i]) + 1);
strcpy(n->syms[i], e->syms[i]);
n->vals[i] = lval_copy(e->vals[i]);
}
return n;
}