summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjdlugosz963 <jdlugosz963@gmail.com>2023-03-05 23:10:15 +0100
committerjdlugosz963 <jdlugosz963@gmail.com>2023-03-05 23:10:15 +0100
commit49aa5542a8e13d2d808f7dee6bd7418add6d74ea (patch)
treed182dbf69f5f7b421283bf2a504ed3b40811a668
parentf44f1f8c7ef7b6266667dce76db686af3258adfc (diff)
downloadjadl-49aa5542a8e13d2d808f7dee6bd7418add6d74ea.tar.gz
jadl-49aa5542a8e13d2d808f7dee6bd7418add6d74ea.zip
Add primitive evaluation system
-rw-r--r--eval.c61
-rw-r--r--eval.h20
-rw-r--r--parser.c11
-rw-r--r--repl.c109
-rw-r--r--repl.h6
-rw-r--r--types.c224
-rw-r--r--types.h27
7 files changed, 446 insertions, 12 deletions
diff --git a/eval.c b/eval.c
new file mode 100644
index 0000000..4e593d9
--- /dev/null
+++ b/eval.c
@@ -0,0 +1,61 @@
1#include "eval.h"
2#include "types.h"
3
4
5LISP_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
25LISP_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
52LISP_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}
diff --git a/eval.h b/eval.h
new file mode 100644
index 0000000..0af0c87
--- /dev/null
+++ b/eval.h
@@ -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
16LISP_OBJECT *eval_apply(LISP_OBJECT *lisp_list, HashMap *env);
17LISP_OBJECT *eval_prepere_args(LISP_OBJECT *lisp_list, HashMap *env);
18LISP_OBJECT *eval(LISP_OBJECT *lisp_obj, HashMap *env);
19
20#endif
diff --git a/parser.c b/parser.c
index 574d2ac..4b408ab 100644
--- a/parser.c
+++ b/parser.c
@@ -161,14 +161,3 @@ LISP_OBJECT *parser_make_nil(Token **token)
161 return lisp_obj; 161 return lisp_obj;
162} 162}
163 163
164int 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}
diff --git a/repl.c b/repl.c
new file mode 100644
index 0000000..53be144
--- /dev/null
+++ b/repl.c
@@ -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
11LISP_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
27LISP_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
36LISP_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
45LISP_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
54LISP_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
63LISP_OBJECT *READ(char *input)
64{
65 return parser_parse_str(input);
66}
67
68LISP_OBJECT *EVAL(LISP_OBJECT *input, HashMap *env)
69{
70 return eval(input, env);
71}
72
73void PRINT(LISP_OBJECT *input)
74{
75 lisp_object_print(input, 0);
76 lisp_object_free(input);
77}
78
79void rep(char *input, HashMap *env)
80{
81 PRINT(EVAL(READ(input), env));
82}
83
84
85int 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}
diff --git a/repl.h b/repl.h
new file mode 100644
index 0000000..faf70b4
--- /dev/null
+++ b/repl.h
@@ -0,0 +1,6 @@
1#include "types.h"
2
3LISP_OBJECT PRINT(char *input);
4LISP_OBJECT EVAL(char *input);
5LISP_OBJECT READ(char *input);
6LISP_OBJECT rep(char *input);
diff --git a/types.c b/types.c
index 42359bb..4fd00d2 100644
--- a/types.c
+++ b/types.c
@@ -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
6List *list_make(void *ptr) 7List *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
178LISP_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
177int lisp_object_print(LISP_OBJECT *obj, int indent) 186int 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
243int 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
256int 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
284int 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
300int 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
309int 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
318HashMap *hash_map_make(char *key, LISP_OBJECT *value)
319{
320 return hash_map_push(NULL, key, value);
321}
322
323HashMap *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
345HashMap *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
363void 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
379HashMap *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
395HashMap *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
430void 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
445HashMap *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}
diff --git a/types.h b/types.h
index 632e283..f6e3fcf 100644
--- a/types.h
+++ b/types.h
@@ -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);
59LISP_OBJECT *lisp_object_make_nil(); 60LISP_OBJECT *lisp_object_make_nil();
60LISP_OBJECT *lisp_object_make_true(); 61LISP_OBJECT *lisp_object_make_true();
61LISP_OBJECT *lisp_object_make_false(); 62LISP_OBJECT *lisp_object_make_false();
63LISP_OBJECT *lisp_object_make_func(LISP_OBJECT *(*func)(LISP_OBJECT*));
62 64
63int lisp_object_print(LISP_OBJECT *obj, int indent); 65int lisp_object_print(LISP_OBJECT *obj, int indent);
64 66
67int lisp_object_cmp_types(LISP_OBJECT *a, LISP_OBJECT *b);
68int lisp_object_cmp(LISP_OBJECT *a, LISP_OBJECT *b);
69int lisp_object_cmp_symbol(LISP_OBJECT *a, LISP_OBJECT *b);
70int lisp_object_cmp_numbers(LISP_OBJECT *a, LISP_OBJECT *b);
71int lisp_object_cmp_string(LISP_OBJECT *a, LISP_OBJECT *b);
72
73typedef struct _HashMap
74{
75 char *key;
76 LISP_OBJECT *value;
77 struct _HashMap *prev;
78 struct _HashMap *next;
79
80} HashMap;
81
82HashMap *hash_map_make(char *key, LISP_OBJECT *value);
83HashMap *hash_map_push(HashMap *hash_map, char *key, LISP_OBJECT *value);
84HashMap *hash_map_reverse(HashMap *hash_map);
85HashMap *hash_map_find(HashMap *hash_map, char* key);
86HashMap *hash_map_delete(HashMap *hash_map, char* key);
87void hash_map_free(HashMap *hash_map);
88void hash_map_print(HashMap *hash_map);
89
65#endif 90#endif