From fa4a45d37f383d1fdbf7059738b62fe3fd7b68fe Mon Sep 17 00:00:00 2001 From: shove Date: Thu, 3 Nov 2022 19:32:07 +0800 Subject: [PATCH] all: make fmt support two kinds of interpolation at the same time. (#16308) --- vlib/v/ast/ast.v | 1 + vlib/v/ast/str.v | 6 ++++-- vlib/v/fmt/fmt.v | 4 +++- vlib/v/parser/parser.v | 8 ++++++-- vlib/v/scanner/scanner.v | 2 +- vlib/v/token/token.v | 8 ++++++-- 6 files changed, 21 insertions(+), 8 deletions(-) diff --git a/vlib/v/ast/ast.v b/vlib/v/ast/ast.v index 5f6eea6276..22229371ba 100644 --- a/vlib/v/ast/ast.v +++ b/vlib/v/ast/ast.v @@ -216,6 +216,7 @@ pub: fills []bool fmt_poss []token.Pos pos token.Pos + has_dollar []bool // two interpolation ways are temporarily supported pub mut: exprs []Expr expr_types []Type diff --git a/vlib/v/ast/str.v b/vlib/v/ast/str.v index 9dd9c9ee33..879bf2442b 100644 --- a/vlib/v/ast/str.v +++ b/vlib/v/ast/str.v @@ -230,7 +230,7 @@ pub fn (lit &StringInterLiteral) get_fspec_braces(i int) (string, bool) { needs_fspec := lit.need_fmts[i] || lit.pluss[i] || (lit.fills[i] && lit.fwidths[i] >= 0) || lit.fwidths[i] != 0 || lit.precisions[i] != 987698 - mut needs_braces := needs_fspec + mut needs_braces := !lit.has_dollar[i] || needs_fspec sx := lit.exprs[i].str() if sx.contains(r'"') || sx.contains(r"'") { needs_braces = true @@ -480,7 +480,9 @@ pub fn (x Expr) str() string { if i >= x.exprs.len { break } - res.write_string('$') + if x.has_dollar[i] { + res.write_string('$') + } fspec_str, needs_braces := x.get_fspec_braces(i) if needs_braces { res.write_string('{') diff --git a/vlib/v/fmt/fmt.v b/vlib/v/fmt/fmt.v index 4b21b7bb9b..d1a3630886 100644 --- a/vlib/v/fmt/fmt.v +++ b/vlib/v/fmt/fmt.v @@ -2684,7 +2684,9 @@ pub fn (mut f Fmt) string_inter_literal(node ast.StringInterLiteral) { if i >= node.exprs.len { break } - f.write('$') + if node.has_dollar[i] { + f.write('$') + } fspec_str, needs_braces := node.get_fspec_braces(i) if needs_braces { f.write('{') diff --git a/vlib/v/parser/parser.v b/vlib/v/parser/parser.v index 405b603904..19c067aa13 100644 --- a/vlib/v/parser/parser.v +++ b/vlib/v/parser/parser.v @@ -3056,7 +3056,7 @@ fn (mut p Parser) string_expr() ast.Expr { val := p.tok.lit mut pos := p.tok.pos() pos.last_line = pos.line_nr + val.count('\n') - if p.peek_tok.kind != .str_dollar { + if p.peek_tok.kind != .str_dollar && p.peek_tok.kind != .str_lcbr { p.next() p.filter_string_vet_errors(pos) node = ast.StringLiteral{ @@ -3076,14 +3076,16 @@ fn (mut p Parser) string_expr() ast.Expr { mut fills := []bool{} mut fmts := []u8{} mut fposs := []token.Pos{} + mut has_dollar := []bool{} // Handle $ interpolation p.inside_str_interp = true for p.tok.kind == .string { vals << p.tok.lit p.next() - if p.tok.kind != .str_dollar { + if p.tok.kind != .str_dollar && p.tok.kind != .str_lcbr { break } + has_dollar_ := p.tok.kind == .str_dollar p.next() exprs << p.expr(0) mut has_fmt := false @@ -3136,6 +3138,7 @@ fn (mut p Parser) string_expr() ast.Expr { fmts << fmt fills << fill fposs << p.prev_tok.pos() + has_dollar << has_dollar_ } pos = pos.extend(p.prev_tok.pos()) p.filter_string_vet_errors(pos) @@ -3150,6 +3153,7 @@ fn (mut p Parser) string_expr() ast.Expr { fmts: fmts fmt_poss: fposs pos: pos + has_dollar: has_dollar } // need_fmts: prelimery - until checker finds out if really needed p.inside_str_interp = false diff --git a/vlib/v/scanner/scanner.v b/vlib/v/scanner/scanner.v index e5acbbeb83..5d0a0aaca0 100644 --- a/vlib/v/scanner/scanner.v +++ b/vlib/v/scanner/scanner.v @@ -813,7 +813,7 @@ fn (mut s Scanner) text_scan() token.Token { if !s.is_inside_interpolation && !next_char.is_space() && next_char != `}` && prev_char !in [`$`, `{`] { s.is_inside_interpolation = true - return s.new_token(.str_dollar, '', 1) + return s.new_token(.str_lcbr, '', 1) } if s.is_inside_interpolation && prev_char == `$` { // Skip { in `${` in strings diff --git a/vlib/v/token/token.v b/vlib/v/token/token.v index 8f0a221b11..4b82f25e84 100644 --- a/vlib/v/token/token.v +++ b/vlib/v/token/token.v @@ -46,7 +46,8 @@ pub enum Kind { hash // # dollar // $ at // @ - str_dollar + str_dollar // ${} or $, old interpolation + str_lcbr // {interpolation left_shift // << right_shift // >> unsigned_right_shift // >>> @@ -269,7 +270,8 @@ fn build_token_str() []string { s[Kind.nl] = 'NLL' s[Kind.dollar] = '$' s[Kind.at] = '@' - s[Kind.str_dollar] = '$2' + s[Kind.str_dollar] = 'string interpolation1' + s[Kind.str_lcbr] = 'string interpolation2' s[Kind.key_assert] = 'assert' s[Kind.key_struct] = 'struct' s[Kind.key_if] = 'if' @@ -539,6 +541,7 @@ pub fn kind_to_string(k Kind) string { .dollar { 'dollar' } .at { 'at' } .str_dollar { 'str_dollar' } + .str_lcbr { 'str_lcbr' } .left_shift { 'left_shift' } .right_shift { 'right_shift' } .unsigned_right_shift { 'unsigned_right_shift' } @@ -660,6 +663,7 @@ pub fn kind_from_string(s string) !Kind { 'dollar' { .dollar } 'at' { .at } 'str_dollar' { .str_dollar } + 'str_lcbr' { .str_lcbr } 'left_shift' { .left_shift } 'right_shift' { .right_shift } 'unsigned_right_shift' { .unsigned_right_shift }