diff options
-rw-r--r-- | eval.c | 61 | ||||
-rw-r--r-- | eval.h | 20 | ||||
-rw-r--r-- | parser.c | 11 | ||||
-rw-r--r-- | repl.c | 109 | ||||
-rw-r--r-- | repl.h | 6 | ||||
-rw-r--r-- | types.c | 224 | ||||
-rw-r--r-- | types.h | 27 |
7 files changed, 446 insertions, 12 deletions
@@ -0,0 +1,61 @@ | |||
1 | #include "eval.h" | ||
2 | #include "types.h" | ||
3 | |||
4 | |||
5 | LISP_OBJECT *eval_apply(LISP_OBJECT *lisp_list, HashMap *env) | ||
6 | { | ||
7 | if(lisp_list == NULL || lisp_list->type != LISP_TYPE_LIST) | ||
8 | return lisp_list; | ||
9 | |||
10 | LISP_OBJECT *symbol = lisp_list->value.list->ptr; | ||
11 | List *args = lisp_list->value.list->next; | ||
12 | |||
13 | LISP_OBJECT *func = hash_map_find(env, symbol->value.symbol)->value; | ||
14 | |||
15 | if(func->type != LISP_TYPE_FUNC) | ||
16 | return lisp_list; | ||
17 | |||
18 | List *tmp = lisp_list->value.list; | ||
19 | lisp_list->value.list = args; | ||
20 | LISP_OBJECT *ret = func->value.func(lisp_list); | ||
21 | lisp_list->value.list = tmp; | ||
22 | return ret; | ||
23 | } | ||
24 | |||
25 | LISP_OBJECT *eval_prepere_args(LISP_OBJECT *lisp_list, HashMap *env) | ||
26 | { | ||
27 | if(lisp_list == NULL || lisp_list->type != LISP_TYPE_LIST) | ||
28 | return lisp_list; | ||
29 | |||
30 | LISP_OBJECT *args = lisp_object_make_list(); | ||
31 | List **args_list = &args->value.list; | ||
32 | |||
33 | List *list = lisp_list->value.list; | ||
34 | LISP_OBJECT *obj = NULL; | ||
35 | |||
36 | while(list) | ||
37 | { | ||
38 | obj = list->ptr; | ||
39 | if(obj->type==LISP_TYPE_LIST) | ||
40 | obj = eval(obj, env); | ||
41 | |||
42 | *args_list = list_push(*args_list, obj); | ||
43 | list = list->next; | ||
44 | } | ||
45 | |||
46 | *args_list = list_reverse(*args_list); | ||
47 | |||
48 | return eval_apply(args, env); | ||
49 | } | ||
50 | |||
51 | |||
52 | LISP_OBJECT *eval(LISP_OBJECT *lisp_obj, HashMap *env) | ||
53 | { | ||
54 | if(lisp_obj == NULL) | ||
55 | return NULL; | ||
56 | |||
57 | if(lisp_obj->type == LISP_TYPE_LIST) | ||
58 | return eval_prepere_args(lisp_obj, env); | ||
59 | |||
60 | return lisp_obj; | ||
61 | } | ||
@@ -0,0 +1,20 @@ | |||
1 | #ifndef _EVAL | ||
2 | #define _EVAL | ||
3 | |||
4 | #include <stddef.h> | ||
5 | #include <stdio.h> | ||
6 | #include <stdlib.h> | ||
7 | #include <string.h> | ||
8 | #include <ctype.h> | ||
9 | |||
10 | #include "types.h" | ||
11 | #include "memory.h" | ||
12 | |||
13 | |||
14 | // HashMap *repl_env = NULL; | ||
15 | |||
16 | LISP_OBJECT *eval_apply(LISP_OBJECT *lisp_list, HashMap *env); | ||
17 | LISP_OBJECT *eval_prepere_args(LISP_OBJECT *lisp_list, HashMap *env); | ||
18 | LISP_OBJECT *eval(LISP_OBJECT *lisp_obj, HashMap *env); | ||
19 | |||
20 | #endif | ||
@@ -161,14 +161,3 @@ LISP_OBJECT *parser_make_nil(Token **token) | |||
161 | return lisp_obj; | 161 | return lisp_obj; |
162 | } | 162 | } |
163 | 163 | ||
164 | int main() | ||
165 | { | ||
166 | char *test = "(display (string-append \"4*3+2=\" (number->string (+ (* 4 3) 1))))"; | ||
167 | |||
168 | |||
169 | LISP_OBJECT *obj = NULL; | ||
170 | |||
171 | obj = parser_parse_str(test); | ||
172 | lisp_object_print(obj, 0); | ||
173 | lisp_object_free(obj); | ||
174 | } | ||
@@ -0,0 +1,109 @@ | |||
1 | #include <stdio.h> | ||
2 | #include <stdlib.h> | ||
3 | #include <string.h> | ||
4 | #include <readline/readline.h> | ||
5 | |||
6 | #include "types.h" | ||
7 | #include "parser.h" | ||
8 | #include "eval.h" | ||
9 | |||
10 | |||
11 | LISP_OBJECT *Fadd(LISP_OBJECT *l) | ||
12 | { | ||
13 | long long natural=0; | ||
14 | |||
15 | List *list = l->value.list; | ||
16 | LISP_OBJECT *a = NULL; | ||
17 | while(list) | ||
18 | { | ||
19 | a = list->ptr; | ||
20 | natural += *a->value.number_natural; | ||
21 | list = list->next; | ||
22 | } | ||
23 | LISP_OBJECT *c = lisp_object_make_number_natural(natural); | ||
24 | return c; | ||
25 | } | ||
26 | |||
27 | LISP_OBJECT *Fminus(LISP_OBJECT *l) | ||
28 | { | ||
29 | LISP_OBJECT *a = l->value.list->ptr; | ||
30 | LISP_OBJECT *b = l->value.list->next->ptr; | ||
31 | LISP_OBJECT *c = lisp_object_make_number_natural( | ||
32 | *a->value.number_natural - *b->value.number_natural); | ||
33 | return c; | ||
34 | } | ||
35 | |||
36 | LISP_OBJECT *Fmul(LISP_OBJECT *l) | ||
37 | { | ||
38 | LISP_OBJECT *a = l->value.list->ptr; | ||
39 | LISP_OBJECT *b = l->value.list->next->ptr; | ||
40 | LISP_OBJECT *c = lisp_object_make_number_natural( | ||
41 | *a->value.number_natural * *b->value.number_natural); | ||
42 | return c; | ||
43 | } | ||
44 | |||
45 | LISP_OBJECT *Fdiv(LISP_OBJECT *l) | ||
46 | { | ||
47 | LISP_OBJECT *a = l->value.list->ptr; | ||
48 | LISP_OBJECT *b = l->value.list->next->ptr; | ||
49 | LISP_OBJECT *c = lisp_object_make_number_natural( | ||
50 | *a->value.number_natural / *b->value.number_natural); | ||
51 | return c; | ||
52 | } | ||
53 | |||
54 | LISP_OBJECT *Fplusone(LISP_OBJECT *l) | ||
55 | { | ||
56 | LISP_OBJECT *a = l->value.list->ptr; | ||
57 | LISP_OBJECT *c = lisp_object_make_number_natural( | ||
58 | *a->value.number_natural+1); | ||
59 | return c; | ||
60 | } | ||
61 | |||
62 | |||
63 | LISP_OBJECT *READ(char *input) | ||
64 | { | ||
65 | return parser_parse_str(input); | ||
66 | } | ||
67 | |||
68 | LISP_OBJECT *EVAL(LISP_OBJECT *input, HashMap *env) | ||
69 | { | ||
70 | return eval(input, env); | ||
71 | } | ||
72 | |||
73 | void PRINT(LISP_OBJECT *input) | ||
74 | { | ||
75 | lisp_object_print(input, 0); | ||
76 | lisp_object_free(input); | ||
77 | } | ||
78 | |||
79 | void rep(char *input, HashMap *env) | ||
80 | { | ||
81 | PRINT(EVAL(READ(input), env)); | ||
82 | } | ||
83 | |||
84 | |||
85 | int main() | ||
86 | { | ||
87 | HashMap *env = NULL; | ||
88 | env = hash_map_push(env, "+", lisp_object_make_func(&Fadd)); | ||
89 | env = hash_map_push(env, "-", lisp_object_make_func(&Fminus)); | ||
90 | env = hash_map_push(env, "*", lisp_object_make_func(&Fmul)); | ||
91 | env = hash_map_push(env, "/", lisp_object_make_func(&Fdiv)); | ||
92 | env = hash_map_push(env, "++", lisp_object_make_func(&Fplusone)); | ||
93 | |||
94 | char *input1 = NULL; | ||
95 | char *input = NULL; | ||
96 | |||
97 | while(1) | ||
98 | { | ||
99 | input = readline("JADL> "); | ||
100 | input1 = malloc(sizeof(char) * strlen(input) + 1); | ||
101 | strcpy(input1, input); | ||
102 | input1[strlen(input)] = '\0'; | ||
103 | |||
104 | free(input); | ||
105 | |||
106 | rep(input1, env); | ||
107 | free(input1); | ||
108 | } | ||
109 | } | ||
@@ -0,0 +1,6 @@ | |||
1 | #include "types.h" | ||
2 | |||
3 | LISP_OBJECT PRINT(char *input); | ||
4 | LISP_OBJECT EVAL(char *input); | ||
5 | LISP_OBJECT READ(char *input); | ||
6 | LISP_OBJECT rep(char *input); | ||
@@ -1,6 +1,7 @@ | |||
1 | #include "types.h" | 1 | #include "types.h" |
2 | #include "memory.h" | 2 | #include "memory.h" |
3 | #include <stdio.h> | 3 | #include <stdio.h> |
4 | #include <string.h> | ||
4 | 5 | ||
5 | 6 | ||
6 | List *list_make(void *ptr) | 7 | List *list_make(void *ptr) |
@@ -174,6 +175,14 @@ LISP_OBJECT *lisp_object_make_false() | |||
174 | return lisp_obj; | 175 | return lisp_obj; |
175 | } | 176 | } |
176 | 177 | ||
178 | LISP_OBJECT *lisp_object_make_func(LISP_OBJECT *(*func)(LISP_OBJECT*)) | ||
179 | { | ||
180 | LISP_OBJECT *lisp_obj = lisp_object_make(); | ||
181 | lisp_obj->type = LISP_TYPE_FUNC; | ||
182 | lisp_obj->value.func = func; | ||
183 | return lisp_obj; | ||
184 | } | ||
185 | |||
177 | int lisp_object_print(LISP_OBJECT *obj, int indent) | 186 | int lisp_object_print(LISP_OBJECT *obj, int indent) |
178 | { | 187 | { |
179 | int count = 0; | 188 | int count = 0; |
@@ -230,3 +239,218 @@ int lisp_object_print(LISP_OBJECT *obj, int indent) | |||
230 | } | 239 | } |
231 | return count; | 240 | return count; |
232 | } | 241 | } |
242 | |||
243 | int lisp_object_cmp_types(LISP_OBJECT *a, LISP_OBJECT *b) | ||
244 | { | ||
245 | if(a==NULL && b==NULL) | ||
246 | return 1; | ||
247 | else if(a==NULL || b==NULL) | ||
248 | return 0; | ||
249 | else if(a->type != b->type) | ||
250 | return 0; | ||
251 | else if(a->type == b->type) | ||
252 | return 1; | ||
253 | return 0; | ||
254 | } | ||
255 | |||
256 | int lisp_object_cmp(LISP_OBJECT *a, LISP_OBJECT *b) | ||
257 | { | ||
258 | int is_same_type = lisp_object_cmp_types(a, b); | ||
259 | if(!is_same_type) | ||
260 | return 0; | ||
261 | |||
262 | switch(a->type) | ||
263 | { | ||
264 | case LISP_TYPE_LIST: | ||
265 | break; | ||
266 | case LISP_TYPE_NUMBER: | ||
267 | return lisp_object_cmp_numbers(a, b); | ||
268 | break; | ||
269 | case LISP_TYPE_STRING: | ||
270 | lisp_object_cmp_string(a, b); | ||
271 | break; | ||
272 | case LISP_TYPE_SYMBOL: | ||
273 | lisp_object_cmp_symbol(a, b); | ||
274 | break; | ||
275 | case LISP_TYPE_NIL: | ||
276 | case LISP_TYPE_TRUE: | ||
277 | case LISP_TYPE_FALSE: | ||
278 | case LISP_TYPE_ERROR: | ||
279 | return 1; | ||
280 | break; | ||
281 | } | ||
282 | } | ||
283 | |||
284 | int lisp_object_cmp_numbers(LISP_OBJECT *a, LISP_OBJECT *b) // TODO: make it works | ||
285 | { | ||
286 | int is_same_type= lisp_object_cmp_types(a, b); | ||
287 | if(!is_same_type && a->type == LISP_TYPE_NUMBER) | ||
288 | return 0; | ||
289 | |||
290 | if(a->is_decimal_point && b->is_decimal_point) | ||
291 | return *a->value.number_float == *b->value.number_float; | ||
292 | else if(a->is_decimal_point && !b->is_decimal_point) | ||
293 | return *a->value.number_float == *(double *)b->value.number_natural; | ||
294 | else if(!a->is_decimal_point && b->is_decimal_point) | ||
295 | return *(double *)a->value.number_natural == *b->value.number_float; | ||
296 | else | ||
297 | return *a->value.number_natural == *b->value.number_natural; | ||
298 | } | ||
299 | |||
300 | int lisp_object_cmp_symbol(LISP_OBJECT *a, LISP_OBJECT *b) | ||
301 | { | ||
302 | int is_same_type= lisp_object_cmp_types(a, b); | ||
303 | if(!is_same_type && a->type == LISP_TYPE_SYMBOL) | ||
304 | return 0; | ||
305 | |||
306 | return strcmp(a->value.symbol, b->value.symbol) == 0; | ||
307 | } | ||
308 | |||
309 | int lisp_object_cmp_string(LISP_OBJECT *a, LISP_OBJECT *b) | ||
310 | { | ||
311 | int is_same_type= lisp_object_cmp_types(a, b); | ||
312 | if(!is_same_type && a->type == LISP_TYPE_STRING) | ||
313 | return 0; | ||
314 | |||
315 | return strcmp(a->value.string, b->value.string) == 0; | ||
316 | } | ||
317 | |||
318 | HashMap *hash_map_make(char *key, LISP_OBJECT *value) | ||
319 | { | ||
320 | return hash_map_push(NULL, key, value); | ||
321 | } | ||
322 | |||
323 | HashMap *hash_map_push(HashMap *hash_map, char *key, LISP_OBJECT *value) | ||
324 | { | ||
325 | HashMap *is_exist = hash_map_find(hash_map, key); | ||
326 | |||
327 | if(is_exist != NULL) | ||
328 | return NULL; | ||
329 | |||
330 | HashMap *new_hash_map = jadl_malloc(sizeof(HashMap)); | ||
331 | |||
332 | new_hash_map->key = jadl_malloc(sizeof(char) * strlen(key));; | ||
333 | strcpy(new_hash_map->key, key); | ||
334 | |||
335 | new_hash_map->value = value; | ||
336 | new_hash_map->prev = NULL; | ||
337 | |||
338 | if(hash_map != NULL) | ||
339 | hash_map->prev = new_hash_map; | ||
340 | new_hash_map->next = hash_map; | ||
341 | |||
342 | return new_hash_map; | ||
343 | } | ||
344 | |||
345 | HashMap *hash_map_reverse(HashMap *hash_map) | ||
346 | { | ||
347 | HashMap *current = hash_map; | ||
348 | HashMap *next = NULL; | ||
349 | HashMap *new_hash_map = NULL; | ||
350 | while (current) { | ||
351 | next = current->next; | ||
352 | |||
353 | current->next = new_hash_map; | ||
354 | new_hash_map = current; | ||
355 | |||
356 | current = next; | ||
357 | } | ||
358 | |||
359 | return new_hash_map; | ||
360 | } | ||
361 | |||
362 | |||
363 | void hash_map_free(HashMap *hash_map) | ||
364 | { | ||
365 | HashMap *next = NULL; | ||
366 | |||
367 | while (hash_map) | ||
368 | { | ||
369 | next = hash_map->next; | ||
370 | |||
371 | jadl_free(hash_map->key); | ||
372 | lisp_object_free(hash_map->value); | ||
373 | jadl_free(hash_map); | ||
374 | |||
375 | hash_map = next; | ||
376 | } | ||
377 | } | ||
378 | |||
379 | HashMap *hash_map_find(HashMap *hash_map, char* key) | ||
380 | { | ||
381 | if (hash_map == NULL) | ||
382 | return NULL; | ||
383 | |||
384 | while (hash_map) | ||
385 | { | ||
386 | if(strcmp(hash_map->key, key) == 0) | ||
387 | return hash_map; | ||
388 | |||
389 | hash_map = hash_map->next; | ||
390 | } | ||
391 | |||
392 | return NULL; | ||
393 | } | ||
394 | |||
395 | HashMap *hash_map_delete(HashMap *hash_map, char* key) | ||
396 | { | ||
397 | HashMap *hash_map_to_free = hash_map_find(hash_map, key); | ||
398 | |||
399 | if(hash_map_to_free == NULL) | ||
400 | return hash_map; | ||
401 | |||
402 | HashMap *new_hash_map = NULL; | ||
403 | |||
404 | if(hash_map_to_free->prev == NULL) | ||
405 | { | ||
406 | new_hash_map = hash_map_to_free->next; | ||
407 | new_hash_map->prev = NULL; | ||
408 | } else | ||
409 | { | ||
410 | new_hash_map = hash_map_to_free->prev; | ||
411 | new_hash_map->next=hash_map_to_free->next; | ||
412 | if(new_hash_map->next) | ||
413 | new_hash_map->next->prev = new_hash_map; | ||
414 | } | ||
415 | |||
416 | HashMap *prev = new_hash_map->prev; | ||
417 | while(prev) | ||
418 | { | ||
419 | new_hash_map = prev; | ||
420 | prev = prev->prev; | ||
421 | } | ||
422 | |||
423 | hash_map_to_free->next = NULL; | ||
424 | hash_map_free(hash_map_to_free); | ||
425 | |||
426 | return new_hash_map; | ||
427 | } | ||
428 | |||
429 | |||
430 | void hash_map_print(HashMap *hash_map) | ||
431 | { | ||
432 | while (hash_map) | ||
433 | { | ||
434 | printf("-------------\n"); | ||
435 | printf("HashMap->key = %s\n", hash_map->key); | ||
436 | printf("HashMap->value: \n"); | ||
437 | lisp_object_print(hash_map->value, 0); | ||
438 | |||
439 | hash_map = hash_map->next; | ||
440 | } | ||
441 | |||
442 | printf("-------------\n"); | ||
443 | } | ||
444 | |||
445 | HashMap *hash_last(HashMap *hash_map) | ||
446 | { | ||
447 | HashMap *next = NULL; | ||
448 | while (hash_map) | ||
449 | { | ||
450 | next = hash_map->next; | ||
451 | if(!next) | ||
452 | return hash_map; | ||
453 | hash_map = next; | ||
454 | } | ||
455 | return NULL; | ||
456 | } | ||
@@ -16,6 +16,7 @@ typedef enum _LispType { | |||
16 | LISP_TYPE_NIL, | 16 | LISP_TYPE_NIL, |
17 | LISP_TYPE_TRUE, | 17 | LISP_TYPE_TRUE, |
18 | LISP_TYPE_FALSE, | 18 | LISP_TYPE_FALSE, |
19 | LISP_TYPE_FUNC, | ||
19 | LISP_TYPE_ERROR | 20 | LISP_TYPE_ERROR |
20 | } LispType; | 21 | } LispType; |
21 | 22 | ||
@@ -39,7 +40,7 @@ typedef struct _LispObject { | |||
39 | char *error; | 40 | char *error; |
40 | long long *number_natural; | 41 | long long *number_natural; |
41 | double *number_float; | 42 | double *number_float; |
42 | struct _LispObject (*function)(struct _LispObject*); | 43 | struct _LispObject *(*func)(struct _LispObject*); |
43 | List *list; | 44 | List *list; |
44 | void *ptr; | 45 | void *ptr; |
45 | } value; | 46 | } value; |
@@ -59,7 +60,31 @@ LISP_OBJECT *lisp_object_make_error(char *str); | |||
59 | LISP_OBJECT *lisp_object_make_nil(); | 60 | LISP_OBJECT *lisp_object_make_nil(); |
60 | LISP_OBJECT *lisp_object_make_true(); | 61 | LISP_OBJECT *lisp_object_make_true(); |
61 | LISP_OBJECT *lisp_object_make_false(); | 62 | LISP_OBJECT *lisp_object_make_false(); |
63 | LISP_OBJECT *lisp_object_make_func(LISP_OBJECT *(*func)(LISP_OBJECT*)); | ||
62 | 64 | ||
63 | int lisp_object_print(LISP_OBJECT *obj, int indent); | 65 | int lisp_object_print(LISP_OBJECT *obj, int indent); |
64 | 66 | ||
67 | int lisp_object_cmp_types(LISP_OBJECT *a, LISP_OBJECT *b); | ||
68 | int lisp_object_cmp(LISP_OBJECT *a, LISP_OBJECT *b); | ||
69 | int lisp_object_cmp_symbol(LISP_OBJECT *a, LISP_OBJECT *b); | ||
70 | int lisp_object_cmp_numbers(LISP_OBJECT *a, LISP_OBJECT *b); | ||
71 | int lisp_object_cmp_string(LISP_OBJECT *a, LISP_OBJECT *b); | ||
72 | |||
73 | typedef struct _HashMap | ||
74 | { | ||
75 | char *key; | ||
76 | LISP_OBJECT *value; | ||
77 | struct _HashMap *prev; | ||
78 | struct _HashMap *next; | ||
79 | |||
80 | } HashMap; | ||
81 | |||
82 | HashMap *hash_map_make(char *key, LISP_OBJECT *value); | ||
83 | HashMap *hash_map_push(HashMap *hash_map, char *key, LISP_OBJECT *value); | ||
84 | HashMap *hash_map_reverse(HashMap *hash_map); | ||
85 | HashMap *hash_map_find(HashMap *hash_map, char* key); | ||
86 | HashMap *hash_map_delete(HashMap *hash_map, char* key); | ||
87 | void hash_map_free(HashMap *hash_map); | ||
88 | void hash_map_print(HashMap *hash_map); | ||
89 | |||
65 | #endif | 90 | #endif |