hare

[hare] The Hare programming language
git clone https://git.torresjrjr.com/hare.git
Log | Files | Refs | README | LICENSE

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 };