diff --git a/vlib/v/ast/str.v b/vlib/v/ast/str.v index 6b1c76572d..3f42cc9f3e 100644 --- a/vlib/v/ast/str.v +++ b/vlib/v/ast/str.v @@ -116,7 +116,7 @@ pub fn (x &InfixExpr) str() string { pub fn (lit &StringInterLiteral) get_fspec_braces(i int) (string, bool) { mut res := []string{} needs_fspec := lit.need_fmts[i] || lit.pluss[i] || - (lit.fills[i] && lit.fwidths[i] >= 0) || lit.fwidths[i] != 0 || lit.precisions[i] != 0 + (lit.fills[i] && lit.fwidths[i] >= 0) || lit.fwidths[i] != 0 || lit.precisions[i] != 987698 mut needs_braces := needs_fspec if !needs_braces { if i + 1 < lit.vals.len && lit.vals[i + 1].len > 0 { @@ -164,7 +164,7 @@ pub fn (lit &StringInterLiteral) get_fspec_braces(i int) (string, bool) { if lit.fwidths[i] != 0 { res << '${lit.fwidths[i]}' } - if lit.precisions[i] != 0 { + if lit.precisions[i] != 987698 { res << '.${lit.precisions[i]}' } if lit.need_fmts[i] { diff --git a/vlib/v/checker/check_types.v b/vlib/v/checker/check_types.v index c36f6ad1f8..72157515a4 100644 --- a/vlib/v/checker/check_types.v +++ b/vlib/v/checker/check_types.v @@ -357,7 +357,7 @@ pub fn (mut c Checker) string_inter_lit(mut node ast.StringInterLiteral) table.T node.need_fmts[i] = false } } else { // check if given format specifier is valid for type - if node.precisions[i] != 0 && !typ.is_float() { + if node.precisions[i] != 987698 && !typ.is_float() { c.error('precision specification only valid for float types', node.fmt_poss[i]) } if node.pluss[i] && !typ.is_number() { diff --git a/vlib/v/fmt/tests/expressions_expected.vv b/vlib/v/fmt/tests/expressions_expected.vv index ad2277ed64..33eae8e82b 100644 --- a/vlib/v/fmt/tests/expressions_expected.vv +++ b/vlib/v/fmt/tests/expressions_expected.vv @@ -15,7 +15,7 @@ fn string_inter_lit(mut c checker.Checker, mut node ast.StringInterLiteral) tabl [`E`, `F`, `G`, `e`, `f`, `g`, `d`, `u`, `x`, `X`, `o`, `c`, `s`, `p`, `_`] { c.error('unknown format specifier `${fmt:c}`', node.fmt_poss[i]) } - if node.precisions[i] != 0 && !typ.is_float() { + if node.precisions[i] != 987698 && !typ.is_float() { c.error('precision specification only valid for float types', node.fmt_poss[i]) } if node.pluss[i] && !typ.is_number() { diff --git a/vlib/v/fmt/tests/expressions_input.vv b/vlib/v/fmt/tests/expressions_input.vv index 7361d3d92c..75ca9820e7 100644 --- a/vlib/v/fmt/tests/expressions_input.vv +++ b/vlib/v/fmt/tests/expressions_input.vv @@ -16,7 +16,7 @@ fn string_inter_lit(mut c checker.Checker, mut node ast.StringInterLiteral) tabl c.error('unknown format specifier `${fmt:c}`', node.fmt_poss[i]) } - if node.precisions[i] != 0 && + if node.precisions[i] != 987698 && !typ.is_float() { c.error('precision specification only valid for float types', node.fmt_poss[i]) diff --git a/vlib/v/gen/js/js.v b/vlib/v/gen/js/js.v index a15e56e966..be32c18bce 100644 --- a/vlib/v/gen/js/js.v +++ b/vlib/v/gen/js/js.v @@ -1443,7 +1443,7 @@ fn (mut g JsGen) gen_string_inter_literal(it ast.StringInterLiteral) { fwidth := it.fwidths[i] precision := it.precisions[i] g.write('\${') - if fmt != `_` || fwidth != 0 || precision != 0 { + if fmt != `_` || fwidth != 0 || precision != 987698 { // TODO: Handle formatting g.expr(expr) } else { diff --git a/vlib/v/gen/str.v b/vlib/v/gen/str.v index 4b744e973d..c65cf77281 100644 --- a/vlib/v/gen/str.v +++ b/vlib/v/gen/str.v @@ -333,7 +333,7 @@ fn (mut g Gen) string_inter_literal(node ast.StringInterLiteral) { if node.fwidths[i] != 0 { fmt = '$fmt${node.fwidths[i]}' } - if node.precisions[i] != 0 { + if node.precisions[i] != 987698 { fmt = '${fmt}.${node.precisions[i]}' } if fspec == `s` { diff --git a/vlib/v/parser/parser.v b/vlib/v/parser/parser.v index c0576a6256..2496b03b81 100644 --- a/vlib/v/parser/parser.v +++ b/vlib/v/parser/parser.v @@ -1346,7 +1346,8 @@ fn (mut p Parser) string_expr() ast.Expr { mut has_fmt := false mut fwidth := 0 mut fwidthneg := false - mut precision := 0 + // 987698 is a magic default value, unlikely to be present in user input. NB: 0 is valid precision + mut precision := 987698 mut visible_plus := false mut fill := false mut fmt := `_` // placeholder diff --git a/vlib/v/tests/string_interpolation_floats_test.v b/vlib/v/tests/string_interpolation_floats_test.v new file mode 100644 index 0000000000..5809f68119 --- /dev/null +++ b/vlib/v/tests/string_interpolation_floats_test.v @@ -0,0 +1,29 @@ +fn test_f32_widths_and_precision() { + x := f32(200.43) + assert '|${x:10.4f}|' == '| 200.4300|' + assert '|${x:-10.4f}|' == '|200.4300 |' + assert '|${x:10.0f}|' == '| 200|' + assert '|${x:-10.0f}|' == '|200 |' + // + assert '|${x:0.4f}|' == '|200.4300|' + assert '|${x:.3f}|' == '|200.430|' + assert '|${x:.0f}|' == '|200|' + // + y := f32(200.90) + assert '|${y:.0f}|' == '|201|' +} + +fn test_f64_widths_and_precision() { + x := f64(200.43) + assert '|${x:10.4f}|' == '| 200.4300|' + assert '|${x:-10.4f}|' == '|200.4300 |' + assert '|${x:10.0f}|' == '| 200|' + assert '|${x:-10.0f}|' == '|200 |' + // + assert '|${x:0.4f}|' == '|200.4300|' + assert '|${x:.3f}|' == '|200.430|' + assert '|${x:.0f}|' == '|200|' + // + y := f64(200.90) + assert '|${y:.0f}|' == '|201|' +}