commit 1cc35875af4ad60084dc16c61fa9fc833c65d297
parent f3608da092b501d946629acec907fbc3edebfcfe
Author: Byron Torres <b@torresjrjr.com>
Date: Sun, 18 Dec 2022 22:34:19 +0000
cmdfn -> cmdname
Diffstat:
M | command.ha | | | 39 | +++++++++++++++++++++++++++++++++++++-- |
M | parse.ha | | | 117 | ++++++++++++++++++++++--------------------------------------------------------- |
2 files changed, 69 insertions(+), 87 deletions(-)
diff --git a/command.ha b/command.ha
@@ -9,7 +9,7 @@ use strings;
type command = struct {
addrs: []address,
linenums: []size,
- cmdfn: commandfn,
+ cmdname: rune,
printmode: printmode,
arg: str,
arg2: str,
@@ -46,6 +46,41 @@ type nofilename = !void;
type buffermodified = !void;
+fn lookupcmd(name: rune) commandfn = {
+ switch (name) {
+ case 'a' => return &cmd_append;
+ case 'c' => return &cmd_change;
+ case 'd' => return &cmd_delete;
+ case 'e' => return &cmd_edit;
+ case 'E' => return &cmd_edit_forced;
+ case 'f' => return &cmd_filename;
+ case 'g' => return &cmd_global;
+ case 'G' => return &cmd_global_manual;
+ case 'h' => return &cmd_help;
+ case 'H' => return &cmd_helpmode;
+ case 'i' => return &cmd_insert;
+ case 'j' => return &cmd_join;
+ case 'k' => return &cmd_mark;
+ case 'l' => return &cmd_list;
+ case 'm' => return &cmd_move;
+ case 'n' => return &cmd_number;
+ case 'p' => return &cmd_print;
+ case 'P' => return &cmd_prompt;
+ case 'q' => return &cmd_quit;
+ case 'Q' => return &cmd_quit_forced;
+ case 'r' => return &cmd_read;
+ case 's' => return &cmd_substitute;
+ case 't' => return &cmd_copy;
+ case 'u' => return &cmd_undo;
+ case 'v' => return &cmd_invglobal;
+ case 'V' => return &cmd_invglobal_manual;
+ case 'w' => return &cmd_write;
+ case '=' => return &cmd_linenumber;
+ case '!' => return &cmd_shellescape;
+ case '\x00' => return &cmd_null;
+ };
+};
+
// Executes the session's .cmd command.
fn execute(s: *session, cmd: *command) (void | error) = {
// TODO: move this into the cmd_* functions?
@@ -59,7 +94,7 @@ fn execute(s: *session, cmd: *command) (void | error) = {
// TODO: finish the command at a higher level (main()) ?.
defer delete(cmd.linenums[..]);
- match (cmd.cmdfn(s, cmd)) {
+ match (lookupcmd(cmd.cmdname)(s, cmd)) {
case void => void;
case let err: error =>
return errormsg(s, err);
diff --git a/parse.ha b/parse.ha
@@ -32,28 +32,20 @@ fn parse(cmd: *command, input: str) (bool | parseerror) = {
const iter = strings::iter(input);
cmd.addrs = scan_addrs(&iter);
- cmd.cmdfn = scan_cmdfn(&iter)?;
+ cmd.cmdname = scan_cmdname(&iter)?;
- switch (cmd.cmdfn) {
- case // [ ]
- &cmd_null,
- =>
+ switch (cmd.cmdname) {
+ // [ ]
+ case '\x00' =>
return true;
- case // (q|Q)
- &cmd_quit,
- &cmd_quit_forced,
- =>
+ // (q|Q)
+ case 'q', 'Q' =>
scan_end_assert(&iter)?;
return true;
- case // .[ <file>]
- &cmd_edit,
- &cmd_edit_forced,
- &cmd_filename,
- &cmd_read,
- &cmd_write,
- =>
+ // .[ <file>]
+ case 'e', 'E', 'f', 'r', 'w' =>
if (scan_blanks(&iter) == 0) {
match (strings::next(&iter)) {
case let r: rune =>
@@ -66,9 +58,8 @@ fn parse(cmd: *command, input: str) (bool | parseerror) = {
return true;
};
- case // k<x>
- &cmd_mark,
- =>
+ // k<x>
+ case 'k' =>
match (strings::next(&iter)) {
case let r: rune =>
cmd.arg = strings::fromrunes([r]);
@@ -78,43 +69,25 @@ fn parse(cmd: *command, input: str) (bool | parseerror) = {
scan_end_assert(&iter)?;
return true;
- case // !<shellcmd>
- &cmd_shellescape,
- =>
+ // !<shellcmd>
+ case '!' =>
cmd.arg = scan_rest(&iter);
return true;
- case // .[s] where 's' is '(l|n|p)'
- &cmd_append,
- &cmd_change,
- &cmd_delete,
- &cmd_help,
- &cmd_helpmode,
- &cmd_insert,
- &cmd_join,
- &cmd_list,
- &cmd_number,
- &cmd_print,
- &cmd_prompt,
- &cmd_undo,
- &cmd_linenumber,
- =>
+ // .[s] where 's' is '(l|n|p)'
+ case 'a', 'c', 'd', 'h', 'H', 'i', 'j', 'l', 'n', 'p', 'P', 'u', '=' =>
cmd.printmode = scan_suffix(&iter);
scan_end_assert(&iter)?;
return true;
- case // .[s][ ]<addr>
- &cmd_move,
- &cmd_copy,
- =>
+ // .[s][ ]<addr>
+ case 'm', 't' =>
cmd.printmode = scan_suffix(&iter);
cmd.arg = scan_rest(&iter);
return true;
- case // ./<regex>[/]
- &cmd_global_manual,
- &cmd_invglobal_manual,
- =>
+ // ./<regex>[/] where delimiter '/' is arbitrary
+ case 'G', 'V' =>
const delim = match (strings::next(&iter)) {
case void =>
return expectedargument;
@@ -130,9 +103,8 @@ fn parse(cmd: *command, input: str) (bool | parseerror) = {
scan_end_assert(&iter)?;
return true;
- case // s/<regex>/[<replace>[/[<flags>]]]
- &cmd_substitute,
- =>
+ // s/<regex>/[<replace>[/[<flags>]]]
+ case 's' =>
const delim = match (strings::next(&iter)) {
case void =>
return expectedargument;
@@ -158,10 +130,8 @@ fn parse(cmd: *command, input: str) (bool | parseerror) = {
cmd.arg3 = scan_rest(&iter); // TODO: scan properly here?
return true;
- case // ./regex/CMDLIST
- &cmd_global,
- &cmd_invglobal,
- =>
+ // ./<regex>/<cmdlist...>
+ case 'g', 'v' =>
abort("TODO: parse: global, invglobal");
case =>
@@ -350,47 +320,24 @@ fn scan_offset(iter: *strings::iterator) int = {
};
};
-fn scan_cmdfn(iter: *strings::iterator) (commandfn | unknowncommand)= {
+fn scan_cmdname(iter: *strings::iterator) (rune | unknowncommand)= {
scan_blanks(iter);
let r = match (strings::next(iter)) {
case void =>
- return &cmd_null;
+ return '\x00';
case let r: rune =>
yield r;
};
switch (r) {
- case 'a' => return &cmd_append;
- case 'c' => return &cmd_change;
- case 'd' => return &cmd_delete;
- case 'e' => return &cmd_edit;
- case 'E' => return &cmd_edit_forced;
- case 'f' => return &cmd_filename;
- case 'g' => return &cmd_global;
- case 'G' => return &cmd_global_manual;
- case 'h' => return &cmd_help;
- case 'H' => return &cmd_helpmode;
- case 'i' => return &cmd_insert;
- case 'j' => return &cmd_join;
- case 'k' => return &cmd_mark;
- case 'l' => return &cmd_list;
- case 'm' => return &cmd_move;
- case 'n' => return &cmd_number;
- case 'p' => return &cmd_print;
- case 'P' => return &cmd_prompt;
- case 'q' => return &cmd_quit;
- case 'Q' => return &cmd_quit_forced;
- case 'r' => return &cmd_read;
- case 's' => return &cmd_substitute;
- case 't' => return &cmd_copy;
- case 'u' => return &cmd_undo;
- case 'v' => return &cmd_invglobal;
- case 'V' => return &cmd_invglobal_manual;
- case 'w' => return &cmd_write;
- case '=' => return &cmd_linenumber;
- case '!' => return &cmd_shellescape;
-// case 'b' => return &cmd_dumpbuffer;
- case => return r: unknowncommand;
+ case
+ 'a', 'c', 'd', 'e', 'E', 'f', 'g', 'G', 'h', 'H',
+ 'i', 'j', 'k', 'l', 'm', 'n', 'p', 'P', 'q', 'Q',
+ 'r', 's', 't', 'u', 'v', 'V', 'w', '=', '!',
+ =>
+ return r;
+ case =>
+ return r: unknowncommand;
};
};