shelly-shell 0.5.2

A Rust based Unix style shell with a typed and structured language syntax.
# Receiver-dependent method contracts specialize from collection metadata.
let $fixture = $args[0]
fn receiver_annotation_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}" }
}
receiver_annotation_case "fn Array::push(\$value: \$self.value_type) { \$self = [\$value, \$self...] }; let \$a: [Integer] = []; \$a.push 2; \$a.push 1; echo \$a..." "1 2\n" ""
receiver_annotation_case "fn Array::push(\$value: \$self.value_type) { \$self = [\$value, \$self...] }; fn Array::push_many(\$values: \$self.value_type...) { \$self = [\$values.reverse..., \$self...] }; fn Array::pop(): \$self.value_type | () { if \$self.count == 0 { return () }; let \$item = \$self[0]; \$self = \$self[1..]; \$item }; let \$a: [Float] = []; \$a.push 1; \$a.push_many 2 3; echo \$a...; echo \$a.pop \$a.pop \$a.pop \$a.pop" "3.0 2.0 1.0\n3.0 2.0 1.0 ()\n" ""
receiver_annotation_case "fn Array::push_many(\$values: \$self.value_type...) { \$self = [\$values.reverse..., \$self...] }; let \$a: [Number] = []; \$a.push_many 1 2.5; echo \$a..." "2.5 1\n" ""
receiver_annotation_case "fn Array::push_many(\$values: \$self.value_type...) { \$self = [\$values.reverse..., \$self...] }; let \$a: [Integer | String] = []; \$a.push_many 1 \"s\"; echo \$a..." "s 1\n" ""
receiver_annotation_case "fn Array::push_many(\$values: \$self.value_type...) { \$self = [\$values.reverse..., \$self...] }; let \$a: [any] = [1]; \$a.push_many \"s\" true; echo \$a..." "true s 1\n" ""
receiver_annotation_case "fn Array::push(\$value: \$self.value_type) { \$self = [\$value, \$self...] }; let \$a = []; \$a.push \"s\"; echo \$a... \$a.value_type" "s String\n" ""
receiver_annotation_case "fn Array::push(\$value: \$self.value_type) { \$self = [\$value, \$self...] }; let \$a = [1,\"s\"]; \$a.push true; echo \$a..." "true 1 s\n" ""
receiver_annotation_case "fn Array::push(\$value: \$self.value_type) { \$self = [\$value, \$self...] }; type Count = Integer; let \$a: [Count] = []; \$a.push 7; echo \$a.count (\$a[0].type == Count)" "1 true\n" ""
receiver_annotation_case "fn Array::push(\$value: \$self.value_type) { \$self = [\$value, \$self...] }; fn Array::pop(): \$self.value_type | () { if \$self.count == 0 { return () }; let \$item = \$self[0]; \$self = \$self[1..]; \$item }; type Items = [Float]; let \$a: Items = []; \$a.push 1; echo \$a.pop \$a.value_type" "1.0 Float\n" ""
receiver_annotation_case "fn Array::push(\$value: \$self.value_type) { \$self = [\$value, \$self...] }; let \$a: [[Float]] = []; \$a.push [1,2]; echo \$a[0]... \$a[0].value_type" "1.0 2.0 Float\n" ""
receiver_annotation_case "fn Array::combine(\$other: [\$self.value_type]): [\$self.value_type] { [\$self..., \$other...] }; let \$a: [Float] = [1]; let \$b: [Float] = \$a.combine [2,3]; echo \$a...; echo \$b..." "1.0\n1.0 2.0 3.0\n" ""
receiver_annotation_case "fn Array::pop(): \$self.value_type | () { if \$self.count == 0 { return () }; let \$item = \$self[0]; \$self = \$self[1..]; \$item }; let \$a = [1]; echo \$a.pop \$a.value_type; echo \$a.pop" "1 any\n()\n" ""
receiver_annotation_case "fn Array::push(\$value: \$self.value_type) { \$self = [\$value, \$self...] }; struct Box { items: [Float] }; let \$b = Box(items: []); \$b.items.push 1; echo \$b.items..." "1.0\n" ""
receiver_annotation_case "fn Array::push(\$value: \$self.value_type) { \$self = [\$value, \$self...] }; let \$a: [[Float]] = [[]]; \$a[0].push 2; echo \$a[0]..." "2.0\n" ""
receiver_annotation_case "fn Array::push(\$value: \$self.value_type) { \$self = [\$value, \$self...] }; let \$a: [String: [Float]] = [\"x\":[]]; \$a[\"x\"].push 2; echo \$a[\"x\"]..." "2.0\n" ""
receiver_annotation_case "fn Array::push_many(\$values: \$self.value_type...) { \$self = [\$values.reverse..., \$self...] }; let \$a: [Float] = []; let \$values = [1,2]; \$a.push_many \$values...; echo \$a..." "2.0 1.0\n" ""
receiver_annotation_case "fn Array::named(\$label: String, \$items: \$self.value_type...) { \$self = [\$items..., \$self...] }; let \$a: [Float] = []; \$a.named \"label\" 1 2; echo \$a..." "1.0 2.0\n" ""
receiver_annotation_case "fn HashMap::put(\$key: \$self.key_type, \$value: \$self.value_type) { \$self[\$key] = \$value }; fn HashMap::get(\$key: \$self.key_type): \$self.value_type | () { \$self[\$key] }; let \$h: [String: Float] = [:]; \$h.put \"a\" 1; echo (\$h.get \"a\") (\$h.get \"missing\") \$h.key_type \$h.value_type" "1.0 () String Float\n" ""
receiver_annotation_case "fn HashMap::put(\$key: \$self.key_type, \$value: \$self.value_type) { \$self[\$key] = \$value }; let \$h = [\"x\":1]; \$h.put \"y\" 2; echo \$h[\"y\"]" "2\n" ""
receiver_annotation_case "fn HashMap::put(\$key: \$self.key_type, \$value: \$self.value_type) { \$self[\$key] = \$value }; type Key = String; type Count = Integer; let \$h: [Key: Count] = [:]; \$h.put \"x\" 3; echo (\$h[Key(\"x\")].type == Count)" "true\n" ""
receiver_annotation_case "fn HashMap::put(\$key: \$self.key_type, \$value: \$self.value_type) { \$self[\$key] = \$value }; type Table = [String: Float]; let \$h: Table = [:]; \$h.put \"x\" 3; echo \$h[\"x\"]" "3.0\n" ""
receiver_annotation_case "fn HashMap::put(\$key: \$self.key_type, \$value: \$self.value_type) { \$self[\$key] = \$value }; let \$h: [String: [Float]] = [:]; \$h.put \"x\" [1,2]; echo \$h[\"x\"]..." "1.0 2.0\n" ""
receiver_annotation_case "fn HashMap::copy(\$other: [\$self.key_type: \$self.value_type]): [\$self.key_type: \$self.value_type] { \$other }; let \$h: [String: Float] = [:]; let \$copy = \$h.copy [\"x\":1]; echo \$copy[\"x\"]" "1.0\n" ""
receiver_annotation_case "fn HashMap::pair(\$key: \$self.key_type, \$value: \$self.value_type): [\$self.key_type, \$self.value_type] { [\$key,\$value] }; let \$h: [String: Float] = [:]; echo (\$h.pair \"x\" 1)..." "x 1.0\n" ""
receiver_annotation_case "fn Array::accept(\$value: \$self.value_type): \$self.value_type { \$value }; let \$a: [Integer] = []; let \$f: fn(Integer): Integer = `\$a.accept; echo (\$f 2)" "2\n" ""
receiver_annotation_case "fn Array::accept(\$value: \$self.value_type): \$self.value_type { \$value }; let \$a: [Float] = []; let \$f: fn(Integer): Float = `\$a.accept; echo (\$f 2)" "2.0\n" ""
receiver_annotation_case "fn Array::accept(\$value: \$self.value_type): \$self.value_type { \$value }; let \$a = [1]; let \$f = `\$a.accept; echo (\$f 2); \$a = [\"s\"]; echo (\$f \"x\")" "2\nx\n" ""
receiver_annotation_case "fn Array::apply(\$f: fn(\$self.value_type): \$self.value_type): \$self.value_type { \$f \$self[0] }; let \$a: [Float] = [1]; echo (\$a.apply fn(\$x: Float): Float { \$x + 1 })" "2.0\n" ""
receiver_annotation_case "fn Array::push(\$value: \$self.value_type) { \$self = [\$value, \$self...] }; let \$a: [Integer] = []; echo \"unreachable\"; \$a.push \"wrong\"" "" "Compile error"
receiver_annotation_case "fn Array::push_many(\$values: \$self.value_type...) { \$self = [\$values.reverse..., \$self...] }; let \$a: [Integer] = []; echo \"unreachable\"; \$a.push_many 1 \"wrong\"" "" "Compile error"
receiver_annotation_case "fn Array::push_many(\$values: \$self.value_type...) { \$self = [\$values.reverse..., \$self...] }; let \$a: [Integer] = []; let \$values: [String] = [\"wrong\"]; echo \"unreachable\"; \$a.push_many \$values..." "" "Compile error"
receiver_annotation_case "fn Array::combine(\$other: [\$self.value_type]): [\$self.value_type] { [\$self..., \$other...] }; let \$a: [Integer] = []; echo \"unreachable\"; \$a.combine [\"wrong\"]" "" "Compile error"
receiver_annotation_case "fn HashMap::put(\$key: \$self.key_type, \$value: \$self.value_type) { \$self[\$key] = \$value }; let \$h: [String: Integer] = [:]; echo \"unreachable\"; \$h.put 1 2" "" "Compile error"
receiver_annotation_case "fn HashMap::put(\$key: \$self.key_type, \$value: \$self.value_type) { \$self[\$key] = \$value }; let \$h: [String: Integer] = [:]; echo \"unreachable\"; \$h.put \"x\" \"wrong\"" "" "Compile error"
receiver_annotation_case "fn HashMap::get(\$key: \$self.key_type): \$self.value_type | () { \$self[\$key] }; let \$h: [String: Integer] = [:]; echo \"unreachable\"; \$h.get 1" "" "Compile error"
receiver_annotation_case "fn Array::accept(\$value: \$self.value_type): \$self.value_type { \$value }; let \$a: [Integer] = []; echo \"unreachable\"; let \$bad: String = \$a.accept 1" "" "Compile error"
receiver_annotation_case "fn Array::pop(): \$self.value_type | () { if \$self.count == 0 { return () }; let \$item = \$self[0]; \$self = \$self[1..]; \$item }; let \$a: [Integer] = []; echo \"unreachable\"; let \$bad: String = \$a.pop" "" "Compile error"
receiver_annotation_case "fn Array::push(\$value: \$self.value_type) { \$self = [\$value, \$self...] }; fn dynamic(\$a: Array, \$v: any) { \$a.push \$v }; let \$a = [1]; echo \"started\"; dynamic \$a \"wrong\"" "started\n" "Expected Integer, got String"
receiver_annotation_case "fn HashMap::put(\$key: \$self.key_type, \$value: \$self.value_type) { \$self[\$key] = \$value }; fn dynamic(\$h: HashMap, \$k: any, \$v: any) { \$h.put \$k \$v }; echo \"started\"; dynamic [\"x\":1] \"y\" \"wrong\"" "started\n" "Expected Integer, got String"
receiver_annotation_case "fn Array::accept(\$value: \$self.value_type): \$self.value_type { \$value }; let \$a = [1]; let \$f = `\$a.accept; echo \"started\"; \$f \"wrong\"" "started\n" "Expected Integer, got String"
receiver_annotation_case "fn Array::bad(): \$self.value_type { \$self = []; return \"wrong\" }; let \$a = [1]; echo \"started\"; echo \$a.bad" "started\n" "Type error for return value"
receiver_annotation_case "fn Array::accept(\$value: \$self.value_type): \$self.value_type { \$value }; let \$a: [Integer] = []; let \$f: fn(String): String = `\$a.accept" "" "incompatible with prototype"
receiver_annotation_case "fn HashMap::echo_value(\$v: \$self.value_type): \$self.key_type { \$v }; let \$h: [String: Integer] = [:]; echo \"started\"; echo (\$h.echo_value 1)" "started\n" "Type error for return value"
receiver_annotation_case "fn Array::invalid(\$v: \$self.key_type) {}" "" "compatible collection method receiver"
receiver_annotation_case "fn String::invalid(\$v: \$self.value_type) {}" "" "compatible collection method receiver"
receiver_annotation_case "fn invalid(\$v: \$self.value_type) {}" "" "compatible collection method receiver"
receiver_annotation_case "let \$invalid: \$self.value_type = 1" "" "compatible collection method receiver"
receiver_annotation_case "type Invalid = \$self.value_type" "" "compatible collection method receiver"
receiver_annotation_case "struct Invalid { value: \$self.value_type }" "" "compatible collection method receiver"
receiver_annotation_case "fn Array::from_string(\$v: \$self.value_type): Array { [] }" "" "compatible collection method receiver"
receiver_annotation_case "fn Array::invalid(\$v: \$other.value_type) {}" "" "Expected \$self.key_type or \$self.value_type"
receiver_annotation_case "fn Array::invalid(\$v: \$self.count) {}" "" "Expected \$self.key_type or \$self.value_type"
receiver_annotation_case "fn Array::push(\$v: \$self.value_type) { \$self = [\$v,\$self...] }; let \$a = [1]; \$a.push \"wrong\"" "" "Compile error"
receiver_annotation_case "fn Array::push(\$v: \$self.value_type) { \$self = [\$v,\$self...] }; let \$a = [1]; fn change(): String { \$a = [\"s\"]; return \"x\" }; \$a.push (change); echo \$a..." "x s\n" ""
receiver_annotation_case "type Items = [Integer]; fn Items::bad(\$v: \$self.value_type): \$self.value_type { return \"wrong\" }" "" "Compile error"
receiver_annotation_case "type Table = [String: Integer]; fn Table::put(\$k: \$self.key_type, \$v: \$self.value_type) { \$self[\$k] = \$v }; let \$h: Table = [:]; \$h.put \"x\" 1; echo \$h[\"x\"]" "1\n" ""
receiver_annotation_case "fn Array::accept(\$v: \$self.value_type): \$self.value_type { \$v }; let \$a: [Integer, Integer] = [1,2]; echo (\$a.accept 1)" "1\n" ""
receiver_annotation_case "fn Array::accept(\$v: \$self.value_type): \$self.value_type { \$v }; let \$a: [Integer, String] = [1,\"s\"]; echo (\$a.accept true)" "true\n" ""
receiver_annotation_case "fn HashMap::keys(\$keys: \$self.key_type...): [\$self.key_type] { \$keys }; let \$h: [String: Integer] = [:]; echo (\$h.keys \"a\" \"b\")..." "a b\n" ""
receiver_annotation_case "fn HashMap::keys(\$keys: \$self.key_type...): [\$self.key_type] { \$keys }; let \$h: [String: Integer] = [:]; echo \"unreachable\"; \$h.keys \"a\" 1" "" "Compile error"
printf "%s" "pub fn Array::push(\$v: \$self.value_type) { \$self = [\$v,\$self...] }; pub fn HashMap::put(\$k: \$self.key_type, \$v: \$self.value_type) { \$self[\$k] = \$v }; pub fn Array::head(): \$self.value_type { \$self[0] }; " -> "${fixture}/annotations.shy"
receiver_annotation_case "import annotations; let \$a: [Float] = []; \$a.push 1; let \$h: [String: Float] = [:]; \$h.put \"x\" 2; echo \$a... \$h[\"x\"]" "1.0 2.0\n" ""
receiver_annotation_case "import annotations; let \$a: [Integer] = []; echo \"unreachable\"; \$a.push \"wrong\"" "" "Compile error"
receiver_annotation_case "import annotations; let \$h: [String: Integer] = [:]; echo \"unreachable\"; \$h.put 1 2" "" "Compile error"
receiver_annotation_case "import annotations; let \$a: [Integer] = [1]; echo \"unreachable\"; let \$v: String = \$a.head" "" "Compile error"
receiver_annotation_case "fn Array::accept(\$v: \$self.value_type): \$self.value_type { \$v }; let \$a: [Integer] = []; let \$p = \$a.properties; let \$f: fn(Integer): Integer = \$p[\"accept\"]; echo (\$f 3)" "3\n" ""
receiver_annotation_case "fn Array::apply(\$f: fn(\$self.value_type): \$self.value_type): \$self.value_type { \$f \$self[0] }; let \$a: [Integer] = [1]; echo \"unreachable\"; \$a.apply fn(\$x: String): String { \$x }" "" "Compile error"
receiver_annotation_case "fn Array::accept(\$v: optional \$self.value_type): optional \$self.value_type { \$v }; let \$a: [Float] = []; echo (\$a.accept) (\$a.accept 1)" "() 1.0\n" ""
receiver_annotation_case "fn Array::accept(\$v: \$self.value_type | String): \$self.value_type | String { \$v }; let \$a: [Float] = []; echo (\$a.accept \"s\") (\$a.accept 1)" "s 1.0\n" ""
receiver_annotation_case "fn Array::push_many(\$v: \$self.value_type...) { \$self = [\$v...,\$self...] }; let \$a: [Integer] = []; \$a.push_many; echo \$a.count" "0\n" ""
receiver_annotation_case "fn Array::accept(\$v: \$self.value_type): \$self.value_type { \$v }; let \$a: [Integer | String] = []; echo (\$a.accept true)" "" "Compile error"
receiver_annotation_case "fn HashMap::put(\$k: \$self.key_type, \$v: \$self.value_type) { \$self[\$k] = \$v }; let \$h: [Float: Float] = [:]; \$h.put 1 2; echo \$h[1]" "2.0\n" ""
receiver_annotation_case "type Items = [Integer]; fn Items::accept(\$v: \$self.value_type): \$self.value_type { \$v }; let \$a: Items = []; echo \"unreachable\"; \$a.accept \"wrong\"" "" "Compile error"
receiver_annotation_case "fn Array::push_many(\$v: \$self.value_type...) { \$self = [\$v...,\$self...] }; let \$a: [Integer] = []; let \$r = 1..4; \$a.push_many \$r...; echo \$a..." "1 2 3\n" ""
receiver_annotation_case "fn Array::push_many(\$v: \$self.value_type...) { \$self = [\$v...,\$self...] }; let \$a: [Float] = []; \$a.push_many (1..4)...; echo \$a..." "1.0 2.0 3.0\n" ""
receiver_annotation_case "fn Array::push_many(\$v: \$self.value_type...) { \$self = [\$v...,\$self...] }; let \$a: [Integer] = []; let \$v: [Number] = [1,2.5]; echo \"unreachable\"; \$a.push_many \$v..." "" "Compile error"
receiver_annotation_case "fn Array::push_many(\$v: \$self.value_type...) { \$self = [\$v...,\$self...] }; let \$a: [Float] = []; let \$v: [Number] = [1,2.5]; \$a.push_many \$v...; echo \$a..." "1.0 2.5\n" ""