fmt: single line matches

pull/4461/head^2
Alexander Medvednikov 2020-04-17 20:51:16 +02:00
parent 67cd90de6e
commit 2c778c8849
3 changed files with 112 additions and 135 deletions

View File

@ -67,7 +67,7 @@ fn (f mut Fmt) find_comment(line_nr int) {
} }
} }
*/ */
pub fn (f mut Fmt) write(s string) { pub fn (var f Fmt) write(s string) {
if f.indent > 0 && f.empty_line { if f.indent > 0 && f.empty_line {
f.out.write(tabs[f.indent]) f.out.write(tabs[f.indent])
f.line_len += f.indent * 4 f.line_len += f.indent * 4
@ -77,7 +77,7 @@ pub fn (f mut Fmt) write(s string) {
f.empty_line = false f.empty_line = false
} }
pub fn (f mut Fmt) writeln(s string) { pub fn (var f Fmt) writeln(s string) {
if f.indent > 0 && f.empty_line { if f.indent > 0 && f.empty_line {
// println(f.indent.str() + s) // println(f.indent.str() + s)
f.out.write(tabs[f.indent]) f.out.write(tabs[f.indent])
@ -87,7 +87,7 @@ pub fn (f mut Fmt) writeln(s string) {
f.line_len = 0 f.line_len = 0
} }
fn (f mut Fmt) mod(mod ast.Module) { fn (var f Fmt) mod(mod ast.Module) {
f.cur_mod = mod.name f.cur_mod = mod.name
if mod.is_skipped { if mod.is_skipped {
return return
@ -95,7 +95,7 @@ fn (f mut Fmt) mod(mod ast.Module) {
f.writeln('module $mod.name\n') f.writeln('module $mod.name\n')
} }
fn (f mut Fmt) imports(imports []ast.Import) { fn (var f Fmt) imports(imports []ast.Import) {
if f.did_imports || imports.len == 0 { if f.did_imports || imports.len == 0 {
return return
} }
@ -129,7 +129,7 @@ fn (f Fmt) imp_stmt_str(imp ast.Import) string {
return '${imp.mod}${imp_alias_suffix}' return '${imp.mod}${imp_alias_suffix}'
} }
fn (f mut Fmt) stmts(stmts []ast.Stmt) { fn (var f Fmt) stmts(stmts []ast.Stmt) {
f.indent++ f.indent++
for stmt in stmts { for stmt in stmts {
f.stmt(stmt) f.stmt(stmt)
@ -137,7 +137,7 @@ fn (f mut Fmt) stmts(stmts []ast.Stmt) {
f.indent-- f.indent--
} }
fn (f mut Fmt) stmt(node ast.Stmt) { fn (var f Fmt) stmt(node ast.Stmt) {
match node { match node {
ast.AssignStmt { ast.AssignStmt {
for i, ident in it.left { for i, ident in it.left {
@ -178,12 +178,8 @@ fn (f mut Fmt) stmt(node ast.Stmt) {
} }
ast.BranchStmt { ast.BranchStmt {
match it.tok.kind { match it.tok.kind {
.key_break { .key_break { f.writeln('break') }
f.writeln('break') .key_continue { f.writeln('continue') }
}
.key_continue {
f.writeln('continue')
}
else {} else {}
} }
} }
@ -379,7 +375,7 @@ fn (f mut Fmt) stmt(node ast.Stmt) {
} }
} }
fn (f mut Fmt) type_decl(node ast.TypeDecl) { fn (var f Fmt) type_decl(node ast.TypeDecl) {
match node { match node {
ast.AliasTypeDecl { ast.AliasTypeDecl {
if it.is_pub { if it.is_pub {
@ -406,7 +402,7 @@ fn (f mut Fmt) type_decl(node ast.TypeDecl) {
f.writeln('\n') f.writeln('\n')
} }
fn (f mut Fmt) struct_decl(node ast.StructDecl) { fn (var f Fmt) struct_decl(node ast.StructDecl) {
if node.is_pub { if node.is_pub {
f.write('pub ') f.write('pub ')
} }
@ -453,17 +449,17 @@ fn (f mut Fmt) struct_decl(node ast.StructDecl) {
} }
fn (f &Fmt) type_to_str(t table.Type) string { fn (f &Fmt) type_to_str(t table.Type) string {
mut res := f.table.type_to_str(t) var res := f.table.type_to_str(t)
// type_ptr => &type // type_ptr => &type
if res.ends_with('_ptr') { if res.ends_with('_ptr') {
res = res[0 .. res.len-4] res = res[0..res.len - 4]
start_pos := 2 * res.count('[]') start_pos := 2 * res.count('[]')
res = res[0 .. start_pos] + '&' + res[start_pos .. res.len] res = res[0..start_pos] + '&' + res[start_pos..res.len]
} }
return res.replace(f.cur_mod + '.', '') return res.replace(f.cur_mod + '.', '')
} }
fn (f mut Fmt) expr(node ast.Expr) { fn (var f Fmt) expr(node ast.Expr) {
match node { match node {
ast.ArrayInit { ast.ArrayInit {
if it.exprs.len == 0 && it.typ != 0 && it.typ != table.void_type { if it.exprs.len == 0 && it.typ != 0 && it.typ != table.void_type {
@ -582,46 +578,7 @@ fn (f mut Fmt) expr(node ast.Expr) {
f.write('}') f.write('}')
} }
ast.MatchExpr { ast.MatchExpr {
f.write('match ') f.match_expr(it)
if it.is_mut {
f.write('var ')
}
f.expr(it.cond)
f.writeln(' {')
f.indent++
for i, branch in it.branches {
if branch.comment.text != '' {
f.comment(branch.comment)
}
if !branch.is_else {
// normal branch
for j, expr in branch.exprs {
f.expr(expr)
if j < branch.exprs.len - 1 {
f.write(', ')
}
}
} else {
// else branch
f.write('else')
}
if branch.stmts.len == 0 {
f.writeln(' {}')
} else {
// TODO single line branches
// if branch.stmts.len < 2 {
// f.write(' { ')
// } else {
f.writeln(' {')
// f.single_line_if = true
// }
f.stmts(branch.stmts)
// f.single_line_if = false
f.writeln('}')
}
}
f.indent--
f.write('}')
} }
ast.None { ast.None {
f.write('none') f.write('none')
@ -737,7 +694,7 @@ fn (f mut Fmt) expr(node ast.Expr) {
} }
} }
fn (f mut Fmt) wrap_long_line() { fn (var f Fmt) wrap_long_line() {
if f.line_len > max_len { if f.line_len > max_len {
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)
@ -747,7 +704,7 @@ fn (f mut Fmt) wrap_long_line() {
} }
} }
fn (f mut Fmt) call_args(args []ast.CallArg) { fn (var f Fmt) call_args(args []ast.CallArg) {
for i, arg in args { for i, arg in args {
if arg.is_mut { if arg.is_mut {
f.write('mut ') f.write('mut ')
@ -762,7 +719,7 @@ fn (f mut Fmt) call_args(args []ast.CallArg) {
} }
} }
fn (f mut Fmt) or_expr(or_block ast.OrExpr) { fn (var f Fmt) or_expr(or_block ast.OrExpr) {
if or_block.stmts.len > 0 { if or_block.stmts.len > 0 {
f.writeln(' or {') f.writeln(' or {')
f.stmts(or_block.stmts) f.stmts(or_block.stmts)
@ -770,7 +727,7 @@ fn (f mut Fmt) or_expr(or_block ast.OrExpr) {
} }
} }
fn (f mut Fmt) comment(node ast.Comment) { fn (var f Fmt) comment(node ast.Comment) {
if !node.text.contains('\n') { if !node.text.contains('\n') {
is_separate_line := node.text.starts_with('|') is_separate_line := node.text.starts_with('|')
var s := if is_separate_line { node.text[1..] } else { node.text } var s := if is_separate_line { node.text[1..] } else { node.text }
@ -806,7 +763,7 @@ fn short_module(name string) string {
return vals[vals.len - 2] + '.' + vals[vals.len - 1] return vals[vals.len - 2] + '.' + vals[vals.len - 1]
} }
fn (f mut Fmt) if_expr(it ast.IfExpr) { fn (var f Fmt) if_expr(it ast.IfExpr) {
single_line := it.branches.len == 2 && it.has_else && it.branches[0].stmts.len == 1 && single_line := it.branches.len == 2 && it.has_else && it.branches[0].stmts.len == 1 &&
it.branches[1].stmts.len == 1 && (it.is_expr || f.is_assign) it.branches[1].stmts.len == 1 && (it.is_expr || f.is_assign)
f.single_line_if = single_line f.single_line_if = single_line
@ -839,7 +796,7 @@ fn (f mut Fmt) if_expr(it ast.IfExpr) {
f.single_line_if = false f.single_line_if = false
} }
fn (f mut Fmt) call_expr(node ast.CallExpr) { fn (var f Fmt) call_expr(node ast.CallExpr) {
if node.is_method { if node.is_method {
match node.left { match node.left {
ast.Ident { ast.Ident {
@ -876,13 +833,77 @@ fn (f mut Fmt) call_expr(node ast.CallExpr) {
} }
} }
fn (f mut Fmt) mark_types_module_as_used(typ table.Type) { fn (var f Fmt) match_expr(it ast.MatchExpr) {
f.write('match ')
if it.is_mut {
f.write('var ')
}
f.expr(it.cond)
f.writeln(' {')
f.indent++
var single_line := true
for i, branch in it.branches {
if branch.stmts.len > 1 {
single_line = false
break
}
}
for i, branch in it.branches {
if branch.comment.text != '' {
f.comment(branch.comment)
}
if !branch.is_else {
// normal branch
for j, expr in branch.exprs {
f.expr(expr)
if j < branch.exprs.len - 1 {
f.write(', ')
}
}
} else {
// else branch
f.write('else')
}
if branch.stmts.len == 0 {
f.writeln(' {}')
} else {
if single_line {
f.write(' { ')
} else {
f.writeln(' {')
}
f.stmts(branch.stmts)
if single_line {
f.remove_new_line()
f.writeln(' }')
} else {
f.writeln('}')
}
}
}
f.indent--
f.write('}')
}
fn (var f Fmt) remove_new_line() {
var i := 0
for i = f.out.len - 1; i >= 0; i-- {
if !f.out.buf[i].is_space() { // != `\n` {
break
}
}
f.out.go_back(f.out.len - i - 1)
f.empty_line = false
// f.writeln('sdf')
}
fn (var f Fmt) mark_types_module_as_used(typ table.Type) {
sym := f.table.get_type_symbol(typ) sym := f.table.get_type_symbol(typ)
f.mark_module_as_used(sym.name) f.mark_module_as_used(sym.name)
} }
// `name` is a function (`foo.bar()`) or type (`foo.Bar{}`) // `name` is a function (`foo.bar()`) or type (`foo.Bar{}`)
fn (f mut Fmt) mark_module_as_used(name string) { fn (var f Fmt) mark_module_as_used(name string) {
if !name.contains('.') { if !name.contains('.') {
return return
} }

View File

@ -1,12 +1,8 @@
fn match_expr() { fn match_expr() {
a := 10 a := 10
match a { match a {
10 { 10 { println('10') }
println('10') 20 { println('20') }
}
20 {
println('20')
}
else {} else {}
} }
} }
@ -14,14 +10,8 @@ fn match_expr() {
fn match_expr_assignment() { fn match_expr_assignment() {
a := 20 a := 20
b := match a { b := match a {
10 { 10 { 10 }
10 5 { 5 }
} else { 2 }
5 {
5
}
else {
2
}
} }
} }

View File

@ -9,59 +9,35 @@ pub fn (c Color) str() string {
} }
fn test_match_integers() { fn test_match_integers() {
mut a := 3 var a := 3
mut b := 0 var b := 0
match a { match a {
2 { 2 { println('two') }
println('two')
}
3 { 3 {
println('three') println('three')
b = 3 b = 3
} }
4 { 4 { println('four') }
println('four') else { println('???') }
}
else {
println('???')
}
} }
assert b == 3 assert b == 3
assert match 2 { assert match 2 {
1 { 1 { 2 }
2 2 { 3 }
} else { 5 }
2 {
3
}
else {
5
}
} == 3 } == 3
assert match 0 { assert match 0 {
1 { 1 { 2 }
2 2 { 3 }
} else { 5 }
2 {
3
}
else {
5
}
} == 5 } == 5
assert match 1 { assert match 1 {
else { else { 5 }
5
}
} == 5 } == 5
a = 0 a = 0
match 2 { match 2 {
0 { 0 { a = 1 }
a = 1 1 { a = 2 }
}
1 {
a = 2
}
else { else {
a = 3 a = 3
println('a is $a') println('a is $a')
@ -70,9 +46,7 @@ fn test_match_integers() {
assert a == 3 assert a == 3
a = 0 a = 0
match 1 { match 1 {
0 { 0 { a = 1 }
a = 1
}
1 { 1 {
a = 2 a = 2
a = a + 2 a = a + 2
@ -83,22 +57,16 @@ fn test_match_integers() {
assert a == 6 assert a == 6
a = 0 a = 0
match 1 { match 1 {
else { else { a = -2 }
a = -2
}
} }
assert a == -2 assert a == -2
} }
fn test_match_enums() { fn test_match_enums() {
mut b := Color.red var b := Color.red
match b { match b {
.red { .red { b = .green }
b = .green .green { b = .blue }
}
.green {
b = .blue
}
else { else {
println('b is ${b.str()}') println('b is ${b.str()}')
b = .red b = .red
@ -106,9 +74,7 @@ fn test_match_enums() {
} }
assert b == .green assert b == .green
match b { match b {
.red { .red { b = .green }
b = .green
}
else { else {
println('b is ${b.str()}') println('b is ${b.str()}')
b = .blue b = .blue