From 4aeae5a6d0ecec5558b69492e489535e41b49649 Mon Sep 17 00:00:00 2001 From: Leo Tenenbaum Date: Wed, 26 Feb 2020 21:19:45 -0500 Subject: syntax for including something into a namespace --- main.c | 2 +- parse.c | 48 +++++++++++++++++++++++++++++++++++++++++++++++- test.toc | 12 ++++++++---- toc.c | 1 + 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); -- cgit v1.2.3