summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjdlugosz963 <jdlugosz963@gmail.com>2023-03-01 23:30:31 +0100
committerjdlugosz963 <jdlugosz963@gmail.com>2023-03-01 23:30:31 +0100
commitf44f1f8c7ef7b6266667dce76db686af3258adfc (patch)
treee0775e2a07713f1ac23d37b5271340fe8cbebd16
downloadjadl-f44f1f8c7ef7b6266667dce76db686af3258adfc.tar.gz
jadl-f44f1f8c7ef7b6266667dce76db686af3258adfc.zip
Build simple abstract syntax tree
-rw-r--r--lexer.c243
-rw-r--r--lexer.h65
-rw-r--r--memory.c27
-rw-r--r--memory.h15
-rw-r--r--parser.c174
-rw-r--r--parser.h18
-rw-r--r--types.c232
-rw-r--r--types.h65
8 files changed, 839 insertions, 0 deletions
diff --git a/lexer.c b/lexer.c
new file mode 100644
index 0000000..0c5e649
--- /dev/null
+++ b/lexer.c
@@ -0,0 +1,243 @@
1#include "lexer.h"
2#include <stdio.h>
3#include <stdlib.h>
4#include <string.h>
5
6Lexer *lexer_make()
7{
8 Lexer *lexer = (Lexer *)malloc(sizeof(Lexer));
9 return lexer;
10}
11
12void lexer_free(Lexer *lexer)
13{
14 Token *token = lexer->tokens;
15 Token *token_next = NULL;
16
17 while (token)
18 {
19 token_next = token->next;
20 jadl_free(token->value);
21 jadl_free(token);
22 token = token_next;
23 }
24 jadl_free(lexer);
25}
26
27Token *lexer_token_make(char *value, int value_len, TokenType type)
28{
29 Token *token = jadl_malloc(sizeof(token));
30 token->value = jadl_malloc(sizeof(char) * value_len + 1);
31 token->value[value_len] = '\0';
32 token->type = type;
33 strncpy(token->value, value, value_len);
34 token->is_decimal_point = 0;
35 return token;
36}
37
38Lexer *lexer_token_push(Lexer *lexer, Token *token)
39{
40 token->next = lexer->tokens;
41 lexer->tokens = token;
42 return lexer;
43}
44
45Lexer *lexer_tokens_reverse(Lexer *lexer)
46{
47 Token *token = lexer->tokens;
48 Token *token_next = NULL;
49 lexer->tokens=NULL;
50
51 while (token)
52 {
53 token_next = token->next;
54
55 lexer_token_push(lexer, token);
56
57 token = token_next;
58 }
59 return lexer;
60}
61
62char *lexer_token_make_string(char *str, Token **token)
63{
64 char *end = str;
65 int is_string_read = 1;
66 str += 1;
67
68 do
69 {
70 end = strchr(end+1, '"');
71 if (!end)
72 {
73 lexer_token_make_error("Cannot find end of string!", token);
74 is_string_read = 0;
75 break;
76 }
77 is_string_read = 1;
78 } while(*(end-1) == '\\');
79
80 if(is_string_read)
81 {
82 int str_len = (end - str);
83 *token = lexer_token_make(str, str_len, TOKEN_TYPE_STRING);
84 }
85
86 return (!is_string_read) ? NULL : end + 1;
87}
88
89char *lexer_token_make_number(char *str, Token **token)
90{
91 char *end = lexer_token_terminated_symbol(str);
92
93 char *next = str;
94 int is_decimal_point=0;
95 int is_number_read=1;
96
97 while(next<end)
98 {
99 if (!is_decimal_point && *next == '.')
100 is_decimal_point=1;
101 else if(*next == '.') {
102 lexer_token_make_error(
103 "Cannot read number, becouse it has too many decimal points!", token);
104 is_number_read = 0;
105 break;
106 }
107 else if(!isdigit(*next)) {
108 lexer_token_make_error("Cannot read number, becouse it isnt digit!", token);
109 is_number_read = 0;
110 break;
111 }
112
113 is_number_read = 1;
114 next+=1;
115 }
116
117 if(is_number_read)
118 {
119 int str_len = (end - str + 1); *token = lexer_token_make(str, str_len, TOKEN_TYPE_NUMBER);
120 (*token)->is_decimal_point = is_decimal_point;
121 }
122
123 return (is_number_read) ? end + 1 : NULL;
124}
125
126char *lexer_token_terminated_symbol(char *str)
127{
128 static char *chars_to_terminate = " ()[],;\"`";
129 char *terminated = strpbrk(str, chars_to_terminate);
130 terminated = (terminated == NULL) ? &str[strlen(str) - 1] : terminated - 1;
131 return terminated;
132}
133
134char *lexer_token_make_symbol(char *str, Token **token)
135{
136 char *end = lexer_token_terminated_symbol(str);
137
138 int str_len = (end - str + 1);
139
140 *token = lexer_token_make(str, str_len, TOKEN_TYPE_SYMBOL);
141
142 if(strncmp(str, SYMBOL_NIL, str_len) == 0)
143 (*token)->type = TOKEN_TYPE_NIL;
144 else if(strncmp(str, SYMBOL_FALSE, str_len) == 0 ||
145 strncmp(str, SYMBOL_FALSE_SHORT, str_len) == 0)
146 (*token)->type = TOKEN_TYPE_FALSE;
147 else if(strncmp(str, SYMBOL_TRUE, str_len) == 0 ||
148 strncmp(str, SYMBOL_TRUE_SHORT, str_len == 0))
149 (*token)->type = TOKEN_TYPE_TRUE;
150
151 return end + 1;
152}
153
154char *lexer_token_make_special(char *str, Token **token)
155{
156 *token = lexer_token_make(str, 1, TOKEN_TYPE_SPECIAL);
157 return str + 1;
158}
159
160
161void lexer_token_make_error(char *message, Token **token)
162{
163 unsigned long message_len = strlen(message);
164 *token = lexer_token_make(message, message_len, TOKEN_TYPE_ERROR);
165}
166
167
168Lexer *lexer_tokenize(char *str) {
169 Lexer *lexer = lexer_make();
170 Token *token = NULL;
171
172 while (str && *str) {
173 /* if(!*str) return lexer; */
174
175 switch (*str) {
176 case ' ':
177 case ';':
178 token = NULL;
179 str += 1;
180 break;
181 case '(':
182 case ')':
183 case '[':
184 case ']':
185 str = lexer_token_make_special(str, &token);
186 break;
187 case '0':
188 case '1':
189 case '2':
190 case '3':
191 case '4':
192 case '5':
193 case '6':
194 case '7':
195 case '8':
196 case '9':
197 str = lexer_token_make_number(str, &token);
198 break;
199 case '"':
200 str = lexer_token_make_string(str, &token);
201 break;
202 default:
203 str = lexer_token_make_symbol(str, &token);
204 break;
205 }
206 if (token)
207 lexer_token_push(lexer, token);
208 }
209
210 return lexer;
211}
212
213void lexer_tokens_print(Lexer *lexer)
214{
215 Token *token = lexer->tokens;
216 while (token) {
217 switch(token->type) {
218 case TOKEN_TYPE_STRING:
219 printf("String: ");
220 break;
221 case TOKEN_TYPE_SYMBOL:
222 printf("Symbol: ");
223 break;
224 case TOKEN_TYPE_SPECIAL:
225 printf("Special: ");
226 break;
227 case TOKEN_TYPE_NUMBER:
228 printf("Number: ");
229 break;
230 case TOKEN_TYPE_TRUE:
231 printf("True: ");
232 break;
233 case TOKEN_TYPE_FALSE:
234 printf("False: ");
235 break;
236 case TOKEN_TYPE_NIL:
237 printf("Nil: ");
238 break;
239 }
240 printf("%s\n", token->value);
241 token = token->next;
242 }
243}
diff --git a/lexer.h b/lexer.h
new file mode 100644
index 0000000..87fc008
--- /dev/null
+++ b/lexer.h
@@ -0,0 +1,65 @@
1#ifndef _LEXER
2#define _LEXER
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#define SYMBOL_NIL "nil"
14#define SYMBOL_TRUE_SHORT "#t"
15#define SYMBOL_TRUE "#true"
16#define SYMBOL_FALSE_SHORT "#f"
17#define SYMBOL_FALSE "#false"
18
19
20typedef enum _TokenType {
21 TOKEN_TYPE_SYMBOL,
22 TOKEN_TYPE_NUMBER,
23 TOKEN_TYPE_STRING,
24 TOKEN_TYPE_TRUE,
25 TOKEN_TYPE_FALSE,
26 TOKEN_TYPE_NIL,
27 TOKEN_TYPE_SPECIAL,
28 TOKEN_TYPE_ERROR
29} TokenType;
30
31
32typedef struct _Token {
33 TokenType type;
34 int is_decimal_point;
35 char *value;
36 struct _Token *next;
37} Token;
38
39typedef struct _Lexer {
40 int error;
41 Token *tokens;
42} Lexer;
43
44int lexer_tokens_count(char *str);
45
46Lexer *lexer_make();
47void lexer_free(Lexer *lexer);
48Token *lexer_token_make(char *value, int value_len, TokenType type);
49Lexer *lexer_token_push(Lexer *lexer, Token *token);
50
51char *lexer_token_terminated_symbol(char *str);
52char *lexer_token_make_string(char *str, Token **token);
53char *lexer_token_make_symbol(char *str, Token **token);
54char *lexer_token_make_special(char *str, Token **token);
55char *lexer_token_make_number(char *str, Token **token);
56
57void lexer_token_make_error(char *message, Token **token);
58
59Lexer *lexer_tokenize(char *str);
60
61
62void lexer_tokens_print(Lexer *lexer);
63Lexer *lexer_tokens_reverse(Lexer *lexer);
64
65#endif
diff --git a/memory.c b/memory.c
new file mode 100644
index 0000000..387268b
--- /dev/null
+++ b/memory.c
@@ -0,0 +1,27 @@
1#include "memory.h"
2
3#include <stdio.h>
4
5void *jadl_malloc(size_t size) {
6 void *ptr = malloc(size);
7 if(ptr == NULL)
8 {
9 printf("malloc: ERROR");
10 exit(1);
11 }
12 return ptr;
13}
14
15void jadl_free(void *ptr) {
16 return free(ptr);
17}
18
19long usage() {
20 struct rusage r_usage;
21 getrusage(RUSAGE_SELF, &r_usage);
22 return r_usage.ru_maxrss;
23}
24
25void usage_print() {
26 printf("Mem usage: %ld kilobytes\n", usage());
27}
diff --git a/memory.h b/memory.h
new file mode 100644
index 0000000..ba78b22
--- /dev/null
+++ b/memory.h
@@ -0,0 +1,15 @@
1#ifndef _MEMORY
2#define _MEMORY
3
4#include <stddef.h>
5#include <stdio.h>
6#include <stdlib.h>
7#include <sys/resource.h>
8
9void *jadl_malloc(size_t size);
10void jadl_free(void *ptr);
11
12long usage();
13void usage_print();
14
15#endif
diff --git a/parser.c b/parser.c
new file mode 100644
index 0000000..574d2ac
--- /dev/null
+++ b/parser.c
@@ -0,0 +1,174 @@
1#include "parser.h"
2#include "lexer.h"
3#include "types.h"
4#include <stdio.h>
5
6
7LISP_OBJECT *parser_parse_str(char *str)
8{
9 Lexer *lexer = lexer_tokenize(str);
10 lexer_tokens_reverse(lexer);
11
12 Token *token = lexer->tokens;
13 LISP_OBJECT *lisp_obj = NULL;
14 lisp_obj = parser_parse_tokens(&token);
15
16 lexer_free(lexer);
17
18 return lisp_obj;
19}
20
21LISP_OBJECT *parser_parse_tokens(Token **token)
22{
23 LISP_OBJECT *lisp_obj = NULL;
24 switch((*token)->type)
25 {
26 case TOKEN_TYPE_SPECIAL:
27 lisp_obj = parser_make_list(token);
28 break;
29 case TOKEN_TYPE_NUMBER:
30 lisp_obj = parser_make_number(token);
31 break;
32 case TOKEN_TYPE_STRING:
33 lisp_obj = parser_make_string(token);
34 break;
35 case TOKEN_TYPE_SYMBOL:
36 lisp_obj = parser_make_symbol(token);
37 break;
38 case TOKEN_TYPE_TRUE:
39 lisp_obj = parser_make_true(token);
40 break;
41 case TOKEN_TYPE_FALSE:
42 lisp_obj = parser_make_false(token);
43 break;
44 case TOKEN_TYPE_NIL:
45 lisp_obj = parser_make_nil(token);
46 break;
47 case TOKEN_TYPE_ERROR:
48 lisp_obj = lisp_object_make_error((*token)->value);
49 *token = (*token)->next;
50 break;
51 default:
52 *token = (*token)->next;
53 lisp_obj = lisp_object_make_error("Something bad happenend!");
54 }
55 return lisp_obj;
56}
57
58LISP_OBJECT *parser_make_list(Token **token)
59{
60 LISP_OBJECT *lisp_list_obj = lisp_object_make_list();
61 char close_delimiter = ( *(*token)->value == '(' ) ? ')' : ']';
62 *token = (*token)->next;
63 int is_close_delimiter = 1;
64
65 while(*token)
66 {
67 if((*token)->type==TOKEN_TYPE_SPECIAL &&
68 *(*token)->value==close_delimiter)
69 {
70 is_close_delimiter=0;
71 *token=(*token)->next;
72 break;
73 }
74
75 lisp_object_list_push(lisp_list_obj,
76 (void *)parser_parse_tokens(token));
77
78 }
79
80
81 List *list = list_reverse(lisp_list_obj->value.list);
82 lisp_list_obj->value.list = list;
83
84 if(is_close_delimiter != 0)
85 {
86 LISP_OBJECT *err_msg = lisp_object_make_error("Unbalanced parenthesis!");
87 lisp_object_list_push(lisp_list_obj, err_msg);
88 }
89
90 return lisp_list_obj;
91}
92
93
94LISP_OBJECT *parser_make_number(Token **token)
95{
96 LISP_OBJECT *lisp_obj = NULL;
97 char *number_str = (*token)->value;
98 union
99 {
100 long long natural;
101 double floating;
102
103 } number;
104
105 if((*token)->is_decimal_point)
106 {
107 sscanf(number_str, "%lf", &number.floating);
108 lisp_obj = lisp_object_make_number_float(number.floating);
109 }
110 else
111 {
112 sscanf(number_str, "%lld", &number.natural);
113 lisp_obj = lisp_object_make_number_natural(number.natural);
114 }
115
116
117 *token=(*token)->next;
118 return lisp_obj;
119}
120
121LISP_OBJECT *parser_make_string(Token **token)
122{
123 char *str = (*token)->value;
124 LISP_OBJECT *lisp_obj = lisp_object_make_string(str);
125
126 *token=(*token)->next;
127 return lisp_obj;
128}
129
130LISP_OBJECT *parser_make_symbol(Token **token)
131{
132 char *str = (*token)->value;
133 LISP_OBJECT *lisp_obj = lisp_object_make_symbol(str);
134
135 *token=(*token)->next;
136 return lisp_obj;
137}
138
139LISP_OBJECT *parser_make_true(Token **token)
140{
141 LISP_OBJECT *lisp_obj = lisp_object_make_true();
142
143 *token=(*token)->next;
144 return lisp_obj;
145}
146
147LISP_OBJECT *parser_make_false(Token **token)
148{
149 LISP_OBJECT *lisp_obj = lisp_object_make_false();
150
151 *token=(*token)->next;
152 return lisp_obj;
153}
154
155
156LISP_OBJECT *parser_make_nil(Token **token)
157{
158 LISP_OBJECT *lisp_obj = lisp_object_make_nil();
159
160 *token=(*token)->next;
161 return lisp_obj;
162}
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/parser.h b/parser.h
new file mode 100644
index 0000000..2a4c523
--- /dev/null
+++ b/parser.h
@@ -0,0 +1,18 @@
1#ifndef _PARSER
2#define _PARSER
3
4#include "types.h"
5#include "lexer.h"
6
7LISP_OBJECT *parser_parse_str(char *str);
8LISP_OBJECT *parser_parse_tokens(Token **token);
9
10LISP_OBJECT *parser_make_list(Token **token);
11LISP_OBJECT *parser_make_number(Token **token);
12LISP_OBJECT *parser_make_string(Token **token);
13LISP_OBJECT *parser_make_symbol(Token **token);
14LISP_OBJECT *parser_make_true(Token **token);
15LISP_OBJECT *parser_make_false(Token **token);
16LISP_OBJECT *parser_make_nil(Token **token);
17
18#endif
diff --git a/types.c b/types.c
new file mode 100644
index 0000000..42359bb
--- /dev/null
+++ b/types.c
@@ -0,0 +1,232 @@
1#include "types.h"
2#include "memory.h"
3#include <stdio.h>
4
5
6List *list_make(void *ptr)
7{
8 return list_push(NULL, ptr);
9}
10
11List *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
20List *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
36void 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
51void 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
57LISP_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
64void 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
86void 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
102LISP_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
110LISP_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
119LISP_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
129LISP_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
138LISP_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
147LISP_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
156LISP_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
163LISP_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
170LISP_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
177int 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}
diff --git a/types.h b/types.h
new file mode 100644
index 0000000..632e283
--- /dev/null
+++ b/types.h
@@ -0,0 +1,65 @@
1#ifndef _TYPES
2#define _TYPES
3
4#include <stddef.h>
5#include <stdlib.h>
6#include <string.h>
7
8#include "memory.h"
9
10
11typedef enum _LispType {
12 LISP_TYPE_SYMBOL,
13 LISP_TYPE_LIST,
14 LISP_TYPE_STRING,
15 LISP_TYPE_NUMBER,
16 LISP_TYPE_NIL,
17 LISP_TYPE_TRUE,
18 LISP_TYPE_FALSE,
19 LISP_TYPE_ERROR
20} LispType;
21
22
23typedef struct _List {
24 void *ptr;
25 struct _List *next;
26} List;
27
28List *list_make(void *ptr);
29List *list_push(List *list, void *ptr);
30List *list_reverse(List *list);
31
32typedef struct _LispObject {
33 LispType type;
34 int is_decimal_point;
35
36 union {
37 char *string;
38 char *symbol;
39 char *error;
40 long long *number_natural;
41 double *number_float;
42 struct _LispObject (*function)(struct _LispObject*);
43 List *list;
44 void *ptr;
45 } value;
46} LISP_OBJECT;
47
48void lisp_object_free(LISP_OBJECT *lisp_obj);
49
50void lisp_object_list_push(LISP_OBJECT *lisp_list_obj, void *ptr);
51
52LISP_OBJECT *lisp_object_make();
53LISP_OBJECT *lisp_object_make_list();
54LISP_OBJECT *lisp_object_make_number_natural(long long number);
55LISP_OBJECT *lisp_object_make_number_float(double number);
56LISP_OBJECT *lisp_object_make_string(char *str);
57LISP_OBJECT *lisp_object_make_symbol(char *str);
58LISP_OBJECT *lisp_object_make_error(char *str);
59LISP_OBJECT *lisp_object_make_nil();
60LISP_OBJECT *lisp_object_make_true();
61LISP_OBJECT *lisp_object_make_false();
62
63int lisp_object_print(LISP_OBJECT *obj, int indent);
64
65#endif