shelly-shell 0.5.2

A Rust based Unix style shell with a typed and structured language syntax.
# Type names are read-only String data, including collection metadata and reflection.
let $fixture = $args[0]
fn type_name_case($source: String, $stdout: String, $diagnostic: String)
{
    let $reply = run_process [`$shelly, "-m", "-c", $source] [
        "cwd": $fixture, "env": ["PATH": "/usr/bin:/bin", "SHELLY_STD_PATH": ""],
        "stdout_file": "${fixture}/out", "stderr_file": "${fixture}/err",
        "timeout_ms": 3000]
    let $out: String
    let $err: String
    "${fixture}/out" -> $out
    "${fixture}/err" -> $err
    let $status = if $diagnostic == "" { 0 } else { 1 }
    require (($reply["exit_code"] == $status) && ($reply["signal"] == ()) &&
        ($reply["error"] == ()) && (!$reply["timed_out"]) && ($out == $stdout)) "${source}: ${out} ${err}"
    if $diagnostic == "" { require ($err == "") $source }
    else { require ($err.contains $diagnostic) "${source}: ${err}" }
}
type_name_case "echo (Integer).name (Float).name (String).name (Type).name (any).name" "Integer Float String Type any\n" ""
type_name_case "echo (Integer).type.name [(Integer)][0].name [Integer].value_type.name [1].value_type.name" "Type Integer Integer Integer\n" ""
type_name_case "let \$t: Type = Integer; let \$name: String = \$t.name; echo \$name \$name.type" "Integer String\n" ""
type_name_case "fn name(\$t: Type): String { \$t.name }; echo (name (Integer)); fn dynamic(\$t: any): String { \$t.name }; echo (dynamic (Float))" "Integer\nFloat\n" ""
type_name_case "type Count = Integer; type Callback = fn(): String; struct Item { name: String }; enum Color { Red }; echo (Count).name (Callback).name (Item).name (Color).name; echo Item(name: \"field\").name" "Count Callback Item Color\nfield\n" ""
type_name_case "let \$a: [Integer] = []; let \$h: [String: Float] = [:]; echo \$a.value_type.name \$h.key_type.name \$h.value_type.name" "Integer String Float\n" ""
type_name_case "let \$a: [Integer] = []; let \$p = \$a.properties; echo \$p[\"value_type\"].name; let \$p = (Integer).properties; echo \$p[\"name\"] \$p[\"name\"].type" "Integer\nInteger String\n" ""
type_name_case "let \$t = Integer; \$t.name = \"Other\"" "" "read-only"
type_name_case "let \$types = [(Integer)]; \$types[0].name = \"Other\"" "" "read-only"
type_name_case "fn Type::name(): String { \"Other\" }" "" "conflicts with a data member"
type_name_case "let \$bad: Integer = (Integer).name" "" "Expected Integer, got String"
type_name_case "fn bad(\$t: Type): Integer { \$t.name }" "" "Expected Integer, got String"
type_name_case "echo (1).name" "" "Cannot access"
type_name_case "let \$p = (Integer).properties; \$p[\"name\"] = \"Other\"; echo (Integer).name" "Integer\n" ""