ed

[hare] The standard editor
Log | Files | Refs | README | LICENSE

commit e83abfecdbc4ccdf84d53a380b108877b11627cf
parent f7a20a064e15675bd5151ce6c5eee64d520e151d
Author: Byron Torres <b@torresjrjr.com>
Date:   Sun,  7 Jan 2024 19:55:01 +0000

tidy main.ha, parse.ha

Diffstat:
Mmain.ha | 47++++++++++++++++++++++++-----------------------
Mparse.ha | 86++++++++++++++++++++++++++++++++++++++-----------------------------------------
2 files changed, 65 insertions(+), 68 deletions(-)

diff --git a/main.ha b/main.ha @@ -24,7 +24,7 @@ type Session = struct{ type Error = !(...InteractionError | ...ParseError | ...CmdError); -def help: [_]getopt::help = [ +def proghelp: [_]getopt::help = [ "standard line editor", ('p', "prompt", "set the command prompt"), ('s', "suppress byte counts and '!' prompt"), @@ -32,18 +32,18 @@ def help: [_]getopt::help = [ ]; export fn main() void = { - const main_cmd = getopt::parse(os::args, help...); - defer getopt::finish(&main_cmd); + const progcmd = getopt::parse(os::args, proghelp...); + defer getopt::finish(&progcmd); const input = bufio::newscanner(os::stdin, types::SIZE_MAX); - defer bufio::finish(&input); + defer bufio::finish(&input); const buffer = Buffer{ lines = *alloc([ alloc(Line{ ... }) ]), trash = *alloc([]: []*Line), ... }; - defer buffer_finish(&buffer); + defer buffer_finish(&buffer); let s = Session{ input = &input, @@ -54,51 +54,52 @@ export fn main() void = { ... }; - for (let i = 0z; i < len(main_cmd.opts); i += 1) { - const opt = main_cmd.opts[i]; + for (let i = 0z; i < len(progcmd.opts); i += 1) { + const opt = progcmd.opts[i]; switch (opt.0) { case 'p' => s.prompt = opt.1; s.promptmode = true; case 's' => s.suppressmode = true; - case => abort(); + case => + abort(); }; }; - if (len(main_cmd.args) > 1) + if (len(progcmd.args) > 1) exit_usage(); - if (len(main_cmd.args) == 1) - switch (main_cmd.args[0]) { + if (len(progcmd.args) == 1) + switch (progcmd.args[0]) { case "-" => fmt::fatal("Invalid filename '-'"); case "" => fmt::fatal("Invalid filename ''"); case => - s.buf.filename = strings::dup(main_cmd.args[0]); + s.buf.filename = strings::dup(progcmd.args[0]); }; - if (len(s.buf.filename) != 0) { - let cmd = Command{ ... }; - cmd.arg1 = strings::dup(s.buf.filename); - cmd_edit(&s, &cmd): void; // TODO: handle error? - }; + if (len(s.buf.filename) != 0) + cmd_edit(&s, &Command{ + arg1 = strings::dup(s.buf.filename), + ... + }): void; // TODO: handle error for (true) :repl { if (s.promptmode) fmt::error(s.prompt)!; const cmd = match (parse(&input)) { - case let cmd: Command => - yield cmd; + case let c: Command => + yield c; case io::EOF => yield Command{ name = 'q', ... }; - case let err: ParseError => - errormsg(&s, strerror(err)); + case let e: ParseError => + errormsg(&s, strerror(e)); continue; }; - defer command_finish(&cmd); + defer command_finish(&cmd); if (cmd.name == '&') { errormsg(&s, '&': UnknownCommand); @@ -116,7 +117,7 @@ export fn main() void = { }; fn exit_usage() never = { - getopt::printusage(os::stderr, os::args[0], help)!; + getopt::printusage(os::stderr, os::args[0], proghelp)!; os::exit(1); }; diff --git a/parse.ha b/parse.ha @@ -118,17 +118,15 @@ fn parse_cmdargs(cmd: *Command, iter: *strings::iterator) (bool | ParseError) = // .[ <file>] case 'e', 'E', 'f', 'r', 'w' => - if (scan_blanks(iter) == 0) { + if (scan_blanks(iter) == 0) match (strings::next(iter)) { case let r: rune => return r: UnexpectedSuffix; case void => return true; }; - } else { - cmd.arg1 = scan_rest(iter); - return true; - }; + cmd.arg1 = scan_rest(iter); + return true; // k<x> case 'k' => @@ -322,48 +320,46 @@ fn scan_addr(iter: *strings::iterator) (Address | void) = { // debug("scan_addr(): r={}", r); - const addrform: (AddressForm | void) = - if (r == '.') { - yield CurrentLine; - } else if (r == '$') { - yield LastLine; - } else if (ascii::isdigit(r)) { - strings::prev(iter); - yield scan_uint(iter): size; - } else if (r == '\'') { - yield scan_mark(iter); - } else if (r == '/') { - const rad = RegexAddr{ - expr = scan_item(iter, '/'), - direction = true, - }; - strings::next(iter); - yield rad; - } else if (r == '?') { - const rad = RegexAddr{ - expr = scan_item(iter, '?'), - direction = false, - }; - strings::next(iter); - yield rad; - } else { - strings::prev(iter); - yield void; + const addrform: (AddressForm | void) = switch (r) { + case '.' => + yield CurrentLine; + case '$' => + yield LastLine; + case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' => + strings::prev(iter); + yield scan_uint(iter): size; + case '\'' => + yield scan_mark(iter); + case '/' => + const rad = RegexAddr{ + expr = scan_item(iter, '/'), + direction = true, }; - - const offs = scan_offsets(iter); - - const addrform: AddressForm = match (addrform) { - case void => - yield if (len(offs) == 0) { - return void; - } else { - yield CurrentLine; + strings::next(iter); + yield rad; + case '?' => + const rad = RegexAddr{ + expr = scan_item(iter, '?'), + direction = false, }; + strings::next(iter); + yield rad; case => - yield addrform as AddressForm; + strings::prev(iter); + yield void; }; + const offs = scan_offsets(iter); + + if (addrform is void && len(offs) == 0) + return void; + + const addrform: AddressForm = + if (addrform is void) + CurrentLine + else + addrform as AddressForm; + let addr = Address{ addrform = addrform, lineoffset = 0, @@ -474,7 +470,7 @@ fn scan_rest(iter: *strings::iterator) str = { return strings::trim(strings::fromrunes(rs)); }; -fn scan_item(iter: *strings::iterator, end: rune) str = { +fn scan_item(iter: *strings::iterator, delim: rune) str = { let rs: []rune = []; for (true) { let r = match (strings::next(iter)) { @@ -488,14 +484,14 @@ fn scan_item(iter: *strings::iterator, end: rune) str = { case void => break; // TODO: Error here? how? case let r: rune => - if (r == end) { + if (r == delim) { append(rs, r); } else { append(rs, ['\\', r]...); }; continue; }; - } else if (r == end) { + } else if (r == delim) { strings::prev(iter); break; };