commit d5902aae514af4fa2197f0908888e8e4eb3e93cc
parent 4f459aee76753804e7a0c814f42ddc2485de6766
Author: Byron Torres <b@torresjrjr.com>
Date: Sun, 12 Sep 2021 17:07:57 +0100
Add parse.ha, primitive repl
Diffstat:
M | Makefile | | | 3 | ++- |
M | buffer.ha | | | 7 | ++++++- |
M | ed.ha | | | 44 | ++++++++++++++++---------------------------- |
A | parse.ha | | | 64 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
4 files changed, 88 insertions(+), 30 deletions(-)
diff --git a/Makefile b/Makefile
@@ -1,10 +1,11 @@
HARE=hare
HAREFLAGS=
-source= \
+source=\
ed.ha \
buffer.ha \
command.ha \
+ parse.ha \
util.ha
all: ed
diff --git a/buffer.ha b/buffer.ha
@@ -1,28 +1,33 @@
use bufio;
use fmt;
-
+// Holds text and state.
type buffer = struct {
cur: cursor,
head: *linenode,
tail: *linenode,
};
+// Represents a cursor.
type cursor = struct {
num: uint,
node: *linenode,
};
+// Represents a line of text within a buffer.
type linenode = struct {
value: value,
prev: *linenode,
next: *linenode,
};
+// Represents what kind of linenode a linenode is, or its content text.
type value = (headnode | str | tailnode);
+// Signifies a linenode is the head of a buffer.
type headnode = void;
+// Signifies a linenode is the tail of a buffer.
type tailnode = void;
diff --git a/ed.ha b/ed.ha
@@ -47,42 +47,30 @@ export fn main() void = {
cmd_edit(buf, fname);
};
- for (true) {
+ for (true) :repl {
+ fmt::error(prompt)!;
+
const rawline = match (bufio::scanline(os::stdin)) {
* => abort(),
io::EOF => break,
rawline: []u8 => rawline,
};
defer free(rawline);
+
const command = fmt::bsprint(rawline);
- parse_cmd(command);
- break;
+ const ops = parse_cmd(command);
+
+ for (let i = 0z; i < len(ops); i += 1) :ops {
+ const op = ops[i];
+ switch (op.cmd_alias) {
+ "e" => cmd_edit(buf, fname),
+ "r" => cmd_read(buf, fname),
+ "w" => cmd_write(buf, fname),
+ " p" => print_buffer(buf), // DEBUG ONLY
+ * => continue :repl // TODO: do user-error
+ };
+ };
};
-
- // test examples
- print_buffer(buf);
-
- cmd_edit(buf, fname);
- print_buffer(buf);
-
- cmd_read(buf, "./tmp/li.txt");
- print_buffer(buf);
-
- cmd_write(buf, "./tmp/out");
- print_buffer(buf);
-};
-
-// TODO
-// "3,7,/a/,+2m4"
-// 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 = {
diff --git a/parse.ha b/parse.ha
@@ -0,0 +1,64 @@
+// TODO: parse command line input, including commands, prefixes, ranges, etc.
+//
+// Possible direction:
+//
+// "3,7,/a/,+2m4"
+//
+// 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
+// } ->
+//
+// Note: Whats the theory around undo? What do we track? How do we calculate an
+// undo? Should commands return some history, state, or even a undo-function?
+
+use fmt;
+
+// Represents an intended action by a user to the main buffer.
+type operation = struct {
+ optype: optype,
+ cmd_alias: str, // command function name alias
+ param_fname: filename,
+};
+
+// Represents what kind of action a user intends to perform.
+type optype = enum {
+ CMD, // execute a command
+ CUR_LINENUM, // move cursor to a line number
+ CUR_REGEX, // move cursor to a matching line
+ CUR_MARK, // move cursor to a mark
+};
+
+// Parses command line input into intended operations.
+fn parse_cmd(cmd: str) []operation = {
+ let ops: []operation = [];
+ switch (cmd) {
+ "e" => append(ops, operation {
+ optype = optype::CMD,
+ cmd_alias = "e",
+ param_fname = void, // TODO
+ }),
+ "r" => append(ops, operation {
+ optype = optype::CMD,
+ cmd_alias = "r",
+ param_fname = void, // TODO
+ }),
+ "w" => append(ops, operation {
+ optype = optype::CMD,
+ cmd_alias = "w",
+ param_fname = void, // TODO
+ }),
+ " p" => append(ops, operation { // DEBUG ONLY
+ optype = optype::CMD,
+ cmd_alias = " p",
+ param_fname = void,
+ }),
+ * => void, // TODO
+ };
+
+ return ops;
+};
+