summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--main.c3
-rw-r--r--parse.c6
-rw-r--r--test.toc6
-rw-r--r--tokenizer.c15
-rw-r--r--types.c18
-rw-r--r--types.h27
6 files changed, 45 insertions, 30 deletions
diff --git a/main.c b/main.c
index c78630c..0ff8002 100644
--- a/main.c
+++ b/main.c
@@ -8,8 +8,7 @@
/*
TODO:
-#include_forced
-better #foreign system- something like f := #foreign fn (int,float, #C int);
+better #foreign system- something like f := #foreign fn (int,float, #C int, #C longlong);
---
constants in structs
#if
diff --git a/parse.c b/parse.c
index 44b4d25..a9d7ba9 100644
--- a/parse.c
+++ b/parse.c
@@ -1853,6 +1853,7 @@ static Status parse_expr(Parser *p, Expression *e, Token *end) {
case DIRECT_FOREIGN:
case DIRECT_EXPORT:
case DIRECT_INCLUDE:
+ case DIRECT_FORCE:
tokr_err(t, "Unrecognized expression.");
return false;
case DIRECT_COUNT: assert(0); break;
@@ -2172,6 +2173,11 @@ static Status parse_stmt(Parser *p, Statement *s, bool *was_a_statement) {
case DIRECT_INCLUDE: {
++t->token;
s->kind = STMT_INCLUDE;
+ s->inc.flags = 0;
+ if (token_is_direct(t->token, DIRECT_FORCE)) {
+ s->inc.flags |= INC_FORCED;
+ ++t->token;
+ }
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)) {
diff --git a/test.toc b/test.toc
index 69794b5..2a4b107 100644
--- a/test.toc
+++ b/test.toc
@@ -1,6 +1,6 @@
-#include "std/io.toc", io;
-#include "std/io.toc", foo;
-#include "std/io.toc";
+#include #force "std/io.toc", io;
+#include #force "std/io.toc", foo;
+#include #force "std/io.toc";
a ::= nms {
b ::= nms {
diff --git a/tokenizer.c b/tokenizer.c
index e31c2eb..15f7452 100644
--- a/tokenizer.c
+++ b/tokenizer.c
@@ -3,24 +3,9 @@
This file is part of toc. toc is distributed under version 3 of the GNU General Public License, without any warranty whatsoever.
You should have received a copy of the GNU General Public License along with toc. If not, see <https://www.gnu.org/licenses/>.
*/
-static const char *const keywords[KW_COUNT] =
- {";", ":", ",", "(", ")", "{", "}", "[", "]", "==",
- "+=", "-=", "*=", "/=", "%=",
- "!=", "<=", "<", ">=", ">",
- "+", "-", "*", "!", "&", "/", "%", "..", ".",
- "=",
- "if", "elif", "else", "while", "for", "return", "fn", "as",
- "new", "del", "struct",
- "int", "i8", "i16", "i32", "i64",
- "u8", "u16", "u32", "u64", "float", "f32", "f64", "Type",
- "Namespace",
- "char", "bool", "true", "false", "nms"};
static inline const char *kw_to_str(Keyword k) { return keywords[k]; }
-static const char *directives[DIRECT_COUNT] =
- {"C", "sizeof", "alignof", "export", "foreign", "builtin", "include"};
-
/* Returns KW_COUNT if it's not a keyword */
/* OPTIM: don't use strncmp so much */
static Keyword tokenize_kw(char **s) {
diff --git a/types.c b/types.c
index e772715..017e23c 100644
--- a/types.c
+++ b/types.c
@@ -2902,14 +2902,16 @@ static Status types_stmt(Typer *tr, Statement *s) {
size_t filename_len = strlen(filename);
IncludedFile *inc_f = NULL;
if (s->flags & STMT_INC_TO_NMS) {
- inc_f = str_hash_table_get(&tr->included_files, filename, filename_len);
- if (inc_f) {
- tr->nms->body.idents = inc_f->main_nms->body.idents;
- tr->nms->body.idents.scope = &tr->nms->body;
- tr->nms->points_to = inc_f->main_nms;
- s->inc.inc_file = inc_f;
- s->inc.stmts = inc_f->stmts;
- break;
+ if (!(s->inc.flags & INC_FORCED)) {
+ inc_f = str_hash_table_get(&tr->included_files, filename, filename_len);
+ if (inc_f) {
+ tr->nms->body.idents = inc_f->main_nms->body.idents;
+ tr->nms->body.idents.scope = &tr->nms->body;
+ tr->nms->points_to = inc_f->main_nms;
+ s->inc.inc_file = inc_f;
+ s->inc.stmts = inc_f->stmts;
+ break;
+ }
}
s->inc.inc_file = inc_f = str_hash_table_insert(&tr->included_files, filename, filename_len);
inc_f->main_nms = tr->nms;
diff --git a/types.h b/types.h
index 10525a6..fb848f9 100644
--- a/types.h
+++ b/types.h
@@ -232,9 +232,13 @@ typedef enum {
DIRECT_FOREIGN,
DIRECT_BUILTIN,
DIRECT_INCLUDE,
+ DIRECT_FORCE,
DIRECT_COUNT
} Directive;
+static const char *directives[DIRECT_COUNT] =
+ {"C", "sizeof", "alignof", "export", "foreign", "builtin", "include", "force"};
+
typedef enum {
KW_SEMICOLON,
KW_COLON,
@@ -300,6 +304,18 @@ typedef enum {
KW_COUNT
} Keyword;
+static const char *const keywords[KW_COUNT] =
+ {";", ":", ",", "(", ")", "{", "}", "[", "]", "==",
+ "+=", "-=", "*=", "/=", "%=",
+ "!=", "<=", "<", ">=", ">",
+ "+", "-", "*", "!", "&", "/", "%", "..", ".",
+ "=",
+ "if", "elif", "else", "while", "for", "return", "fn", "as",
+ "new", "del", "struct",
+ "int", "i8", "i16", "i32", "i64",
+ "u8", "u16", "u32", "u64", "float", "f32", "f64", "Type",
+ "Namespace",
+ "char", "bool", "true", "false", "nms"};
typedef enum {
NUM_LITERAL_INT,
@@ -850,9 +866,16 @@ typedef struct {
struct Statement *stmts;
} IncludedFile;
+enum {
+ INC_FORCED = 0x01
+};
+
typedef union {
- Expression filename; /* before typing */
- struct Statement *stmts; /* after typing */
+ U8 flags;
+ union {
+ Expression filename; /* before typing */
+ struct Statement *stmts; /* after typing */
+ };
IncludedFile *inc_file;
} Include;