diff options
| -rw-r--r-- | docs/c_grammar.md | 10 | ||||
| -rw-r--r-- | src/parse.c | 24 | ||||
| -rw-r--r-- | tests/assert.c | 10 |
3 files changed, 36 insertions, 8 deletions
diff --git a/docs/c_grammar.md b/docs/c_grammar.md index 3bde591..807db1a 100644 --- a/docs/c_grammar.md +++ b/docs/c_grammar.md @@ -18,7 +18,7 @@ * `{ A |? S }*`: 1 or more repetitions of A separated by S, allowing optional trailing S * Equivalent to `{ A |? S }+?` * `( A )`: Grouping -* `# ...`: Additional constraints +* `/* ... */`: Additional constraints ## Expressions @@ -429,10 +429,6 @@ translation-unit: { external-declaration }+ external-declaration: - function-definition - declaration - -external-declaration: static_assert-declaration attribute-specifier-sequence ';' attribute-specifier-sequence function-definition-or-declaration-rest @@ -441,6 +437,6 @@ external-declaration: function-definition-or-declaration-rest: declaration-specifiers init-declarator-list ';' declaration-specifiers init-declarator-list compound-stmt - # Each item of init-declarator-list must not have initializer. - # The length of init-declarator-list must be one. + /* Each item of init-declarator-list must not have initializer. */ + /* The length of init-declarator-list must be one. */ ``` diff --git a/src/parse.c b/src/parse.c index 494e4a2..f703f17 100644 --- a/src/parse.c +++ b/src/parse.c @@ -2607,8 +2607,26 @@ static AstNode* parse_return_stmt(Parser* p) { return ast_new_return_stmt(expr); } +// static_assert-declaration: +// 'static_assert' '(' constant-expr ( ',' string-literal )? ')' ';' +static AstNode* parse_static_assert_declaration(Parser* p) { + expect(p, TokenKind_keyword_static_assert); + expect(p, TokenKind_paren_l); + AstNode* predicate = parse_constant_expr(p); + Token* message = NULL; + if (consume_token_if(p, TokenKind_comma)) { + message = expect(p, TokenKind_literal_str); + } + // TODO: validate the assertion. + (void)predicate; + (void)message; + expect(p, TokenKind_paren_r); + expect(p, TokenKind_semicolon); + return NULL; +} + // external-declaration: -// TODO static_assert-declaration +// static_assert-declaration // TODO attribute-specifier-sequence ';' // TODO attribute-specifier-sequence function-definition-or-declaration-rest // function-definition-or-declaration-rest @@ -2617,6 +2635,10 @@ static AstNode* parse_return_stmt(Parser* p) { // declaration-specifiers init-declarator-list ';' // declaration-specifiers init-declarator-list compound-stmt static AstNode* parse_external_declaration(Parser* p) { + if (peek_token(p)->kind == TokenKind_keyword_static_assert) { + return parse_static_assert_declaration(p); + } + Type* ty = parse_declaration_specifiers(p); if (consume_token_if(p, TokenKind_semicolon)) { // Type declaration. diff --git a/tests/assert.c b/tests/assert.c new file mode 100644 index 0000000..e57f3e3 --- /dev/null +++ b/tests/assert.c @@ -0,0 +1,10 @@ +#include <helpers.h> + +static_assert(1); +static_assert(1, "always true"); +static_assert(1 + 1); +static_assert(123 == 123); +static_assert(sizeof(int) == sizeof(unsigned int)); + +int main() { +} |
