File: strings.nbt

package info (click to toggle)
rust-numbat 1.11.0-6
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 996 kB
  • sloc: makefile: 2
file content (75 lines) | stat: -rw-r--r-- 2,785 bytes parent folder | download | duplicates (2)
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