hare

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

stoi.ha (3149B)


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