fmt: single line match fix; x64: minor fixes

pull/4534/head^2
Alexander Medvednikov 2020-04-21 04:51:50 +02:00
parent 4ea4d1c8c4
commit cc0e0ed281
3 changed files with 118 additions and 49 deletions

View File

@ -863,6 +863,18 @@ fn (var f Fmt) match_expr(it ast.MatchExpr) {
single_line = false
break
}
if branch.stmts.len == 0 {
continue
}
stmt := branch.stmts[0]
if stmt is ast.ExprStmt {
// If expressions inside match branches can't be one a single line
expr_stmt := stmt as ast.ExprStmt
if !expr_is_single_line(expr_stmt.expr) {
single_line = false
break
}
}
}
for i, branch in it.branches {
if branch.comment.text != '' {
@ -933,3 +945,11 @@ fn (var f Fmt) mark_module_as_used(name string) {
f.used_imports << mod
// println('marking module $mod as used')
}
fn expr_is_single_line(expr ast.Expr) bool {
match expr {
ast.IfExpr { return false }
else {}
}
return true
}

View File

@ -21,9 +21,12 @@ const (
'extern'
'float'
'inline'
'int', 'long', 'register', 'restrict', 'short', 'signed', 'sizeof', 'static', 'switch'
'typedef'
'union', 'unsigned', 'void', 'volatile', 'while']
'int'
'long'
'register'
'restrict', 'short', 'signed', 'sizeof', 'static', 'switch', 'typedef', 'union', 'unsigned'
'void'
'volatile', 'while']
)
fn foo(t token.Token) {
@ -435,9 +438,11 @@ fn (var g Gen) stmt(node ast.Stmt) {
// no ; after an if expression }
match expr {
ast.IfExpr {}
else { if !g.inside_ternary {
else {
if !g.inside_ternary {
g.writeln(';')
} }
}
}
}
}
ast.FnDecl {
@ -1340,7 +1345,8 @@ fn (var g Gen) infix_expr(node ast.InfixExpr) {
g.write(' })')
}
} else if (node.left_type == node.right_type) && node.left_type in [table.f32_type_idx,
table.f64_type_idx] && node.op in [.eq, .ne] {
table.f64_type_idx
] && node.op in [.eq, .ne] {
// floats should be compared with epsilon
if node.left_type == table.f64_type_idx {
if node.op == .eq {
@ -1649,15 +1655,9 @@ fn (var g Gen) index_expr(node ast.IndexExpr) {
} else if sym.kind == .array {
info := sym.info as table.Array
elem_type_str := g.typ(info.elem_type)
var is_selector := false
match node.left {
ast.SelectorExpr {
// `vals[i].field = x` is an exception and requires `array_get`:
// `(*(Val*)array_get(vals, i)).field = x;`
is_selector = true
}
else {}
}
// `vals[i].field = x` is an exception and requires `array_get`:
// `(*(Val*)array_get(vals, i)).field = x;`
is_selector := node.left is ast.SelectorExpr
if g.is_assign_lhs && !is_selector && node.is_setter {
g.is_array_set = true
g.write('array_set(')
@ -1810,8 +1810,6 @@ fn (var g Gen) return_statement(node ast.Return) {
is_none = true
}
ast.CallExpr {
// TODO: why?
// if !it.is_method {
if it.name == 'error' {
is_error = true // TODO check name 'error'
}
@ -2925,4 +2923,3 @@ fn (g Gen) type_to_fmt(typ table.Type) string {
}
return '%d'
}

View File

@ -21,18 +21,41 @@ mut:
}
// string_addr map[string]i64
// The registers are ordered for faster generation
// push rax => 50
// push rcx => 51 etc
enum Register {
rax
rcx
rdx
rbx
rsp
rbp
rsi
rdi
eax
edi
rax
rdi
rsi
rbp
edx
rdx
r8
r9
r10
r11
r12
r13
r14
r15
}
/*
rax // 0
rcx // 1
rdx // 2
rbx // 3
rsp // 4
rbp // 5
rsi // 6
rdi // 7
*/
enum Size {
_8
_16
@ -216,10 +239,23 @@ pub fn (var g Gen) ret() {
}
pub fn (var g Gen) push(reg Register) {
if reg < .r8 {
g.write8(0x50 + reg)
} else {
g.write8(0x41)
g.write8(0x50 + reg - 8)
}
/*
match reg {
.rbp { g.write8(0x55) }
else {}
}
*/
}
pub fn (var g Gen) pop(reg Register) {
g.write8(0x58 + reg)
// TODO r8...
}
// returns label's relative address
@ -274,7 +310,7 @@ pub fn (var g Gen) gen_exit() {
fn (var g Gen) mov(reg Register, val int) {
match reg {
.eax {
.eax, .rax {
g.write8(0xb8)
}
.edi {
@ -325,37 +361,22 @@ pub fn (var g Gen) call_fn(name string) {
fn (var g Gen) stmt(node ast.Stmt) {
match node {
ast.ConstDecl {}
ast.FnDecl {
is_main := it.name == 'main'
println('saving addr $it.name $g.buf.len.hex()')
if is_main {
g.save_main_fn_addr()
} else {
g.register_function_address(it.name)
}
for arg in it.args {
}
for stmt in it.stmts {
g.stmt(stmt)
}
if is_main {
println('end of main: gen exit')
g.gen_exit()
// return
}
g.ret()
ast.AssignStmt {
g.assign_stmt(it)
}
ast.ConstDecl {}
ast.ExprStmt {
g.expr(it.expr)
}
ast.FnDecl {
g.fn_decl(it)
}
ast.ForStmt {}
ast.Return {
g.gen_exit()
g.ret()
}
ast.AssignStmt {}
ast.ForStmt {}
ast.StructDecl {}
ast.ExprStmt {
g.expr(it.expr)
}
else {
println('x64.stmt(): bad node')
}
@ -395,6 +416,37 @@ fn (var g Gen) expr(node ast.Expr) {
}
}
fn (var g Gen) assign_stmt(node ast.AssignStmt) {
// `a := 1` | `a,b := 1,2`
for i, ident in node.left {
}
}
fn (var g Gen) fn_decl(it ast.FnDecl) {
is_main := it.name == 'main'
println('saving addr $it.name $g.buf.len.hex()')
if is_main {
g.save_main_fn_addr()
} else {
g.register_function_address(it.name)
g.push(.rbp)
}
for arg in it.args {
}
for stmt in it.stmts {
g.stmt(stmt)
}
if is_main {
println('end of main: gen exit')
g.gen_exit()
// return
}
if !is_main {
g.pop(.rbp)
}
g.ret()
}
fn verror(s string) {
util.verror('x64 gen error', s)
}