commit 47c37a24c3250598b8eb14fd586cd2cbd1c59a3f
parent b459d51057d6791a1cac2eaca0f471dc4b9e3ef1
Author: Byron Torres <b@torresjrjr.com>
Date: Thu, 9 Sep 2021 08:33:52 +0100
Create data structures and example code
Diffstat:
M | ed.ha | | | 87 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
1 file changed, 87 insertions(+), 0 deletions(-)
diff --git a/ed.ha b/ed.ha
@@ -1,3 +1,4 @@
+use bufio;
use fmt;
use fs;
use getopt;
@@ -5,8 +6,26 @@ use io;
use os;
type filename = (str | void);
+
type file = (io::file | void);
+type buffer = struct {
+ head: *line,
+ tail: *line,
+};
+
+type line = struct {
+ value: value,
+ prev: *line,
+ next: *line,
+};
+
+type value = (headtype | str | tailtype);
+
+type headtype = void;
+
+type tailtype = void;
+
export fn main() void = {
const help: [_]getopt::help = [
"standard line editor",
@@ -48,6 +67,74 @@ export fn main() void = {
file: io::file => file,
},
};
+
+ const buf = new_buffer();
+
+ if (file is io::file) {
+ cmd_edit(file: io::file);
+ };
+};
+
+fn cmd_edit(file: io::file) void = {
+ print_buffer(read(&file));
+};
+
+// Initialises a new buffer.
+fn new_buffer() *buffer = {
+ const head = alloc(line { value = headtype, ... });
+ const tail = alloc(line { value = tailtype, prev = head });
+ head.next = tail;
+ return alloc(buffer {
+ head = head,
+ tail = tail,
+ });
+};
+
+// Reads text from source into a new buffer.
+fn read(source: *io::stream) *buffer = {
+ const buf = new_buffer();
+ let localhead = buf.head;
+ const localtail = buf.tail;
+
+ for (true) {
+ const rawline = match (bufio::scanline(source)) {
+ err: io::error => abort("io::error"),
+ io::EOF => break,
+ rawline: []u8 => rawline,
+ };
+ //defer free(rawline);
+ const value = fmt::bsprint(rawline);
+
+ const line = alloc(line {
+ value = value,
+ prev = localhead,
+ next = localtail,
+ });
+
+ localhead.next = line;
+ localtail.prev = line;
+
+ localhead = line;
+ };
+
+ return buf;
+};
+
+// Sequencially prints lines of a buffer.
+fn print_buffer(buf: *buffer) void = {
+ let line = buf.head;
+ for (true) {
+ match (line.value) {
+ headtype => {
+ line = line.next;
+ },
+ s: str => {
+ fmt::println(s)?;
+ line = line.next;
+ },
+ tailtype => break
+ };
+ };
};
@noreturn fn exit_usage(help: []getopt::help) void = {