`text ${expression} text`
`)${expression} where expression is any valid HQL expression( or [ is excluded (reserved for quasiquote syntax)The tokenizer matches template literals with a regex that handles:
\ followed by any character)$ not followed by { (literal dollar sign)${...} interpolation blocksThe parser (parseTemplateLiteral) then:
${: tracks brace depth to find the matching }tokenize + parseExpressionprocessSingleEscape(template-literal "str1" expr1 "str2" ...) s-expressionOptimization: if the template literal contains no interpolations, the parser returns a plain string literal instead of a template-literal form.
interface IRTemplateLiteral {
type: IRNodeType.TemplateLiteral;
quasis: IRNode[]; // String literal parts
expressions: IRNode[]; // Interpolated expressions
}
Invariant: quasis.length === expressions.length + 1 (matching JavaScript's template literal structure). Empty string literals are inserted as needed to maintain this invariant.
Emits a JavaScript template literal:
`quasi0${expr0}quasi1${expr1}quasi2`
String parts (quasis) are emitted as raw text (not JSON-stringified). Expressions are generated in expression context.
Handled during parsing (not in codegen). Supported escapes include:
\$ — literal dollar sign\n — newline\t — tab\\ — backslashprocessSingleEscapeInside ${}, any valid HQL expression is accepted:
`${42}` ;; number literal
`${name}` ;; variable reference
`${(+ 2 3)}` ;; function call
`${(* (+ 2 3) 4)}` ;; nested expressions
`${(get arr 1)}` ;; array/object access
`${(? true "yes" "no")}` ;; ternary
Brace depth is tracked so nested braces inside expressions (e.g., object literals) are handled correctly by the parser. Note: the tokenizer regex uses a simpler pattern for ${...} that does not track nested braces, but the parser re-parses the content with full brace depth tracking.
Template literals follow JavaScript's toString() coercion rules at runtime. No special coercion is performed by the transpiler.
String.raw)