From 35d80c91353a4a0b1d6d5575a481e3c2afeb2a06 Mon Sep 17 00:00:00 2001 From: Leo Tenenbaum Date: Fri, 26 Jun 2020 15:37:12 -0400 Subject: finished moving #include to parsing --- allocator.c | 7 +++++++ copy.c | 1 + development.md | 21 +++++++++++++++++++++ err.c | 10 +++++++--- parse.c | 19 ++++++++++++++----- rung | 2 +- test.toc | 16 +--------------- types.c | 13 ++++++++----- 8 files changed, 60 insertions(+), 29 deletions(-) diff --git a/allocator.c b/allocator.c index 98005ef..f3fbff6 100644 --- a/allocator.c +++ b/allocator.c @@ -114,3 +114,10 @@ static void allocr_free_all(Allocator *a) { page = next; } } + +static char *allocr_str_to_cstr(Allocator *a, String s) { + char *ret = allocr_malloc(a, s.len + 1); + memcpy(ret, s.str, s.len); + ret[s.len] = 0; + return ret; +} diff --git a/copy.c b/copy.c index e96b2ac..0adce52 100644 --- a/copy.c +++ b/copy.c @@ -419,6 +419,7 @@ static void copy_stmt(Copier *c, Statement *out, Statement *in) { break; case STMT_INLINE_BLOCK: { size_t nstmts = arr_len(in->inline_block); + out->inline_block = NULL; arr_set_lena(out->inline_block, nstmts, c->allocr); for (size_t i = 0; i < nstmts; ++i) { copy_stmt(c, &out->inline_block[i], &in->inline_block[i]); diff --git a/development.md b/development.md index daa0735..e3ec8c4 100644 --- a/development.md +++ b/development.md @@ -36,3 +36,24 @@ declaration). It is assumed that the number of identifiers in a declaration, or parameters to a function will fit in an int, since a function with (at least) 32768 parameters is ridiculous. + + +#### Miscellaneous thoughts + +Wouldn't it be nice if `#include` could be done during typing, so that the filename wouldn't have to be a +string literal? Well, unfortunately we end up in situations like this: +``` +asdf ::= fn() { + x ::= bar(); + a: [x]int; + // ... +} +#include "foo.toc"; // foo defined here +bar ::= fn() int { + return foo(17); +} +``` +The way we evaluate `bar()` is by typing the function `bar` when we come across it in the declaration `x ::= bar();`. +In order to evaluate `foo`, we need to know what it refers to, and we don't know at this point that it comes from the +include, because we haven't expanded it yet. We could potentially expand all includes preceding any function which +is evaluated during typing, but that seems a bit cumbersome and would probably cause other problems. diff --git a/err.c b/err.c index 334fa69..4853966 100644 --- a/err.c +++ b/err.c @@ -86,7 +86,7 @@ static void print_location_highlight(FILE *out, Location where) { assert(where.end >= where.start); File *f = where.file; ErrCtx *ctx = f->ctx; - if (where.start == 0 && where.end == 0) { err_fprint(ctx, "\n"); return; } /* null location */ + if (where.start == 0 && where.end == 0) { fprintf(out, "\n"); return; } /* null location */ Token *first = &f->tokens[where.start]; Token *last = &f->tokens[where.end-1]; @@ -96,8 +96,12 @@ static void print_location_highlight(FILE *out, Location where) { /* for debugging */ static void fprint_location(FILE *out, Location location) { File *f = location.file; - fprintf(out, "Line %ld of %s: ", (long)f->tokens[location.start].pos.line, f->filename); - print_location_highlight(out, location); + if (location.start == 0 && location.end == 0) { + fprintf(out, "In %s\n", f->filename); + } else { + fprintf(out, "Line %ld of %s: ", (long)f->tokens[location.start].pos.line, f->filename); + print_location_highlight(out, location); + } } static void print_location(Location location) { diff --git a/parse.c b/parse.c index 1f0bdd7..5679e20 100644 --- a/parse.c +++ b/parse.c @@ -2501,7 +2501,7 @@ static Status parse_stmt(Parser *p, Statement *s, bool *was_a_statement) { tokr_err(t, "#include file name must be string literal."); return false; } - char *filename = str_to_cstr(t->token->str); + char *filename = allocr_str_to_cstr(p->allocr, t->token->str); ++t->token; Identifier nms_ident = NULL; /* identifier of namespace to include to */ if (token_is_kw(t->token, KW_COMMA)) { @@ -2560,8 +2560,8 @@ static Status parse_stmt(Parser *p, Statement *s, bool *was_a_statement) { i->decl = d; d->expr.kind = EXPR_NMS; d->expr.nms = inc_nms; - d->expr.flags = EXPR_FOUND_TYPE; d->expr.type = d->type; + parser_put_end(p, &s->where); d->where = d->expr.where = s->where; /* we need to be in the block to parse it properly */ p->block = &inc_nms->body; @@ -2610,6 +2610,14 @@ static Status parse_stmt(Parser *p, Statement *s, bool *was_a_statement) { if (!tokenize_file(&tokr, file)) { success = false; goto nms_done; } + + #if 0 + arr_foreach(tokr.tokens, Token, token) { + fprint_token(stdout, token); + printf(" "); + } + #endif + Parser parser; parser_create(&parser, p->globals, &tokr, p->allocr, p->main_file); parser.block = p->block; @@ -2634,7 +2642,6 @@ static Status parse_stmt(Parser *p, Statement *s, bool *was_a_statement) { } if (inc_f) inc_f->flags &= (IncFileFlags)~(IncFileFlags)INC_FILE_INCLUDING; if (!success) return false; - free(filename); } break; case DIRECT_IF: goto if_stmt; @@ -2662,8 +2669,7 @@ static Status parse_stmt(Parser *p, Statement *s, bool *was_a_statement) { tokr_skip_semicolon(t); return false; } - break; - } + } break; case DIRECT_INIT: { *was_a_statement = false; Initialization *init = parser_arr_add_ptr(p, p->parsed_file->inits); @@ -3063,6 +3069,8 @@ static void fprint_stmt(FILE *out, Statement *s) { bool first = true; while (i) { if (i->cond) { + if (first && (i->flags & IF_STATIC)) + fprintf(out, "#"); fprintf(out, "%sif ", first ? "" : "el"); fprint_expr(out, i->cond); } else { @@ -3070,6 +3078,7 @@ static void fprint_stmt(FILE *out, Statement *s) { } fprint_block(out, &i->body); first = false; + i = i->next_elif; } } break; case STMT_WHILE: { diff --git a/rung b/rung index 3de6ab2..1450fc8 100755 --- a/rung +++ b/rung @@ -1,2 +1,2 @@ #!/bin/bash -gdb toc +gdb -q toc diff --git a/test.toc b/test.toc index ca38680..5976415 100644 --- a/test.toc +++ b/test.toc @@ -1,20 +1,6 @@ #include "tests/std/io.toc"; -#init(-50) init(1); -#init(30) init(2); -#init(-7) init(3); -#init(-42) init(4); - -init ::= fn(a: int) { - writes("Initializing... #"); - writei(a); - x = 5; -} - -x: int; - main ::= fn() { - writes("Main's value of x is: "); - puti(x); + puts("hello"); } diff --git a/types.c b/types.c index da95847..c01cac6 100644 --- a/types.c +++ b/types.c @@ -3039,7 +3039,6 @@ static Status types_decl(Typer *tr, Declaration *d) { && tr->fn == NULL) { e->typeval->struc->name = d->idents[0]; } - if (!types_expr(tr, e)) { success = false; goto ret; @@ -3266,7 +3265,6 @@ top: } } } break; - case STMT_FOR: { bool in_header = true; Block *prev_block = tr->block; { /* additional block because c++ */ @@ -3792,9 +3790,14 @@ top: else typer_arr_add(tr, tr->uses, u); } break; - case STMT_INLINE_BLOCK: - assert(0); /* only exists after typing */ - break; + case STMT_INLINE_BLOCK: { + bool success = true; + arr_foreach(s->inline_block, Statement, sub) { + if (!types_stmt(tr, sub)) + success = false; + } + if (!success) return false; + } break; } success: s->flags |= STMT_TYPED; -- cgit v1.2.3