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 /parser.c | |
download | jadl-f44f1f8c7ef7b6266667dce76db686af3258adfc.tar.gz jadl-f44f1f8c7ef7b6266667dce76db686af3258adfc.zip |
Build simple abstract syntax tree
Diffstat (limited to 'parser.c')
-rw-r--r-- | parser.c | 174 |
1 files changed, 174 insertions, 0 deletions
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 | |||
7 | LISP_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 | |||
21 | LISP_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 | |||
58 | LISP_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 | |||
94 | LISP_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 | |||
121 | LISP_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 | |||
130 | LISP_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 | |||
139 | LISP_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 | |||
147 | LISP_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 | |||
156 | LISP_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 | |||
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 | } | ||