From 88988817d0bdd3c50160125fffecc060cd7d6acd Mon Sep 17 00:00:00 2001 From: Alexander Medvednikov Date: Mon, 10 Aug 2020 19:54:38 +0200 Subject: [PATCH] parser: minor `match` simplification --- vlib/builtin/int.v | 1 + vlib/v/builder/x64.v | 2 +- vlib/v/checker/checker.v | 8 +++++++- vlib/v/gen/auto_str_methods.v | 1 + vlib/v/gen/x64/gen.v | 20 +++++++++++++++++--- vlib/v/parser/{if.v => if_match.v} | 16 ++++++++++------ vlib/v/tests/match_test.v | 27 +++++++++++++-------------- 7 files changed, 50 insertions(+), 25 deletions(-) rename vlib/v/parser/{if.v => if_match.v} (94%) diff --git a/vlib/builtin/int.v b/vlib/builtin/int.v index f8f4c7b287..751449cac7 100644 --- a/vlib/builtin/int.v +++ b/vlib/builtin/int.v @@ -411,6 +411,7 @@ pub fn (b []byte) clone() []byte { return res } +// TODO remove this once runes are implemented pub fn (b []byte) bytestr() string { return bytes2string(b) } diff --git a/vlib/v/builder/x64.v b/vlib/v/builder/x64.v index 24037d1215..5d6004f04f 100644 --- a/vlib/v/builder/x64.v +++ b/vlib/v/builder/x64.v @@ -21,7 +21,7 @@ pub fn (mut b Builder) build_x64(v_files []string, out_file string) { t2 := time.ticks() check_time := t2 - t1 b.timing_message('CHECK', check_time) - x64.gen(b.parsed_files, out_file, b.pref) + x64.gen(b.parsed_files, b.table, out_file, b.pref) t3 := time.ticks() gen_time := t3 - t2 b.timing_message('x64 GEN', gen_time) diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 69ee63ca10..20ac11080f 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -1589,6 +1589,9 @@ pub fn (mut c Checker) enum_decl(decl ast.EnumDecl) { pub fn (mut c Checker) assign_stmt(mut assign_stmt ast.AssignStmt) { c.expected_type = table.none_type // TODO a hack to make `x := if ... work` + defer { + c.expected_type = table.void_type + } right_first := assign_stmt.right[0] mut right_len := assign_stmt.right.len if right_first is ast.CallExpr || right_first is ast.IfExpr || right_first is ast.MatchExpr { @@ -1720,6 +1723,10 @@ pub fn (mut c Checker) assign_stmt(mut assign_stmt ast.AssignStmt) { assign_stmt.op !in [.assign, .decl_assign] && !c.inside_unsafe { c.warn('pointer arithmetic is only allowed in `unsafe` blocks', assign_stmt.pos) } + if c.pref.translated { + // TODO fix this in C2V instead, for example cast enums to int before using `|` on them. + return + } // Single side check match assign_stmt.op { .assign {} // No need to do single side check for =. But here put it first for speed. @@ -1774,7 +1781,6 @@ pub fn (mut c Checker) assign_stmt(mut assign_stmt ast.AssignStmt) { right.position()) } } - c.expected_type = table.void_type } fn (mut c Checker) check_array_init_para_type(para string, expr ast.Expr, pos token.Position) { diff --git a/vlib/v/gen/auto_str_methods.v b/vlib/v/gen/auto_str_methods.v index 84eb356c7b..62aedb6a51 100644 --- a/vlib/v/gen/auto_str_methods.v +++ b/vlib/v/gen/auto_str_methods.v @@ -49,6 +49,7 @@ fn (mut g Gen) gen_str_for_type_with_styp(typ table.Type, styp string) string { table.Struct { g.gen_str_for_struct(it, styp, str_fn_name) } table.Map { g.gen_str_for_map(it, styp, str_fn_name) } table.MultiReturn { g.gen_str_for_multi_return(it, styp, str_fn_name) } + table.SumType {} else { verror("could not generate string method $str_fn_name for type \'$styp\'") } } } diff --git a/vlib/v/gen/x64/gen.v b/vlib/v/gen/x64/gen.v index 5301b2c179..215697a6c9 100644 --- a/vlib/v/gen/x64/gen.v +++ b/vlib/v/gen/x64/gen.v @@ -10,11 +10,13 @@ import v.errors import v.pref import term import strings +import v.table pub struct Gen { out_name string pref &pref.Preferences // Preferences shared from V struct mut: + table &table.Table buf []byte sect_header_name_pos int offset i64 @@ -78,8 +80,9 @@ enum Size { _64 } -pub fn gen(files []ast.File, out_name string, pref &pref.Preferences) { +pub fn gen(files []ast.File, table &table.Table, out_name string, pref &pref.Preferences) { mut g := Gen{ + table: table sect_header_name_pos: 0 out_name: out_name pref: pref @@ -725,11 +728,22 @@ fn (mut g Gen) assign_stmt(node ast.AssignStmt) { g.allocate_var(name, 4, 0) // `mov DWORD PTR [rbp-0x8],eax` offset := g.get_var_offset(name) - println('ASS $name offset=$offset.hex2()') + println('infix assignment $name offset=$offset.hex2()') g.mov_reg_to_rbp(offset, .eax) } + ast.StructInit { + sym := g.table.get_type_symbol(right.typ) + // println(sym) + // println(typeof(sym.info)) + info := sym.info as table.Struct + for field in info.fields { + field_name := name + '.' + field.name + println(field_name) + g.allocate_var(field_name, 4, 0) + } + } else { - g.error_with_pos('assign_stmt unhandled expr: ' + typeof(right), right.position()) + g.error_with_pos('x64 assign_stmt unhandled expr: ' + typeof(right), right.position()) } } // } diff --git a/vlib/v/parser/if.v b/vlib/v/parser/if_match.v similarity index 94% rename from vlib/v/parser/if.v rename to vlib/v/parser/if_match.v index 7613100a79..ea71b9550a 100644 --- a/vlib/v/parser/if.v +++ b/vlib/v/parser/if_match.v @@ -152,7 +152,9 @@ fn (mut p Parser) match_expr() ast.MatchExpr { p.next() var_name = p.check_name() } - p.check(.lcbr) + if p.tok.kind == .lcbr { + p.check(.lcbr) + } mut branches := []ast.MatchBranch{} for { branch_first_pos := p.tok.position() @@ -164,9 +166,9 @@ fn (mut p Parser) match_expr() ast.MatchExpr { if p.tok.kind == .key_else { is_else = true p.next() - } else if p.tok.kind == .name && !(p.tok.lit == 'C' && p.peek_tok.kind == .dot) && - (p.tok.lit in table.builtin_type_names || p.tok.lit[0].is_capital() || - (p.peek_tok.kind == .dot && p.peek_tok2.lit[0].is_capital())) { + } else if p.tok.kind == .name && !(p.tok.lit == 'C' && + p.peek_tok.kind == .dot) && (p.tok.lit in table.builtin_type_names || p.tok.lit[0].is_capital() || + (p.peek_tok.kind == .dot && p.peek_tok2.lit[0].is_capital())) { if var_name.len == 0 { match cond { ast.Ident { @@ -256,7 +258,7 @@ fn (mut p Parser) match_expr() ast.MatchExpr { post_comments: post_comments } p.close_scope() - if p.tok.kind == .rcbr { + if p.tok.kind == .rcbr || is_else { break } } @@ -266,7 +268,9 @@ fn (mut p Parser) match_expr() ast.MatchExpr { pos: match_first_pos.pos len: match_last_pos.pos - match_first_pos.pos + match_last_pos.len } - p.check(.rcbr) + if p.tok.kind == .rcbr { + p.check(.rcbr) + } // return ast.StructInit{} return ast.MatchExpr{ branches: branches diff --git a/vlib/v/tests/match_test.v b/vlib/v/tests/match_test.v index 79c548c98f..77967d996c 100644 --- a/vlib/v/tests/match_test.v +++ b/vlib/v/tests/match_test.v @@ -11,20 +11,19 @@ pub fn (c Color) str() string { fn test_match_integers() { mut a := 3 mut b := 0 - match a { - 2 { - println('two') - } - 3 { - println('three') - b = 3 - } - 4 { - println('four') - } - else { - println('???') - } + match a + 2 { + println('two') + } + 3 { + println('three') + b = 3 + } + 4 { + println('four') + } + else { + println('???') } assert b == 3 assert match 2 {