stoi.ha (3136B)
1 // SPDX-License-Identifier: MPL-2.0 2 // (c) Hare authors <https://harelang.org> 3 4 use types; 5 6 // Converts a string to an i64. Returns [[invalid]] if the string is empty or 7 // contains invalid characters. Returns [[overflow]] if the number is too large 8 // to be represented by an i64. 9 export fn stoi64(s: str, base: base = base::DEC) (i64 | invalid | overflow) = { 10 let (sign, u) = parseint(s, base)?; 11 // Two's complement: I64_MIN = -I64_MAX - 1 12 let max = if (sign) types::I64_MAX: u64 + 1 else types::I64_MAX: u64; 13 if (u > max) { 14 return overflow; 15 }; 16 return u: i64 * (if (sign) -1 else 1); 17 }; 18 19 fn stoiminmax( 20 s: str, 21 base: base, 22 min: i64, 23 max: i64, 24 ) (i64 | invalid | overflow) = { 25 const n = stoi64(s, base)?; 26 if (n < min || n > max) { 27 return overflow; 28 }; 29 return n; 30 }; 31 32 // Converts a string to an i32. Returns [[invalid]] if the string is empty or 33 // contains invalid characters. Returns [[overflow]] if the number is too large 34 // to be represented by an i32. 35 export fn stoi32(s: str, base: base = base::DEC) (i32 | invalid | overflow) = 36 stoiminmax(s, base, types::I32_MIN, types::I32_MAX)?: i32; 37 38 // Converts a string to an i16. Returns [[invalid]] if the string is empty or 39 // contains invalid characters. Returns [[overflow]] if the number is too large 40 // to be represented by an i16. 41 export fn stoi16(s: str, base: base = base::DEC) (i16 | invalid | overflow) = 42 stoiminmax(s, base, types::I16_MIN, types::I16_MAX)?: i16; 43 44 // Converts a string to an i8. Returns [[invalid]] if the string is empty or 45 // contains invalid characters. Returns [[overflow]] if the number is too large 46 // to be represented by an i8. 47 export fn stoi8(s: str, base: base = base::DEC) (i8 | invalid | overflow) = 48 stoiminmax(s, base, types::I8_MIN, types::I8_MAX)?: i8; 49 50 // Converts a string to an int. Returns [[invalid]] if the string is empty or 51 // contains invalid characters. Returns [[overflow]] if the number is too large 52 // to be represented by an int. 53 export fn stoi(s: str, base: base = base::DEC) (int | invalid | overflow) = 54 stoiminmax(s, base, types::INT_MIN, types::INT_MAX)?: int; 55 56 @test fn stoi() void = { 57 assert(stoi64("") as invalid == 0); 58 assert(stoi64("abc") as invalid == 0); 59 assert(stoi64("1a") as invalid == 1); 60 assert(stoi64("+") as invalid == 1); 61 assert(stoi64("-+") as invalid == 1); 62 assert(stoi64("-z") as invalid == 1); 63 64 assert(stoi64("9223372036854775808") is overflow); 65 assert(stoi64("-9223372036854775809") is overflow); 66 67 assert(stoi64("0") as i64 == 0); 68 assert(stoi64("1") as i64 == 1); 69 assert(stoi64("+1") as i64 == 1); 70 assert(stoi64("-1") as i64 == -1); 71 assert(stoi64("9223372036854775807") as i64 == types::I64_MAX); 72 assert(stoi64("-9223372036854775808") as i64 == types::I64_MIN); 73 74 assert(stoi32("2147483648") is overflow); 75 assert(stoi32("-2147483649") is overflow); 76 77 assert(stoi32("2147483647") as i32 == 2147483647); 78 assert(stoi32("-2147483648") as i32 == -2147483648); 79 }; 80 81 @test fn stoi_bases() void = { 82 assert(stoi64("-7f", 16) as i64 == -0x7f); 83 assert(stoi64("7F", 16) as i64 == 0x7f); 84 assert(stoi64("37", 8) as i64 == 0o37); 85 assert(stoi64("-110101", 2) as i64 == -0b110101); 86 };