Programming Language

Nocter

A self-contained systems language built around simplicity, encapsulation, and foolproof design.

frequency.nct

use std/cli.Application
use std/io.{BlockingFile, BlockingReader}
use std/io
use std/path.Utf8Path
use std/string.String

see ./index.nct

blocking func run(): i32! {
    var application = Application.new("line-frequency", "Count matching lines in one file.")?
    application.add_positional("PATH", true, "UTF-8 file to read.")?
    application.add_positional("NEEDLE", true, "Exact line to count.")?
    let arguments = application.parse_process() catch failure {
        if !failure.has_code("std.cli.missing_positional")
        && !failure.has_code("std.cli.unexpected_positional") {
            return move failure
        }
        let usage = application.usage()
        io.print(&usage)?
        io.print("\n")?
        return 2
    }
    let requested = arguments.positional("PATH") otherwise { return 2 }
    let requested_needle = arguments.positional("NEEDLE") otherwise { return 2 }
    let path = Utf8Path.new(requested)?
    var file = BlockingFile.open(&path)?
    let text = file.read_to_string_blocking()?

    var frequencies: Map<String, usize> = Map.empty()
    var unique: Set<String> = Set.empty()
    var line_count: usize = 0
    for line in text.lines() {
        line_count += 1
        let key = String.copy(line)
        if frequencies.contains_key(&key) {
            frequencies[&key] += 1
        } else {
            let _ = frequencies.insert(move key, 1)
        }
        let _ = unique.insert(String.copy(line))
    }

    let needle = String.copy(requested_needle)
    let matching = if frequencies.contains_key(&needle) {
        frequencies[&needle]
    } else {
        0
    }
    let lines_text = line_count.to_string()
    let unique_text = unique.len().to_string()
    let matching_text = matching.to_string()
    let output = String.concat(
        "lines: ",
        &lines_text,
        "\nunique: ",
        &unique_text,
        "\nmatching: ",
        &matching_text,
        "\n",
    )
    io.print(&output)?
    return 0
}