From 74a8a2b10a0513f5346ec47aa9b463e30f2b972e Mon Sep 17 00:00:00 2001 From: hachem Date: Sat, 19 Sep 2026 12:03:34 +0200 Subject: feat: add void, int32_t, byte, size_t, remove_cv_t --- ast.h | 5 +++++ eval.c | 16 ++++++++++++++-- eval.h | 3 +++ examples/types.sfinae | 5 +++++ sfinae.l | 5 +++++ sfinae.y | 17 ++++++++++++++++- 6 files changed, 48 insertions(+), 3 deletions(-) create mode 100644 examples/types.sfinae 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); } ; -- cgit v1.3