diff options
Diffstat (limited to 'src/parser.c')
-rw-r--r-- | src/parser.c | 91 |
1 files changed, 83 insertions, 8 deletions
diff --git a/src/parser.c b/src/parser.c index 8a6c4ce..5551dd2 100644 --- a/src/parser.c +++ b/src/parser.c | |||
@@ -103,6 +103,7 @@ parse_lambda(Parser *parser, Errors *errors) { | |||
103 | .line = tok.line, | 103 | .line = tok.line, |
104 | .col = tok.col, | 104 | .col = tok.col, |
105 | }); | 105 | }); |
106 | return NULL; | ||
106 | } | 107 | } |
107 | 108 | ||
108 | // Parse body. | 109 | // Parse body. |
@@ -119,23 +120,81 @@ parse_lambda(Parser *parser, Errors *errors) { | |||
119 | } | 120 | } |
120 | 121 | ||
121 | Object * | 122 | Object * |
122 | parse_list(Parser *parser, Errors *errors) { | 123 | parse_if(Parser *parser, Errors *errors) { |
123 | if (errors->n != 0) { | 124 | Token start = next_token(parser); |
125 | Object *obj_if = object_alloc(start, OBJ_TYPE_IF); | ||
126 | |||
127 | Token tok = peek_token(parser); | ||
128 | if (tok.type == TOKEN_RPAREN) { | ||
129 | error_push(errors, (Error){ | ||
130 | .type = ERR_TYPE_PARSER, | ||
131 | .value = ERR_NOT_ENOUGH_ARGS, | ||
132 | .line = tok.line, | ||
133 | .col = tok.col, | ||
134 | }); | ||
124 | return NULL; | 135 | return NULL; |
125 | } | 136 | } |
137 | obj_if->condition = parse_tree(parser, errors); | ||
126 | 138 | ||
127 | Token tok = peek_token(parser); | 139 | tok = peek_token(parser); |
128 | if (tok.type == TOKEN_RPAREN) { | 140 | if (tok.type == TOKEN_RPAREN) { |
129 | error_push(errors, (Error){ | 141 | error_push(errors, (Error){ |
130 | .type = ERR_TYPE_PARSER, | 142 | .type = ERR_TYPE_PARSER, |
131 | .value = ERR_UNBALANCED_PAREN, | 143 | .value = ERR_NOT_ENOUGH_ARGS, |
132 | .line = tok.line, | 144 | .line = tok.line, |
133 | .col = tok.col, | 145 | .col = tok.col, |
134 | }); | 146 | }); |
135 | return NULL; | 147 | return NULL; |
136 | } | 148 | } |
137 | if (tok.type == TOKEN_LAMBDA) { | 149 | obj_if->expr_true = parse_tree(parser, errors); |
138 | return parse_lambda(parser, errors); | 150 | |
151 | // Optional else expression. | ||
152 | tok = peek_token(parser); | ||
153 | if (tok.type == TOKEN_RPAREN) { | ||
154 | next_token(parser); | ||
155 | obj_if->expr_false = NULL; | ||
156 | return obj_if; | ||
157 | } | ||
158 | obj_if->expr_false = parse_tree(parser, errors); | ||
159 | |||
160 | tok = peek_token(parser); | ||
161 | if (tok.type != TOKEN_RPAREN) { | ||
162 | error_push(errors, (Error){ | ||
163 | .type = ERR_TYPE_PARSER, | ||
164 | .value = ERR_TOO_MANY_ARGS, | ||
165 | .line = tok.line, | ||
166 | .col = tok.col, | ||
167 | }); | ||
168 | return NULL; | ||
169 | } | ||
170 | next_token(parser); | ||
171 | return obj_if; | ||
172 | } | ||
173 | |||
174 | Object * | ||
175 | parse_list(Parser *parser, Errors *errors) { | ||
176 | if (errors->n != 0) { | ||
177 | return NULL; | ||
178 | } | ||
179 | |||
180 | Token tok = peek_token(parser); | ||
181 | switch (tok.type) { | ||
182 | case TOKEN_RPAREN: { | ||
183 | error_push(errors, (Error){ | ||
184 | .type = ERR_TYPE_PARSER, | ||
185 | .value = ERR_UNBALANCED_PAREN, | ||
186 | .line = tok.line, | ||
187 | .col = tok.col, | ||
188 | }); | ||
189 | return NULL; | ||
190 | } break; | ||
191 | case TOKEN_LAMBDA: { | ||
192 | return parse_lambda(parser, errors); | ||
193 | } break; | ||
194 | case TOKEN_IF: { | ||
195 | return parse_if(parser, errors); | ||
196 | } break; | ||
197 | default: break; | ||
139 | } | 198 | } |
140 | 199 | ||
141 | Token start = previous_token(parser); | 200 | Token start = previous_token(parser); |
@@ -327,13 +386,29 @@ object_display(Object *obj) { | |||
327 | printf(")"); | 386 | printf(")"); |
328 | } break; | 387 | } break; |
329 | case OBJ_TYPE_LAMBDA: { | 388 | case OBJ_TYPE_LAMBDA: { |
330 | printf("#{lambda( "); | 389 | printf("#{ lambda( "); |
331 | for (size_t i = 0; i < array_size(obj->params); i++) { | 390 | for (size_t i = 0; i < array_size(obj->params); i++) { |
332 | object_display(obj->params[i]); | 391 | object_display(obj->params[i]); |
333 | printf(" "); | 392 | printf(" "); |
334 | } | 393 | } |
335 | printf(")}"); | 394 | printf(") "); |
395 | for (size_t i = 0; i < array_size(obj->body); i++) { | ||
396 | object_display(obj->body[i]); | ||
397 | printf(" "); | ||
398 | } | ||
399 | printf("}"); | ||
336 | } break; | 400 | } break; |
401 | case OBJ_TYPE_IF: { | ||
402 | printf("#{ if "); | ||
403 | object_display(obj->condition); | ||
404 | printf(" "); | ||
405 | object_display(obj->expr_true); | ||
406 | if (obj->expr_false != NULL) { | ||
407 | printf(" "); | ||
408 | object_display(obj->expr_false); | ||
409 | } | ||
410 | printf(" }"); | ||
411 | }; | ||
337 | } | 412 | } |
338 | return; | 413 | return; |
339 | } | 414 | } |