diff options
| author | hachem <im@hachem.wtf> | 2026-09-19 22:22:26 +0200 |
|---|---|---|
| committer | hachem <im@hachem.wtf> | 2026-09-19 22:22:26 +0200 |
| commit | 4bcc54914d059e950cab79164fb13ed67376ee5d (patch) | |
| tree | ca4df456c92247a950be7e5ebc5da49ff96b7b3d /README | |
| parent | 2da2c56c72e7085bd9a52f848df90c6fc701de7f (diff) | |
docs: README + LICENSE
Diffstat (limited to 'README')
| -rw-r--r-- | README | 90 |
1 files changed, 87 insertions, 3 deletions
@@ -1,13 +1,13 @@ # sfinae -Substitution Failure Is Not An Error. Everything else is. -A toy language which takes' C++ template metaprogramming to another level. +Substitution Failure Is Not An Error. everything else is. +a toy language which takes' C++ template metaprogramming to another level. ## build make release build, ./sfinae in the root, objects in bin/ make debug rebuild with address and undefined sanitizers - make check run examples/ against their .expected files + make check run every program in examples/ and tutorial/ make format clang-format the sources make lint clang-tidy naming check make clean @@ -15,3 +15,87 @@ A toy language which takes' C++ template metaprogramming to another level. ## run ./sfinae examples/hello.sfinae + +## learning it + +six lessons under tutorial/, each a program that runs and explains itself in +its comments. read them in order: + + 01_hello.sfinae there are no strings, a string is a tuple of characters + 02_numbers.sfinae there are no numbers, a number is the distance between two characters + 03_variables.sfinae a variable holds a type, and there is no assignment + 04_conditions.sfinae nothing is a condition until you say ::value + 05_loops.sfinae ::repeat, and counting with the undeclare dance + 06_functions.sfinae functions take types, return types, and see only their parameters + +examples/ has more, including fib(0) to fib(10). + +## the rules + +- every notion starts with `::` and every statement ends with `::commit;`. + nothing happens until it is committed +- there are no numeric literals. a digit is a lexer error. the only way to get + a number is to subtract two characters: `::difference<'F', 'A'>` is 5 +- there are no strings. a string is a `::tuple` of `::integral_constant<::char, N>` + types, one per character, each its own distance from `'\0'` +- names are lists of characters: `::name<'f', 'i', 'b'>`, at most 15 of them +- a variable holds a type, and the type must be a `::decltype(...)` of a value or + it cannot be declared +- reassignment does not exist. `::undeclare` it, then `::declare` it again +- conditions are not conditions until you say `::value` +- loop, if and function bodies are a `::sequence<...>` of committed statements, + separated by commas +- functions take types, return types, and see nothing but their parameters +- comments are `//` to the end of the line + +## statements + + ::declare<NAME, TYPE>::commit; + ::undeclare<NAME>::commit; + ::emit<TYPE>::commit; prints what the type says, then a newline + ::repeat<VALUE, SEQUENCE>::commit; + ::enable_if_t<COND, SEQUENCE>::commit; + ::static_assert<COND>::commit; fails at runtime + ::define<NAME, ::parameters<NAME, ...>, SEQUENCE>::commit; + ::return<TYPE>::commit; only inside a function + +## types + + ::void ::int32_t ::byte ::size_t ::char + ::remove_cv_t<TYPE> does nothing + ::array<TYPE, VALUE> an array type with an extent + ::conditional_t<COND, TYPE, TYPE> + ::decltype(VALUE) the only type that carries a value + ::integral_constant<::char, VALUE> a character + ::tuple<TYPE, ...> says what its elements say, in order + ::invoke_result_t<NAME, ::arguments<TYPE, ...>> a call + +## values + + ::difference<'c', 'c'> the one and only literal + ::sum<V, V> ::product<V, V> ::quotient<V, V> + ::value_of<NAME> + ::extent<TYPE>::value an array's extent, 0 otherwise + ::tuple_size<TYPE>::value same thing, longer + ::integral_constant<::size_t, V>::value also does nothing + ::conditional<COND, V, V> + ::declval<TYPE>() the value inside a decltype + +## conditions + + ::true_type::value ::false_type::value + ::is_same<TYPE, TYPE>::value + ::equal<V, V>::value ::less<V, V>::value + +## what emit prints + + ::decltype(V) the number + ::integral_constant<::char, V> the character + ::tuple<...> its elements, glued together + ::array<T, N> array[N] + ::void nothing, not even a newline + anything else the type's name + +## license + +MIT, see LICENSE. |
