diff options
Diffstat (limited to 'bootstrap')
| -rw-r--r-- | bootstrap/Makefile | 13 | ||||
| -rw-r--r-- | bootstrap/token.c | 120 |
2 files changed, 73 insertions, 60 deletions
diff --git a/bootstrap/Makefile b/bootstrap/Makefile index 2e8bb8e..6c9a77c 100644 --- a/bootstrap/Makefile +++ b/bootstrap/Makefile @@ -150,7 +150,8 @@ $(builddir)/stage2: $(STAGE2_OBJECTS) $(RTL_C_HEADERS) longlines outdirs # TODO add a proper test once the stage2 compiler is done check: $(builddir)/stage2 -check-all: check check-valgrind check-boundschecked clang-analyze longlines +check-all: check check-valgrind check-boundschecked clang-analyze \ + check-tokens longlines check-valgrind: $(builddir)/stage1 valgrind --leak-check=yes -q $(builddir)/stage1 $(STAGE1_ARGS) check-boundschecked: $(builddir)/stage1-boundschecked @@ -165,6 +166,16 @@ longlines: else \ true ;\ fi +check-tokens: + grep -E '^ +CMP_KW' $(srcdir)/token.c | \ + sed -E -e 's/^.*, "([^"]+)", T_KW_([a-zA-Z0-9_]+)\)/\1 \2/' | \ + while read kwstr kwconst; do \ + if [ "x$$kwstr" != "x$$kwconst" ]; then \ + printf "Keyword str \"%s\" and enum \"%s\" mismatch\n" \ + "$$kwstr" "$$kwconst" >&2; \ + exit 1; \ + fi; \ + done # Gives a lot of warnings (possibly false positives) and output gets mixed # up (unless a single file is processed). So not included in check-all. gcc-analyzer: diff --git a/bootstrap/token.c b/bootstrap/token.c index 322a3cc..99e4480 100644 --- a/bootstrap/token.c +++ b/bootstrap/token.c @@ -150,91 +150,93 @@ static enum Token tok_symbol(struct LexemeInfo *li_out) } -#define CMP_KW(length, keyword) \ - if (memcmp(ident, #keyword, (length)) == 0) { \ - return T_KW_##keyword; \ +#define CMP_KW(length, keyword_str, keyword_const) \ + if (memcmp(ident, keyword_str, (length)) == 0) { \ + return keyword_const; \ } static enum Token match_keyword(const char *ident, size_t len) { + /* These can be checked with `make -s check-tokens` + (included in `make check-all`) */ switch (len) { case 2: - CMP_KW(2, if) - CMP_KW(2, in) - CMP_KW(2, io) - CMP_KW(2, of) - CMP_KW(2, or) - CMP_KW(2, to) + CMP_KW(2, "if", T_KW_if) + CMP_KW(2, "in", T_KW_in) + CMP_KW(2, "io", T_KW_io) + CMP_KW(2, "of", T_KW_of) + CMP_KW(2, "or", T_KW_or) + CMP_KW(2, "to", T_KW_to) break; case 3: - CMP_KW(3, and) - CMP_KW(3, end) - CMP_KW(3, for) - CMP_KW(3, int) - CMP_KW(3, mod) - CMP_KW(3, not) + CMP_KW(3, "and", T_KW_and) + CMP_KW(3, "end", T_KW_end) + CMP_KW(3, "for", T_KW_for) + CMP_KW(3, "int", T_KW_int) + CMP_KW(3, "mod", T_KW_mod) + CMP_KW(3, "not", T_KW_not) /* XXX should there be `and`/`or`, or `all_of`/`any_of`/`none_of`? maybe there should be a T... safe-vararg, like in Java. */ break; case 4: - CMP_KW(4, bool) - CMP_KW(4, byte) - CMP_KW(4, case) - CMP_KW(4, code) - CMP_KW(4, elif) - CMP_KW(4, else) - CMP_KW(4, enum) - CMP_KW(4, from) - CMP_KW(4, func) - CMP_KW(4, long) - CMP_KW(4, none) - CMP_KW(4, sets) - CMP_KW(4, this) - CMP_KW(4, true) + CMP_KW(4, "bool", T_KW_bool) + CMP_KW(4, "byte", T_KW_byte) + CMP_KW(4, "case", T_KW_case) + CMP_KW(4, "code", T_KW_code) + CMP_KW(4, "elif", T_KW_elif) + CMP_KW(4, "else", T_KW_else) + CMP_KW(4, "enum", T_KW_enum) + CMP_KW(4, "from", T_KW_from) + CMP_KW(4, "func", T_KW_func) + CMP_KW(4, "long", T_KW_long) + CMP_KW(4, "none", T_KW_none) + CMP_KW(4, "sets", T_KW_sets) + CMP_KW(4, "this", T_KW_this) + CMP_KW(4, "true", T_KW_true) break; case 5: - CMP_KW(5, break) - CMP_KW(5, class) - CMP_KW(5, entry) - CMP_KW(5, false) - CMP_KW(5, local) - CMP_KW(5, reads) - CMP_KW(5, trait) - CMP_KW(5, while) + CMP_KW(5, "break", T_KW_break) + CMP_KW(5, "class", T_KW_class) + CMP_KW(5, "entry", T_KW_entry) + CMP_KW(5, "false", T_KW_false) + CMP_KW(5, "local", T_KW_local) + CMP_KW(5, "reads", T_KW_reads) + CMP_KW(5, "trait", T_KW_trait) + CMP_KW(5, "while", T_KW_while) break; case 6: - CMP_KW(6, assert) - CMP_KW(6, export) - CMP_KW(6, giveme) - CMP_KW(6, ignore) - CMP_KW(6, record) - CMP_KW(6, return) - CMP_KW(6, signed) - CMP_KW(6, switch) + CMP_KW(6, "assert", T_KW_assert) + CMP_KW(6, "export", T_KW_export) + CMP_KW(6, "giveme", T_KW_giveme) + CMP_KW(6, "ignore", T_KW_ignore) + CMP_KW(6, "record", T_KW_record) + CMP_KW(6, "return", T_KW_return) + CMP_KW(6, "signed", T_KW_signed) + CMP_KW(6, "switch", T_KW_switch) break; case 7: - CMP_KW(7, aliased) - CMP_KW(7, default) - CMP_KW(7, loopend) - CMP_KW(7, returns) - CMP_KW(7, section) + CMP_KW(7, "aliased", T_KW_aliased) + CMP_KW(7, "default", T_KW_default) + CMP_KW(7, "loopend", T_KW_loopend) + CMP_KW(7, "returns", T_KW_returns) + CMP_KW(7, "section", T_KW_section) break; case 8: - CMP_KW(8, continue) - CMP_KW(8, modifies) - CMP_KW(8, unsigned) - CMP_KW(8, volatile) - CMP_KW(8, wrapping) + CMP_KW(8, "continue", T_KW_continue) + CMP_KW(8, "modifies", T_KW_modifies) + CMP_KW(8, "unsigned", T_KW_unsigned) + CMP_KW(8, "volatile", T_KW_volatile) + CMP_KW(8, "wrapping", T_KW_wrapping) break; case 9: - CMP_KW(9, loopempty) - CMP_KW(9, templates) + CMP_KW(9, "loopempty", T_KW_loopempty) + CMP_KW(9, "templates", T_KW_templates) break; case 10: - CMP_KW(10, calledfrom) + CMP_KW(10, "calledfrom", T_KW_calledfrom) break; case 11: - CMP_KW(11, constructor) + CMP_KW(11, "constructor", T_KW_constructor) break; } return 0; |
