From cc0e0ed2819d6bca023fe3b60ea95e63c921c914 Mon Sep 17 00:00:00 2001 From: Alexander Medvednikov Date: Tue, 21 Apr 2020 04:51:50 +0200 Subject: [PATCH] fmt: single line match fix; x64: minor fixes --- vlib/v/fmt/fmt.v | 20 ++++++++ vlib/v/gen/cgen.v | 33 ++++++------- vlib/v/gen/x64/gen.v | 114 +++++++++++++++++++++++++++++++------------ 3 files changed, 118 insertions(+), 49 deletions(-) diff --git a/vlib/v/fmt/fmt.v b/vlib/v/fmt/fmt.v index a826261191..0fe3757b73 100644 --- a/vlib/v/fmt/fmt.v +++ b/vlib/v/fmt/fmt.v @@ -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 +} diff --git a/vlib/v/gen/cgen.v b/vlib/v/gen/cgen.v index 716a1d74df..1aa8aca605 100644 --- a/vlib/v/gen/cgen.v +++ b/vlib/v/gen/cgen.v @@ -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' } - diff --git a/vlib/v/gen/x64/gen.v b/vlib/v/gen/x64/gen.v index 6a26a96851..412a14215b 100644 --- a/vlib/v/gen/x64/gen.v +++ b/vlib/v/gen/x64/gen.v @@ -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) }