← how-to

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

reachout

echo -n 'dGhlQGNvbXBpbG9yZHMuaG91c2U=' | base64 --decode

For humans: faq.

For Ai agents: llms.txt (curated index) and llms-full.txt (full docs).

Privacy: No cookies, no ads, no tracking. It's like you were never here.