From abff7b458fb4206381489e3344bdb5b4cfc22886 Mon Sep 17 00:00:00 2001 From: yuyi Date: Tue, 18 Jun 2024 23:02:45 +0800 Subject: [PATCH] checker: fix match expr with auto promote number --- vlib/v/checker/match.v | 3 + ...match_expr_with_auto_promote_number_test.v | 102 ++++++++++++++++++ 2 files changed, 105 insertions(+) create mode 100644 vlib/v/tests/match_expr_with_auto_promote_number_test.v diff --git a/vlib/v/checker/match.v b/vlib/v/checker/match.v index be1a5921d4fbfc..9e33f7e95eb310 100644 --- a/vlib/v/checker/match.v +++ b/vlib/v/checker/match.v @@ -114,6 +114,9 @@ fn (mut c Checker) match_expr(mut node ast.MatchExpr) ast.Type { stmt.typ = ast.error_type } else { c.check_match_branch_last_stmt(stmt, ret_type, expr_type) + if ret_type.is_number() && expr_type.is_number() && !c.inside_return { + ret_type = c.promote_num(ret_type, expr_type) + } } } if stmt.typ != ast.error_type { diff --git a/vlib/v/tests/match_expr_with_auto_promote_number_test.v b/vlib/v/tests/match_expr_with_auto_promote_number_test.v new file mode 100644 index 00000000000000..8f08045346c8ea --- /dev/null +++ b/vlib/v/tests/match_expr_with_auto_promote_number_test.v @@ -0,0 +1,102 @@ +// convert strings like 10K to i164 +const block = 512 +// const block = i64(512) + +// **1 +const kilo = i64(1024) +const kilobyte = i64(1000) + +// **2 +const mega = kilo * kilo +const megabyte = kilobyte * kilobyte + +// **3 +const giga = mega * kilo +const gigabyte = megabyte * kilobyte + +// **4 +const terra = giga * kilo +const terrabyte = gigabyte * kilobyte + +// **5 +const peta = mega * kilo +const petabyte = megabyte * kilobyte + +// **6 +const exa = peta * kilo +const exabyte = peta * kilo + +// **7 +const zetta = exa * kilo +const zettabyte = exabyte * kilobyte + +// **8 +const yotta = zetta * kilo +const yottabyte = zettabyte * kilobyte + +// **9 +const ronna = yotta * kilo +const ronnabyte = yottabyte * kilobyte + +// **10 +const quetta = ronna * kilo +const quettabyte = ronnabyte * kilobyte + +fn string_to_i64(s string) ?i64 { + if s.len == 0 { + return none + } + + mut index := 0 + for index < s.len { + match true { + s[index].is_digit() {} + s[index] == `+` && index == 0 {} + s[index] == `-` && index == 0 {} + else { break } + } + index += 1 + } + + number := s[0..index].i64() + suffix := if index < s.len { s[index..] } else { 'c' } + + multiplier := match suffix.to_lower() { + 'b' { block } + 'k' { kilo } + 'kb', 'kib' { kilobyte } + 'm' { mega } + 'mb', 'mib' { megabyte } + 'g' { giga } + 'gb', 'gib' { gigabyte } + 't' { terra } + 'tb', 'tib' { terrabyte } + 'p' { peta } + 'pb', 'pib' { petabyte } + 'e' { exa } + 'eb', 'eib' { exabyte } + 'z' { zetta } + 'zb', 'zib' { zettabyte } + 'y' { yotta } + 'yb', 'yib' { yottabyte } + 'r' { ronna } + 'rb', 'rib' { ronnabyte } + 'q' { quetta } + 'qb', 'qib' { quettabyte } + // oddball formats found in __xstrtol source + 'c' { 1 } + 'w' { 2 } + else { return none } + } + + result := number * multiplier + if result == 0 && number != 0 { + return none + } + return result +} + +fn test_match_expr_with_auto_promote_number() { + assert string_to_i64('19P')! == 19 * peta + assert string_to_i64('18T')! == 18 * terra +}