From 7160bdb390ef1c9bdcfb0c075b33be39d62860f3 Mon Sep 17 00:00:00 2001 From: hachem Date: Sat, 19 Sep 2026 13:54:59 +0200 Subject: feat: static_assert --- ast.h | 3 ++- eval.c | 16 ++++++++++++++++ examples/assert.sfinae | 12 ++++++++++++ sfinae.l | 1 + sfinae.y | 3 +++ 5 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 examples/assert.sfinae diff --git a/ast.h b/ast.h index d993c2e..39924b6 100644 --- a/ast.h +++ b/ast.h @@ -24,7 +24,8 @@ enum NodeKind COND_IS_SAME, COND_EQUAL, COND_LESS, - STMT_EMIT + STMT_EMIT, + STMT_STATIC_ASSERT }; struct Node diff --git a/eval.c b/eval.c index eddeb6b..b0ad454 100644 --- a/eval.c +++ b/eval.c @@ -168,11 +168,27 @@ static enum RunStatus emit(const struct Node* node) return RUN_DONE; } +static enum RunStatus static_assert_statement(const struct Node* node) +{ + bool truth = false; + if (evaluate_condition(node->first, &truth)) + return RUN_FAILED; + + if (!truth) + { + (void)complain(node, "static assertion failed, at runtime, which is the best time"); + return RUN_FAILED; + } + + return RUN_DONE; +} + static enum RunStatus execute_one(const struct Node* node) { switch (node->kind) { case STMT_EMIT: return emit(node); + case STMT_STATIC_ASSERT: return static_assert_statement(node); default: break; } diff --git a/examples/assert.sfinae b/examples/assert.sfinae new file mode 100644 index 0000000..0ef7459 --- /dev/null +++ b/examples/assert.sfinae @@ -0,0 +1,12 @@ +::static_assert< + ::equal< + ::difference<'C', 'A'>, + ::sum<::difference<'B', 'A'>, ::difference<'B', 'A'>> + >::value +>::commit; + +::static_assert<::is_same<::remove_cv_t<::byte>, ::byte>::value>::commit; +::emit<::decltype(::difference<'B', 'A'>)>::commit; + + + diff --git a/sfinae.l b/sfinae.l index 4832ed0..2ee7a3d 100644 --- a/sfinae.l +++ b/sfinae.l @@ -33,6 +33,7 @@ static int fail(const char* message) "::" return TOK_COLONCOLON; "emit" return TOK_EMIT; +"static_assert" return TOK_STATIC_ASSERT; "commit" return TOK_COMMIT; "void" return TOK_VOID; "int32_t" return TOK_INT32; diff --git a/sfinae.y b/sfinae.y index ca3121d..0d7f0ee 100644 --- a/sfinae.y +++ b/sfinae.y @@ -17,6 +17,7 @@ void yyerror(const char* message); %token TOK_COLONCOLON %token TOK_EMIT +%token TOK_STATIC_ASSERT %token TOK_COMMIT %token TOK_VOID %token TOK_INT32 @@ -61,6 +62,8 @@ statements statement : TOK_COLONCOLON TOK_EMIT '<' type '>' TOK_COLONCOLON TOK_COMMIT { $$ = node_unary(STMT_EMIT, $4); } + | TOK_COLONCOLON TOK_STATIC_ASSERT '<' condition '>' TOK_COLONCOLON TOK_COMMIT + { $$ = node_unary(STMT_STATIC_ASSERT, $4); } ; type -- cgit v1.3