diff options
Diffstat (limited to 'src/parser.c')
-rw-r--r-- | src/parser.c | 97 |
1 files changed, 82 insertions, 15 deletions
diff --git a/src/parser.c b/src/parser.c index 5551dd2..f831e50 100644 --- a/src/parser.c +++ b/src/parser.c | |||
@@ -122,7 +122,7 @@ parse_lambda(Parser *parser, Errors *errors) { | |||
122 | Object * | 122 | Object * |
123 | parse_if(Parser *parser, Errors *errors) { | 123 | parse_if(Parser *parser, Errors *errors) { |
124 | Token start = next_token(parser); | 124 | Token start = next_token(parser); |
125 | Object *obj_if = object_alloc(start, OBJ_TYPE_IF); | 125 | Object *ret = object_alloc(start, OBJ_TYPE_IF); |
126 | 126 | ||
127 | Token tok = peek_token(parser); | 127 | Token tok = peek_token(parser); |
128 | if (tok.type == TOKEN_RPAREN) { | 128 | if (tok.type == TOKEN_RPAREN) { |
@@ -134,7 +134,7 @@ parse_if(Parser *parser, Errors *errors) { | |||
134 | }); | 134 | }); |
135 | return NULL; | 135 | return NULL; |
136 | } | 136 | } |
137 | obj_if->condition = parse_tree(parser, errors); | 137 | ret->condition = parse_tree(parser, errors); |
138 | 138 | ||
139 | tok = peek_token(parser); | 139 | tok = peek_token(parser); |
140 | if (tok.type == TOKEN_RPAREN) { | 140 | if (tok.type == TOKEN_RPAREN) { |
@@ -146,16 +146,16 @@ parse_if(Parser *parser, Errors *errors) { | |||
146 | }); | 146 | }); |
147 | return NULL; | 147 | return NULL; |
148 | } | 148 | } |
149 | obj_if->expr_true = parse_tree(parser, errors); | 149 | ret->expr_true = parse_tree(parser, errors); |
150 | 150 | ||
151 | // Optional else expression. | 151 | // Optional else expression. |
152 | tok = peek_token(parser); | 152 | tok = peek_token(parser); |
153 | if (tok.type == TOKEN_RPAREN) { | 153 | if (tok.type == TOKEN_RPAREN) { |
154 | next_token(parser); | 154 | next_token(parser); |
155 | obj_if->expr_false = NULL; | 155 | ret->expr_false = NULL; |
156 | return obj_if; | 156 | return ret; |
157 | } | 157 | } |
158 | obj_if->expr_false = parse_tree(parser, errors); | 158 | ret->expr_false = parse_tree(parser, errors); |
159 | 159 | ||
160 | tok = peek_token(parser); | 160 | tok = peek_token(parser); |
161 | if (tok.type != TOKEN_RPAREN) { | 161 | if (tok.type != TOKEN_RPAREN) { |
@@ -168,7 +168,62 @@ parse_if(Parser *parser, Errors *errors) { | |||
168 | return NULL; | 168 | return NULL; |
169 | } | 169 | } |
170 | next_token(parser); | 170 | next_token(parser); |
171 | return obj_if; | 171 | return ret; |
172 | } | ||
173 | |||
174 | Object * | ||
175 | parse_var(Parser *parser, Errors *errors) { | ||
176 | Token start = next_token(parser); | ||
177 | ObjectType type = start.type == TOKEN_DEF ? OBJ_TYPE_DEF : OBJ_TYPE_SET; | ||
178 | Object *ret = object_alloc(start, type); | ||
179 | |||
180 | // Variable name. | ||
181 | Token tok = peek_token(parser); | ||
182 | if (tok.type == TOKEN_RPAREN) { | ||
183 | error_push(errors, (Error){ | ||
184 | .type = ERR_TYPE_PARSER, | ||
185 | .value = ERR_NOT_ENOUGH_ARGS, | ||
186 | .line = tok.line, | ||
187 | .col = tok.col, | ||
188 | }); | ||
189 | return NULL; | ||
190 | } | ||
191 | if (tok.type != TOKEN_SYMBOL) { | ||
192 | error_push(errors, (Error){ | ||
193 | .type = ERR_TYPE_PARSER, | ||
194 | .value = ERR_WRONG_ARG_TYPE, | ||
195 | .line = tok.line, | ||
196 | .col = tok.col, | ||
197 | }); | ||
198 | return NULL; | ||
199 | } | ||
200 | ret->var_name = parse_tree(parser, errors); | ||
201 | |||
202 | // Variable value (expression). | ||
203 | tok = peek_token(parser); | ||
204 | if (tok.type == TOKEN_RPAREN) { | ||
205 | error_push(errors, (Error){ | ||
206 | .type = ERR_TYPE_PARSER, | ||
207 | .value = ERR_NOT_ENOUGH_ARGS, | ||
208 | .line = tok.line, | ||
209 | .col = tok.col, | ||
210 | }); | ||
211 | return NULL; | ||
212 | } | ||
213 | ret->var_expr = parse_tree(parser, errors); | ||
214 | |||
215 | tok = peek_token(parser); | ||
216 | if (tok.type != TOKEN_RPAREN) { | ||
217 | error_push(errors, (Error){ | ||
218 | .type = ERR_TYPE_PARSER, | ||
219 | .value = ERR_TOO_MANY_ARGS, | ||
220 | .line = tok.line, | ||
221 | .col = tok.col, | ||
222 | }); | ||
223 | return NULL; | ||
224 | } | ||
225 | next_token(parser); | ||
226 | return ret; | ||
172 | } | 227 | } |
173 | 228 | ||
174 | Object * | 229 | Object * |
@@ -188,12 +243,10 @@ parse_list(Parser *parser, Errors *errors) { | |||
188 | }); | 243 | }); |
189 | return NULL; | 244 | return NULL; |
190 | } break; | 245 | } break; |
191 | case TOKEN_LAMBDA: { | 246 | case TOKEN_LAMBDA: { return parse_lambda(parser, errors); } break; |
192 | return parse_lambda(parser, errors); | 247 | case TOKEN_IF: { return parse_if(parser, errors); } break; |
193 | } break; | 248 | case TOKEN_DEF: { return parse_var(parser, errors); } break; |
194 | case TOKEN_IF: { | 249 | case TOKEN_SET: { return parse_var(parser, errors); } break; |
195 | return parse_if(parser, errors); | ||
196 | } break; | ||
197 | default: break; | 250 | default: break; |
198 | } | 251 | } |
199 | 252 | ||
@@ -386,7 +439,7 @@ object_display(Object *obj) { | |||
386 | printf(")"); | 439 | printf(")"); |
387 | } break; | 440 | } break; |
388 | case OBJ_TYPE_LAMBDA: { | 441 | case OBJ_TYPE_LAMBDA: { |
389 | printf("#{ lambda( "); | 442 | printf("#{ lambda ( "); |
390 | for (size_t i = 0; i < array_size(obj->params); i++) { | 443 | for (size_t i = 0; i < array_size(obj->params); i++) { |
391 | object_display(obj->params[i]); | 444 | object_display(obj->params[i]); |
392 | printf(" "); | 445 | printf(" "); |
@@ -408,7 +461,21 @@ object_display(Object *obj) { | |||
408 | object_display(obj->expr_false); | 461 | object_display(obj->expr_false); |
409 | } | 462 | } |
410 | printf(" }"); | 463 | printf(" }"); |
411 | }; | 464 | } break; |
465 | case OBJ_TYPE_DEF: { | ||
466 | printf("#{ def "); | ||
467 | object_display(obj->var_name); | ||
468 | printf(" "); | ||
469 | object_display(obj->var_expr); | ||
470 | printf(" }"); | ||
471 | } break; | ||
472 | case OBJ_TYPE_SET: { | ||
473 | printf("#{ set! "); | ||
474 | object_display(obj->var_name); | ||
475 | printf(" "); | ||
476 | object_display(obj->var_expr); | ||
477 | printf(" }"); | ||
478 | } break; | ||
412 | } | 479 | } |
413 | return; | 480 | return; |
414 | } | 481 | } |