diff options
author | jdlugosz963 <jdlugosz963@gmail.com> | 2023-03-01 23:30:31 +0100 |
---|---|---|
committer | jdlugosz963 <jdlugosz963@gmail.com> | 2023-03-01 23:30:31 +0100 |
commit | f44f1f8c7ef7b6266667dce76db686af3258adfc (patch) | |
tree | e0775e2a07713f1ac23d37b5271340fe8cbebd16 /types.c | |
download | jadl-f44f1f8c7ef7b6266667dce76db686af3258adfc.tar.gz jadl-f44f1f8c7ef7b6266667dce76db686af3258adfc.zip |
Build simple abstract syntax tree
Diffstat (limited to 'types.c')
-rw-r--r-- | types.c | 232 |
1 files changed, 232 insertions, 0 deletions
@@ -0,0 +1,232 @@ | |||
1 | #include "types.h" | ||
2 | #include "memory.h" | ||
3 | #include <stdio.h> | ||
4 | |||
5 | |||
6 | List *list_make(void *ptr) | ||
7 | { | ||
8 | return list_push(NULL, ptr); | ||
9 | } | ||
10 | |||
11 | List *list_push(List *list, void *ptr) | ||
12 | { | ||
13 | List *new_head = (List*)malloc(sizeof(List)); | ||
14 | new_head->next=list; | ||
15 | new_head->ptr=ptr; | ||
16 | return new_head; | ||
17 | } | ||
18 | |||
19 | |||
20 | List *list_reverse(List *list) | ||
21 | { | ||
22 | List *current = list; | ||
23 | List *next = NULL; | ||
24 | List *new_list = NULL; | ||
25 | while (current) { | ||
26 | next = current->next; | ||
27 | |||
28 | current->next = new_list; | ||
29 | new_list = current; | ||
30 | |||
31 | current = next; | ||
32 | } | ||
33 | return new_list; | ||
34 | } | ||
35 | |||
36 | void list_free(List *list) | ||
37 | { | ||
38 | List *next = NULL; | ||
39 | while (list) | ||
40 | { | ||
41 | next = list->next; | ||
42 | |||
43 | jadl_free(list->ptr); | ||
44 | jadl_free(list); | ||
45 | |||
46 | list = next; | ||
47 | } | ||
48 | |||
49 | } | ||
50 | |||
51 | void lisp_object_list_push(LISP_OBJECT *lisp_list_obj, void *ptr) | ||
52 | { | ||
53 | List *new_head = list_push(lisp_list_obj->value.list, ptr); | ||
54 | lisp_list_obj->value.list = new_head; | ||
55 | } | ||
56 | |||
57 | LISP_OBJECT *lisp_object_make() | ||
58 | { | ||
59 | LISP_OBJECT *lisp_obj = jadl_malloc(sizeof(LISP_OBJECT)); | ||
60 | lisp_obj->is_decimal_point = 0; | ||
61 | return lisp_obj; | ||
62 | } | ||
63 | |||
64 | void lisp_object_list_free(LISP_OBJECT *lisp_obj_list) | ||
65 | { | ||
66 | if(lisp_obj_list->type != LISP_TYPE_LIST) | ||
67 | return; | ||
68 | |||
69 | List *list = lisp_obj_list->value.list; | ||
70 | List *next = NULL; | ||
71 | |||
72 | while (list) | ||
73 | { | ||
74 | next = list->next; | ||
75 | |||
76 | LISP_OBJECT *lisp_obj = list->ptr; | ||
77 | |||
78 | lisp_object_free(lisp_obj); | ||
79 | |||
80 | jadl_free(list); | ||
81 | list = next; | ||
82 | } | ||
83 | jadl_free(lisp_obj_list); | ||
84 | } | ||
85 | |||
86 | void lisp_object_free(LISP_OBJECT *lisp_obj) | ||
87 | { | ||
88 | if (lisp_obj->type == LISP_TYPE_LIST) | ||
89 | lisp_object_list_free(lisp_obj); | ||
90 | else | ||
91 | { | ||
92 | if (lisp_obj->type != LISP_TYPE_FALSE && | ||
93 | lisp_obj->type != LISP_TYPE_TRUE && | ||
94 | lisp_obj->type != LISP_TYPE_NIL) | ||
95 | { | ||
96 | jadl_free(lisp_obj->value.ptr); | ||
97 | } | ||
98 | jadl_free(lisp_obj); | ||
99 | } | ||
100 | } | ||
101 | |||
102 | LISP_OBJECT *lisp_object_make_list() | ||
103 | { | ||
104 | LISP_OBJECT *lisp_obj = lisp_object_make(); | ||
105 | lisp_obj->type = LISP_TYPE_LIST; | ||
106 | lisp_obj->value.ptr = NULL; | ||
107 | return lisp_obj; | ||
108 | } | ||
109 | |||
110 | LISP_OBJECT *lisp_object_make_number_natural(long long number) | ||
111 | { | ||
112 | LISP_OBJECT *lisp_obj = lisp_object_make(); | ||
113 | lisp_obj->type = LISP_TYPE_NUMBER; | ||
114 | lisp_obj->value.number_natural = jadl_malloc(sizeof(long long)); | ||
115 | *lisp_obj->value.number_natural = number; | ||
116 | return lisp_obj; | ||
117 | } | ||
118 | |||
119 | LISP_OBJECT *lisp_object_make_number_float(double number) | ||
120 | { | ||
121 | LISP_OBJECT *lisp_obj = lisp_object_make(); | ||
122 | lisp_obj->type = LISP_TYPE_NUMBER; | ||
123 | lisp_obj->value.number_float = jadl_malloc(sizeof(double)); | ||
124 | *lisp_obj->value.number_float = number; | ||
125 | lisp_obj->is_decimal_point = 1; | ||
126 | return lisp_obj; | ||
127 | } | ||
128 | |||
129 | LISP_OBJECT *lisp_object_make_string(char *str) | ||
130 | { | ||
131 | LISP_OBJECT *lisp_obj = lisp_object_make(); | ||
132 | lisp_obj->type = LISP_TYPE_STRING; | ||
133 | lisp_obj->value.string = jadl_malloc(sizeof(char)*strlen(str)); | ||
134 | strcpy(lisp_obj->value.string, str); | ||
135 | return lisp_obj; | ||
136 | } | ||
137 | |||
138 | LISP_OBJECT *lisp_object_make_symbol(char *str) | ||
139 | { | ||
140 | LISP_OBJECT *lisp_obj = lisp_object_make(); | ||
141 | lisp_obj->type = LISP_TYPE_SYMBOL; | ||
142 | lisp_obj->value.symbol = jadl_malloc(sizeof(char)*strlen(str)); | ||
143 | strcpy(lisp_obj->value.symbol, str); | ||
144 | return lisp_obj; | ||
145 | } | ||
146 | |||
147 | LISP_OBJECT *lisp_object_make_error(char *str) | ||
148 | { | ||
149 | LISP_OBJECT *lisp_obj = lisp_object_make(); | ||
150 | lisp_obj->type = LISP_TYPE_ERROR; | ||
151 | lisp_obj->value.error = jadl_malloc(sizeof(char)*strlen(str)); | ||
152 | strcpy(lisp_obj->value.error, str); | ||
153 | return lisp_obj; | ||
154 | } | ||
155 | |||
156 | LISP_OBJECT *lisp_object_make_nil() | ||
157 | { | ||
158 | LISP_OBJECT *lisp_obj = lisp_object_make(); | ||
159 | lisp_obj->type = LISP_TYPE_NIL; | ||
160 | return lisp_obj; | ||
161 | } | ||
162 | |||
163 | LISP_OBJECT *lisp_object_make_true() | ||
164 | { | ||
165 | LISP_OBJECT *lisp_obj = lisp_object_make(); | ||
166 | lisp_obj->type = LISP_TYPE_TRUE; | ||
167 | return lisp_obj; | ||
168 | } | ||
169 | |||
170 | LISP_OBJECT *lisp_object_make_false() | ||
171 | { | ||
172 | LISP_OBJECT *lisp_obj = lisp_object_make(); | ||
173 | lisp_obj->type = LISP_TYPE_FALSE; | ||
174 | return lisp_obj; | ||
175 | } | ||
176 | |||
177 | int lisp_object_print(LISP_OBJECT *obj, int indent) | ||
178 | { | ||
179 | int count = 0; | ||
180 | for(int i=0; i<indent; i++) { printf(" "); } | ||
181 | |||
182 | switch(obj->type) | ||
183 | { | ||
184 | case LISP_TYPE_LIST: | ||
185 | printf(" │\n"); | ||
186 | break; | ||
187 | default: | ||
188 | printf("└─ "); | ||
189 | break; | ||
190 | } | ||
191 | |||
192 | switch(obj->type) | ||
193 | { | ||
194 | case LISP_TYPE_LIST: | ||
195 | List *lst = obj->value.list; | ||
196 | int temp = 0; | ||
197 | while (lst) | ||
198 | { | ||
199 | count ++; | ||
200 | temp = lisp_object_print((LISP_OBJECT *)lst->ptr, | ||
201 | indent+1); | ||
202 | count += temp; | ||
203 | lst = lst->next; | ||
204 | } | ||
205 | break; | ||
206 | case LISP_TYPE_STRING: | ||
207 | printf("STRING: %s\n", obj->value.string); | ||
208 | break; | ||
209 | case LISP_TYPE_ERROR: | ||
210 | printf("ERROR: %s\n", obj->value.error); | ||
211 | break; | ||
212 | case LISP_TYPE_SYMBOL: | ||
213 | printf("SYMBOL: %s\n", obj->value.symbol); | ||
214 | break; | ||
215 | case LISP_TYPE_NUMBER: | ||
216 | if(obj->is_decimal_point) | ||
217 | printf("NUMBER: %lf\n", *obj->value.number_float); | ||
218 | else | ||
219 | printf("NUMBER: %lld\n", *obj->value.number_natural); | ||
220 | break; | ||
221 | case LISP_TYPE_TRUE: | ||
222 | printf("TRUE\n"); | ||
223 | break; | ||
224 | case LISP_TYPE_FALSE: | ||
225 | printf("FALSE\n"); | ||
226 | break; | ||
227 | case LISP_TYPE_NIL: | ||
228 | printf("NIL\n"); | ||
229 | break; | ||
230 | } | ||
231 | return count; | ||
232 | } | ||