summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeo Tenenbaum <pommicket@gmail.com>2020-05-08 16:40:20 -0400
committerLeo Tenenbaum <pommicket@gmail.com>2020-05-08 16:40:20 -0400
commit270ce8372aeddaa3f10362f88473ceb1159b9b5f (patch)
treeddbb7cc772d385bdcfb596722c8c09fff32c664c
parent1fac85b953b4a522e6b03fafa97c25a61e1c62ea (diff)
#no_warn
-rw-r--r--err.c8
-rw-r--r--main.c1
-rw-r--r--misc.c18
-rw-r--r--test.toc17
-rw-r--r--tests/misc.toc3
-rw-r--r--tests/misc_expected1
-rw-r--r--tokenizer.c12
-rw-r--r--types.h4
8 files changed, 47 insertions, 17 deletions
diff --git a/err.c b/err.c
index 1a78e64..334fa69 100644
--- a/err.c
+++ b/err.c
@@ -238,6 +238,14 @@ static void warn_print_(
va_list args;
ErrCtx *ctx = where.file->ctx;
if (!ctx->enabled) return;
+ if (where.file) {
+ /* check if there's a #no_warn directive */
+ U32 *no_warn_lines = where.file->no_warn_lines;
+ if (bsearch_u32(no_warn_lines, arr_len(no_warn_lines), where.file->tokens[where.start].pos.line)) {
+ /* yes there is */
+ return;
+ }
+ }
#if ERR_SHOW_SOURCE_LOCATION
if (file)
err_fprint(ctx, "Generated by line %d of %s:\n", line, file);
diff --git a/main.c b/main.c
index 02f488b..631e456 100644
--- a/main.c
+++ b/main.c
@@ -8,7 +8,6 @@
/*
@TODO:
-#no_warn
start making a standard library... (printf; stringbuilder would be nice to have)
if we do #include "foo.toc", bar; and foo.toc fails, bar should be declared as TYPE_UNKNOWN (right now it's undeclared)
improve type_to_str:
diff --git a/misc.c b/misc.c
index 0a8ee86..655fce8 100644
--- a/misc.c
+++ b/misc.c
@@ -88,3 +88,21 @@ static const char *indefinite_article(const char *s) {
return "a";
}
+
+static U32 *bsearch_u32(U32 *data, size_t count, U32 search) {
+ size_t lo = 0;
+ size_t hi = count;
+ while (hi > lo) {
+ size_t mid = (lo+hi) / 2;
+ U32 datum = data[mid];
+ if (datum > search)
+ hi = mid;
+ else if (datum < search)
+ lo = mid + 1;
+ else
+ return &data[mid];
+ }
+ return NULL;
+}
+
+
diff --git a/test.toc b/test.toc
index 0f4d5a4..6c66a8b 100644
--- a/test.toc
+++ b/test.toc
@@ -1,14 +1,9 @@
#include "std/io.toc", io;
-foo ::= fn() {
- x := bar(12);
- io.puti(x);
+main ::= fn() {
+ #warn("foo"); #no_warn
+ x := 0 as &int; #no_warn
+ #warn("foo"); #no_warn
+ #warn("foo"); #no_warn
+ #warn("foo"); #no_warn
}
-
-bar ::= fn(x: int) int {
- y := x;
- io.puti(y);
- y
-}
-
-foo();
diff --git a/tests/misc.toc b/tests/misc.toc
index 5dcd1eb..3673a07 100644
--- a/tests/misc.toc
+++ b/tests/misc.toc
@@ -37,4 +37,7 @@ main ::= fn() {
p.e = 100;
io.puti(p["bar"]);
io.puti(p["e"]);
+
+ foo := 4483 as &int; #no_warn
+ io.puti(foo as int); #no_warn
};
diff --git a/tests/misc_expected b/tests/misc_expected
index e35eecf..8e67335 100644
--- a/tests/misc_expected
+++ b/tests/misc_expected
@@ -4,3 +4,4 @@ Hello!
0
3
100
+4483
diff --git a/tokenizer.c b/tokenizer.c
index d90a4f6..9c48a1a 100644
--- a/tokenizer.c
+++ b/tokenizer.c
@@ -325,10 +325,14 @@ static Status tokenize_file(Tokenizer *t, File *file) {
Directive direct = tokenize_direct(&t->s);
if (direct != DIRECT_COUNT) {
/* it's a directive */
- tokr_put_end_pos(t, &token);
- token.kind = TOKEN_DIRECT;
- token.direct = direct;
- arr_adda(t->tokens, token, t->allocr);
+ if (direct == DIRECT_NO_WARN) {
+ arr_adda(file->no_warn_lines, t->line, t->allocr);
+ } else {
+ tokr_put_end_pos(t, &token);
+ token.kind = TOKEN_DIRECT;
+ token.direct = direct;
+ arr_adda(t->tokens, token, t->allocr);
+ }
continue;
}
--t->s; /* go back to # */
diff --git a/types.h b/types.h
index ed5f75f..8d68ab7 100644
--- a/types.h
+++ b/types.h
@@ -248,12 +248,13 @@ typedef enum {
DIRECT_ERROR,
DIRECT_WARN,
DIRECT_INFO,
+ DIRECT_NO_WARN,
DIRECT_COUNT
} Directive;
static const char *directives[DIRECT_COUNT] = {
"C", "sizeof", "alignof", "export", "foreign", "builtin", "include", "force", "if", "error", "warn",
- "info"
+ "info", "no_warn"
};
typedef enum {
@@ -389,6 +390,7 @@ typedef struct {
const char *filename;
char *contents;
Token *tokens;
+ U32 *no_warn_lines; /* in sorted order; right now we do a binary search */
} File;
typedef struct Location {