ed

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

commit 08909ddf1f3227d36c9e1a628dfccf6060872a4d
parent 47c37a24c3250598b8eb14fd586cd2cbd1c59a3f
Author: Byron Torres <b@torresjrjr.com>
Date:   Fri, 10 Sep 2021 23:46:57 +0100

Add command line repl loop, adjust types

Diffstat:
DMakefile | 17-----------------
Med.ha | 148++++++++++++++++++++++++++++++++++++++++++++++++-------------------------------
2 files changed, 90 insertions(+), 75 deletions(-)

diff --git a/Makefile b/Makefile @@ -1,17 +0,0 @@ -.POSIX: -.SUFFIXES: -HARE=hare -HAREFLAGS= - -all: ed - -clean: - rm -f ed - -.PHONY: all clean - -.SUFFIXES: .ha -.ha: - $(HARE) build $(HAREFLAGS) -o $@ $< - -ed: ed.ha diff --git a/ed.ha b/ed.ha @@ -5,26 +5,28 @@ use getopt; use io; use os; -type filename = (str | void); +let prompt: str = ""; + +let surpress: bool = false; -type file = (io::file | void); +type filename = (str | void); type buffer = struct { - head: *line, - tail: *line, + head: *linenode, + tail: *linenode, }; -type line = struct { +type linenode = struct { value: value, - prev: *line, - next: *line, + prev: *linenode, + next: *linenode, }; -type value = (headtype | str | tailtype); +type value = (headnode | str | tailnode); -type headtype = void; +type headnode = void; -type tailtype = void; +type tailnode = void; export fn main() void = { const help: [_]getopt::help = [ @@ -36,14 +38,11 @@ export fn main() void = { const cmd = getopt::parse(os::args, help...); defer getopt::finish(&cmd); - let prompt = ""; - let verbose = true; - for (let i = 0z; i < len(cmd.opts); i += 1) { const opt = cmd.opts[i]; switch (opt.0) { 'p' => prompt = opt.1, - 's' => verbose = false, + 's' => surpress = true, }; }; @@ -51,38 +50,56 @@ export fn main() void = { exit_usage(help); }; - let filename: filename = switch (len(cmd.args) == 1) { - false => void, - true => switch (cmd.args[0]) { + let fname: filename = if (len(cmd.args) == 1) { + yield void; + } else { + yield switch (cmd.args[0]) { "-" => fmt::fatal("Invalid filename '-'"), "" => fmt::fatal("Invalid filename ''"), - * => cmd.args[0], - }, - }; - - let file: file = match (filename) { - void => void, - filename: str => match (os::open(filename)) { - err: fs::error => fmt::fatal("Error {}", fs::strerror(err)), - file: io::file => file, - }, + * => yield cmd.args[0], + }; }; const buf = new_buffer(); - if (file is io::file) { - cmd_edit(file: io::file); + if (fname is str) { + cmd_edit(buf, fname); + }; + + for (true) { + const rawline = match (bufio::scanline(os::stdin)) { + err: io::error => abort("io::error"), + io::EOF => break, + rawline: []u8 => rawline, + }; + defer free(rawline); + const command = fmt::bsprint(rawline); + parse_cmd(command); + break; }; }; -fn cmd_edit(file: io::file) void = { - print_buffer(read(&file)); +// "3,7,/a/,+3m4" +// 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 = { + getopt::printusage(os::stderr, os::args[0], help); + os::exit(1); }; // Initialises a new buffer. fn new_buffer() *buffer = { - const head = alloc(line { value = headtype, ... }); - const tail = alloc(line { value = tailtype, prev = head }); + const head = alloc(linenode { value = headnode, ... }); + const tail = alloc(linenode { value = tailnode, prev = head }); head.next = tail; return alloc(buffer { head = head, @@ -90,12 +107,13 @@ fn new_buffer() *buffer = { }); }; -// Reads text from source into a new buffer. -fn read(source: *io::stream) *buffer = { - const buf = new_buffer(); +// Reads text from source, writes to a buffer. +fn read(source: *io::stream, buf: *buffer) size = { let localhead = buf.head; const localtail = buf.tail; + let total = 0z; + for (true) { const rawline = match (bufio::scanline(source)) { err: io::error => abort("io::error"), @@ -103,41 +121,55 @@ fn read(source: *io::stream) *buffer = { rawline: []u8 => rawline, }; //defer free(rawline); + total += len(rawline); + const value = fmt::bsprint(rawline); - const line = alloc(line { + const ln = alloc(linenode { value = value, prev = localhead, next = localtail, }); - localhead.next = line; - localtail.prev = line; + localhead.next = ln; + localtail.prev = ln; - localhead = line; + localhead = ln; }; - return buf; + return total; }; -// Sequencially prints lines of a buffer. -fn print_buffer(buf: *buffer) void = { - let line = buf.head; - for (true) { - match (line.value) { - headtype => { - line = line.next; - }, - s: str => { - fmt::println(s)?; - line = line.next; +// // Sequencially prints lines of a buffer. +// fn print_buffer(buf: *buffer) void = { +// let linenode = buf.head; +// for (true) { +// match (linenode.value) { +// headnode => { +// linenode = linenode.next; +// }, +// s: str => { +// fmt::println(s)?; +// linenode = linenode.next; +// }, +// tailnode => break +// }; +// }; +// }; + +// 'e' command +fn cmd_edit(buf: *buffer, fname: filename) void = { + match (fname) { + void => void, + fname: str => match (os::open(fname)) { + err: fs::error => fmt::fatal("Error {}", fs::strerror(err)), + f: io::file => { + const n = read(&f, buf); + if (!surpress) { + fmt::println(n)?; + }; }, - tailtype => break - }; + }, }; }; -@noreturn fn exit_usage(help: []getopt::help) void = { - getopt::printusage(os::stderr, os::args[0], help); - os::exit(1); -};