1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
|
use core::scalar
use core::functions
fn str_length(s: String) -> Scalar
fn str_slice(s: String, start: Scalar, end: Scalar) -> String
fn chr(n: Scalar) -> String
fn lowercase(s: String) -> String
fn uppercase(s: String) -> String
fn str_append(a: String, b: String) -> String = "{a}{b}"
fn str_contains(haystack: String, needle: String) -> Bool =
if str_length(haystack) == 0
then false
else if str_slice(haystack, 0, str_length(needle)) == needle
then true
else str_contains(str_slice(haystack, 1, str_length(haystack)), needle)
fn str_replace(s: String, pattern: String, replacement: String) -> String =
if pattern == ""
then s
else if str_contains(s, pattern)
then if str_slice(s, 0, str_length(pattern)) == pattern
then str_append(replacement, str_replace(str_slice(s, str_length(pattern), str_length(s)), pattern, replacement))
else str_append(str_slice(s, 0, 1), str_replace(str_slice(s, 1, str_length(s)), pattern, replacement))
else s
fn str_repeat(a: String, n: Scalar) -> String =
if n > 0
then str_append(a, str_repeat(a, n - 1))
else ""
fn _bin_digit(x: Scalar) -> String =
chr(48 + mod(x, 2))
fn _oct_digit(x: Scalar) -> String =
chr(48 + mod(x, 8))
fn _hex_digit(x: Scalar) -> String =
if mod(x, 16) < 10 then chr(48 + mod(x, 16)) else chr(97 + mod(x, 16) - 10)
fn _digit_in_base(x: Scalar, base: Scalar) -> String =
if base < 2 || base > 16
then "?" # TODO: better error handling once we can specify the return type of 'error(msg)' as '!' (see error.nbt).
else if mod(x, 16) < 10 then chr(48 + mod(x, 16)) else chr(97 + mod(x, 16) - 10)
fn _number_in_base(x: Scalar, b: Scalar) -> String =
if x < 0
then "-{_number_in_base(-x, b)}"
else if x < b
then _digit_in_base(x, b)
else str_append(_number_in_base(floor(x / b), b), _digit_in_base(mod(x, b), b))
fn bin(x: Scalar) -> String = if x < 0 then "-{bin(-x)}" else "0b{_number_in_base(x, 2)}"
fn oct(x: Scalar) -> String = if x < 0 then "-{oct(-x)}" else "0o{_number_in_base(x, 8)}"
fn dec(x: Scalar) -> String = _number_in_base(x, 10)
fn hex(x: Scalar) -> String = if x < 0 then "-{hex(-x)}" else "0x{_number_in_base(x, 16)}"
# TODO: once we have anonymous functions / closures, we can implement base in a way
# that it returns a partially-applied version of '_number_in_base'. This would allow
# arbitrary 'x -> base(b)' conversions.
fn _not_implemented(unused: Scalar) -> String = "<bases other than 2, 8, 10, and 16 are currently not implemented>"
fn base(b: Scalar) -> Fn[(Scalar) -> String] =
if b == 2
then bin
else if b == 8
then oct
else if b == 10
then dec
else if b == 16
then hex
else _not_implemented
|