word count
zo / tasks
program
load core::cli; struct Counts { lines: bool, words: bool, size: bool, } fun count_words(text: str) -> int { mut count: int = 0; imu lines: []str = text.lines(); for line := lines { imu words: []str = line.trim().split(" "); for word := words { if word != "" { count += 1; } } } count } fun report(text: str, label: str, want: Counts) -> str { imu line_count: int = text.lines().len(); imu word_count: int = count_words(text); imu byte_count: int = text.len; mut out: str = ""; if want.lines { out = out ++ line_count.to_str() ++ "\t"; } if want.words { out = out ++ word_count.to_str() ++ "\t"; } if want.size { out = out ++ byte_count.to_str() ++ "\t"; } out ++ label } fun main() { imu cli: Cli = Cli::new("wc", "count lines, words, and bytes") .flag("l", "lines", "count lines") .flag("w", "words", "count words") .flag("c", "bytes", "count bytes"); imu parsed: Parsed = cli.parse(args()); imu files: []str = parsed.positionals(); imu has_lines: bool = parsed.has("lines"); imu has_words: bool = parsed.has("words"); imu has_bytes: bool = parsed.has("bytes"); imu all: bool = !has_lines && !has_words && !has_bytes; imu want: Counts = Counts { lines = all || has_lines, words = all || has_words, size = all || has_bytes, }; -- No file named — read stdin, the way `wc` does for a pipe. if files.len() == 0 { match read() { Result::Pass(text) => showln(report(text, "", want)), Result::Fail(_) => eshowln("wc: stdin: cannot read"), } } else { for path := files { match read_file(path) { Result::Pass(text) => showln(report(text, path, want)), Result::Fail(_) => eshowln("wc: {path}: cannot read"), } } } }
output
2 5 23