diff --git a/src/parser/scanner.ts b/src/parser/scanner.ts index ae161bcc..691c3f68 100644 --- a/src/parser/scanner.ts +++ b/src/parser/scanner.ts @@ -491,6 +491,7 @@ export class Scanner implements ITokenStream { let buf = ''; let tokenBuf: Token[] = []; let state: 'string' | 'escape' | 'expr' | 'finish' = 'string'; + let exprBracketDepth = 0; const pos = this.stream.getPos(); let elementPos = pos; @@ -556,17 +557,23 @@ export class Scanner implements ITokenStream { this.stream.next(); continue; } - // 埋め込み式の終了 + if (this.stream.char === '{') { + exprBracketDepth++; + } if ((this.stream.char as string) === '}') { - elements.push(TOKEN(TokenKind.TemplateExprElement, elementPos, { hasLeftSpacing, children: tokenBuf })); - // ここから文字列エレメントになるので位置を更新 - elementPos = this.stream.getPos(); - // TemplateExprElementトークンの終了位置をTokenStreamが取得するためのEOFトークンを追加 - tokenBuf.push(TOKEN(TokenKind.EOF, elementPos)); - tokenBuf = []; - state = 'string'; - this.stream.next(); - break; + // 埋め込み式の終了 + if (exprBracketDepth === 0) { + elements.push(TOKEN(TokenKind.TemplateExprElement, elementPos, { hasLeftSpacing, children: tokenBuf })); + // ここから文字列エレメントになるので位置を更新 + elementPos = this.stream.getPos(); + // TemplateExprElementトークンの終了位置をTokenStreamが取得するためのEOFトークンを追加 + tokenBuf.push(TOKEN(TokenKind.EOF, elementPos)); + tokenBuf = []; + state = 'string'; + this.stream.next(); + break; + } + exprBracketDepth--; } const token = this.readToken(); tokenBuf.push(token); diff --git a/test/literals.ts b/test/literals.ts index 731d11b4..590edfc7 100644 --- a/test/literals.ts +++ b/test/literals.ts @@ -185,5 +185,12 @@ describe('Template syntax', () => { `); eq(res, STR('`a{b}c`')); }); + + test.concurrent('nested brackets', async () => { + const res = await exe(` + <: \`{if true {1} else {2}}\` + `); + eq(res, STR('1')); + }); }); diff --git a/unreleased/braces-in-template-expression.md b/unreleased/braces-in-template-expression.md new file mode 100644 index 00000000..ed05c887 --- /dev/null +++ b/unreleased/braces-in-template-expression.md @@ -0,0 +1 @@ +- テンプレートリテラルに波括弧を含む式を埋め込むことができるようになりました。