diff options
| author | s-ol <s+removethis@s-ol.nu> | 2025-03-14 23:44:10 +0000 |
|---|---|---|
| committer | s-ol <s+removethis@s-ol.nu> | 2025-03-15 14:14:04 +0000 |
| commit | 79696a272d1d8f2959a0b9cfdd8487d356416a05 (patch) | |
| tree | 0d6e28f00b6a62e2fd7488b1df772305f56a812a /alv/template_string.moon | |
| parent | somewhat clean up alv.parsing (diff) | |
| download | alive-79696a272d1d8f2959a0b9cfdd8487d356416a05.tar.gz alive-79696a272d1d8f2959a0b9cfdd8487d356416a05.zip | |
implement template strings
Diffstat (limited to 'alv/template_string.moon')
| -rw-r--r-- | alv/template_string.moon | 83 |
1 files changed, 83 insertions, 0 deletions
diff --git a/alv/template_string.moon b/alv/template_string.moon new file mode 100644 index 0000000..bd6ae0f --- /dev/null +++ b/alv/template_string.moon @@ -0,0 +1,83 @@ +---- +-- A string with substitutions, partially implements the `AST` interface. +-- +-- Is automatically "splatted" into multiple expressions when the containing +-- `Cell` is evaluated: the original string (str=), but with with substitution +-- markers like `#{1}`, `#{2}` and so on and one expression for each substitution. +-- +-- `#` symbols in the original string are escaped to `##`. +-- +-- @classmod TemplateString +import Constant from require 'alv.result' + +-- @type TemplateString +class TemplateString +--- AST interface +-- +-- `TemplateString` partially implements the `AST` interface. +-- @section ast + + --- create a clone with its own identity. + -- + -- creates a clone of this TemplateString by cloning all child expressions + -- recursively. + -- + -- @tparam Tag parent + -- @treturn TemplateString + clone: (parent) => + children = [child\clone parent for child in *@children] + @@ @string, children + + --- stringify this TemplateString. + -- + -- if `depth` is passed, does not faithfully recreate the original string but + -- rather create useful debug output. + -- + -- @tparam[opt] int depth the maximum depth, defaults to infinite + -- @treturn string the exact string this TemplateString was parsed from + stringify: (depth=-1) => + children = ['#' .. child\stringify depth for child in *@children] + str = @@.subst @.string!, (i) -> '#' .. @children[i]\stringify depth + '#"' .. str .. '"' + +--- static functions +-- @section static + + new: (@string, @children) => + + --- apply substitutions to a template string. + -- + -- This also reverses the escaping that the parser applied. + -- + -- @classmethod + -- @tparam string str the evaluated `TemplateString.string` + -- @tparam function fn function called with index i to obtain string to substitute + -- @treturn string + @subst: (str, fn) -> + str = str\gsub '##', '#' + str\gsub '#{(%d+)}', (i) -> fn tonumber i + + --- parse a TemplateString (for parsing with Lpeg). + -- + -- @classmethod + -- @tparam {string|AST,...} pieces + -- @treturn TemplateString + @parse: (...) => + string = '' + children = {} + + i = 1 + for elem in *{...} + string ..= if elem == '##' then elem + elseif 'string' == type elem then elem\gsub '#', '##' + else + table.insert children, elem + '#{' .. #children .. '}' + + string = Constant.str string + + @@ string, children + +{ + :TemplateString +} |
