diff options
Diffstat (limited to 'src/bootstrap/main.c')
-rwxr-xr-x | src/bootstrap/main.c | 51 |
1 files changed, 30 insertions, 21 deletions
diff --git a/src/bootstrap/main.c b/src/bootstrap/main.c index a0b0f69..fad3333 100755 --- a/src/bootstrap/main.c +++ b/src/bootstrap/main.c | |||
@@ -153,6 +153,17 @@ tokenize(StringView sv) { | |||
153 | return (Tokens){.start = (StringView *)&tokens_buf, .n = n}; | 153 | return (Tokens){.start = (StringView *)&tokens_buf, .n = n}; |
154 | } | 154 | } |
155 | 155 | ||
156 | StringView * | ||
157 | consume_token(Tokens *tokens) { | ||
158 | if (tokens->n == 0) { | ||
159 | return NULL; | ||
160 | } | ||
161 | StringView *ret = tokens->start; | ||
162 | tokens->start = &tokens->start[1]; | ||
163 | tokens->n--; | ||
164 | return ret; | ||
165 | } | ||
166 | |||
156 | typedef enum ObjectType { | 167 | typedef enum ObjectType { |
157 | OBJ_TYPE_FIXNUM, | 168 | OBJ_TYPE_FIXNUM, |
158 | OBJ_TYPE_BOOL, | 169 | OBJ_TYPE_BOOL, |
@@ -278,27 +289,27 @@ token_is_fixnum(StringView token) { | |||
278 | #define FALSE_TOKEN (StringView){"false", 5} | 289 | #define FALSE_TOKEN (StringView){"false", 5} |
279 | 290 | ||
280 | Object * | 291 | Object * |
281 | build_ast(Tokens tokens) { | 292 | build_ast(Tokens *tokens) { |
282 | // DEBUG: Printing tokens. | 293 | // DEBUG: Printing tokens. |
283 | // printf("N_TOKENS: %ld\n", tokens.n); | 294 | // printf("N_TOKENS: %ld\n", tokens->n); |
284 | // for (size_t i = 0; i < tokens.n; i++) { | 295 | // for (size_t i = 0; i < tokens->n; i++) { |
285 | // printf("TOKEN: "); | 296 | // printf("TOKEN: "); |
286 | // sv_write(tokens.start[i]); | 297 | // sv_write(tokens->start[i]); |
287 | // printf("\tN: %ld", tokens.start[i].n); | 298 | // printf("\tN: %ld", tokens->start[i].n); |
288 | // printf("\n"); | 299 | // printf("\n"); |
289 | // } | 300 | // } |
290 | 301 | ||
291 | // TODO: Report error if we haven't consumed all the tokens? | 302 | // TODO: Report error if we haven't consumed all the tokens? |
292 | for (size_t i = 0; i < tokens.n; i++) { | 303 | while (tokens->n > 0) { |
293 | StringView token = tokens.start[i]; | 304 | StringView *token = consume_token(tokens); |
294 | 305 | ||
295 | // OBJ_TYPE_FIXNUM | 306 | // OBJ_TYPE_FIXNUM |
296 | if (token_is_fixnum(token)) { | 307 | if (token_is_fixnum(*token)) { |
297 | // Convert token to fixnum. | 308 | // Convert token to fixnum. |
298 | ssize_t num = 0; | 309 | ssize_t num = 0; |
299 | int sign = 1; | 310 | int sign = 1; |
300 | for (size_t i = 0; i < token.n; i++) { | 311 | for (size_t i = 0; i < token->n; i++) { |
301 | char c = token.start[i]; | 312 | char c = token->start[i]; |
302 | if (c == '-') { | 313 | if (c == '-') { |
303 | sign = -1; | 314 | sign = -1; |
304 | continue; | 315 | continue; |
@@ -309,35 +320,32 @@ build_ast(Tokens tokens) { | |||
309 | } | 320 | } |
310 | 321 | ||
311 | // OBJ_TYPE_BOOL | 322 | // OBJ_TYPE_BOOL |
312 | if (sv_equal(token, TRUE_TOKEN)) { | 323 | if (sv_equal(*token, TRUE_TOKEN)) { |
313 | return make_boolean(true); | 324 | return make_boolean(true); |
314 | } | 325 | } |
315 | if (sv_equal(token, FALSE_TOKEN)) { | 326 | if (sv_equal(*token, FALSE_TOKEN)) { |
316 | return make_boolean(false); | 327 | return make_boolean(false); |
317 | } | 328 | } |
318 | 329 | ||
319 | // OBJ_TYPE_LIST | 330 | // OBJ_TYPE_LIST |
320 | if (token.start[0] == ')') { | 331 | if (token->start[0] == ')') { |
321 | return NULL; | 332 | return NULL; |
322 | } | 333 | } |
323 | if (token.start[0] == '(') { | 334 | if (token->start[0] == '(') { |
324 | if ((i + 1) < tokens.n && tokens.start[i + 1].start[0] == ')') { | 335 | if (tokens->n > 0 && tokens->start[0].start[0] == ')') { |
325 | return make_empty_list(); | 336 | return make_empty_list(); |
326 | } | 337 | } |
327 | 338 | ||
328 | Object *list = make_empty_list(); | 339 | Object *list = make_empty_list(); |
329 | Object *next_obj = NULL; | 340 | Object *next_obj = NULL; |
330 | while (((i + 1) < tokens.n) && (next_obj = build_ast((Tokens){&tokens.start[i + 1], tokens.n - i - 1})) != NULL) { | 341 | while (tokens->n > 0 && (next_obj = build_ast(tokens)) != NULL) { |
331 | push_obj_to_list(list, &next_obj); | 342 | push_obj_to_list(list, &next_obj); |
332 | // FIXME: must consume tokens instead, otherwise recursive lists | ||
333 | // will not work. | ||
334 | i++; | ||
335 | } | 343 | } |
336 | return list; | 344 | return list; |
337 | } | 345 | } |
338 | 346 | ||
339 | // OBJ_TYPE_SYMBOL | 347 | // OBJ_TYPE_SYMBOL |
340 | return make_symbol(token.start, token.n); | 348 | return make_symbol(token->start, token->n); |
341 | } | 349 | } |
342 | 350 | ||
343 | return NULL; | 351 | return NULL; |
@@ -393,7 +401,8 @@ main(void) { | |||
393 | while (true) { | 401 | while (true) { |
394 | printf(REPL_PROMPT); | 402 | printf(REPL_PROMPT); |
395 | StringView line = read_line(); | 403 | StringView line = read_line(); |
396 | Object *ast = build_ast(tokenize(line)); | 404 | Tokens tokens = tokenize(line); |
405 | Object *ast = build_ast(&tokens); | ||
397 | if (ast) { | 406 | if (ast) { |
398 | display(ast); | 407 | display(ast); |
399 | printf("\n"); | 408 | printf("\n"); |