shelly-shell 0.5.2

A Rust based Unix style shell with a typed and structured language syntax.
check_repl ["id": "TYPE_GUARDS", "name": "Type identity, narrowing, and recovery across submissions", "steps": [
    ["let \$foo: any = 1024", "quiet", ""],
    ["echo (\$foo.type == Integer) \$foo.type", "output", "true Integer"],
    ["fn show(\$foo: any): String { match \$foo.type { Integer => { let \$n: Integer = \$foo; \"int\" } Float => { let \$n: Float = \$foo; \"float\" } _ => { \"other\" } } }", "quiet", ""],
    ["echo (show \$foo) (show 1.0) (show \"s\")", "output", "int float other"],
    ["fn wrong(\$foo: any) { if \$foo.type == Integer && \$foo == 1024 { let \$s: String = \$foo } }", "error", "Expected String, got Integer"],
    ["echo (show \$foo)", "output", "int"],
    ["type Count = Integer; let \$count: Count = 7; let \$old_type = \$count.type", "quiet", ""],
    ["echo (\$count.type == Count) (\$count.type == Integer) (\$old_type.type == Type)", "output", "true false true"],
    ["type Count = Float; let \$new: Count = 7", "quiet", ""],
    ["echo (\$count.type == Count) (\$new.type == Count) (\$old_type == \$count.type)", "output", "false true true"],
    ["let \$old = fn (\$v: any) { \$v.type == Count }", "quiet", ""],
    ["type Count = String", "quiet", ""],
    ["echo (\$old \$new) (\$new.type == Count)", "output", "true false"],
    ["let \$t: Type = Integer; let \$types: [Type] = [Integer, Float]", "quiet", ""],
    ["echo (\$t == \$foo.type) \$types[0]", "output", "true Integer"],
    ["\$t = \"Integer\"", "error", "Expected Type"],
    ["echo (\$t == \$foo.type)", "output", "true"],
    ["\$foo.type = String", "error", "read-only"],
    ["echo (\$foo.type == Integer)", "output", "true"],
    ["\$foo = \"text\"", "quiet", ""],
    ["echo (show \$foo) (\$foo.type == String)", "output", "other true"],
    ["fn f(\$v: Integer | String): String { if \$v.type == Integer { \"int\" } else { \$v } }", "quiet", ""],
    ["echo (f 7) (f \"text\")", "output", "int text"],
    ["fn bad(\$v: Integer | String): Integer { match \$v.type { Integer => { 0 } _ => { \$v } } }", "error", "Expected Integer, got String"],
    ["echo (f \"ok\")", "output", "ok"],
    ["struct Item { n: Integer }; let \$item: any = Item(n: 1)", "quiet", ""],
    ["fn bad(\$v: any) { if \$v.type == Item && \$v.absent == 1 { () } }", "error", "Cannot access field 'absent' on Item"],
    ["if \$item.type == Item { echo \$item.n }", "output", "1"],
    ["type Count = Integer; fn broken(\$v: any) { if \$v.type == Integer { let \$s: String = \$v } }", "error", "Expected String, got Integer"],
    ["let \$c: Count = \"still string\"", "quiet", ""],
    ["echo String(\$c)", "output", "still string"],
    ["let \$keys: [Type: String] = [Integer: \"int\", Float: \"float\"]", "quiet", ""],
    ["echo \$keys[(7).type] \$keys[(1.0).type]", "output", "int float"],
    ["let \$missing: Type", "error", "requires an initializer"],
    ["echo recovered", "output", "recovered"],
    ["let \$foo: any = 7; let \$read = fn () { if \$foo.type == Integer { let \$n: Integer = \$foo; \$n } else { 0 } }", "quiet", ""],
    ["echo (\$read)", "output", "7"],
    ["\$foo = \"s\"", "quiet", ""],
    ["echo (\$read)", "output", "0"],
    ["struct A { a: Integer }; struct B { b: String }; let \$state: any = A(a: 1); fn change(): Boolean { \$state = B(b: \"new\"); true }", "quiet", ""],
    ["if \$state.type == A && (change) { echo \$state.b }", "output", "new"],
], "exit": 0]