diff options
| author | hachem <im@hachem.wtf> | 2026-09-19 20:50:28 +0200 |
|---|---|---|
| committer | hachem <im@hachem.wtf> | 2026-09-19 20:50:28 +0200 |
| commit | 6487b5b5301f6cb37c95c3571578d5a42adb2a1a (patch) | |
| tree | bf90b803c6fa43058d54190fd1b52d835901bbcd | |
| parent | c6aab10e74d58fbcad723c5f074a0bb51e9f2283 (diff) | |
feat: declval
| -rw-r--r-- | ast.h | 1 | ||||
| -rw-r--r-- | eval.c | 9 | ||||
| -rw-r--r-- | examples/fibonacci.sfinae | 68 | ||||
| -rw-r--r-- | sfinae.l | 1 | ||||
| -rw-r--r-- | sfinae.y | 3 |
5 files changed, 82 insertions, 0 deletions
@@ -33,6 +33,7 @@ enum NodeKind VALUE_INTEGRAL_CONSTANT, VALUE_CONDITIONAL, VALUE_VARIABLE, + VALUE_DECLVAL, COND_TRUE, COND_FALSE, @@ -121,6 +121,15 @@ static int evaluate_value(struct Machine* machine, const struct Node* node, int6 *out = variable->value; return 0; + case VALUE_DECLVAL: + if (evaluate_type(machine, node->first, &type)) + return 1; + + if (type.kind != KIND_VALUE) + return complain(node, "declval of a type with no value in it, what did you expect"); + + *out = type.number; + return 0; case VALUE_CONDITIONAL: if (evaluate_condition(machine, node->first, &truth)) return 1; diff --git a/examples/fibonacci.sfinae b/examples/fibonacci.sfinae new file mode 100644 index 0000000..844aa69 --- /dev/null +++ b/examples/fibonacci.sfinae @@ -0,0 +1,68 @@ +// fib(0) to fib(10), each line a tuple: some characters, the counter, and the call +// ::declval<T>() pulls the value back out of a call result so it can go into ::sum + +::define< + ::name<'f', 'i', 'b'>, + ::parameters<::name<'n'>>, + ::sequence< + ::enable_if_t< + ::less<::value_of<::name<'n'>>, ::difference<'C', 'A'>>::value, + ::sequence<::return<::decltype(::value_of<::name<'n'>>)>::commit> + >::commit, + ::return< + ::decltype( + ::sum< + ::declval< + ::invoke_result_t< + ::name<'f', 'i', 'b'>, + ::arguments< + ::decltype(::sum<::value_of<::name<'n'>>, ::difference<'A', 'B'>>) + > + > + >(), + ::declval< + ::invoke_result_t< + ::name<'f', 'i', 'b'>, + ::arguments< + ::decltype(::sum<::value_of<::name<'n'>>, ::difference<'A', 'C'>>) + > + > + >() + > + ) + >::commit + > +>::commit; + +::declare<::name<'i'>, ::decltype(::difference<'A', 'A'>)>::commit; + +::repeat< + ::difference<'L', 'A'>, + ::sequence< + ::emit< + ::tuple< + ::integral_constant<::char, ::difference<'f', '\0'>>, + ::integral_constant<::char, ::difference<'i', '\0'>>, + ::integral_constant<::char, ::difference<'b', '\0'>>, + ::integral_constant<::char, ::difference<'(', '\0'>>, + ::decltype(::value_of<::name<'i'>>), + ::integral_constant<::char, ::difference<')', '\0'>>, + ::integral_constant<::char, ::difference<' ', '\0'>>, + ::integral_constant<::char, ::difference<'-', '\0'>>, + ::integral_constant<::char, ::difference<'>', '\0'>>, + ::integral_constant<::char, ::difference<' ', '\0'>>, + ::invoke_result_t< + ::name<'f', 'i', 'b'>, + ::arguments<::decltype(::value_of<::name<'i'>>)> + > + > + >::commit, + ::declare< + ::name<'n', 'e', 'x', 't'>, + ::decltype(::sum<::value_of<::name<'i'>>, ::difference<'B', 'A'>>) + >::commit, + ::undeclare<::name<'i'>>::commit, + ::declare<::name<'i'>, ::decltype(::value_of<::name<'n', 'e', 'x', 't'>>)>::commit, + ::undeclare<::name<'n', 'e', 'x', 't'>>::commit + > +>::commit; @@ -47,6 +47,7 @@ static int fail(const char* message) "sequence" return TOK_SEQUENCE; "name" return TOK_NAME; "value_of" return TOK_VALUE_OF; +"declval" return TOK_DECLVAL; "void" return TOK_VOID; "int32_t" return TOK_INT32; "byte" return TOK_BYTE; @@ -33,6 +33,7 @@ void yyerror(const char* message); %token TOK_SEQUENCE %token TOK_NAME %token TOK_VALUE_OF +%token TOK_DECLVAL %token TOK_VOID %token TOK_INT32 %token TOK_BYTE @@ -197,6 +198,8 @@ value { $$ = node_binary(VALUE_QUOTIENT, $4, $6); } | TOK_COLONCOLON TOK_VALUE_OF '<' name '>' { $$ = node_named(VALUE_VARIABLE, &$4, NULL); } + | TOK_COLONCOLON TOK_DECLVAL '<' type '>' '(' ')' + { $$ = node_unary(VALUE_DECLVAL, $4); } | TOK_COLONCOLON TOK_EXTENT '<' type '>' TOK_COLONCOLON TOK_VALUE { $$ = node_unary(VALUE_EXTENT, $4); } | TOK_COLONCOLON TOK_TUPLE_SIZE '<' type '>' TOK_COLONCOLON TOK_VALUE |
