~ecs/madeline

24e5612e6e2a8b19a534365a78b9a8a331a2abf8 — Sebastian 2 months ago 54dcf14
Use done type and for-each iterator loops

Signed-off-by: Sebastian <sebastian@sebsite.pw>
M graph/boundary.ha => graph/boundary.ha +12 -14
@@ 10,7 10,7 @@ export fn boundary(buf: []u8, idx: size) (bool | utf8::invalid) = {
	};
	let next = strings::iter(strings::fromutf8(buf[idx..])!);
	let next = match (strings::next(&next)) {
	case void =>
	case done =>
		// GB1
		return true;
	case let r: rune =>


@@ 18,7 18,7 @@ export fn boundary(buf: []u8, idx: size) (bool | utf8::invalid) = {
	};
	let prev = strings::riter(strings::fromutf8(buf[..idx])?);
	let prev = match (strings::next(&prev)) {
	case void =>
	case done =>
		// GB2
		return true;
	case let r: rune =>


@@ 39,10 39,7 @@ export fn boundary(buf: []u8, idx: size) (bool | utf8::invalid) = {
	if (hasprop(prev, ZWJ) && hasprop(next, EXTENDED_PICTOGRAPHIC)) {
		let it = strings::riter(strings::fromutf8(buf[..idx])?);
		strings::next(&it) as rune;
		for (true) match (strings::next(&it)) {
		case void =>
			break;
		case let r: rune =>
		for (let r => strings::next(&it)) {
			if (!hasprop(r, EXTEND)) {
				if (hasprop(r, EXTENDED_PICTOGRAPHIC)) {
					return false; // GB11


@@ 51,23 48,24 @@ export fn boundary(buf: []u8, idx: size) (bool | utf8::invalid) = {
			};
		};
	};
	if (hasprop(prev, REGIONAL_INDICATOR) && hasprop(next, REGIONAL_INDICATOR)) {
	if (hasprop(prev, REGIONAL_INDICATOR)
			&& hasprop(next, REGIONAL_INDICATOR)) :regional {
		let it = strings::riter(strings::fromutf8(buf[..idx])?);
		strings::next(&it) as rune;
		for (true) match (strings::next(&it)) {
		case void =>
			return false; // GB12
		case let r: rune =>
		for (let r => strings::next(&it)) {
			if (!hasprop(r, REGIONAL_INDICATOR)) {
				return false; // GB13
			};
			match (strings::next(&it)) {
			case void =>
				break;
			case done =>
				yield :regional;
			case let r: rune =>
				if (!hasprop(r, REGIONAL_INDICATOR)) break;
				if (!hasprop(r, REGIONAL_INDICATOR)) {
					yield :regional;
				};
			};
		};
		return false; // GB12
	};
	return true; // GB999
};

M made/actions.ha => made/actions.ha +1 -3
@@ 53,9 53,7 @@ let action_argstr: [_](str, *action_arg) = [

// Pull new lines from other madeline instances into the in-memory history
fn update_hist(s: *state) (void | error) = {
	for (true) match (bufio::read_line(s.ctx.hist.source)?) {
	case io::EOF => break;
	case let buf: []u8 =>
	for (let buf => bufio::read_line(s.ctx.hist.source)?) {
		hist_add(s, strings::fromutf8(buf)?, false);
	};
};

M made/complete.ha => made/complete.ha +6 -4
@@ 27,7 27,7 @@ export fn complete_fs(ctx: *context, buf: []u8, pos: size) (str, [](str, str)) =
	let (first, rest) = strings::cut(buf, "/");
	let first = strings::iter(first);
	match (strings::next(&first)) {
	case void => void;
	case done => void;
	case let r: rune =>
		if (r != '~') yield;
		let user = strings::iterstr(&first);


@@ 71,9 71,11 @@ export fn complete_fs(ctx: *context, buf: []u8, pos: size) (str, [](str, str)) =
	defer fs::finish(it);

	let ret: [](str, str) = [];
	for (true) match (fs::next(it)) {
	case void => break;
	case let d: fs::dirent =>
	for (let d => fs::next(it)) {
		let d = match (d) {
		case let d: fs::dirent => yield d;
		case fs::error => continue;
		};
		if (base == "" && (d.name == "." || d.name == "..")) continue;
		if (strings::hasprefix(d.name, base)) {
			let name = strings::trimprefix(d.name, base);

M made/config.ha => made/config.ha +14 -20
@@ 58,7 58,7 @@ export fn config_free(cfg: config) void = {

fn config_finalize(cfg: *config) (void | error) = for (true) {
	let found = false;
	let done = true;
	let end = true;
	for (let i = 0z; i < len(cfg); i += 1) {
		let m = match (cfg[i].inherit) {
		case void => continue;


@@ 66,7 66,7 @@ fn config_finalize(cfg: *config) (void | error) = for (true) {
		};

		if (cfg[m].inherit is mode) {
			done = false;
			end = false;
			continue;
		};



@@ 85,8 85,8 @@ fn config_finalize(cfg: *config) (void | error) = for (true) {
			append(ib, binding_dup(mb[j]));
		};
	};
	if (!done && !found) return "Inheritance loop in config file": config_error;
	if (done) return;
	if (!end && !found) return "Inheritance loop in config file": config_error;
	if (end) return;
};

export fn config_default(name: str) (config | error) = {


@@ 126,9 126,7 @@ export fn config_handle(cfg: config, in: io::handle) (config | error) = {
	let sc = ini::scan(in);
	defer ini::finish(&sc);

	for (true) match (ini::next(&sc)?) {
	case io::EOF => break;
	case let e: ini::entry =>
	for (let e => ini::next(&sc)?) {
		let b: binding = binding {
			ctx = bctx::ACTION | bctx::MOTION,
			...


@@ 155,16 153,12 @@ export fn config_handle(cfg: config, in: io::handle) (config | error) = {
		};

		let tok = strings::tokenize(e.1, " ");
		for (true) match (parse_event(&tok, &b)?) {
		case void => break;
		case let e: event =>
		for (let e => parse_event(&tok, &b)?) {
			append(b.trigger, e);
		};

		let tok = strings::tokenize(e.2, " ");
		for (true) match (strings::next_token(&tok)) {
		case void => break;
		case let t: str =>
		for (let t => strings::next_token(&tok)) {
			append(b.action, parse_action(t)?);
		};



@@ 194,11 188,9 @@ case =>
	return fmt::asprint("Invalid section title", s, "in config file"): config_error: error;
};

fn parse_event(tok: *strings::tokenizer, b: *binding) (event | void | error) = {
fn parse_event(tok: *strings::tokenizer, b: *binding) (event | done | error) = {
	let m: mods = 0;
	for :loop (true) match (strings::next_token(tok)) {
	case void => return void;
	case let t: str =>
	for :loop (let t => strings::next_token(tok)) {
		switch (t) {
		case "_action" =>
			b.ctx = bctx::ACTION;


@@ 224,11 216,11 @@ fn parse_event(tok: *strings::tokenizer, b: *binding) (event | void | error) = {

		let it = strings::iter(t);
		match :error (strings::next(&it)) {
		case void => void;
		case done => void;
		case let r: rune =>
			if (r == '\\') {
				let r = match (strings::next(&it)) {
				case void => yield :error;
				case done => yield :error;
				case let r: rune =>
					yield r;
				};


@@ 236,7 228,7 @@ fn parse_event(tok: *strings::tokenizer, b: *binding) (event | void | error) = {
				r = strconv::stou32b(strings::iterstr(&it),
					strconv::base::HEX)?: rune;
				return (r, m): event;
			} else if (strings::next(&it) is void) {
			} else if (strings::next(&it) is done) {
				return (r, m): event;
			};
		};


@@ 244,6 236,8 @@ fn parse_event(tok: *strings::tokenizer, b: *binding) (event | void | error) = {
		return fmt::asprintf("Invalid key name '{}' in config file",
			t): config_error: error;
	};

	return done;
};

fn parse_action(s: str) (action | error) = {

M made/hist.ha => made/hist.ha +2 -8
@@ 56,10 56,7 @@ export fn histhandle(file: io::handle) (history | error) = {
		...
	};

	for (true) match (bufio::read_line(file)?) {
	case io::EOF =>
		break;
	case let line: []u8 =>
	for (let line => bufio::read_line(file)?) {
		append(store.hist, strings::fromutf8(line)?);
	};



@@ 96,10 93,7 @@ fn histhandle_mmap(file: io::file) (history | error) = {
	let seen = table { ... };
	defer table_finish(seen);
	let tok = strings::rtokenize(data, "\n");
	for (true) match (strings::next_token(&tok)) {
	case void =>
		break;
	case let line: str =>
	for (let line => strings::next_token(&tok)) {
		if (line == "" || !table_insert(&seen, line)) {
			continue;
		};

M made/input.ha => made/input.ha +1 -1
@@ 176,7 176,7 @@ fn get_csi(s: *state) (event | signal | error) = {
		case void =>
			return (symbol::NOP, 0): event;
		case let ret: str =>
			return ret: done: signal;
			return ret: finished: signal;
		};
	case => return (symbol::NOP, 0): event;
	};

M made/line.ha => made/line.ha +2 -2
@@ 36,7 36,7 @@ export fn line(ctx: *context) (str | void | io::EOF | error) = {
		case let sig: signal =>
			match (sig) {
			case exit => return void;
			case let ret: done => return ret: str;
			case let ret: finished => return ret: str;
			case io::EOF => return io::EOF;
			};
		};


@@ 57,7 57,7 @@ export fn line(ctx: *context) (str | void | io::EOF | error) = {
		case let sig: signal =>
			match (sig) {
			case exit => return void;
			case let ret: done => return ret: str;
			case let ret: finished => return ret: str;
			case io::EOF => return io::EOF;
			};
		};

M made/split.ha => made/split.ha +12 -33
@@ 24,9 24,7 @@ fn default_split(buf: str, idx: size) (str, size, bool) = {
	let last = "";
	let ntok = 0z;
	let it = strings::tokenize(buf, " ");
	for (true) match (strings::next_token(&it)) {
	case void => break;
	case let tok: str =>
	for (let tok => strings::next_token(&it)) {
		last = tok;
		if (ntok == idx) break;
		ntok += 1;


@@ 55,9 53,7 @@ fn sh_split(buf: str, idx: size) (str, size, bool) = {
	let ws = true;

	let it = strings::iter(buf);
	for (true) match (strings::next(&it)) {
	case void => break;
	case let r: rune =>
	for (let r => strings::next(&it)) {
		if (r == ' ' || r == '\t' || r == '\n') {
			if (!ws) {
				if (abs_ntok == idx) break;


@@ 75,7 71,7 @@ fn sh_split(buf: str, idx: size) (str, size, bool) = {
			memio::appendrune(&out, r)!;

			if (r == '>') match (strings::next(&it)) {
			case void => void;
			case done => void;
			case let r: rune =>
				if (r == '>') {
					memio::appendrune(&out, r)!;


@@ 100,19 96,13 @@ fn sh_split(buf: str, idx: size) (str, size, bool) = {
		case '\\' =>
			backslash(&out, &it);
		case '\'' =>
			for (true) match (strings::next(&it)) {
			case void =>
				break;
			case let r: rune =>
			for (let r => strings::next(&it)) {
				if (r == '\'') break;
				if (r == '\\') backslash(&out, &it)
				else memio::appendrune(&out, r)!;
			};
		case '"' =>
			for (true) match (strings::next(&it)) {
			case void =>
				break;
			case let r: rune =>
			for (let r => strings::next(&it)) {
				if (r == '"') break;
				if (r == '\\') backslash(&out, &it)
				else memio::appendrune(&out, r)!;


@@ 126,7 116,7 @@ fn sh_split(buf: str, idx: size) (str, size, bool) = {

fn backslash(out: io::handle, in: *strings::iterator) void = {
	let r = match (strings::next(in)) {
	case void =>
	case done =>
		yield '\\';
	case let r: rune =>
		yield r;


@@ 144,44 134,33 @@ fn sh_escape(ctx: str, buf: str) (str, str, bool) = {
	let ectx = escapectx::NONE;
	let need_esc = false;
	let it = strings::iter(ctx);
	for (true) match (strings::next(&it)) {
	case void =>
		break;
	case let r: rune =>
	for (let r => strings::next(&it)) {
		switch (r) {
		case ' ' =>
			need_esc = false;
		case '\\' =>
			strings::next(&it);
		case '\'' =>
			for (true) match (strings::next(&it)) {
			case void =>
				ectx = escapectx::SINGLE;
				break;
			case let r: rune =>
			for (let r => strings::next(&it)) {
				need_esc ||= needsesc(r);
				if (r == '\'') break;
				if (r == '\\') strings::next(&it);
			};
			ectx = escapectx::SINGLE;
		case '"' =>
			for (true) match (strings::next(&it)) {
			case void =>
				ectx = escapectx::DOUBLE;
				break;
			case let r: rune =>
			for (let r => strings::next(&it)) {
				need_esc ||= needsesc(r);
				if (r == '"') break;
				if (r == '\\') strings::next(&it);
			};
			ectx = escapectx::DOUBLE;
		case => void;
		};
	};

	let out = memio::dynamic();
	it = strings::iter(buf);
	for (true) match (strings::next(&it)) {
	case void => break;
	case let r: rune =>
	for (let r => strings::next(&it)) {
		need_esc ||= needsesc(r);
		let esc = switch (ectx) {
		case escapectx::NONE =>

M made/term.ha => made/term.ha +1 -4
@@ 21,10 21,7 @@ fn draw(s: *state) (void | error) = {

fn dumpstr(out: io::handle, s: str) (void | io::error) = {
	let it = strings::iter(s);
	for (true) match (strings::next(&it)) {
	case void =>
		break;
	case let r: rune =>
	for (let r => strings::next(&it)) {
		if (!ascii::iscntrl(r) || r == '\n') {
			fmt::fprint(out, r)?;
			continue;

M made/types.ha => made/types.ha +2 -2
@@ 26,9 26,9 @@ export type mode = enum {

export type exit = void;

export type done = str;
export type finished = str;

export type signal = (exit | done | io::EOF);
export type signal = (exit | finished | io::EOF);

export type state = struct {
	ctx: *context,

M made/util.ha => made/util.ha +2 -2
@@ 44,14 44,14 @@ fn prefix(strs: [](str, str)) str = {
	let ret = memio::dynamic();
	for :loop (len(its) > 0) {
		let r = match (strings::next(&its[0])) {
		case void =>
		case done =>
			break;
		case let r: rune =>
			yield r;
		};
		for (let i = 1z; i < len(its); i += 1) {
			match (strings::next(&its[i])) {
			case void =>
			case done =>
				break :loop;
			case let r2: rune =>
				if (r != r2) break :loop;