commit d2b6e43d61fc8fb96290ab84f4cb7505e703b041
parent c6c939e39da87ef9e4e3627a2fd7819de2c6adc9
Author: Byron Torres <b@torresjrjr.com>
Date: Fri, 5 Jan 2024 23:21:27 +0000
progress
Diffstat:
9 files changed, 194 insertions(+), 125 deletions(-)
diff --git a/Makefile b/Makefile
@@ -6,6 +6,7 @@ source=\
address.ha \
buffer.ha \
command.ha \
+ interaction.ha \
parse.ha \
util.ha \
diff --git a/address.ha b/address.ha
@@ -1,12 +1,12 @@
use regex;
type Address = struct {
- addrtype: AddressType,
+ addrform: AddressForm,
lineoffset: int,
setcurrentline: bool,
};
-type AddressType = (size | CurrentLine | LastLine | rune | RegexAddr);
+type AddressForm = (size | CurrentLine | LastLine | rune | RegexAddr);
// The dot '.' address.
type CurrentLine = void;
diff --git a/buffer.ha b/buffer.ha
@@ -18,6 +18,11 @@ type Line = struct {
globalmark: bool,
};
+fn buffer_finish(buf: *Buffer) void = {
+ free(buf.filename);
+ // TODO: free other fields?
+};
+
fn buf_insert(buf: *Buffer, n: size, ls: *Line...) void = {
debug("buf_insert(n={}), len(ls)={}", n, len(ls));
// for (let i = 0z; i < len(ls); i += 1) {
diff --git a/command.ha b/command.ha
@@ -14,7 +14,7 @@ type Command = struct {
linenums: []size,
cmdname: rune,
printmode: PrintMode,
- arg: str,
+ arg1: str,
arg2: str,
arg3: str,
input: []str,
@@ -52,6 +52,22 @@ type BufferModified = !void;
type NoPrevShCmd = !void;
+fn command_finish(cmd: *Command) void = {
+ debug("command_finish(): delete(cmd.linenums[..])");
+ delete(cmd.linenums[..]);
+ debug("command_finish(): free(cmd.arg1)");
+ free(cmd.arg1);
+ debug("command_finish(): free(cmd.arg2)");
+ free(cmd.arg2);
+ debug("command_finish(): free(cmd.arg3)");
+ free(cmd.arg3);
+ debug("command_finish(): delete(cmd.input[..])");
+ delete(cmd.input[..]);
+ debug("command_finish(): END");
+ // TODO: free other fields?
+ // TODO: make a separate "fn command_clear()" ? probably not
+};
+
fn lookupcmd(name: rune) CommandFn = {
switch (name) {
case 'a' => return &cmd_append;
@@ -94,7 +110,7 @@ fn cmd_append(s: *Session, cmd: *Command) (void | Error) = {
for (let i = 0z; i < len(cmd.input); i += 1) {
const l = alloc(Line { text = cmd.input[i], ... });
debug("cmd_append(): l.text={}", l.text);
- buf_insert(&s.buf, n + 1 + i, l);
+ buf_insert(s.buf, n + 1 + i, l);
};
s.buf.cursor = n + len(cmd.input);
@@ -114,12 +130,12 @@ fn cmd_change(s: *Session, cmd: *Command) (void | Error) = {
};
};
- buf_delete(&s.buf, a, b);
+ buf_delete(s.buf, a, b);
for (let i = 0z; i < len(cmd.input); i += 1) {
const l = alloc(Line { text = cmd.input[i], ... });
debug("cmd_append(): l.text={}", l.text);
- buf_insert(&s.buf, a + i, l);
+ buf_insert(s.buf, a + i, l);
};
s.buf.cursor = if (len(cmd.input) == 0) {
@@ -142,7 +158,7 @@ fn cmd_delete(s: *Session, cmd: *Command) (void | Error) = {
)?;
assert_nonzero(s, a)?;
- buf_delete(&s.buf, a, b);
+ buf_delete(s.buf, a, b);
s.buf.cursor = if (len(s.buf.lines) == 1) {
yield 0;
} else if (len(s.buf.lines) == a) {
@@ -160,9 +176,10 @@ fn cmd_edit(s: *Session, cmd: *Command) (void | Error) = {
return BufferModified;
};
- const fname = if (len(cmd.arg) != 0) {
- s.buf.filename = cmd.arg;
- yield cmd.arg;
+ const fname = if (len(cmd.arg1) != 0) {
+ //free(s.buf.filename);
+ s.buf.filename = strings::dup(cmd.arg1);
+ yield cmd.arg1;
} else if (len(s.buf.filename) != 0) {
yield s.buf.filename;
} else {
@@ -177,8 +194,8 @@ fn cmd_edit(s: *Session, cmd: *Command) (void | Error) = {
};
defer io::close(h)!;
- buf_deleteall(&s.buf);
- const (sz, _) = buf_read(&s.buf, h, 0)?;
+ buf_deleteall(s.buf);
+ const (sz, _) = buf_read(s.buf, h, 0)?;
if (!s.suppressmode) {
fmt::println(sz)!;
};
@@ -189,10 +206,14 @@ fn cmd_edit_forced(s: *Session, cmd: *Command) (void | Error) = void;
fn cmd_filename(s: *Session, cmd: *Command) (void | Error) = {
assert_noaddrs(s, cmd.linenums)?;
- if (len(cmd.arg) != 0) {
- s.buf.filename = cmd.arg;
- };
- if (len(s.buf.filename) == 0) {
+ if (cmd.arg1 != "") {
+ //debug("cmd_filename(): cmd.arg1 != 0");
+ //free(s.buf.filename);
+ //debug("cmd_filename(): freed");
+ debug("cmd_filename(): s.buf.filename = dup(cmd.arg1)");
+ s.buf.filename = strings::dup(cmd.arg1);
+ };
+ if (s.buf.filename == "") {
return NoFilename;
};
fmt::println(s.buf.filename)!;
@@ -202,8 +223,8 @@ fn cmd_global(s: *Session, cmd: *Command) (void | Error) = {
const (a, b) = get_range(
s,
&cmd.linenums,
- addr_linenum(&s.buf, 1)?,
- addr_lastline(&s.buf),
+ addr_linenum(s.buf, 1)?,
+ addr_lastline(s.buf),
)?;
assert_nonzero(s, a)?;
@@ -214,11 +235,11 @@ fn cmd_global_interative(s: *Session, cmd: *Command) (void | Error) = {
const (a, b) = get_range(
s,
&cmd.linenums,
- addr_linenum(&s.buf, 1)?,
- addr_lastline(&s.buf),
+ addr_linenum(s.buf, 1)?,
+ addr_lastline(s.buf),
)?;
assert_nonzero(s, a)?;
- const regex = regex::compile(cmd.arg)?; defer regex::finish(®ex);
+ const regex = regex::compile(cmd.arg1)?; defer regex::finish(®ex);
for (let i = a; i <= b; i += 1) {
const line = s.buf.lines[i];
@@ -245,17 +266,23 @@ fn cmd_global_interative(s: *Session, cmd: *Command) (void | Error) = {
let cmd = Command { ... };
- const rawinput = match (bufio::read_line(os::stdin)?) {
- case let bs: []u8 =>
- yield bs;
- case io::EOF =>
- abort(); // TODO: ?
- };
- defer free(rawinput);
- const input = strings::fromutf8(rawinput)!;
+ // const rawinput = match (bufio::read_line(os::stdin)?) {
+ // case let bs: []u8 =>
+ // yield bs;
+ // case io::EOF =>
+ // return UnexpectedEOF;
+ // };
+ // defer free(rawinput);
+ // const input = strings::fromutf8(rawinput)?;
+ const input = scanline(s)?;
parse(&cmd, input)?;
execute(s, &cmd)?;
+
+ // TODO: test if line was modified.
+ // TODO: make cmd_ functions save to session whether line was
+ // modified, instead of here?
+ line.globalmark = false;
};
};
@@ -281,7 +308,7 @@ fn cmd_insert(s: *Session, cmd: *Command) (void | Error) = {
for (let i = 0z; i < len(cmd.input); i += 1) {
const l = alloc(Line { text = cmd.input[i], ... });
debug("cmd_append(): l.text={}", l.text);
- buf_insert(&s.buf, n + i, l);
+ buf_insert(s.buf, n + i, l);
};
s.buf.cursor = if (len(cmd.input) == 0) {
@@ -296,7 +323,7 @@ fn cmd_join(s: *Session, cmd: *Command) (void | Error) = {
s,
&cmd.linenums,
s.buf.cursor,
- addr_nextline(&s.buf, s.buf.cursor),
+ addr_nextline(s.buf, s.buf.cursor),
)?;
assert_nonzero(s, a)?;
@@ -321,8 +348,8 @@ fn cmd_join(s: *Session, cmd: *Command) (void | Error) = {
...
});
- buf_delete(&s.buf, a, b);
- buf_insert(&s.buf, a, newline);
+ buf_delete(s.buf, a, b);
+ buf_insert(s.buf, a, newline);
};
fn cmd_mark(s: *Session, cmd: *Command) (void | Error) = {
@@ -332,7 +359,7 @@ fn cmd_mark(s: *Session, cmd: *Command) (void | Error) = {
// TODO: this should use ".suffix", not ".arg", and parse() should
// handle this
// TODO: check len, etc...
- const mark = strings::torunes(cmd.arg)[0];
+ const mark = strings::torunes(cmd.arg1)[0];
debug("cmd_mark(): mark={}", mark);
:search {
@@ -372,7 +399,7 @@ fn cmd_list(s: *Session, cmd: *Command) (void | Error) = {
assert_nonzero(s, a)?;
debug("cmd_list(): (a, b)=({}, {})", a, b);
- printlistlns(&s.buf, a, b)?;
+ printlistlns(s.buf, a, b)?;
s.buf.cursor = b;
};
@@ -386,7 +413,7 @@ fn cmd_move(s: *Session, cmd: *Command) (void | Error) = {
assert_nonzero(s, a)?;
// TODO: parse this properly in parse.ha?
- const iter = strings::iter(cmd.arg);
+ const iter = strings::iter(cmd.arg1);
const n = match (scan_addr(&iter)) {
case let addr: Address =>
const n = match (exec_addr(s, addr)) {
@@ -415,9 +442,9 @@ fn cmd_move(s: *Session, cmd: *Command) (void | Error) = {
yield n;
};
- const ls = alloc(s.buf.lines[a..b+1]...); defer free(ls);
- buf_delete(&s.buf, a, b);
- buf_insert(&s.buf, dest, ls...);
+ const ls = alloc(s.buf.lines[a..b+1]...); defer free(ls); // TODO: ?
+ buf_delete(s.buf, a, b);
+ buf_insert(s.buf, dest, ls...);
s.buf.cursor = dest - 1 + len(ls);
};
@@ -430,9 +457,9 @@ fn cmd_number(s: *Session, cmd: *Command) (void | Error) = {
s.buf.cursor,
)?;
assert_nonzero(s, a)?;
- debug("cmd_number(): (a, b)=({}, {})", a, b);
+ //debug("cmd_number(): (a, b)=({}, {})", a, b);
- printnumberlns(&s.buf, a, b)?;
+ printnumberlns(s.buf, a, b)?;
s.buf.cursor = b;
};
@@ -445,7 +472,7 @@ fn cmd_print(s: *Session, cmd: *Command) (void | Error) = {
)?;
assert_nonzero(s, a)?;
- printlns(&s.buf, a, b)?;
+ printlns(s.buf, a, b)?;
s.buf.cursor = b;
};
@@ -460,9 +487,9 @@ fn cmd_quit_forced(s: *Session, cmd: *Command) (void | Error) = void;
fn cmd_read(s: *Session, cmd: *Command) (void | Error) = {
const n = get_linenum(cmd.linenums, s.buf.cursor);
- const fname = if (len(cmd.arg) != 0) {
- s.buf.filename = cmd.arg;
- yield cmd.arg;
+ const fname = if (len(cmd.arg1) != 0) {
+ s.buf.filename = cmd.arg1;
+ yield cmd.arg1;
} else {
yield if (len(s.buf.filename) != 0) {
yield s.buf.filename;
@@ -474,7 +501,7 @@ fn cmd_read(s: *Session, cmd: *Command) (void | Error) = {
const h = os::open(fname)?: io::handle;
defer io::close(h)!;
- const (sz, _) = buf_read(&s.buf, h, n)?;
+ const (sz, _) = buf_read(s.buf, h, n)?;
if (!s.suppressmode) {
fmt::println(sz)!;
};
@@ -491,7 +518,7 @@ fn cmd_substitute(s: *Session, cmd: *Command) (void | Error) = {
assert_nonzero(s, a)?;
const replacement = cmd.arg2;
- const regex = regex::compile(cmd.arg)?; defer regex::finish(®ex);
+ const regex = regex::compile(cmd.arg1)?; defer regex::finish(®ex);
for (let i = a; i <= b; i += 1) {
const old = s.buf.lines[i].text;
@@ -522,8 +549,8 @@ fn cmd_substitute(s: *Session, cmd: *Command) (void | Error) = {
...
});
- buf_delete(&s.buf, i, i);
- buf_insert(&s.buf, i, newline);
+ buf_delete(s.buf, i, i);
+ buf_insert(s.buf, i, newline);
};
};
@@ -537,7 +564,7 @@ fn cmd_copy(s: *Session, cmd: *Command) (void | Error) = {
assert_nonzero(s, a)?;
// TODO: parse this properly in parse.ha?
- const iter = strings::iter(cmd.arg);
+ const iter = strings::iter(cmd.arg1);
const dest = match (scan_addr(&iter)) {
case let addr: Address =>
yield 1 + (match (exec_addr(s, addr)) {
@@ -551,8 +578,8 @@ fn cmd_copy(s: *Session, cmd: *Command) (void | Error) = {
};
debug("cmd_copy(): dest={}", dest);
- const ls = alloc(s.buf.lines[a..b+1]...); defer free(ls);
- buf_insert(&s.buf, dest, ls...);
+ const ls = alloc(s.buf.lines[a..b+1]...); defer free(ls); // TODO: ?
+ buf_insert(s.buf, dest, ls...);
s.buf.cursor = dest - 1 + len(ls);
};
@@ -567,14 +594,15 @@ fn cmd_write(s: *Session, cmd: *Command) (void | Error) = {
const (a, b) = get_range(
s,
&cmd.linenums,
- addr_linenum(&s.buf, 1)?,
- addr_lastline(&s.buf),
+ addr_linenum(s.buf, 1)?,
+ addr_lastline(s.buf),
)?;
assert_nonzero(s, a)?;
- const fname = if (len(cmd.arg) != 0) {
- s.buf.filename = cmd.arg;
- yield cmd.arg;
+ const fname = if (len(cmd.arg1) != 0) {
+ // free(s.buf.filename);
+ s.buf.filename = strings::dup(cmd.arg1);
+ yield s.buf.filename;
} else {
yield if (len(s.buf.filename) != 0) {
yield s.buf.filename;
@@ -596,19 +624,19 @@ fn cmd_write(s: *Session, cmd: *Command) (void | Error) = {
};
defer io::close(h)!;
- const sz = buf_write(&s.buf, h, a, b)?;
+ const sz = buf_write(s.buf, h, a, b)?;
if (!s.suppressmode) {
fmt::println(sz)!;
};
};
fn cmd_linenumber(s: *Session, cmd: *Command) (void | Error) = {
- const n = get_linenum(cmd.linenums, addr_lastline(&s.buf));
+ const n = get_linenum(cmd.linenums, addr_lastline(s.buf));
fmt::println(n)!;
};
fn cmd_shellescape(s: *Session, cmd: *Command) (void | Error) = {
- let iter = strings::iter(cmd.arg);
+ let iter = strings::iter(cmd.arg1);
let new = memio::dynamic(); defer io::close(&new)!;
let preview = false;
@@ -674,7 +702,7 @@ fn cmd_shellescape(s: *Session, cmd: *Command) (void | Error) = {
fn cmd_null(s: *Session, cmd: *Command) (void | Error) = {
const n = get_linenum(
cmd.linenums,
- addr_nextline(&s.buf, s.buf.cursor),
+ addr_nextline(s.buf, s.buf.cursor),
);
assert_nonzero(s, n)?;
diff --git a/execute.ha b/execute.ha
@@ -1,36 +1,33 @@
// Executes the Session's .cmd Command.
-fn execute(s: *Session, cmd: *Command) (void | CmdError) = {
+fn execute(s: *Session, cmd: *Command) (void | Error) = {
// TODO: move this into the cmd_* functions?
match (exec_addrs(s, cmd)) {
case void => void;
case let err: CmdError =>
- delete(cmd.linenums[..]);
errormsg(s, err);
return err;
};
- // TODO: write finish_cmd()
- // TODO: finish the Command at a higher level (main()) ?.
- defer delete(cmd.linenums[..]);
match (lookupcmd(cmd.cmdname)(s, cmd)) {
case void => void;
- case let err: CmdError =>
+ case let err: Error =>
errormsg(s, err);
return err;
};
+ debug("execute(): end");
};
fn exec_addrs(s: *Session, cmd: *Command) (void | CmdError) = {
for (let i = 0z; i < len(cmd.addrs); i += 1) {
const addr = cmd.addrs[i];
let n = exec_addr(s, addr)?;
- debug("exec_addrs(): offs={}", addr.lineoffset);
+ //debug("exec_addrs(): offs={}", addr.lineoffset);
n = n + addr.lineoffset: size; // beware of negatives
- debug("exec_addrs(): n={}", n);
+ //debug("exec_addrs(): n={}", n);
append(cmd.linenums, n);
for (let j = 0z; j < len(cmd.linenums); j += 1) {
- debug("exec_addrs(): cmd.linenums[{}]={}", j, cmd.linenums[j]);
+ void; //debug("exec_addrs(): cmd.linenums[{}]={}", j, cmd.linenums[j]);
};
if (addr.setcurrentline) {
@@ -40,23 +37,23 @@ fn exec_addrs(s: *Session, cmd: *Command) (void | CmdError) = {
};
fn exec_addr(s: *Session, addr: Address) (size | CmdError) = {
- match (addr.addrtype) {
+ match (addr.addrform) {
case let n: size =>
- return addr_linenum(&s.buf, n)?;
+ return addr_linenum(s.buf, n)?;
case CurrentLine =>
return s.buf.cursor;
case LastLine =>
- return addr_lastline(&s.buf);
+ return addr_lastline(s.buf);
case let m: rune =>
- return addr_mark(&s.buf, m)?;
+ return addr_mark(s.buf, m)?;
case let rad: RegexAddr =>
- return addr_regex(&s.buf, rad, s.buf.cursor)?;
+ return addr_regex(s.buf, rad, s.buf.cursor)?;
};
};
fn get_range(s: *Session, lns: *[]size, a: size, b: size) ((size, size) | InvalidAddress) = {
- debug("get_range(): len(lns)={}", len(lns));
+ //debug("get_range(): len(lns)={}", len(lns));
const (a, b) = if (len(lns) == 0) {
yield (a, b);
} else if (len(lns) == 1) {
@@ -64,7 +61,7 @@ fn get_range(s: *Session, lns: *[]size, a: size, b: size) ((size, size) | Invali
} else {
yield (lns[ len(lns) - 2 ], lns[ len(lns) - 1 ]);
};
- debug("get_range(): (a, b)=({}, {})", a, b);
+ //debug("get_range(): (a, b)=({}, {})", a, b);
if (a < 0 || a > b || b >= len(s.buf.lines)) {
return InvalidAddress;
};
diff --git a/interaction.ha b/interaction.ha
@@ -0,0 +1,23 @@
+use bufio;
+use encoding::utf8;
+use io;
+use os;
+use strings;
+use types;
+
+type InteractionError = !(
+ UnexpectedEOF
+ | utf8::invalid
+ | io::error
+);
+
+type UnexpectedEOF = !io::EOF;
+
+fn scanline(s: *Session) (str | InteractionError) = {
+ match (bufio::scan_line(s.input)?) {
+ case let string: const str =>
+ return string;
+ case io::EOF =>
+ return UnexpectedEOF;
+ };
+};
diff --git a/main.ha b/main.ha
@@ -7,9 +7,11 @@ use io;
use os;
use regex;
use strings;
+use types;
type Session = struct {
- buf: Buffer,
+ input: *bufio::scanner,
+ buf: *Buffer,
mode: InputMode,
helpmode: bool,
lasterror: (void | Error),
@@ -25,7 +27,7 @@ type InputMode = enum {
TEXT,
};
-type Error = (ParseError | CmdError);
+type Error = !(...InteractionError | ParseError | CmdError);
export fn main() void = {
const help: [_]getopt::help = [
@@ -37,20 +39,25 @@ export fn main() void = {
const main_cmd = getopt::parse(os::args, help...);
defer getopt::finish(&main_cmd);
+ const input = bufio::newscanner(os::stdin, types::SIZE_MAX);
+ defer bufio::finish(&input);
+
+ const buffer = Buffer {
+ lines = *alloc([ alloc(Line { ... }) ]),
+ trash = *alloc([]: []*Line),
+ ...
+ };
+ defer buffer_finish(&buffer);
+
let s = Session {
- buf = Buffer {
- lines = *alloc([ alloc(Line { ... }) ]),
- trash = *alloc([]: []*Line),
- ...
- },
+ input = &input,
+ buf = &buffer,
prompt = "*",
prev_shcmd = void,
lasterror = void,
...
};
- let cmd = Command { ... };
-
for (let i = 0z; i < len(main_cmd.opts); i += 1) {
const opt = main_cmd.opts[i];
switch (opt.0) {
@@ -74,13 +81,14 @@ export fn main() void = {
case "" =>
fmt::fatal("Invalid filename ''");
case =>
- s.buf.filename = main_cmd.args[0];
+ s.buf.filename = strings::dup(main_cmd.args[0]);
};
};
if (len(s.buf.filename) != 0) {
- cmd.arg = s.buf.filename;
- cmd_edit(&s, &cmd): void;
+ let cmd = Command { ... };
+ cmd.arg1 = strings::dup(s.buf.filename);
+ cmd_edit(&s, &cmd): void; // TODO: handle error?
};
let cmd = Command { ... };
@@ -90,28 +98,19 @@ export fn main() void = {
fmt::error(s.prompt)!;
};
- const rawline = match (bufio::read_line(os::stdin)) {
- case let bs: []u8 =>
- yield bs;
+ const inputstr = match (bufio::scan_line(s.input)) {
+ case let s: const str =>
+ yield s;
case io::EOF =>
fmt::println()!;
break;
case let err: io::error =>
fmt::fatal(io::strerror(err));
};
- defer free(rawline);
-
- const input = match (strings::fromutf8(rawline)) {
- case let s: str =>
- yield s;
- case encoding::utf8::invalid =>
- fmt::errorln("Error: Invalid UTF-8 input")!;
- continue;
- };
switch (s.mode) {
case InputMode::COMMAND =>
- const execnow = match (parse(&cmd, input)) {
+ const execnow = match (parse(&cmd, inputstr)) {
case let err: ParseError =>
errormsg(&s, strerror(err));
continue;
@@ -121,20 +120,22 @@ export fn main() void = {
if (execnow) {
// TODO: handle all ": void"s
execute(&s, &cmd): void;
- //cmd = command { ... };
+ debug("main(): before command_finish()");
+ command_finish(&cmd);
+ debug("main(): after command_finish()");
} else {
s.mode = InputMode::TEXT;
continue;
};
case InputMode::TEXT =>
- if (input == ".") {
+ if (inputstr == ".") {
execute(&s, &cmd): void;
- delete(cmd.input[..]);
+ command_finish(&cmd);
s.mode = InputMode::COMMAND;
continue;
};
- debug("repl: input={}", input);
- append(cmd.input, strings::dup(input));
+ debug("repl: input={}", inputstr);
+ append(cmd.input, strings::dup(inputstr));
};
};
@@ -157,6 +158,16 @@ fn errormsg(s: *Session, err: Error) void = {
fn strerror(err: Error) str = {
match (err) {
+ // InteractionError
+ case let e: InteractionError =>
+ match (e) {
+ case UnexpectedEOF =>
+ return "Unexpected end-of-file input";
+ case let e: encoding::utf8::invalid =>
+ return encoding::utf8::strerror(e);
+ case let e: io::error =>
+ return io::strerror(e);
+ };
// CmdError
case InvalidAddress =>
return "Invalid address";
@@ -175,6 +186,7 @@ fn strerror(err: Error) str = {
case let e: regex::error =>
return regex::strerror(e);
case let e: fs::error =>
+ debug("foo");
return fs::strerror(e);
// ParseError
case UnknownCommand =>
diff --git a/parse.ha b/parse.ha
@@ -1,4 +1,5 @@
use ascii;
+use io;
use regex;
use strconv;
use strings;
@@ -54,7 +55,7 @@ fn parse(cmd: *Command, input: str) (bool | ParseError) = {
return true;
};
} else {
- cmd.arg = scan_rest(&iter);
+ cmd.arg1 = scan_rest(&iter);
return true;
};
@@ -62,7 +63,7 @@ fn parse(cmd: *Command, input: str) (bool | ParseError) = {
case 'k' =>
match (strings::next(&iter)) {
case let r: rune =>
- cmd.arg = strings::fromrunes([r]);
+ cmd.arg1 = strings::fromrunes([r]);
case void =>
return ExpectedMark;
};
@@ -71,7 +72,7 @@ fn parse(cmd: *Command, input: str) (bool | ParseError) = {
// !<shellcmd>
case '!' =>
- cmd.arg = scan_rest(&iter);
+ cmd.arg1 = scan_rest(&iter);
return true;
// .[s] where 's' is '(l|n|p)'
@@ -89,7 +90,7 @@ fn parse(cmd: *Command, input: str) (bool | ParseError) = {
// .[s][ ]<addr>
case 'm', 't' =>
cmd.printmode = scan_suffix(&iter);
- cmd.arg = scan_rest(&iter);
+ cmd.arg1 = scan_rest(&iter);
return true;
// ./<regex>[/] where delimiter '/' is arbitrary
@@ -104,7 +105,7 @@ fn parse(cmd: *Command, input: str) (bool | ParseError) = {
yield r;
};
};
- cmd.arg = scan_item(&iter, delim);
+ cmd.arg1 = scan_item(&iter, delim);
strings::next(&iter); // scan delimiter if exists
scan_end_assert(&iter)?;
return true;
@@ -121,7 +122,7 @@ fn parse(cmd: *Command, input: str) (bool | ParseError) = {
yield r;
};
};
- cmd.arg = scan_item(&iter, delim);
+ cmd.arg1 = scan_item(&iter, delim);
strings::next(&iter); // scan delimiter if exists
cmd.arg2 = scan_rest(&iter);
if (strings::prev(&iter) as rune == '\\') {
@@ -141,7 +142,7 @@ fn parse(cmd: *Command, input: str) (bool | ParseError) = {
yield r;
};
};
- cmd.arg = scan_item(&iter, delim);
+ cmd.arg1 = scan_item(&iter, delim);
match (strings::next(&iter)) {
case rune => void;
case void =>
@@ -174,14 +175,14 @@ fn scan_addrs(iter: *strings::iterator) []Address = {
case ',' =>
specialfirst = true;
append(addrs, Address {
- addrtype = 1z,
+ addrform = 1z,
lineoffset = 0,
setcurrentline = false,
});
case ';' =>
specialfirst = true;
append(addrs, Address {
- addrtype = CurrentLine,
+ addrform = CurrentLine,
lineoffset = 0,
setcurrentline = true,
});
@@ -195,7 +196,7 @@ fn scan_addrs(iter: *strings::iterator) []Address = {
case void =>
yield if (specialfirst) {
yield Address {
- addrtype = LastLine,
+ addrform = LastLine,
lineoffset = 0,
...
};
@@ -246,7 +247,7 @@ fn scan_addr(iter: *strings::iterator) (Address | void) = {
// debug("scan_addr(): r={}", r);
- const addrtype: (AddressType | void) =
+ const addrform: (AddressForm | void) =
if (r == '.') {
yield CurrentLine;
} else if (r == '$') {
@@ -277,7 +278,7 @@ fn scan_addr(iter: *strings::iterator) (Address | void) = {
const offs = scan_offsets(iter);
- const addrtype: AddressType = match (addrtype) {
+ const addrform: AddressForm = match (addrform) {
case void =>
yield if (len(offs) == 0) {
return void;
@@ -285,11 +286,11 @@ fn scan_addr(iter: *strings::iterator) (Address | void) = {
yield CurrentLine;
};
case =>
- yield addrtype as AddressType;
+ yield addrform as AddressForm;
};
let addr = Address {
- addrtype = addrtype,
+ addrform = addrform,
lineoffset = 0,
...
};
@@ -443,7 +444,8 @@ fn scan_mark(iter: *strings::iterator) rune = {
// TODO: rename and appropriate to "scan_size()"?
fn scan_uint(iter: *strings::iterator) uint = {
- let num: []u8 = [];
+ // reimplement this function using another iterator
+ let num: []rune = [];
defer free(num);
for (true) {
let r = match (strings::next(iter)) {
@@ -454,18 +456,19 @@ fn scan_uint(iter: *strings::iterator) uint = {
};
if (ascii::isdigit(r)) {
- append(num, r: u32: u8);
+ append(num, r);
} else {
strings::prev(iter);
break;
};
};
+ // TODO: return void instead?
if (len(num) == 0) {
return 0;
};
- match (strconv::stou(strings::fromutf8(num)!)) {
+ match (strconv::stou(strings::fromrunes(num))) {
case (strconv::invalid | strconv::overflow) =>
abort("Invalid");
case let u: uint =>
diff --git a/util.ha b/util.ha
@@ -3,7 +3,7 @@ use io;
use strings;
fn cmd_dumpbuffer(s: *Session, cmd: *Command) (void | Error) = {
- return dumpbuffer(&s.buf);
+ return dumpbuffer(s.buf);
};
fn dumpbuffer(buf: *Buffer) void = {