hachem.wtf
aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorhachem <im@hachem.wtf>2026-09-19 12:03:34 +0200
committerhachem <im@hachem.wtf>2026-09-19 12:03:34 +0200
commit74a8a2b10a0513f5346ec47aa9b463e30f2b972e (patch)
treefd126ece2e3e544c00866ba0aef03989c92a7a05
parentb20c46c555986a99be70de61d91bc225e53f31d2 (diff)
feat: add void, int32_t, byte, size_t, remove_cv_t
-rw-r--r--ast.h5
-rw-r--r--eval.c16
-rw-r--r--eval.h3
-rw-r--r--examples/types.sfinae5
-rw-r--r--sfinae.l5
-rw-r--r--sfinae.y17
6 files changed, 48 insertions, 3 deletions
diff --git a/ast.h b/ast.h
index 778a765..52814d5 100644
--- a/ast.h
+++ b/ast.h
@@ -3,6 +3,11 @@
enum NodeKind
{
NODE_CHAR,
+ TYPE_VOID,
+ TYPE_INT32,
+ TYPE_BYTE,
+ TYPE_SIZE,
+ TYPE_REMOVE_CV,
TYPE_DECLTYPE,
VALUE_DIFFERENCE,
VALUE_SUM,
diff --git a/eval.c b/eval.c
index f9f47b6..3c4ea34 100644
--- a/eval.c
+++ b/eval.c
@@ -63,6 +63,11 @@ static int evaluate_type(const struct Node* node, struct Type* out)
out->number = 0;
switch (node->kind)
{
+ case TYPE_VOID: return 0;
+ case TYPE_INT32: out->kind = KIND_INT32; return 0;
+ case TYPE_BYTE: out->kind = KIND_BYTE; return 0;
+ case TYPE_SIZE: out->kind = KIND_SIZE; return 0;
+ case TYPE_REMOVE_CV: return evaluate_type(node->first, out);
case TYPE_DECLTYPE:
if (evaluate_value(node->first, &out->number))
return 1;
@@ -81,8 +86,15 @@ static enum RunStatus emit(const struct Node* node)
if (evaluate_type(node->first, &type))
return RUN_FAILED;
- if (type.kind == KIND_VALUE)
- (void)printf("%" PRId64 "\n", type.number);
+ switch (type.kind)
+ {
+ case KIND_VOID: break;
+ case KIND_INT32: (void)printf("int32_t\n"); break;
+ case KIND_BYTE: (void)printf("byte\n"); break;
+ case KIND_SIZE: (void)printf("size_t\n"); break;
+ case KIND_VALUE: (void)printf("%" PRId64 "\n", type.number); break;
+ }
+
return RUN_DONE;
}
diff --git a/eval.h b/eval.h
index 49101f1..3c5d947 100644
--- a/eval.h
+++ b/eval.h
@@ -7,6 +7,9 @@
enum TypeKind
{
KIND_VOID,
+ KIND_INT32,
+ KIND_BYTE,
+ KIND_SIZE,
KIND_VALUE
};
diff --git a/examples/types.sfinae b/examples/types.sfinae
new file mode 100644
index 0000000..7adb870
--- /dev/null
+++ b/examples/types.sfinae
@@ -0,0 +1,5 @@
+// a type that carries no value emits its name, because why would it print a number
+::emit<::int32_t>::commit;
+::emit<::remove_cv_t<::byte>>::commit;
+::emit<::size_t>::commit;
+::emit<::void>::commit;
diff --git a/sfinae.l b/sfinae.l
index 5857a2b..37ddd1a 100644
--- a/sfinae.l
+++ b/sfinae.l
@@ -34,6 +34,11 @@ static int fail(const char* message)
"::" return TOK_COLONCOLON;
"emit" return TOK_EMIT;
"commit" return TOK_COMMIT;
+"void" return TOK_VOID;
+"int32_t" return TOK_INT32;
+"byte" return TOK_BYTE;
+"size_t" return TOK_SIZE_T;
+"remove_cv_t" return TOK_REMOVE_CV;
"decltype" return TOK_DECLTYPE;
"difference" return TOK_DIFFERENCE;
"sum" return TOK_SUM;
diff --git a/sfinae.y b/sfinae.y
index 3e7c9b1..5a590a2 100644
--- a/sfinae.y
+++ b/sfinae.y
@@ -18,6 +18,11 @@ void yyerror(const char* message);
%token TOK_COLONCOLON
%token TOK_EMIT
%token TOK_COMMIT
+%token TOK_VOID
+%token TOK_INT32
+%token TOK_BYTE
+%token TOK_SIZE_T
+%token TOK_REMOVE_CV
%token TOK_DECLTYPE
%token TOK_DIFFERENCE
%token TOK_SUM
@@ -47,7 +52,17 @@ statement
;
type
- : TOK_COLONCOLON TOK_DECLTYPE '(' value ')'
+ : TOK_COLONCOLON TOK_VOID
+ { $$ = node_leaf(TYPE_VOID); }
+ | TOK_COLONCOLON TOK_INT32
+ { $$ = node_leaf(TYPE_INT32); }
+ | TOK_COLONCOLON TOK_BYTE
+ { $$ = node_leaf(TYPE_BYTE); }
+ | TOK_COLONCOLON TOK_SIZE_T
+ { $$ = node_leaf(TYPE_SIZE); }
+ | TOK_COLONCOLON TOK_REMOVE_CV '<' type '>'
+ { $$ = node_unary(TYPE_REMOVE_CV, $4); }
+ | TOK_COLONCOLON TOK_DECLTYPE '(' value ')'
{ $$ = node_unary(TYPE_DECLTYPE, $4); }
;