|
|
@@ -108,32 +108,119 @@ void print_tree(NODE *tree) {
|
|
108
|
108
|
print_tree0(tree, 0);
|
|
109
|
109
|
}
|
|
110
|
110
|
|
|
|
111
|
+int count_args(NODE *tree) {
|
|
|
112
|
+ NODE *tmp = tree;
|
|
|
113
|
+ int a = 1;
|
|
|
114
|
+ while (tmp != NULL) {
|
|
|
115
|
+ if (tmp->type != ',') {
|
|
|
116
|
+ break;
|
|
|
117
|
+ }
|
|
|
118
|
+ tmp = tmp->left;
|
|
|
119
|
+ a++;
|
|
|
120
|
+ }
|
|
|
121
|
+ return a;
|
|
|
122
|
+}
|
|
|
123
|
+
|
|
|
124
|
+void add_args_to_env(NODE *tree, ENV *env_ptr) {
|
|
|
125
|
+ if (tree->type == '~') {
|
|
|
126
|
+ BIND* arg;
|
|
|
127
|
+ TOKEN *tok, *name;
|
|
|
128
|
+ // we found an argument
|
|
|
129
|
+ name = (TOKEN*)tree->right->left;
|
|
|
130
|
+ tok = new_token(INT);
|
|
|
131
|
+ tok->value = 0;
|
|
|
132
|
+ asprintf(&tok->lexeme, "%d", tok->value);
|
|
|
133
|
+ arg = create_binding(name, (NODE*) tok, NULL);
|
|
|
134
|
+ if (env_ptr->bindings == NULL) {
|
|
|
135
|
+ env_ptr->bindings = create_list(arg, NULL);
|
|
|
136
|
+ } else {
|
|
|
137
|
+ append_list(env_ptr->bindings, arg);
|
|
|
138
|
+ }
|
|
|
139
|
+ } else {
|
|
|
140
|
+ add_args_to_env(tree->left, env_ptr);
|
|
|
141
|
+ add_args_to_env(tree->right, env_ptr);
|
|
|
142
|
+ }
|
|
|
143
|
+}
|
|
|
144
|
+
|
|
|
145
|
+void populate_arg_list(NODE *tree, TOKEN** arr, int arr_len) {
|
|
|
146
|
+ if (tree->type == '~') {
|
|
|
147
|
+ for (int i = 0; i < arr_len; i++) {
|
|
|
148
|
+ if (arr[i] == NULL) {
|
|
|
149
|
+ TOKEN* name = (TOKEN*)tree->right->left;
|
|
|
150
|
+ arr[i] = name;
|
|
|
151
|
+ break;
|
|
|
152
|
+ }
|
|
|
153
|
+ }
|
|
|
154
|
+ } else {
|
|
|
155
|
+ populate_arg_list(tree->left, arr, arr_len);
|
|
|
156
|
+ populate_arg_list(tree->right, arr, arr_len);
|
|
|
157
|
+ }
|
|
|
158
|
+}
|
|
|
159
|
+
|
|
|
160
|
+TOKEN** get_argument_list(NODE *tree) {
|
|
|
161
|
+ int num_args = count_args(tree->left->right->right);
|
|
|
162
|
+ TOKEN** arr = (TOKEN**) malloc(sizeof(TOKEN*) * num_args);
|
|
|
163
|
+ populate_arg_list(tree->left->right->right, arr, num_args);
|
|
|
164
|
+ return arr;
|
|
|
165
|
+}
|
|
|
166
|
+
|
|
111
|
167
|
void add_function_to_env(NODE *tree, ENV *env_ptr) {
|
|
112
|
168
|
BIND* existing;
|
|
113
|
169
|
NODE* func_name = tree->left->right->left->left;
|
|
114
|
170
|
TOKEN* name_token = (TOKEN*) func_name;
|
|
115
|
|
- if (tree->left->right->right == NULL) {
|
|
116
|
|
- printf("%s has no arguments\n", name_token->lexeme);
|
|
117
|
|
- }
|
|
118
|
171
|
if ((existing = find_name_in_env(name_token, env_ptr)) == NULL) {
|
|
119
|
172
|
/* printf("Added function name %s to environment with value: \n", name_token->lexeme); */
|
|
120
|
173
|
/* print_tree(tree); */
|
|
|
174
|
+ ENV* new_func_env = create_new_function_env(env_ptr);
|
|
|
175
|
+ if (tree->left->right->right != NULL) {
|
|
|
176
|
+ add_args_to_env(tree->left->right->right, new_func_env);
|
|
|
177
|
+ }
|
|
121
|
178
|
if (env_ptr->bindings == NULL) {
|
|
122
|
|
- env_ptr->bindings = create_list(create_binding(name_token, tree, env_ptr), NULL);
|
|
|
179
|
+ env_ptr->bindings = create_list(create_binding(name_token, tree, new_func_env), NULL);
|
|
123
|
180
|
} else {
|
|
124
|
|
- append_list(env_ptr->bindings, create_binding(name_token, tree, env_ptr));
|
|
|
181
|
+ append_list(env_ptr->bindings, create_binding(name_token, tree, new_func_env));
|
|
125
|
182
|
}
|
|
126
|
183
|
} else {
|
|
127
|
184
|
printf("Error: redefinition of function with name %s\n", name_token->lexeme);
|
|
128
|
185
|
}
|
|
129
|
186
|
}
|
|
130
|
187
|
|
|
|
188
|
+void populate_val_list(NODE* tree, TOKEN** arr, int num_args) {
|
|
|
189
|
+ if (tree->type == LEAF) {
|
|
|
190
|
+ for (int i = 0; i < num_args; i++) {
|
|
|
191
|
+ if (arr[i] == NULL) {
|
|
|
192
|
+ TOKEN* tok = (TOKEN*) tree->left;
|
|
|
193
|
+ arr[i] = tok;
|
|
|
194
|
+ break;
|
|
|
195
|
+ }
|
|
|
196
|
+ }
|
|
|
197
|
+ } else {
|
|
|
198
|
+ populate_val_list(tree->left, arr, num_args);
|
|
|
199
|
+ populate_val_list(tree->right, arr, num_args);
|
|
|
200
|
+ }
|
|
|
201
|
+}
|
|
|
202
|
+
|
|
|
203
|
+TOKEN** get_val_list(NODE *tree) {
|
|
|
204
|
+ int num_args = count_args(tree);
|
|
|
205
|
+ TOKEN** arr = (TOKEN**) malloc(sizeof(TOKEN*) * num_args);
|
|
|
206
|
+ populate_val_list(tree, arr, num_args);
|
|
|
207
|
+ return arr;
|
|
|
208
|
+}
|
|
|
209
|
+
|
|
|
210
|
+void bind_arg(TOKEN* val, TOKEN* arg_name, ENV *env_ptr) {
|
|
|
211
|
+ BIND* existing = find_name_in_list(arg_name, env_ptr->bindings);
|
|
|
212
|
+ if (existing == NULL) {
|
|
|
213
|
+ printf("fatal error\n");
|
|
|
214
|
+ exit(1);
|
|
|
215
|
+ }
|
|
|
216
|
+ existing->tree = (NODE*) val;
|
|
|
217
|
+}
|
|
131
|
218
|
|
|
132
|
219
|
void add_var_to_env(NODE *tree, ENV *env_ptr) {
|
|
133
|
220
|
BIND* existing;
|
|
134
|
221
|
NODE* var_name = tree->left->left;
|
|
135
|
222
|
TOKEN* name_token = (TOKEN*) var_name;
|
|
136
|
|
- TOKEN* tok = new_token(INT);
|
|
|
223
|
+ TOKEN* tok = new_token(CONSTANT);
|
|
137
|
224
|
tok->value = recursive_interpret(tree->right, env_ptr);
|
|
138
|
225
|
asprintf(&tok->lexeme, "%d", tok->value);
|
|
139
|
226
|
if ((existing = find_name_in_env(name_token, env_ptr)) == NULL) {
|
|
|
@@ -168,7 +255,7 @@ int recursive_interpret(NODE *tree, ENV *env_ptr) {
|
|
168
|
255
|
printf("Could not find variable %s\n", tok->lexeme);
|
|
169
|
256
|
exit(1);
|
|
170
|
257
|
}
|
|
171
|
|
- if (var_bind->tree->type == INT) {
|
|
|
258
|
+ if (var_bind->tree->type == CONSTANT) {
|
|
172
|
259
|
TOKEN* var_tok = (TOKEN *) var_bind->tree;
|
|
173
|
260
|
return var_tok->value;
|
|
174
|
261
|
} else {
|
|
|
@@ -194,6 +281,22 @@ int recursive_interpret(NODE *tree, ENV *env_ptr) {
|
|
194
|
281
|
printf("Could not find binding for function with name %s\n", func_name->lexeme);
|
|
195
|
282
|
exit(1);
|
|
196
|
283
|
}
|
|
|
284
|
+ if (tree->right != NULL) {
|
|
|
285
|
+ TOKEN** arg_list;
|
|
|
286
|
+ TOKEN** val_list;
|
|
|
287
|
+ int exp_args = count_args(func->tree->left->right->right);
|
|
|
288
|
+ int num_args = count_args(tree->right);
|
|
|
289
|
+ arg_list = get_argument_list(func->tree);
|
|
|
290
|
+ val_list = get_val_list(tree->right);
|
|
|
291
|
+ if (exp_args == num_args) {
|
|
|
292
|
+ for (int i = 0; i < num_args; i++) {
|
|
|
293
|
+ bind_arg(val_list[i], arg_list[i], func->env);
|
|
|
294
|
+ }
|
|
|
295
|
+ } else {
|
|
|
296
|
+ printf("Error! Arguments not right!!\n");
|
|
|
297
|
+ exit(1);
|
|
|
298
|
+ }
|
|
|
299
|
+ }
|
|
197
|
300
|
return recursive_interpret(func->tree->right, func->env);
|
|
198
|
301
|
}
|
|
199
|
302
|
if (tree->type == IF) {
|