Until I can spec this out properly, I’ll quote an old post:
TPP stands for either Text Pre-Parser or Template Pre-Parser. The original design derived from the C pre-processor and a simplified Eiffel version. Having encountered StringTemplate, however, I thought of doing a Lua interpretation of that instead. (Maybe with a more readable syntax.)
Preprocessor
Conditionals
Leaving aside operator precedence for a moment, this is the EBNF for
all conditional expressions in an ifdef
and ifndef
condition ::= SYMBOL
| condition ( boolop condition )+
| "!" condition
| "(" condition ")"
boolop ::= "&&" | "||"
SYMBOL ::= [A-Z][A-Z0-9a-z_]*
Directives
define
#define <symbol>
error
#error "<msg>"
undefine
#undefine <symbol>
ifdef
#ifdef <condition>
...
#else
...
#endif [<condition>]
ifndef
#ifndef <condition>
...
#else
...
#endif [<condition>]
include
#include "<path>"
warning
#warning "<msg>"
Template Language
While the Preprocessor simply acts on flags, the Template Language processes a data model to generate HTML, code, or anything else.
It incorporates the commands of the Preprocessor, plus those listed below.
The Data Model
TODO
- Array
- Boolean
true
false
- Integer
- BigInt
- SmallInt
- Number
- BigDecimal
- Float
NaN
Inf
-Inf
- Object
- String
null
- undefined
True and False
TODO
{}
[]
""
NaN
false
null
- undefined
Notably, 0 and 0.0 are treated as true
, although NaN
is considered
false
.
Expressions
Ignoring the blurry line between syntax and functions in the Lisp-like expression language, here’s the syntax for expressions:
expr ::= boolexpr | cntexp | ifexpr | funcall | path | const | "(" expr ")"
const ::= STRING | INTEGER | NUMBER | "true" | "false" | "null"
boolexp ::= expr boolop expr
boolop ::= "&&" | "||" | "!"
| "==" | "!=" | "<" | "<=" | ">" | ">="
| "??" | "!?"
cntexp ::= "#" path
ifexpr ::= boolexpr "?" expr ":" expr
funcall ::= fcnname "(" expr* ")"
fcnname ::= SYMBOL
path ::= SYMBOL ( ( "." SYMBOL ) | ( "[" expr "]" ) )*
SYMBOL ::= [A-Za-z][A-Za-z0-9_]*
STRING ::= "\"" ( [^"]* | "\\"" )* "\""
INTEGER ::= "0" | [+-][1-9][0-9]*
NUMBER ::= INTEGER ( "." [0-9]* )? ( [eE] [+-]? [0-9]+ )?
VAR ::= SYMBOL | "_"
WS ::= ( " " | "\t" )*
Substitutions
${<path>}
TODO
$(<expr>)
TODO
Directives
if
#if <expr>
...
#elseif <expr>
...
#else
...
#endif
TODO
foreach (Array)
#foreach <symbol> <array-expr>
...
#else
...
#endfor
TODO
foreach (Object)
#foreach <var> <var> <object-expr>
...
#else
...
#endfor
TODO
Syntax
and
expr &&
expr ⇒ Boolean
TODO
count
#
array ⇒ Integer
Count the number of elements in an Array.
#
object ⇒ Integer
Count the number of keys in an Object.
#
string ⇒ Integer
Count the number of characters in an Array or Object.
defined
??
symbol ⇒ Boolean
TODO
??
expr ⇒ Boolean
TODO
eq
expr ==
expr ⇒ Boolean
TODO
ge
expr >=
expr ⇒ Boolean
TODO
gt
expr >
expr ⇒ Boolean
TODO
if
boolexpr ?
expr1 :
expr2
If boolexpr evaluates to true, evaluate and substitute expr1. Otherwise, evaluate and substitute expr2.
le
expr <=
expr ⇒ Boolean
TODO
lt
expr <
expr ⇒ Boolean
TODO
neq
expr !=
expr ⇒ Boolean
TODO
not
!
expr ⇒ Boolean
TODO
or
expr ||
expr ⇒ Boolean
TODO
undefined
?!
symbol ⇒ Boolean
TODO
?!
expr ⇒ Boolean
TODO
Functions
TODO
A future release may allow users to define their own functions. Until then, add function results to the data model and refer to that.
join
join (<str>, <array-or-object>)
⇒ String
Join the elements of an array or object into a single string, separated by the string object.
tojson
tojson (<expr>)
⇒ String
Convert the expression to a JSON string.