I will soon be writing a template expansion function in Fexl. I have started with the following documentation.
The template expansion function takes two arguments: a string source and an environment function env. The source string may contain embedded fragments ~(EXP) where EXP is a valid Fexl expression. Each of these embedded expressions is evaluated by the env function and expanded inline.
The token "~(" indicates where an expression starts, and the Fexl parser reads from just after the tilde through the closing ")".
The function starts at position 0 in the source and loops as follows.
It looks for the next occurrence of the token in the source starting at the current position. If it does not find the token, it returns the entire remainder of the source starting at the current position.
If it finds the token, it defines prefix as the slice of the source string from the current position to just before the tilde.
The function then calls the Fexl parser parse_exp starting at the left parenthesis after the tilde. If the expression is not valid Fexl, the function dies with a syntax error.
If the expression is valid, the parser returns a form and leaves the string position at the character after the closing right parenthesis. The function now defines expansion as (env form), the result of applying the environment function to the parsed form. It then calls itself recursively at the new position, returning the tail list.
Finally, the function returns the list consisting of the first two items prefix and expansion, followed by the tail list.
Note that the expansion function can generally return an arbitrarily nested list. If you want to flatten that into a single string, you can apply to_str to it. However, you often don't have to do that, since you can pass the list directly to many functions such as say. You can even take advantage of the lazy nature of the expanded list, allowing features like search functions which proceed on demand.