diff options
-rw-r--r-- | allocator.c | 7 | ||||
-rw-r--r-- | copy.c | 1 | ||||
-rw-r--r-- | development.md | 21 | ||||
-rw-r--r-- | err.c | 10 | ||||
-rw-r--r-- | parse.c | 19 | ||||
-rwxr-xr-x | rung | 2 | ||||
-rw-r--r-- | test.toc | 16 | ||||
-rw-r--r-- | 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; +} @@ -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. @@ -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) { @@ -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: { @@ -1,2 +1,2 @@ #!/bin/bash -gdb toc +gdb -q 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"); } @@ -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; |