Rope data structure implementation in Hare.
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

feat(modules): Moved implementation to `rope/`.

Moved the `rope` implementation to the `rope/` module.

+123 -109
+4
rope/leaf.ha
··· 1 + type Leaf = struct { 2 + string: str, 3 + length: size 4 + };
+20
rope/node.ha
··· 1 + export type Node = (str | Rope); 2 + 3 + fn strtonode(data: str) Node = { 4 + return data; 5 + }; 6 + 7 + fn nodetorope(node: *Node) Rope = { 8 + return Rope { 9 + left = node, 10 + right = null, 11 + length = node_length(node) 12 + }; 13 + }; 14 + 15 + fn node_length(node: *Node) size = { 16 + return match (*node) { 17 + case let leaf: str => yield len(leaf); 18 + case let rope: Rope => yield rope_length(&rope); 19 + }; 20 + };
+94
rope/rope.ha
··· 1 + use fmt; 2 + 3 + export type indexerror = !void; 4 + 5 + export type Rope = struct { 6 + left: nullable *Node, 7 + right: nullable *Node, 8 + length: size, 9 + }; 10 + 11 + fn ropetonode(n: *Rope) *Node = { 12 + return n: *Node; 13 + }; 14 + 15 + 16 + fn rope_length(rope: *Rope) size = { 17 + return rope.length + match (rope.right) { 18 + case null => yield 0: size; 19 + case let good: *Node => yield match (*good) { 20 + case let leaf: str => yield len(leaf); 21 + case let rop: Rope => yield rope_length(&rop); 22 + }; 23 + }; 24 + }; 25 + 26 + export fn new(string: str) Rope = { 27 + let node = strtonode(string); 28 + return nodetorope(&node); 29 + }; 30 + 31 + //fn create_node(l: nullable* Node, r: nullable* Node) Rope = { 32 + // return Rope { 33 + // left = l, 34 + // right = r, 35 + // length = match (l) { 36 + // case null => yield 0; 37 + // case let good: *Node => yield match (*good) { 38 + // case let leaf: Leaf => yield leaf.length; 39 + // case let node: Rope => yield rope_length(node); 40 + // }; 41 + // } 42 + // }; 43 + //}; 44 + 45 + export fn print(rope: *Rope) void = { 46 + match (rope.left) { 47 + case null => fmt::print("")!; 48 + case let good: *Node => match (*good) { 49 + case let leaf: str => fmt::print(leaf)!; 50 + case let rope: Rope => print(&rope); 51 + }; 52 + }; 53 + 54 + match (rope.right) { 55 + case null => fmt::print("")!; 56 + case let good: *Node => match (*good) { 57 + case let leaf: str => fmt::print(leaf)!; 58 + case let rope: Rope => print(&rope); 59 + }; 60 + }; 61 + }; 62 + 63 + export fn println(rope: *Rope) void = { 64 + print(rope); 65 + fmt::println("")!; 66 + }; 67 + 68 + //export fn index(rope: Rope, idx: size) (rune | indexerror) = { 69 + // return if (idx >= rope.length) { 70 + // yield match (rope.right) { 71 + // case null => return indexerror; 72 + // case let good: *Node => yield match (*good) { 73 + // case let leaf: Leaf => yield strings::torunes(leaf.string)[idx - rope.length]; 74 + // case let rop: Rope => yield index(rop, idx - rope.length); 75 + // }; 76 + // }; 77 + // } else { 78 + // yield match (rope.left) { 79 + // case null => return indexerror; 80 + // case let good: *Node => yield match (*good) { 81 + // case let leaf: Leaf => yield strings::torunes(leaf.string)[idx]; 82 + // case let rop: Rope => yield index(rop, idx); 83 + // }; 84 + // }; 85 + // }; 86 + //}; 87 + 88 + export fn concat(l: *Rope, r: *Rope) Rope = { 89 + return Rope { 90 + left = &(*l: Node), 91 + right = &(*r: Node), 92 + length = rope_length(l), 93 + }; 94 + };
+5 -109
src/main.ha
··· 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 - }; 1 + use rope::*; 94 2 95 3 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); 110 - fmt::println("Hello world!")!; 111 - fmt::println(index(a, 21)!)!; 4 + let hello = new("hello "); 5 + let world = new("world!"); 6 + let hello_world = concat(&hello, &world); 7 + println(&hello_world); 112 8 };