diff --git a/include/asm/warning.h b/include/asm/warning.h index 485fdefb..b76f4c65 100644 --- a/include/asm/warning.h +++ b/include/asm/warning.h @@ -22,6 +22,7 @@ enum WarningID { WARNING_EMPTY_ENTRY, /* Empty entry in `db`, `dw` or `dl` */ WARNING_LARGE_CONSTANT, /* Constants too large */ WARNING_LONG_STR, /* String too long for internal buffers */ + WARNING_NESTED_COMMENT, /* Comment-start delimeter in a block comment */ WARNING_OBSOLETE, /* Obsolete things */ WARNING_SHIFT, /* Shifting undefined behavior */ WARNING_SHIFT_AMOUNT, /* Strange shift amount */ diff --git a/src/asm/lexer.c b/src/asm/lexer.c index 36c575c7..0c28fae9 100644 --- a/src/asm/lexer.c +++ b/src/asm/lexer.c @@ -921,6 +921,33 @@ void lexer_DumpStringExpansions(void) free(stack); } +/* Discards an block comment */ +static void discardBlockComment(void) +{ + dbgPrint("Discarding block comment\n"); + for (;;) { + switch (nextChar()) { + case EOF: + error("Unterminated block comment\n"); + return; + case '/': + if (peek(0) == '*') { + warning(WARNING_NESTED_COMMENT, + "/* in block comment\n"); + } + continue; + case '*': + if (peek(0) == '/') { + shiftChars(1); + return; + } + /* fallthrough */ + default: + continue; + } + } +} + /* Function to discard all of a line's comments */ static void discardComment(void) @@ -1476,8 +1503,6 @@ static int yylex_NORMAL(void) return T_OP_ADD; case '-': return T_OP_SUB; - case '/': - return T_OP_DIV; case '~': return T_OP_NOT; @@ -1498,7 +1523,14 @@ static int yylex_NORMAL(void) /* Handle ambiguous 1- or 2-char tokens */ char secondChar; - + case '/': /* Either division or a block comment */ + secondChar = peek(0); + if (secondChar == '*') { + shiftChars(1); + discardBlockComment(); + break; + } + return T_OP_DIV; case '|': /* Either binary or logical OR */ secondChar = peek(0); if (secondChar == '|') { diff --git a/src/asm/warning.c b/src/asm/warning.c index f8ea7cb9..12a5e603 100644 --- a/src/asm/warning.c +++ b/src/asm/warning.c @@ -36,6 +36,7 @@ static enum WarningState const defaultWarnings[NB_WARNINGS] = { [WARNING_EMPTY_ENTRY] = WARNING_DISABLED, [WARNING_LARGE_CONSTANT] = WARNING_DISABLED, [WARNING_LONG_STR] = WARNING_DISABLED, + [WARNING_NESTED_COMMENT] = WARNING_ENABLED, [WARNING_OBSOLETE] = WARNING_ENABLED, [WARNING_SHIFT] = WARNING_DISABLED, [WARNING_SHIFT_AMOUNT] = WARNING_DISABLED, @@ -75,6 +76,7 @@ static char const *warningFlags[NB_WARNINGS_ALL] = { "empty-entry", "large-constant", "long-string", + "nested-comment", "obsolete", "shift", "shift-amount", @@ -104,6 +106,7 @@ static uint8_t const _wallCommands[] = { /* Warnings that are less likely to indicate an error */ static uint8_t const _wextraCommands[] = { WARNING_EMPTY_ENTRY, + WARNING_NESTED_COMMENT, META_WARNING_DONE }; @@ -115,6 +118,7 @@ static uint8_t const _weverythingCommands[] = { WARNING_EMPTY_ENTRY, WARNING_LARGE_CONSTANT, WARNING_LONG_STR, + WARNING_NESTED_COMMENT, WARNING_OBSOLETE, WARNING_SHIFT, WARNING_SHIFT_AMOUNT, diff --git a/test/asm/block-comment-contents-error.asm b/test/asm/block-comment-contents-error.asm new file mode 100644 index 00000000..27706284 --- /dev/null +++ b/test/asm/block-comment-contents-error.asm @@ -0,0 +1,2 @@ +/* block comments containing /* throw warnings */ +PRINTT "reachable\n" diff --git a/test/asm/block-comment-contents-error.err b/test/asm/block-comment-contents-error.err new file mode 100644 index 00000000..29b23d72 --- /dev/null +++ b/test/asm/block-comment-contents-error.err @@ -0,0 +1,2 @@ +warning: block-comment-contents-error.asm(1): [-Wnested-comment] + /* in block comment diff --git a/test/asm/block-comment-contents-error.out b/test/asm/block-comment-contents-error.out new file mode 100644 index 00000000..677f14a8 --- /dev/null +++ b/test/asm/block-comment-contents-error.out @@ -0,0 +1 @@ +reachable diff --git a/test/asm/block-comment-termination-error.asm b/test/asm/block-comment-termination-error.asm new file mode 100644 index 00000000..bfac2131 --- /dev/null +++ b/test/asm/block-comment-termination-error.asm @@ -0,0 +1 @@ +PRINTT /* block comments must terminate before EOF \ No newline at end of file diff --git a/test/asm/block-comment-termination-error.err b/test/asm/block-comment-termination-error.err new file mode 100644 index 00000000..770bc9e9 --- /dev/null +++ b/test/asm/block-comment-termination-error.err @@ -0,0 +1,5 @@ +ERROR: block-comment-termination-error.asm(1): + Unterminated block comment +ERROR: block-comment-termination-error.asm(1): + syntax error +error: Assembly aborted (2 errors)! diff --git a/test/asm/block-comment-termination-error.out b/test/asm/block-comment-termination-error.out new file mode 100644 index 00000000..e69de29b diff --git a/test/asm/block-comment.asm b/test/asm/block-comment.asm new file mode 100644 index 00000000..2ea9b3e6 --- /dev/null +++ b/test/asm/block-comment.asm @@ -0,0 +1,5 @@ +PRINTT /* block comments are ignored // ** */ "hi\n" +PRINTT "block (/* ... */) comments at ends of line are fine\n" /* hi */ +PRINTT /* block comments +can span multiple lines +*/ "mutliline\n" diff --git a/test/asm/block-comment.err b/test/asm/block-comment.err new file mode 100644 index 00000000..e69de29b diff --git a/test/asm/block-comment.out b/test/asm/block-comment.out new file mode 100644 index 00000000..eb9e1196 --- /dev/null +++ b/test/asm/block-comment.out @@ -0,0 +1,3 @@ +hi +block (/* ... */) comments at ends of line are fine +mutliline diff --git a/test/asm/weird-comments.asm b/test/asm/weird-comments.asm new file mode 100644 index 00000000..19e9978c --- /dev/null +++ b/test/asm/weird-comments.asm @@ -0,0 +1,2 @@ +PRINTT /* // PRINTT "this is **comm //ented out\n" */ "this is not commented out\n" +PRINTT /*//*/ "this is not commented out\n" \ No newline at end of file diff --git a/test/asm/weird-comments.err b/test/asm/weird-comments.err new file mode 100644 index 00000000..0167e0ea --- /dev/null +++ b/test/asm/weird-comments.err @@ -0,0 +1,2 @@ +warning: weird-comments.asm(2): [-Wnested-comment] + /* in block comment diff --git a/test/asm/weird-comments.out b/test/asm/weird-comments.out new file mode 100644 index 00000000..9067359e --- /dev/null +++ b/test/asm/weird-comments.out @@ -0,0 +1,2 @@ +this is not commented out +this is not commented out