summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeo Tenenbaum <pommicket@gmail.com>2020-02-26 21:19:45 -0500
committerLeo Tenenbaum <pommicket@gmail.com>2020-02-26 21:19:45 -0500
commit4aeae5a6d0ecec5558b69492e489535e41b49649 (patch)
tree7bf826ae1ac4f98c6da8c3f2e4cd48d621587575
parentbfee5c00eed983ccf74810a366112e106226ace2 (diff)
syntax for including something into a namespace
-rw-r--r--main.c2
-rw-r--r--parse.c48
-rw-r--r--test.toc12
-rw-r--r--toc.c1
4 files changed, 57 insertions, 6 deletions
diff --git a/main.c b/main.c
index 696f7d8..d57401a 100644
--- a/main.c
+++ b/main.c
@@ -8,7 +8,7 @@
/*
TODO:
-nice syntax for #including something into a namespace
+compile without Wno-unused-function
run stuff at compile time without assigning it to a constant
better #foreign system- something like f := #foreign fn (int,float, #C int);
---
diff --git a/parse.c b/parse.c
index 1861996..3e69d0a 100644
--- a/parse.c
+++ b/parse.c
@@ -2173,10 +2173,51 @@ static Status parse_stmt(Parser *p, Statement *s, bool *was_a_statement) {
case DIRECT_INCLUDE: {
++t->token;
s->kind = STMT_INCLUDE;
- if (!parse_expr(p, &s->inc.filename, expr_find_end(p, 0)))
+ if (!parse_expr(p, &s->inc.filename, expr_find_end(p, EXPR_CAN_END_WITH_COMMA)))
return false;
+ if (token_is_kw(t->token, KW_COMMA)) {
+ Expression filename = s->inc.filename;
+ ++t->token;
+ if (t->token->kind != TOKEN_IDENT) {
+ tokr_err(t, "Expected identifier for #include name (after comma).");
+ tokr_skip_semicolon(t);
+ return false;
+ }
+ Identifier ident = parser_ident_insert(p, t->token->ident);
+ ++t->token;
+ s->where.end = t->token;
+ /* this isn't actually a STMT_INCLUDE, but a STMT_DECL! */
+ /* replace #include "io.toc", io => io ::= nms { #include "io.toc"; } */
+ s->kind = STMT_DECL;
+ Declaration *d = s->decl = parser_calloc(p, 1, sizeof *d);
+ d->where = s->where;
+ d->flags |= DECL_HAS_EXPR|DECL_IS_CONST;
+ *(Identifier *)parser_arr_add(p, &d->idents) = ident;
+
+ if (!check_ident_redecl(p, ident)) {
+ tokr_skip_semicolon(t);
+ return false;
+ }
+ ident->decl_kind = IDECL_DECL;
+ ident->decl = d;
+
+ Expression *e = &d->expr;
+ e->kind = EXPR_NMS;
+ e->where = s->where;
+ e->nms.associated_ident = ident;
+ Block *body = &e->nms.body;
+ body->flags |= BLOCK_IS_NMS;
+ body->where = s->where;
+ idents_create(&body->idents, p->allocr, body);
+ Statement *inc_stmt = parser_arr_add(p, &body->stmts);
+ inc_stmt->kind = STMT_INCLUDE;
+ inc_stmt->flags = 0;
+ inc_stmt->where = s->where;
+ inc_stmt->inc.filename = filename;
+ }
if (!token_is_kw(t->token, KW_SEMICOLON)) {
tokr_err(t, "Expected ; after #include directive");
+ tokr_skip_semicolon(t);
return false;
}
++t->token;
@@ -2526,6 +2567,11 @@ static void fprint_decl(FILE *out, Declaration *d) {
}
}
+static void print_decl(Declaration *d) {
+ fprint_decl(stdout, d);
+ printf("\n");
+}
+
static void fprint_stmt(FILE *out, Statement *s) {
PARSE_PRINT_LOCATION(s->where);
switch (s->kind) {
diff --git a/test.toc b/test.toc
index ce0eac0..91b8cbc 100644
--- a/test.toc
+++ b/test.toc
@@ -1,6 +1,10 @@
-realloc ::= fn() int {
- #C("4")
-};
+#include "std/io.toc", io;
+#include "std/io.toc", super;
+#include "std/io.toc", great;
+
main ::= fn() {
- y := realloc();
+ io.puti(7);
+ io.puts("Hello!");
+ super.puts("hey");
+ great.puti(1232);
}; \ No newline at end of file
diff --git a/toc.c b/toc.c
index 5a3b4c7..ce892f2 100644
--- a/toc.c
+++ b/toc.c
@@ -92,6 +92,7 @@
static void print_val(Value v, Type *t);
static void print_token(Token *t);
static void print_block(Block *b);
+static void print_decl(Declaration *d);
static void print_block_location(Block *b);