summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeo Tenenbaum <pommicket@gmail.com>2020-06-26 15:37:12 -0400
committerLeo Tenenbaum <pommicket@gmail.com>2020-06-26 15:37:12 -0400
commit35d80c91353a4a0b1d6d5575a481e3c2afeb2a06 (patch)
tree825938acbcfb68b2d64af68fa4cc7d9ce1178772
parent4ab1fd88714fe4314bef7b1cc2429c655e482540 (diff)
finished moving #include to parsing
-rw-r--r--allocator.c7
-rw-r--r--copy.c1
-rw-r--r--development.md21
-rw-r--r--err.c10
-rw-r--r--parse.c19
-rwxr-xr-xrung2
-rw-r--r--test.toc16
-rw-r--r--types.c13
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;