aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2026-03-14 22:42:22 +0900
committernsfisis <nsfisis@gmail.com>2026-03-14 22:42:22 +0900
commit7435692fec7b82284eac236714931faee8b825d6 (patch)
tree241995dc70f4a7e543bff2411e3dedd6300715df
parentf2c1b79720f7d9ccd22d288defc1804e77c10087 (diff)
downloadducc-7435692fec7b82284eac236714931faee8b825d6.tar.gz
ducc-7435692fec7b82284eac236714931faee8b825d6.tar.zst
ducc-7435692fec7b82284eac236714931faee8b825d6.zip
feat: partially implement static_assert (parsing only)
-rw-r--r--docs/c_grammar.md10
-rw-r--r--src/parse.c24
-rw-r--r--tests/assert.c10
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() {
+}