ed

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

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:
MMakefile | 3++-
Mbuffer.ha | 7++++++-
Med.ha | 44++++++++++++++++----------------------------
Aparse.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; +}; +