hachem.wtf
aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorhachem <im@hachem.wtf>2026-09-19 13:54:59 +0200
committerhachem <im@hachem.wtf>2026-09-19 13:54:59 +0200
commit7160bdb390ef1c9bdcfb0c075b33be39d62860f3 (patch)
treeee22c43995db73ac7fb8fa65cd9becf917f15628
parentd0ca03c84bcad3dc42fd173b0baf3a15e9b52f9b (diff)
feat: static_assert
-rw-r--r--ast.h3
-rw-r--r--eval.c16
-rw-r--r--examples/assert.sfinae12
-rw-r--r--sfinae.l1
-rw-r--r--sfinae.y3
5 files changed, 34 insertions, 1 deletions
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