commit 08909ddf1f3227d36c9e1a628dfccf6060872a4d
parent 47c37a24c3250598b8eb14fd586cd2cbd1c59a3f
Author: Byron Torres <b@torresjrjr.com>
Date: Fri, 10 Sep 2021 23:46:57 +0100
Add command line repl loop, adjust types
Diffstat:
D | Makefile | | | 17 | ----------------- |
M | ed.ha | | | 148 | ++++++++++++++++++++++++++++++++++++++++++++++++------------------------------- |
2 files changed, 90 insertions(+), 75 deletions(-)
diff --git a/Makefile b/Makefile
@@ -1,17 +0,0 @@
-.POSIX:
-.SUFFIXES:
-HARE=hare
-HAREFLAGS=
-
-all: ed
-
-clean:
- rm -f ed
-
-.PHONY: all clean
-
-.SUFFIXES: .ha
-.ha:
- $(HARE) build $(HAREFLAGS) -o $@ $<
-
-ed: ed.ha
diff --git a/ed.ha b/ed.ha
@@ -5,26 +5,28 @@ use getopt;
use io;
use os;
-type filename = (str | void);
+let prompt: str = "";
+
+let surpress: bool = false;
-type file = (io::file | void);
+type filename = (str | void);
type buffer = struct {
- head: *line,
- tail: *line,
+ head: *linenode,
+ tail: *linenode,
};
-type line = struct {
+type linenode = struct {
value: value,
- prev: *line,
- next: *line,
+ prev: *linenode,
+ next: *linenode,
};
-type value = (headtype | str | tailtype);
+type value = (headnode | str | tailnode);
-type headtype = void;
+type headnode = void;
-type tailtype = void;
+type tailnode = void;
export fn main() void = {
const help: [_]getopt::help = [
@@ -36,14 +38,11 @@ export fn main() void = {
const cmd = getopt::parse(os::args, help...);
defer getopt::finish(&cmd);
- let prompt = "";
- let verbose = true;
-
for (let i = 0z; i < len(cmd.opts); i += 1) {
const opt = cmd.opts[i];
switch (opt.0) {
'p' => prompt = opt.1,
- 's' => verbose = false,
+ 's' => surpress = true,
};
};
@@ -51,38 +50,56 @@ export fn main() void = {
exit_usage(help);
};
- let filename: filename = switch (len(cmd.args) == 1) {
- false => void,
- true => switch (cmd.args[0]) {
+ let fname: filename = if (len(cmd.args) == 1) {
+ yield void;
+ } else {
+ yield switch (cmd.args[0]) {
"-" => fmt::fatal("Invalid filename '-'"),
"" => fmt::fatal("Invalid filename ''"),
- * => cmd.args[0],
- },
- };
-
- let file: file = match (filename) {
- void => void,
- filename: str => match (os::open(filename)) {
- err: fs::error => fmt::fatal("Error {}", fs::strerror(err)),
- file: io::file => file,
- },
+ * => yield cmd.args[0],
+ };
};
const buf = new_buffer();
- if (file is io::file) {
- cmd_edit(file: io::file);
+ if (fname is str) {
+ cmd_edit(buf, fname);
+ };
+
+ for (true) {
+ const rawline = match (bufio::scanline(os::stdin)) {
+ err: io::error => abort("io::error"),
+ io::EOF => break,
+ rawline: []u8 => rawline,
+ };
+ defer free(rawline);
+ const command = fmt::bsprint(rawline);
+ parse_cmd(command);
+ break;
};
};
-fn cmd_edit(file: io::file) void = {
- print_buffer(read(&file));
+// "3,7,/a/,+3m4"
+// str -> struct {
+// prefix_ranges: []addr, // "2" "+2" "-1"
+// primary_command: command, // e E f q Q r w !
+// secondary_command: command, // l n p
+// suffix_ranges: []addr,
+// tertiary_commands: []command, // g G v V
+// } ->
+fn parse_cmd(command: str) void = {
+ return;
+};
+
+@noreturn fn exit_usage(help: []getopt::help) void = {
+ getopt::printusage(os::stderr, os::args[0], help);
+ os::exit(1);
};
// Initialises a new buffer.
fn new_buffer() *buffer = {
- const head = alloc(line { value = headtype, ... });
- const tail = alloc(line { value = tailtype, prev = head });
+ const head = alloc(linenode { value = headnode, ... });
+ const tail = alloc(linenode { value = tailnode, prev = head });
head.next = tail;
return alloc(buffer {
head = head,
@@ -90,12 +107,13 @@ fn new_buffer() *buffer = {
});
};
-// Reads text from source into a new buffer.
-fn read(source: *io::stream) *buffer = {
- const buf = new_buffer();
+// Reads text from source, writes to a buffer.
+fn read(source: *io::stream, buf: *buffer) size = {
let localhead = buf.head;
const localtail = buf.tail;
+ let total = 0z;
+
for (true) {
const rawline = match (bufio::scanline(source)) {
err: io::error => abort("io::error"),
@@ -103,41 +121,55 @@ fn read(source: *io::stream) *buffer = {
rawline: []u8 => rawline,
};
//defer free(rawline);
+ total += len(rawline);
+
const value = fmt::bsprint(rawline);
- const line = alloc(line {
+ const ln = alloc(linenode {
value = value,
prev = localhead,
next = localtail,
});
- localhead.next = line;
- localtail.prev = line;
+ localhead.next = ln;
+ localtail.prev = ln;
- localhead = line;
+ localhead = ln;
};
- return buf;
+ return total;
};
-// 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;
+// // Sequencially prints lines of a buffer.
+// fn print_buffer(buf: *buffer) void = {
+// let linenode = buf.head;
+// for (true) {
+// match (linenode.value) {
+// headnode => {
+// linenode = linenode.next;
+// },
+// s: str => {
+// fmt::println(s)?;
+// linenode = linenode.next;
+// },
+// tailnode => break
+// };
+// };
+// };
+
+// 'e' command
+fn cmd_edit(buf: *buffer, fname: filename) void = {
+ match (fname) {
+ void => void,
+ fname: str => match (os::open(fname)) {
+ err: fs::error => fmt::fatal("Error {}", fs::strerror(err)),
+ f: io::file => {
+ const n = read(&f, buf);
+ if (!surpress) {
+ fmt::println(n)?;
+ };
},
- tailtype => break
- };
+ },
};
};
-@noreturn fn exit_usage(help: []getopt::help) void = {
- getopt::printusage(os::stderr, os::args[0], help);
- os::exit(1);
-};