hachem.wtf
aboutsummaryrefslogtreecommitdiff
path: root/README
diff options
context:
space:
mode:
Diffstat (limited to 'README')
-rw-r--r--README90
1 files changed, 87 insertions, 3 deletions
diff --git a/README b/README
index b7e376f..32e77c7 100644
--- a/README
+++ b/README
@@ -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.