Skip to content

Commit 0498ed1

Browse files
authored
checker: fix match expr with auto promote number (#21696)
1 parent 5ebe7d1 commit 0498ed1

File tree

2 files changed

+105
-0
lines changed

2 files changed

+105
-0
lines changed

vlib/v/checker/match.v

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,9 @@ fn (mut c Checker) match_expr(mut node ast.MatchExpr) ast.Type {
114114
stmt.typ = ast.error_type
115115
} else {
116116
c.check_match_branch_last_stmt(stmt, ret_type, expr_type)
117+
if ret_type.is_number() && expr_type.is_number() && !c.inside_return {
118+
ret_type = c.promote_num(ret_type, expr_type)
119+
}
117120
}
118121
}
119122
if stmt.typ != ast.error_type {
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
// convert strings like 10K to i164
2+
const block = 512
3+
// const block = i64(512)
4+
5+
// **1
6+
const kilo = i64(1024)
7+
const kilobyte = i64(1000)
8+
9+
// **2
10+
const mega = kilo * kilo
11+
const megabyte = kilobyte * kilobyte
12+
13+
// **3
14+
const giga = mega * kilo
15+
const gigabyte = megabyte * kilobyte
16+
17+
// **4
18+
const terra = giga * kilo
19+
const terrabyte = gigabyte * kilobyte
20+
21+
// **5
22+
const peta = mega * kilo
23+
const petabyte = megabyte * kilobyte
24+
25+
// **6
26+
const exa = peta * kilo
27+
const exabyte = peta * kilo
28+
29+
// **7
30+
const zetta = exa * kilo
31+
const zettabyte = exabyte * kilobyte
32+
33+
// **8
34+
const yotta = zetta * kilo
35+
const yottabyte = zettabyte * kilobyte
36+
37+
// **9
38+
const ronna = yotta * kilo
39+
const ronnabyte = yottabyte * kilobyte
40+
41+
// **10
42+
const quetta = ronna * kilo
43+
const quettabyte = ronnabyte * kilobyte
44+
45+
fn string_to_i64(s string) ?i64 {
46+
if s.len == 0 {
47+
return none
48+
}
49+
50+
mut index := 0
51+
for index < s.len {
52+
match true {
53+
s[index].is_digit() {}
54+
s[index] == `+` && index == 0 {}
55+
s[index] == `-` && index == 0 {}
56+
else { break }
57+
}
58+
index += 1
59+
}
60+
61+
number := s[0..index].i64()
62+
suffix := if index < s.len { s[index..] } else { 'c' }
63+
64+
multiplier := match suffix.to_lower() {
65+
'b' { block }
66+
'k' { kilo }
67+
'kb', 'kib' { kilobyte }
68+
'm' { mega }
69+
'mb', 'mib' { megabyte }
70+
'g' { giga }
71+
'gb', 'gib' { gigabyte }
72+
't' { terra }
73+
'tb', 'tib' { terrabyte }
74+
'p' { peta }
75+
'pb', 'pib' { petabyte }
76+
'e' { exa }
77+
'eb', 'eib' { exabyte }
78+
'z' { zetta }
79+
'zb', 'zib' { zettabyte }
80+
'y' { yotta }
81+
'yb', 'yib' { yottabyte }
82+
'r' { ronna }
83+
'rb', 'rib' { ronnabyte }
84+
'q' { quetta }
85+
'qb', 'qib' { quettabyte }
86+
// oddball formats found in __xstrtol source
87+
'c' { 1 }
88+
'w' { 2 }
89+
else { return none }
90+
}
91+
92+
result := number * multiplier
93+
if result == 0 && number != 0 {
94+
return none
95+
}
96+
return result
97+
}
98+
99+
fn test_match_expr_with_auto_promote_number() {
100+
assert string_to_i64('19P')! == 19 * peta
101+
assert string_to_i64('18T')! == 18 * terra
102+
}

0 commit comments

Comments
 (0)