-
Notifications
You must be signed in to change notification settings - Fork 4
internal.stringTemplates
String templates can be used to specify where variable Content should be placed in a string. They roughly follow the ${VAR}
style of template string.
A mor comprehensive guide can be found here. Interpolation, If, and For directives are supported.
Warning
- Logical Operators like && and || are not supported! Only Comparison Operators are implemented. (!= is also supported)
- You have to leave one whitespace bevor and after the comparison operator
- The if statement only supports comparison operators, not statements that evaluate to true (a variable with true inside will not work as a condition for an if statement). As a workaround you can check the variable explixitly
value == "true"
- Only one wildcard is allowed per for statement
- Be careful of unfinished or unclosed tags, these cases are not always handled gracefully
- automatic whitespace stripping from hardcoded text or variables is not supported
- You can only access fields on an object, not getters or other methods
The parsing of String templates is split into two (or more) parsing steps, all major sections are parsed in the first pass, all specialized parts, like the heads of if and for statements have their own specialized parser. The main parser will only isolate these entire sections and will hand them of to the more specialized parsers. This is done because these sections have their own syntax rules that are completely separate from the rest of the template, e.g.: variables don't need to be prefixed with a $
, but all hard coded strings need to be enclosed by "
, these rules are completely opposite to the rest of the template. This split in responsibilities removes complexity by not trying to mix both contexts into one class/one (or multiple) functions, but instead making these two discrete steps.
For all major an minor sections the string is first grouped into tokens. Tokens are not much more than tags indicating what this is string of characters means. Tokens are always in a list sorted by there appearance in the string. Tokens are then parsed into statements. Statements are single or multiple Tokens grouped in a logical unit that describes the construct they are a part of. e.g.: A ForStatement contains all information needed to describe and execute a for loop, this includes a list of all statements in the body. So statements are organized in a list of trees.
A Token always consists of a type enum, and a string value.
The string value is the string that were found to be this token, this can literally the word else
for every else
token, but can also be the number of an int, or the hard coded text of a string.
The kind indicates what kind of major or minor token this is, string, int, var, ...
The tokenising is done in the TemplateLexer. It classifies the template string into these tokens:
- TEXT
- VAR
- FOR_HEAD
- FOR_END
- IF_HEAD
- IF_ELSE
- IF_END This is an example of how the Template parser would tokenise a string:
Hello, %{ if var.name != "test" }'${var.name}'%{ else }unnamed%{ endif }!
color | meaning |
---|---|
green | strings/text |
blue | variables |
red | if head |
pink | else |
lila | endif |
(while tokenising, %{} and ${} are also stripped, because they are unnecessary now) |
the TemplateParser then parses these into Statements.
the TemplateInterpreter then uses the resulting tree to build the final string with the provided variables.
Tokens:
- STRING
- INT
- DOUBLE
- BOOLEAN
- VAR
- COMPARISON