···11-export type Node = (str | Rope);
11+use fmt;
22+use strings;
33+44+// TODO: docs
55+export type Node = struct {
66+ left: nullable *Node,
77+ right: nullable *Node,
88+ data: Leaf,
99+ length: size,
1010+};
1111+1212+// TODO: docs
1313+fn node_new() Node = Node {
1414+ left = null,
1515+ right = null,
1616+ data = leaf_new(),
1717+ length = 0: size,
1818+};
1919+2020+// TODO: docs
2121+fn node_close(node: *Node) void = leaf_close(&node.data);
22233-fn strtonode(data: str) Node = {
44- return data;
2323+// Caller must free return value. Do not free the passed string or else the
2424+// internal buffer will become invalid.
2525+fn node_fromstr(string: str) Node = Node {
2626+ left = null,
2727+ right = null,
2828+ data = leaf_fromstr(string),
2929+ length = 0: size,
530};
63177-fn nodetorope(node: *Node) Rope = {
88- return Rope {
99- left = node,
1010- right = null,
1111- length = node_length(node)
1212- };
3232+//fn strtonode(data: str) Node = {
3333+// return data;
3434+//};
3535+//
3636+//fn nodetorope(node: *Node) Rope = {
3737+// return Rope {
3838+// left = node,
3939+// right = null,
4040+// length = node_length(node)
4141+// };
4242+//};
4343+//
4444+//fn node_length(node: *Node) size = {
4545+// return match (*node) {
4646+// case let leaf: str => yield len(leaf);
4747+// case let rope: Rope => yield rope_length(&rope);
4848+// };
4949+//};
5050+5151+// TODO: docs
5252+fn print_node(node: *const Node) void = {
5353+ fmt::print(strings::fromrunes(node.data.buf))!;
1354};
14551515-fn node_length(node: *Node) size = {
1616- return match (*node) {
1717- case let leaf: str => yield len(leaf);
1818- case let rope: Rope => yield rope_length(&rope);
5656+// TODO: docs
5757+fn print_tree(node: nullable *const Node) void = {
5858+ match (node) {
5959+ case null => void;
6060+ case let good: *const Node => {
6161+ print_tree(good.left);
6262+ fmt::print(strings::fromrunes(good.data.buf))!;
6363+ print_tree(good.right);
6464+ };
1965 };
2066};
6767+6868+//fn node_length(node: nullable *const Node) size = {
6969+// //fmt::println(node)!;
7070+// return match (node) {
7171+// case null => yield 0: size;
7272+// case let good: *const Node =>
7373+// yield if (len(good.data) == 0) {
7474+// yield node_length(good.left) + node_length(good.right);
7575+// } else {
7676+// yield len(good.data);
7777+// };
7878+// };
7979+//};
+41-53
rope/rope.ha
···11use fmt;
2233-export type indexerror = !void;
44-33+// TODO: docs
54export type Rope = struct {
66- left: nullable *Node,
77- right: nullable *Node,
88- length: size,
55+ root: nullable *Node,
96};
1071111-fn ropetonode(n: *Rope) *Node = {
1212- return n: *Node;
88+// TODO: docs
99+export fn new() Rope = Rope {
1010+ root = null,
1311};
14121313+// TODO: docs
1414+export fn close(rope: *Rope) void = match (rope.root) {
1515+ case null => void;
1616+ case let root: *Node => node_close(root);
1717+};
1818+1919+//fn rope_length(rope: *Rope) size = {
2020+// return match (rope.root) {
2121+// case null => yield 0: size;
2222+// case let root: *Node => yield node_length(root);
2323+// };
2424+//};
15251616-fn rope_length(rope: *Rope) size = {
1717- return rope.length + match (rope.right) {
1818- case null => yield 0: size;
1919- case let good: *Node => yield match (*good) {
2020- case let leaf: str => yield len(leaf);
2121- case let rop: Rope => yield rope_length(&rop);
2222- };
2323- };
2626+// TODO: docs
2727+export fn fromstr(string: str) Rope = Rope {
2828+ root = alloc(node_fromstr(string)),
2429};
25302626-export fn new(string: str) Rope = {
2727- let node = strtonode(string);
2828- return nodetorope(&node);
2929-};
30313131-//fn create_node(l: nullable* Node, r: nullable* Node) Rope = {
3232+//export fn new() Rope = {
3233// return Rope {
3333-// left = l,
3434-// right = r,
3535-// length = match (l) {
3636-// case null => yield 0;
3737-// case let good: *Node => yield match (*good) {
3838-// case let leaf: Leaf => yield leaf.length;
3939-// case let node: Rope => yield rope_length(node);
4040-// };
4141-// }
3434+// root = null,
4235// };
4336//};
44374545-export fn print(rope: *Rope) void = {
4646- match (rope.left) {
4747- case null => fmt::print("")!;
4848- case let good: *Node => match (*good) {
4949- case let leaf: str => fmt::print(leaf)!;
5050- case let rope: Rope => print(&rope);
5151- };
5252- };
5353-5454- match (rope.right) {
5555- case null => fmt::print("")!;
5656- case let good: *Node => match (*good) {
5757- case let leaf: str => fmt::print(leaf)!;
5858- case let rope: Rope => print(&rope);
5959- };
3838+// TODO: docs
3939+export fn print(rope: *const Rope) void = {
4040+ match (rope.root) {
4141+ case null => void;
4242+ case let root: *Node => print_tree(root);
6043 };
6144};
62456363-export fn println(rope: *Rope) void = {
4646+export fn println(rope: *const Rope) void = {
6447 print(rope);
6548 fmt::println("")!;
6649};
67505151+// TODO: docs
5252+//export type indexerror = !void;
5353+6854//export fn index(rope: Rope, idx: size) (rune | indexerror) = {
6955// return if (idx >= rope.length) {
7056// yield match (rope.right) {
7157// case null => return indexerror;
7258// case let good: *Node => yield match (*good) {
7373-// case let leaf: Leaf => yield strings::torunes(leaf.string)[idx - rope.length];
5959+// case let leaf: str => yield strings::torunes(leaf.string)[idx - rope.length];
7460// case let rop: Rope => yield index(rop, idx - rope.length);
7561// };
7662// };
···7864// yield match (rope.left) {
7965// case null => return indexerror;
8066// case let good: *Node => yield match (*good) {
8181-// case let leaf: Leaf => yield strings::torunes(leaf.string)[idx];
6767+// case let leaf: str => yield strings::torunes(leaf.string)[idx];
8268// case let rop: Rope => yield index(rop, idx);
8369// };
8470// };
8571// };
8672//};
87738888-export fn concat(l: *Rope, r: *Rope) Rope = {
8989- return Rope {
9090- left = &(*l: Node),
9191- right = &(*r: Node),
9292- length = rope_length(l),
9393- };
7474+// TODO: docs
7575+export fn join(l: *Rope, r: *Rope) Rope = Rope {
7676+ root = alloc(Node {
7777+ left = l.root,
7878+ right = r.root,
7979+ length = 0: size,
8080+ data = leaf_new(),
8181+ }),
9482};
+11-5
src/main.ha
···11-use rope::*;
11+use fmt;
22+use rope;
2334export fn main() void = {
44- let hello = new("hello ");
55- let world = new("world!");
66- let hello_world = concat(&hello, &world);
77- println(&hello_world);
55+ let hello = rope::fromstr("hello ");
66+ defer rope::close(&hello);
77+ let world = rope::fromstr("world!");
88+ defer rope::close(&world);
99+1010+ let hello_world = rope::join(&hello, &world);
1111+ defer rope::close(&hello_world);
1212+1313+ rope::println(&hello_world);
814};
+27
text/impl.ha
···11+use strings;
22+33+// A Text object.
44+export type Text = struct {
55+ buf: [] const rune,
66+ length: size,
77+};
88+99+// Returns an empty piece of `text`.
1010+export fn new() Text = Text {
1111+ buf = strings::torunes(""),
1212+ length = 0: size,
1313+};
1414+1515+// Returns a piece of `text` in O(n). The caller must free the return value.
1616+// `free`'ing the string passed into this function will cause the `Text`
1717+// object's internal buffer to be in an unspecified state.
1818+export fn fromstr(string: str) Text = Text {
1919+ buf = strings::torunes(string),
2020+ length = len(string),
2121+};
2222+2323+// Returns a `str` object. The caller cannot free this `str` object.
2424+export fn tostr(text: Text) const str = strings::fromrunes(text.buf);
2525+2626+// Deallocates the buffer associated with a `Text` object.
2727+export fn close(text: *Text) void = free(text.buf);