Rope data structure implementation in Hare.

feat(rope): Added initial rope implementation.

Added initial rope implementation and index functionality.

+107
+107
src/main.ha
··· 1 1 use fmt; 2 + use strconv; 3 + use strings; 4 + 5 + type indexerror = !void; 6 + 7 + type RefString = struct { 8 + data: str, 9 + ref_count: size 10 + }; 11 + 12 + type Leaf = struct { 13 + string: str, 14 + length: size 15 + }; 16 + 17 + // weight = length(left) + all_of(length(left.right)) 18 + type Node = struct { 19 + left: nullable *(Leaf | Node), 20 + right: nullable *(Leaf | Node), 21 + length: size, 22 + }; 23 + 24 + type Rope = Node; 25 + 26 + fn s1(data: str) (Leaf | Node) = { 27 + return Leaf { 28 + string = data, 29 + length = len(data) 30 + }; 31 + }; 32 + 33 + fn n1(n: Node) (Leaf | Node) = { 34 + return n; 35 + }; 36 + 37 + fn r1(n: Node) Rope = { 38 + return n; 39 + }; 40 + 41 + fn combined_length(leaf: nullable* Node) size = { 42 + return match (leaf) { 43 + case null => yield 0: size; 44 + case let good: *Node => yield good.length + 45 + match (good.right) { 46 + case null => yield 0: size; 47 + case let good_right: *(Leaf | Node) => yield 48 + match (*good_right) { 49 + case let leaf: Leaf => yield leaf.length; 50 + case let node: Node => yield combined_length(&node); 51 + }; 52 + }; 53 + }; 54 + }; 55 + 56 + fn create_node(l: nullable* (Leaf | Node), r: nullable* (Leaf | Node)) Node = { 57 + return Node { 58 + left = l, 59 + right = r, 60 + length = match (l) { 61 + case null => yield 0; 62 + case let good: *(Leaf | Node) => yield 63 + match (*good) { 64 + case let leaf: Leaf => yield leaf.length; 65 + case let node: Node => yield combined_length(&node); 66 + }; 67 + } 68 + }; 69 + }; 70 + 71 + fn create_rope(n: Node) Rope = { 72 + return n; 73 + }; 74 + 75 + //----- Operations -----// 76 + fn index(rope: Rope, idx: size) (rune | indexerror) = { 77 + return if (idx >= rope.length) { 78 + yield match (rope.right) { 79 + case null => return indexerror; 80 + case let good: *(Leaf | Node) => yield match (*good) { 81 + case let leaf: Leaf => yield strings::torunes(leaf.string)[idx - rope.length]; 82 + case let node: Node => yield index(r1(node), idx - rope.length); 83 + }; 84 + }; 85 + } else { 86 + yield match (rope.left) { 87 + case null => return indexerror; 88 + case let good: *(Leaf | Node) => yield match (*good) { 89 + case let leaf: Leaf => yield strings::torunes(leaf.string)[idx]; 90 + case let node: Node => yield index(r1(node), idx); 91 + }; 92 + }; 93 + }; 2 94 3 95 export fn main() void = { 96 + let test = ["Hello ", "my ", "na", "me i", "s", " Simon"]; 97 + let e = s1(test[0]); 98 + let f = s1(test[1]); 99 + let j = s1(test[2]); 100 + let k = s1(test[3]); 101 + let m = s1(test[4]); 102 + let n = s1(test[5]); 103 + let c = create_node(&e, &f); 104 + let g = create_node(&j, &k); 105 + let h = create_node(&m, &n); 106 + let d = create_node(&n1(g), &n1(h)); 107 + let b = create_node(&n1(c), &n1(d)); 108 + let a = create_node(&n1(b), null); 109 + let my_rope = create_rope(a); 4 110 fmt::println("Hello world!")!; 111 + fmt::println(index(a, 21)!)!; 5 112 };