fmt: make linebreak smarter by algorithm based on penalty
parent
a609ff4659
commit
0338d4153a
|
@ -11,7 +11,8 @@ const (
|
||||||
tabs = ['', '\t', '\t\t', '\t\t\t', '\t\t\t\t', '\t\t\t\t\t', '\t\t\t\t\t\t', '\t\t\t\t\t\t\t',
|
tabs = ['', '\t', '\t\t', '\t\t\t', '\t\t\t\t', '\t\t\t\t\t', '\t\t\t\t\t\t', '\t\t\t\t\t\t\t',
|
||||||
'\t\t\t\t\t\t\t\t'
|
'\t\t\t\t\t\t\t\t'
|
||||||
]
|
]
|
||||||
max_len = 90
|
// when to break a line dependant on penalty
|
||||||
|
max_len = [0, 30, 85, 100]
|
||||||
)
|
)
|
||||||
|
|
||||||
pub struct Fmt {
|
pub struct Fmt {
|
||||||
|
@ -439,7 +440,7 @@ pub fn (mut f Fmt) type_decl(node ast.TypeDecl) {
|
||||||
if i < sum_type_names.len - 1 {
|
if i < sum_type_names.len - 1 {
|
||||||
f.write(' | ')
|
f.write(' | ')
|
||||||
}
|
}
|
||||||
f.wrap_long_line()
|
f.wrap_long_line(2, true)
|
||||||
}
|
}
|
||||||
// f.write(sum_type_names.join(' | '))
|
// f.write(sum_type_names.join(' | '))
|
||||||
}
|
}
|
||||||
|
@ -629,7 +630,14 @@ pub fn (mut f Fmt) expr(node ast.Expr) {
|
||||||
f.write('$node.op.str()')
|
f.write('$node.op.str()')
|
||||||
} else {
|
} else {
|
||||||
f.write(' $node.op.str() ')
|
f.write(' $node.op.str() ')
|
||||||
f.wrap_long_line()
|
mut penalty := 3
|
||||||
|
if node.left is ast.InfixExpr || node.left is ast.ParExpr {
|
||||||
|
penalty--
|
||||||
|
}
|
||||||
|
if node.right is ast.InfixExpr || node.right is ast.ParExpr {
|
||||||
|
penalty--
|
||||||
|
}
|
||||||
|
f.wrap_long_line(penalty, true)
|
||||||
}
|
}
|
||||||
f.expr(node.right)
|
f.expr(node.right)
|
||||||
}
|
}
|
||||||
|
@ -788,14 +796,14 @@ pub fn (mut f Fmt) expr(node ast.Expr) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (mut f Fmt) wrap_long_line() bool {
|
pub fn (mut f Fmt) wrap_long_line(penalty int, add_indent bool) bool {
|
||||||
if f.line_len <= max_len {
|
if f.line_len <= max_len[penalty] {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if f.out.buf[f.out.buf.len - 1] == ` ` {
|
if f.out.buf[f.out.buf.len - 1] == ` ` {
|
||||||
f.out.go_back(1)
|
f.out.go_back(1)
|
||||||
}
|
}
|
||||||
f.write('\n' + tabs[f.indent + 1])
|
f.write('\n' + tabs[f.indent + if add_indent { 1 } else { 0 }])
|
||||||
f.line_len = 0
|
f.line_len = 0
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
@ -806,7 +814,7 @@ pub fn (mut f Fmt) call_args(args []ast.CallArg) {
|
||||||
f.write('mut ')
|
f.write('mut ')
|
||||||
}
|
}
|
||||||
if i > 0 {
|
if i > 0 {
|
||||||
f.wrap_long_line()
|
f.wrap_long_line(2, true)
|
||||||
}
|
}
|
||||||
f.expr(arg.expr)
|
f.expr(arg.expr)
|
||||||
if i < args.len - 1 {
|
if i < args.len - 1 {
|
||||||
|
@ -1193,15 +1201,24 @@ pub fn (mut f Fmt) array_init(it ast.ArrayInit) {
|
||||||
mut inc_indent := false
|
mut inc_indent := false
|
||||||
mut last_line_nr := it.pos.line_nr // to have the same newlines between array elements
|
mut last_line_nr := it.pos.line_nr // to have the same newlines between array elements
|
||||||
for i, expr in it.exprs {
|
for i, expr in it.exprs {
|
||||||
|
mut penalty := 3
|
||||||
line_nr := expr.position().line_nr
|
line_nr := expr.position().line_nr
|
||||||
if last_line_nr < line_nr {
|
if last_line_nr < line_nr {
|
||||||
if !inc_indent {
|
penalty--
|
||||||
f.indent++
|
}
|
||||||
inc_indent = true
|
if i == 0 || it.exprs[i-1] is ast.ArrayInit || it.exprs[i-1] is ast.StructInit ||
|
||||||
}
|
it.exprs[i-1] is ast.MapInit || it.exprs[i-1] is ast.CallExpr {
|
||||||
f.writeln('')
|
penalty--
|
||||||
|
}
|
||||||
|
if expr is ast.ArrayInit || expr is ast.StructInit ||
|
||||||
|
expr is ast.MapInit || expr is ast.CallExpr {
|
||||||
|
penalty--
|
||||||
|
}
|
||||||
|
is_new_line := f.wrap_long_line(penalty, !inc_indent)
|
||||||
|
if is_new_line && !inc_indent {
|
||||||
|
f.indent++
|
||||||
|
inc_indent = true
|
||||||
}
|
}
|
||||||
is_new_line := last_line_nr < line_nr || f.wrap_long_line()
|
|
||||||
if !is_new_line && i > 0 {
|
if !is_new_line && i > 0 {
|
||||||
f.write(' ')
|
f.write(' ')
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,13 +6,9 @@ const (
|
||||||
eulers = 2.7182
|
eulers = 2.7182
|
||||||
supported_platforms = ['windows', 'mac', 'macos', 'darwin', 'linux', 'freebsd', 'openbsd',
|
supported_platforms = ['windows', 'mac', 'macos', 'darwin', 'linux', 'freebsd', 'openbsd',
|
||||||
'netbsd', 'dragonfly', 'android', 'js', 'solaris', 'haiku', 'linux_or_macos']
|
'netbsd', 'dragonfly', 'android', 'js', 'solaris', 'haiku', 'linux_or_macos']
|
||||||
one_line_supported = ['windows', 'mac', 'macos', 'darwin', 'linux', 'freebsd', 'openbsd',
|
one_line_supported = ['windows', 'mac', 'macos', 'darwin', 'linux', 'freebsd', 'openbsd', 'netbsd',
|
||||||
'netbsd', 'dragonfly', 'android', 'js', 'solaris', 'haiku', 'linux_or_macos']
|
'dragonfly', 'android', 'js', 'solaris', 'haiku', 'linux_or_macos']
|
||||||
another_const = [
|
another_const = ['a', 'b', 'c', 'd', 'e', 'f']
|
||||||
'a', 'b',
|
|
||||||
'c', 'd', 'e',
|
|
||||||
'f'
|
|
||||||
]
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
import v.checker
|
||||||
|
import v.ast
|
||||||
|
import v.table
|
||||||
|
|
||||||
|
pub fn string_inter_lit(mut c checker.Checker, mut node ast.StringInterLiteral) table.Type {
|
||||||
|
for i, expr in node.exprs {
|
||||||
|
ftyp := c.expr(expr)
|
||||||
|
node.expr_types << ftyp
|
||||||
|
typ := c.table.unalias_num_type(ftyp)
|
||||||
|
mut fmt := node.fmts[i]
|
||||||
|
// analyze and validate format specifier
|
||||||
|
if fmt !in [`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() {
|
||||||
|
c.error('precision specification only valid for float types', node.fmt_poss[i])
|
||||||
|
}
|
||||||
|
if node.pluss[i] && !typ.is_number() {
|
||||||
|
c.error('plus prefix only allowd for numbers', node.fmt_poss[i])
|
||||||
|
}
|
||||||
|
if (typ.is_unsigned() && fmt !in [`u`, `x`, `X`, `o`, `c`]) ||
|
||||||
|
(typ.is_signed() && fmt !in [`d`, `x`, `X`, `o`, `c`]) ||
|
||||||
|
(typ.is_any_int() && fmt !in [`d`, `c`, `x`, `X`, `o`, `u`, `x`, `X`, `o`]) ||
|
||||||
|
(typ.is_float() && fmt !in [`E`, `F`, `G`, `e`, `f`, `g`]) ||
|
||||||
|
(typ.is_pointer() && fmt !in [`p`, `x`, `X`]) ||
|
||||||
|
(typ.is_string() && fmt != `s`) ||
|
||||||
|
(typ.idx() in [table.i64_type_idx, table.f64_type_idx] &&
|
||||||
|
fmt == `c`) {
|
||||||
|
c.error('illegal format specifier `${fmt:c}` for type `${c.table.get_type_name(ftyp)}`',
|
||||||
|
node.fmt_poss[i])
|
||||||
|
}
|
||||||
|
node.need_fmts[i] = fmt != c.get_default_fmt(ftyp, typ)
|
||||||
|
}
|
||||||
|
return table.string_type
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_some_val(a_test, b_test, c_test, d_test, e_test, f_test f64) {
|
||||||
|
return a_test * b_test * c_test * d_test +
|
||||||
|
e_test * f_test * a_test * d_test +
|
||||||
|
a_test * b_test * c_test
|
||||||
|
}
|
|
@ -0,0 +1,47 @@
|
||||||
|
import v.checker
|
||||||
|
import v.ast
|
||||||
|
import v.table
|
||||||
|
|
||||||
|
pub fn string_inter_lit(mut c checker.Checker, mut node ast.StringInterLiteral) table.Type {
|
||||||
|
for i, expr in node.exprs {
|
||||||
|
ftyp := c.expr(expr)
|
||||||
|
node.expr_types << ftyp
|
||||||
|
typ := c.table.unalias_num_type(ftyp)
|
||||||
|
mut fmt := node.fmts[i]
|
||||||
|
// analyze and validate format specifier
|
||||||
|
if fmt !in [`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() {
|
||||||
|
c.error('precision specification only valid for float types',
|
||||||
|
node.fmt_poss[i])
|
||||||
|
}
|
||||||
|
if node.pluss[i] && !typ.is_number() {
|
||||||
|
c.error('plus prefix only allowd for numbers', node.fmt_poss[i])
|
||||||
|
}
|
||||||
|
if (typ.is_unsigned() && fmt !in [`u`, `x`, `X`, `o`, `c`]) || (typ.is_signed() &&
|
||||||
|
fmt !in [`d`, `x`, `X`, `o`, `c`]) || (typ.is_any_int()
|
||||||
|
&& fmt !in [`d`, `c`, `x`, `X`, `o`,
|
||||||
|
`u`, `x`, `X`, `o`]) || (typ.is_float() && fmt !in [`E`, `F`,
|
||||||
|
`G`, `e`, `f`, `g`]) || (typ.is_pointer() &&
|
||||||
|
fmt !in [`p`, `x`, `X`]) || (typ.is_string() && fmt != `s`)
|
||||||
|
|| (typ.idx() in [table.i64_type_idx,
|
||||||
|
table.f64_type_idx
|
||||||
|
] && fmt == `c`) {
|
||||||
|
c.error('illegal format specifier `${fmt:c}` for type `${c.table.get_type_name(ftyp)}`',
|
||||||
|
node.fmt_poss[i])
|
||||||
|
}
|
||||||
|
node.need_fmts[i] = fmt != c.get_default_fmt(ftyp, typ)
|
||||||
|
}
|
||||||
|
|
||||||
|
return table.string_type
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_some_val(a_test, b_test, c_test, d_test, e_test, f_test f64) {
|
||||||
|
return a_test*b_test*c_test*
|
||||||
|
d_test+e_test*f_test*a_test*d_test+a_test*
|
||||||
|
b_test*c_test
|
||||||
|
}
|
Loading…
Reference in New Issue