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', | ||||
| 		'\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 { | ||||
|  | @ -439,7 +440,7 @@ pub fn (mut f Fmt) type_decl(node ast.TypeDecl) { | |||
| 				if i < sum_type_names.len - 1 { | ||||
| 					f.write(' | ') | ||||
| 				} | ||||
| 				f.wrap_long_line() | ||||
| 				f.wrap_long_line(2, true) | ||||
| 			} | ||||
| 			// f.write(sum_type_names.join(' | '))
 | ||||
| 		} | ||||
|  | @ -629,7 +630,14 @@ pub fn (mut f Fmt) expr(node ast.Expr) { | |||
| 				f.write('$node.op.str()') | ||||
| 			} else { | ||||
| 				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) | ||||
| 		} | ||||
|  | @ -788,14 +796,14 @@ pub fn (mut f Fmt) expr(node ast.Expr) { | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| pub fn (mut f Fmt) wrap_long_line() bool { | ||||
| 	if f.line_len <= max_len { | ||||
| pub fn (mut f Fmt) wrap_long_line(penalty int, add_indent bool) bool { | ||||
| 	if f.line_len <= max_len[penalty] { | ||||
| 		return false | ||||
| 	} | ||||
| 	if f.out.buf[f.out.buf.len - 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 | ||||
| 	return true | ||||
| } | ||||
|  | @ -806,7 +814,7 @@ pub fn (mut f Fmt) call_args(args []ast.CallArg) { | |||
| 			f.write('mut ') | ||||
| 		} | ||||
| 		if i > 0 { | ||||
| 			f.wrap_long_line() | ||||
| 			f.wrap_long_line(2, true) | ||||
| 		} | ||||
| 		f.expr(arg.expr) | ||||
| 		if i < args.len - 1 { | ||||
|  | @ -1193,15 +1201,24 @@ pub fn (mut f Fmt) array_init(it ast.ArrayInit) { | |||
| 	mut inc_indent := false | ||||
| 	mut last_line_nr := it.pos.line_nr // to have the same newlines between array elements
 | ||||
| 	for i, expr in it.exprs { | ||||
| 		mut penalty := 3 | ||||
| 		line_nr := expr.position().line_nr | ||||
| 		if last_line_nr < line_nr { | ||||
| 			if !inc_indent { | ||||
| 				f.indent++ | ||||
| 				inc_indent = true | ||||
| 			} | ||||
| 			f.writeln('') | ||||
| 			penalty-- | ||||
| 		} | ||||
| 		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 { | ||||
| 			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 { | ||||
| 			f.write(' ') | ||||
| 		} | ||||
|  |  | |||
|  | @ -6,13 +6,9 @@ const ( | |||
| 	eulers              = 2.7182 | ||||
| 	supported_platforms = ['windows', 'mac', 'macos', 'darwin', 'linux', 'freebsd', 'openbsd', | ||||
| 		'netbsd', 'dragonfly', 'android', 'js', 'solaris', 'haiku', 'linux_or_macos'] | ||||
| 	one_line_supported  = ['windows', 'mac', 'macos', 'darwin', 'linux', 'freebsd', 'openbsd', | ||||
| 		'netbsd', 'dragonfly', 'android', 'js', 'solaris', 'haiku', 'linux_or_macos'] | ||||
| 	another_const       = [ | ||||
| 		'a', 'b', | ||||
| 		'c', 'd', 'e', | ||||
| 		'f' | ||||
| 	] | ||||
| 	one_line_supported  = ['windows', 'mac', 'macos', 'darwin', 'linux', 'freebsd', 'openbsd', 'netbsd', | ||||
| 		'dragonfly', 'android', 'js', 'solaris', 'haiku', 'linux_or_macos'] | ||||
| 	another_const       = ['a', 'b', 'c', 'd', 'e', 'f'] | ||||
| ) | ||||
| 
 | ||||
| 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