mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-26 13:29:12 +00:00
Update to use new square brace formatting
This commit is contained in:
parent
0fae5b0bac
commit
4eec34becf
120 changed files with 1149 additions and 1155 deletions
|
@ -3,7 +3,7 @@ platform "test-platform"
|
||||||
exposes []
|
exposes []
|
||||||
packages {}
|
packages {}
|
||||||
imports []
|
imports []
|
||||||
provides [ mainForHost ]
|
provides [mainForHost]
|
||||||
|
|
||||||
MyRcd : { a : U64, b : U128 }
|
MyRcd : { a : U64, b : U128 }
|
||||||
|
|
||||||
|
|
2
bindgen/tests/fixtures/basic-record/app.roc
vendored
2
bindgen/tests/fixtures/basic-record/app.roc
vendored
|
@ -1,6 +1,6 @@
|
||||||
app "app"
|
app "app"
|
||||||
packages { pf: "." }
|
packages { pf: "." }
|
||||||
imports []
|
imports []
|
||||||
provides [ main ] to pf
|
provides [main] to pf
|
||||||
|
|
||||||
main = { a: 1995, b: 42 }
|
main = { a: 1995, b: 42 }
|
||||||
|
|
|
@ -3,9 +3,9 @@ platform "test-platform"
|
||||||
exposes []
|
exposes []
|
||||||
packages {}
|
packages {}
|
||||||
imports []
|
imports []
|
||||||
provides [ mainForHost ]
|
provides [mainForHost]
|
||||||
|
|
||||||
MyEnum : [ Foo, Bar, Baz ]
|
MyEnum : [Foo, Bar, Baz]
|
||||||
|
|
||||||
mainForHost : MyEnum
|
mainForHost : MyEnum
|
||||||
mainForHost = main
|
mainForHost = main
|
||||||
|
|
2
bindgen/tests/fixtures/enumeration/app.roc
vendored
2
bindgen/tests/fixtures/enumeration/app.roc
vendored
|
@ -1,6 +1,6 @@
|
||||||
app "app"
|
app "app"
|
||||||
packages { pf: "." }
|
packages { pf: "." }
|
||||||
imports []
|
imports []
|
||||||
provides [ main ] to pf
|
provides [main] to pf
|
||||||
|
|
||||||
main = Foo
|
main = Foo
|
||||||
|
|
|
@ -3,7 +3,7 @@ platform "test-platform"
|
||||||
exposes []
|
exposes []
|
||||||
packages {}
|
packages {}
|
||||||
imports []
|
imports []
|
||||||
provides [ mainForHost ]
|
provides [mainForHost]
|
||||||
|
|
||||||
Outer : { x : Inner, y : Str, z : List U8 }
|
Outer : { x : Inner, y : Str, z : List U8 }
|
||||||
|
|
||||||
|
|
4
bindgen/tests/fixtures/nested-record/app.roc
vendored
4
bindgen/tests/fixtures/nested-record/app.roc
vendored
|
@ -1,6 +1,6 @@
|
||||||
app "app"
|
app "app"
|
||||||
packages { pf: "." }
|
packages { pf: "." }
|
||||||
imports []
|
imports []
|
||||||
provides [ main ] to pf
|
provides [main] to pf
|
||||||
|
|
||||||
main = { x: { a: 5, b: 24 }, y: "foo", z: [ 1, 2 ] }
|
main = { x: { a: 5, b: 24 }, y: "foo", z: [1, 2] }
|
||||||
|
|
|
@ -3,7 +3,7 @@ platform "test-platform"
|
||||||
exposes []
|
exposes []
|
||||||
packages {}
|
packages {}
|
||||||
imports []
|
imports []
|
||||||
provides [ mainForHost ]
|
provides [mainForHost]
|
||||||
|
|
||||||
# This case is important to test because the U128
|
# This case is important to test because the U128
|
||||||
# gives the whole struct an alignment of 16, but the
|
# gives the whole struct an alignment of 16, but the
|
||||||
|
@ -11,7 +11,7 @@ platform "test-platform"
|
||||||
# a size of 32 (due to alignment, rounded up from Str's 24),
|
# a size of 32 (due to alignment, rounded up from Str's 24),
|
||||||
# and the discriminant is stored in the 8+ bytes of padding
|
# and the discriminant is stored in the 8+ bytes of padding
|
||||||
# that all variants have.
|
# that all variants have.
|
||||||
NonRecursive : [ Foo Str, Bar U128, Blah I32, Baz ]
|
NonRecursive : [Foo Str, Bar U128, Blah I32, Baz]
|
||||||
|
|
||||||
mainForHost : NonRecursive
|
mainForHost : NonRecursive
|
||||||
mainForHost = main
|
mainForHost = main
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
app "app"
|
app "app"
|
||||||
packages { pf: "." }
|
packages { pf: "." }
|
||||||
imports []
|
imports []
|
||||||
provides [ main ] to pf
|
provides [main] to pf
|
||||||
|
|
||||||
main = Foo "This is a test"
|
main = Foo "This is a test"
|
||||||
|
|
|
@ -3,13 +3,13 @@ platform "test-platform"
|
||||||
exposes []
|
exposes []
|
||||||
packages {}
|
packages {}
|
||||||
imports []
|
imports []
|
||||||
provides [ mainForHost ]
|
provides [mainForHost]
|
||||||
|
|
||||||
# This case is important to test because there's no padding
|
# This case is important to test because there's no padding
|
||||||
# after the largest variant, so the compiler adds an extra u8
|
# after the largest variant, so the compiler adds an extra u8
|
||||||
# (rounded up to alignment, so an an extra 8 bytes) in which
|
# (rounded up to alignment, so an an extra 8 bytes) in which
|
||||||
# to store the discriminant. We have to bindgen accordingly!
|
# to store the discriminant. We have to bindgen accordingly!
|
||||||
NonRecursive : [ Foo Str, Bar I64, Blah I32, Baz ]
|
NonRecursive : [Foo Str, Bar I64, Blah I32, Baz]
|
||||||
|
|
||||||
mainForHost : NonRecursive
|
mainForHost : NonRecursive
|
||||||
mainForHost = main
|
mainForHost = main
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
app "app"
|
app "app"
|
||||||
packages { pf: "." }
|
packages { pf: "." }
|
||||||
imports []
|
imports []
|
||||||
provides [ main ] to pf
|
provides [main] to pf
|
||||||
|
|
||||||
main = Foo "This is a test"
|
main = Foo "This is a test"
|
||||||
|
|
|
@ -17,7 +17,7 @@ pub fn generate_bindings(decl_src: &str) -> String {
|
||||||
exposes []
|
exposes []
|
||||||
packages {}
|
packages {}
|
||||||
imports []
|
imports []
|
||||||
provides [ main ]
|
provides [main]
|
||||||
|
|
||||||
"#
|
"#
|
||||||
)
|
)
|
||||||
|
|
|
@ -958,7 +958,7 @@ mod cli_run {
|
||||||
|
|
||||||
Nothing from Symbol is used in this module.
|
Nothing from Symbol is used in this module.
|
||||||
|
|
||||||
3│ imports [ Symbol.{ Ident } ]
|
3│ imports [Symbol.{ Ident }]
|
||||||
^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
Since Symbol isn't used, you don't need to import it.
|
Since Symbol isn't used, you don't need to import it.
|
||||||
|
@ -981,7 +981,7 @@ mod cli_run {
|
||||||
|
|
||||||
I don't know how to generate the foobar function.
|
I don't know how to generate the foobar function.
|
||||||
|
|
||||||
4│ generates Effect with [ after, map, always, foobar ]
|
4│ generates Effect with [after, map, always, foobar]
|
||||||
^^^^^^
|
^^^^^^
|
||||||
|
|
||||||
Only specific functions like `after` and `map` can be generated.Learn
|
Only specific functions like `after` and `map` can be generated.Learn
|
||||||
|
|
2
cli/tests/fixtures/format/NotFormatted.roc
vendored
2
cli/tests/fixtures/format/NotFormatted.roc
vendored
|
@ -1,6 +1,6 @@
|
||||||
app "formatted"
|
app "formatted"
|
||||||
packages { pf: "platform" }
|
packages { pf: "platform" }
|
||||||
provides [ main ] to pf
|
provides [main] to pf
|
||||||
|
|
||||||
main : Str
|
main : Str
|
||||||
main = Dep1.value1 {}
|
main = Dep1.value1 {}
|
||||||
|
|
2
cli/tests/fixtures/multi-dep-str/Dep1.roc
vendored
2
cli/tests/fixtures/multi-dep-str/Dep1.roc
vendored
|
@ -1,4 +1,4 @@
|
||||||
interface Dep1 exposes [ str1 ] imports [ Dep2 ]
|
interface Dep1 exposes [str1] imports [Dep2]
|
||||||
|
|
||||||
str1 : Str
|
str1 : Str
|
||||||
str1 = Dep2.str2
|
str1 = Dep2.str2
|
||||||
|
|
2
cli/tests/fixtures/multi-dep-str/Dep2.roc
vendored
2
cli/tests/fixtures/multi-dep-str/Dep2.roc
vendored
|
@ -1,4 +1,4 @@
|
||||||
interface Dep2 exposes [ str2 ] imports []
|
interface Dep2 exposes [str2] imports []
|
||||||
|
|
||||||
str2 : Str
|
str2 : Str
|
||||||
str2 = "I am Dep2.str2"
|
str2 = "I am Dep2.str2"
|
||||||
|
|
4
cli/tests/fixtures/multi-dep-str/Main.roc
vendored
4
cli/tests/fixtures/multi-dep-str/Main.roc
vendored
|
@ -1,7 +1,7 @@
|
||||||
app "multi-dep-str"
|
app "multi-dep-str"
|
||||||
packages { pf: "platform" }
|
packages { pf: "platform" }
|
||||||
imports [ Dep1 ]
|
imports [Dep1]
|
||||||
provides [ main ] to pf
|
provides [main] to pf
|
||||||
|
|
||||||
main : Str
|
main : Str
|
||||||
main = Dep1.str1
|
main = Dep1.str1
|
||||||
|
|
|
@ -3,7 +3,7 @@ platform "multi-module"
|
||||||
exposes []
|
exposes []
|
||||||
packages {}
|
packages {}
|
||||||
imports []
|
imports []
|
||||||
provides [ mainForHost ]
|
provides [mainForHost]
|
||||||
|
|
||||||
mainForHost : Str
|
mainForHost : Str
|
||||||
mainForHost = main
|
mainForHost = main
|
||||||
|
|
2
cli/tests/fixtures/multi-dep-thunk/Dep1.roc
vendored
2
cli/tests/fixtures/multi-dep-thunk/Dep1.roc
vendored
|
@ -1,4 +1,4 @@
|
||||||
interface Dep1 exposes [ value1 ] imports [ Dep2 ]
|
interface Dep1 exposes [value1] imports [Dep2]
|
||||||
|
|
||||||
value1 : {} -> Str
|
value1 : {} -> Str
|
||||||
value1 = \_ -> Dep2.value2 {}
|
value1 = \_ -> Dep2.value2 {}
|
||||||
|
|
2
cli/tests/fixtures/multi-dep-thunk/Dep2.roc
vendored
2
cli/tests/fixtures/multi-dep-thunk/Dep2.roc
vendored
|
@ -1,4 +1,4 @@
|
||||||
interface Dep2 exposes [ value2 ] imports []
|
interface Dep2 exposes [value2] imports []
|
||||||
|
|
||||||
value2 : {} -> Str
|
value2 : {} -> Str
|
||||||
value2 = \_ -> "I am Dep2.value2"
|
value2 = \_ -> "I am Dep2.value2"
|
||||||
|
|
4
cli/tests/fixtures/multi-dep-thunk/Main.roc
vendored
4
cli/tests/fixtures/multi-dep-thunk/Main.roc
vendored
|
@ -1,7 +1,7 @@
|
||||||
app "multi-dep-thunk"
|
app "multi-dep-thunk"
|
||||||
packages { pf: "platform" }
|
packages { pf: "platform" }
|
||||||
imports [ Dep1 ]
|
imports [Dep1]
|
||||||
provides [ main ] to pf
|
provides [main] to pf
|
||||||
|
|
||||||
main : Str
|
main : Str
|
||||||
main = Dep1.value1 {}
|
main = Dep1.value1 {}
|
||||||
|
|
|
@ -3,7 +3,7 @@ platform "multi-dep-thunk"
|
||||||
exposes []
|
exposes []
|
||||||
packages {}
|
packages {}
|
||||||
imports []
|
imports []
|
||||||
provides [ mainForHost ]
|
provides [mainForHost]
|
||||||
|
|
||||||
mainForHost : Str
|
mainForHost : Str
|
||||||
mainForHost = main
|
mainForHost = main
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
interface Foo
|
interface Foo
|
||||||
exposes [ bar ]
|
exposes [bar]
|
||||||
imports []
|
imports []
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
interface Symbol
|
interface Symbol
|
||||||
exposes [ Ident ]
|
exposes [Ident]
|
||||||
imports []
|
imports []
|
||||||
|
|
||||||
# NOTE: this module is fine, but used by UnusedImport.roc to uselessly import
|
# NOTE: this module is fine, but used by UnusedImport.roc to uselessly import
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
app "type-error"
|
app "type-error"
|
||||||
packages { pf: "platform" }
|
packages { pf: "platform" }
|
||||||
imports [ pf.Stdout.{ line }, pf.Task.{ await } ]
|
imports [pf.Stdout.{ line }, pf.Task.{ await }]
|
||||||
provides [ main ] to pf
|
provides [main] to pf
|
||||||
|
|
||||||
main =
|
main =
|
||||||
_ <- await (line "a")
|
_ <- await (line "a")
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
hosted UnknownGeneratesWith
|
hosted UnknownGeneratesWith
|
||||||
exposes [ Effect, after, map, always ]
|
exposes [Effect, after, map, always]
|
||||||
imports []
|
imports []
|
||||||
generates Effect with [ after, map, always, foobar ]
|
generates Effect with [after, map, always, foobar]
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
interface UnusedImport
|
interface UnusedImport
|
||||||
exposes [ plainText, emText ]
|
exposes [plainText, emText]
|
||||||
imports [ Symbol.{ Ident } ]
|
imports [Symbol.{ Ident }]
|
||||||
|
|
||||||
plainText = \str -> PlainText str
|
plainText = \str -> PlainText str
|
||||||
|
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -10,7 +10,7 @@ Some of these have `#` inside their name (`first#list`, `#lt` ..). This is a tri
|
||||||
|
|
||||||
But we can use these values and some of these are necessary for implementing builtins. For example, `List.get` returns tags, and it is not easy for us to create tags when composing LLVM. What is easier however, is:
|
But we can use these values and some of these are necessary for implementing builtins. For example, `List.get` returns tags, and it is not easy for us to create tags when composing LLVM. What is easier however, is:
|
||||||
- ..writing `List.#getUnsafe` that has the dangerous signature of `List elem, Nat -> elem` in LLVM
|
- ..writing `List.#getUnsafe` that has the dangerous signature of `List elem, Nat -> elem` in LLVM
|
||||||
- ..writing `List elem, Nat -> Result elem [ OutOfBounds ]*` in a type safe way that uses `getUnsafe` internally, only after it checks if the `elem` at `Nat` index exists.
|
- ..writing `List elem, Nat -> Result elem [OutOfBounds]*` in a type safe way that uses `getUnsafe` internally, only after it checks if the `elem` at `Nat` index exists.
|
||||||
|
|
||||||
|
|
||||||
### can/src/builtins.rs
|
### can/src/builtins.rs
|
||||||
|
|
|
@ -705,7 +705,7 @@ pub fn listWalkUntil(
|
||||||
dec: Dec,
|
dec: Dec,
|
||||||
output: Opaque,
|
output: Opaque,
|
||||||
) callconv(.C) void {
|
) callconv(.C) void {
|
||||||
// [ Continue a, Stop a ]
|
// [Continue a, Stop a]
|
||||||
|
|
||||||
if (accum_width == 0) {
|
if (accum_width == 0) {
|
||||||
return;
|
return;
|
||||||
|
@ -734,7 +734,7 @@ pub fn listWalkUntil(
|
||||||
|
|
||||||
caller(data, bytes_ptr, element, bytes_ptr);
|
caller(data, bytes_ptr, element, bytes_ptr);
|
||||||
|
|
||||||
// [ Continue ..., Stop ]
|
// [Continue ..., Stop]
|
||||||
const tag_id = has_tag_id(0, bytes_ptr);
|
const tag_id = has_tag_id(0, bytes_ptr);
|
||||||
|
|
||||||
if (!tag_id.matched) {
|
if (!tag_id.matched) {
|
||||||
|
|
|
@ -547,7 +547,7 @@ fn strSplitInPlace(array: [*]RocStr, string: RocStr, delimiter: RocStr) void {
|
||||||
}
|
}
|
||||||
|
|
||||||
test "strSplitInPlace: empty delimiter" {
|
test "strSplitInPlace: empty delimiter" {
|
||||||
// Str.split "abc" "" == [ "abc" ]
|
// Str.split "abc" "" == ["abc"]
|
||||||
const str_arr = "abc";
|
const str_arr = "abc";
|
||||||
const str = RocStr.init(str_arr, str_arr.len);
|
const str = RocStr.init(str_arr, str_arr.len);
|
||||||
|
|
||||||
|
@ -581,7 +581,7 @@ test "strSplitInPlace: empty delimiter" {
|
||||||
}
|
}
|
||||||
|
|
||||||
test "strSplitInPlace: no delimiter" {
|
test "strSplitInPlace: no delimiter" {
|
||||||
// Str.split "abc" "!" == [ "abc" ]
|
// Str.split "abc" "!" == ["abc"]
|
||||||
const str_arr = "abc";
|
const str_arr = "abc";
|
||||||
const str = RocStr.init(str_arr, str_arr.len);
|
const str = RocStr.init(str_arr, str_arr.len);
|
||||||
|
|
||||||
|
@ -700,7 +700,7 @@ test "strSplitInPlace: delimiter on sides" {
|
||||||
}
|
}
|
||||||
|
|
||||||
test "strSplitInPlace: three pieces" {
|
test "strSplitInPlace: three pieces" {
|
||||||
// Str.split "a!b!c" "!" == [ "a", "b", "c" ]
|
// Str.split "a!b!c" "!" == ["a", "b", "c"]
|
||||||
const str_arr = "a!b!c";
|
const str_arr = "a!b!c";
|
||||||
const str = RocStr.init(str_arr, str_arr.len);
|
const str = RocStr.init(str_arr, str_arr.len);
|
||||||
|
|
||||||
|
@ -786,7 +786,7 @@ pub fn countSegments(string: RocStr, delimiter: RocStr) callconv(.C) usize {
|
||||||
}
|
}
|
||||||
|
|
||||||
test "countSegments: long delimiter" {
|
test "countSegments: long delimiter" {
|
||||||
// Str.split "str" "delimiter" == [ "str" ]
|
// Str.split "str" "delimiter" == ["str"]
|
||||||
// 1 segment
|
// 1 segment
|
||||||
const str_arr = "str";
|
const str_arr = "str";
|
||||||
const str = RocStr.init(str_arr, str_arr.len);
|
const str = RocStr.init(str_arr, str_arr.len);
|
||||||
|
@ -804,7 +804,7 @@ test "countSegments: long delimiter" {
|
||||||
}
|
}
|
||||||
|
|
||||||
test "countSegments: delimiter at start" {
|
test "countSegments: delimiter at start" {
|
||||||
// Str.split "hello there" "hello" == [ "", " there" ]
|
// Str.split "hello there" "hello" == ["", " there"]
|
||||||
// 2 segments
|
// 2 segments
|
||||||
const str_arr = "hello there";
|
const str_arr = "hello there";
|
||||||
const str = RocStr.init(str_arr, str_arr.len);
|
const str = RocStr.init(str_arr, str_arr.len);
|
||||||
|
@ -823,7 +823,7 @@ test "countSegments: delimiter at start" {
|
||||||
}
|
}
|
||||||
|
|
||||||
test "countSegments: delimiter interspered" {
|
test "countSegments: delimiter interspered" {
|
||||||
// Str.split "a!b!c" "!" == [ "a", "b", "c" ]
|
// Str.split "a!b!c" "!" == ["a", "b", "c"]
|
||||||
// 3 segments
|
// 3 segments
|
||||||
const str_arr = "a!b!c";
|
const str_arr = "a!b!c";
|
||||||
const str = RocStr.init(str_arr, str_arr.len);
|
const str = RocStr.init(str_arr, str_arr.len);
|
||||||
|
|
|
@ -54,7 +54,7 @@ interface Dict
|
||||||
## |> Dict.remove "Philadelphia"
|
## |> Dict.remove "Philadelphia"
|
||||||
## |> Dict.keys
|
## |> Dict.keys
|
||||||
## ==
|
## ==
|
||||||
## [ "London", "Amsterdam", "Shanghai", "Delhi" ]
|
## ["London", "Amsterdam", "Shanghai", "Delhi"]
|
||||||
##
|
##
|
||||||
## Notice that the order changed! Philadelphia has been not only removed from the list, but Amsterdam - the last
|
## Notice that the order changed! Philadelphia has been not only removed from the list, but Amsterdam - the last
|
||||||
## entry we inserted - has been moved into the spot where Philadelphia was previously. This is exactly what
|
## entry we inserted - has been moved into the spot where Philadelphia was previously. This is exactly what
|
||||||
|
|
|
@ -59,9 +59,9 @@ interface List
|
||||||
## Types
|
## Types
|
||||||
## A sequential list of values.
|
## A sequential list of values.
|
||||||
##
|
##
|
||||||
## >>> [ 1, 2, 3 ] # a list of numbers
|
## >>> [1, 2, 3] # a list of numbers
|
||||||
## >>> [ "a", "b", "c" ] # a list of strings
|
## >>> ["a", "b", "c"] # a list of strings
|
||||||
## >>> [ [ 1.1 ], [], [ 2.2, 3.3 ] ] # a list of lists of numbers
|
## >>> [[1.1], [], [2.2, 3.3]] # a list of lists of numbers
|
||||||
##
|
##
|
||||||
## The maximum size of a [List] is limited by the amount of heap memory available
|
## The maximum size of a [List] is limited by the amount of heap memory available
|
||||||
## to the current process. If there is not enough memory available, attempting to
|
## to the current process. If there is not enough memory available, attempting to
|
||||||
|
@ -92,11 +92,11 @@ interface List
|
||||||
##
|
##
|
||||||
## Let's look at an example.
|
## Let's look at an example.
|
||||||
##
|
##
|
||||||
## ratings = [ 5, 4, 3 ]
|
## ratings = [5, 4, 3]
|
||||||
##
|
##
|
||||||
## { foo: ratings, bar: ratings }
|
## { foo: ratings, bar: ratings }
|
||||||
##
|
##
|
||||||
## The first line binds the name `ratings` to the list `[ 5, 4, 3 ]`. The list
|
## The first line binds the name `ratings` to the list `[5, 4, 3]`. The list
|
||||||
## begins with a refcount of 1, because so far only `ratings` is referencing it.
|
## begins with a refcount of 1, because so far only `ratings` is referencing it.
|
||||||
##
|
##
|
||||||
## The second line alters this refcount. `{ foo: ratings` references
|
## The second line alters this refcount. `{ foo: ratings` references
|
||||||
|
@ -107,7 +107,7 @@ interface List
|
||||||
## Let's turn this example into a function.
|
## Let's turn this example into a function.
|
||||||
##
|
##
|
||||||
## getRatings = \first ->
|
## getRatings = \first ->
|
||||||
## ratings = [ first, 4, 3 ]
|
## ratings = [first, 4, 3]
|
||||||
##
|
##
|
||||||
## { foo: ratings, bar: ratings }
|
## { foo: ratings, bar: ratings }
|
||||||
##
|
##
|
||||||
|
@ -129,7 +129,7 @@ interface List
|
||||||
## Let's change the last line to be `(getRatings 5).bar` instead of `getRatings 5`:
|
## Let's change the last line to be `(getRatings 5).bar` instead of `getRatings 5`:
|
||||||
##
|
##
|
||||||
## getRatings = \first ->
|
## getRatings = \first ->
|
||||||
## ratings = [ first, 4, 3 ]
|
## ratings = [first, 4, 3]
|
||||||
##
|
##
|
||||||
## { foo: ratings, bar: ratings }
|
## { foo: ratings, bar: ratings }
|
||||||
##
|
##
|
||||||
|
@ -155,7 +155,7 @@ interface List
|
||||||
##
|
##
|
||||||
## Here's the example using a list of numbers.
|
## Here's the example using a list of numbers.
|
||||||
##
|
##
|
||||||
## nums = [ 1, 2, 3, 4, 5, 6, 7 ]
|
## nums = [1, 2, 3, 4, 5, 6, 7]
|
||||||
##
|
##
|
||||||
## first = List.first nums
|
## first = List.first nums
|
||||||
## last = List.last nums
|
## last = List.last nums
|
||||||
|
@ -166,7 +166,7 @@ interface List
|
||||||
##
|
##
|
||||||
## Here's the equivalent code with a list of lists:
|
## Here's the equivalent code with a list of lists:
|
||||||
##
|
##
|
||||||
## lists = [ [ 1 ], [ 2, 3 ], [], [ 4, 5, 6, 7 ] ]
|
## lists = [[1], [2, 3], [], [4, 5, 6, 7]]
|
||||||
##
|
##
|
||||||
## first = List.first lists
|
## first = List.first lists
|
||||||
## last = List.last lists
|
## last = List.last lists
|
||||||
|
@ -181,7 +181,7 @@ interface List
|
||||||
## because the function returned `first`, that element will actually end up
|
## because the function returned `first`, that element will actually end up
|
||||||
## *not* getting freed at the end - but all the others will be.
|
## *not* getting freed at the end - but all the others will be.
|
||||||
##
|
##
|
||||||
## In the `lists` example, `lists = [ ... ]` also creates a list with an initial
|
## In the `lists` example, `lists = [...]` also creates a list with an initial
|
||||||
## refcount of 1. Separately, it also creates several other lists - each with
|
## refcount of 1. Separately, it also creates several other lists - each with
|
||||||
## their own refcounts - to go inside that list. (The empty list at the end
|
## their own refcounts - to go inside that list. (The empty list at the end
|
||||||
## does not use heap memory, and thus has no refcount.)
|
## does not use heap memory, and thus has no refcount.)
|
||||||
|
@ -194,7 +194,7 @@ interface List
|
||||||
## * If possible, it is usually best for performance to use large lists in a way where the optimizer can turn them into in-place mutations. If this is not possible, a persistent data structure might be faster - but this is a rare enough scenario that it would not be good for the average Roc program's performance if this were the way [List] worked by default. Instead, you can look outside Roc's standard modules for an implementation of a persistent data structure - likely built using [List] under the hood!
|
## * If possible, it is usually best for performance to use large lists in a way where the optimizer can turn them into in-place mutations. If this is not possible, a persistent data structure might be faster - but this is a rare enough scenario that it would not be good for the average Roc program's performance if this were the way [List] worked by default. Instead, you can look outside Roc's standard modules for an implementation of a persistent data structure - likely built using [List] under the hood!
|
||||||
## Check if the list is empty.
|
## Check if the list is empty.
|
||||||
##
|
##
|
||||||
## >>> List.isEmpty [ 1, 2, 3 ]
|
## >>> List.isEmpty [1, 2, 3]
|
||||||
##
|
##
|
||||||
## >>> List.isEmpty []
|
## >>> List.isEmpty []
|
||||||
isEmpty : List a -> Bool
|
isEmpty : List a -> Bool
|
||||||
|
@ -206,7 +206,7 @@ replace : List a, Nat, a -> { list : List a, value : a }
|
||||||
|
|
||||||
## Replaces the element at the given index with a replacement.
|
## Replaces the element at the given index with a replacement.
|
||||||
##
|
##
|
||||||
## >>> List.set [ "a", "b", "c" ] 1 "B"
|
## >>> List.set ["a", "b", "c"] 1 "B"
|
||||||
##
|
##
|
||||||
## If the given index is outside the bounds of the list, returns the original
|
## If the given index is outside the bounds of the list, returns the original
|
||||||
## list unmodified.
|
## list unmodified.
|
||||||
|
@ -218,17 +218,17 @@ set = \list, index, value ->
|
||||||
|
|
||||||
## Add a single element to the end of a list.
|
## Add a single element to the end of a list.
|
||||||
##
|
##
|
||||||
## >>> List.append [ 1, 2, 3 ] 4
|
## >>> List.append [1, 2, 3] 4
|
||||||
##
|
##
|
||||||
## >>> [ 0, 1, 2 ]
|
## >>> [0, 1, 2]
|
||||||
## >>> |> List.append 3
|
## >>> |> List.append 3
|
||||||
append : List a, a -> List a
|
append : List a, a -> List a
|
||||||
|
|
||||||
## Add a single element to the beginning of a list.
|
## Add a single element to the beginning of a list.
|
||||||
##
|
##
|
||||||
## >>> List.prepend [ 1, 2, 3 ] 0
|
## >>> List.prepend [1, 2, 3] 0
|
||||||
##
|
##
|
||||||
## >>> [ 2, 3, 4 ]
|
## >>> [2, 3, 4]
|
||||||
## >>> |> List.prepend 1
|
## >>> |> List.prepend 1
|
||||||
prepend : List a, a -> List a
|
prepend : List a, a -> List a
|
||||||
|
|
||||||
|
@ -241,10 +241,10 @@ len : List a -> Nat
|
||||||
|
|
||||||
## Put two lists together.
|
## Put two lists together.
|
||||||
##
|
##
|
||||||
## >>> List.concat [ 1, 2, 3 ] [ 4, 5 ]
|
## >>> List.concat [1, 2, 3] [4, 5]
|
||||||
##
|
##
|
||||||
## >>> [ 0, 1, 2 ]
|
## >>> [0, 1, 2]
|
||||||
## >>> |> List.concat [ 3, 4 ]
|
## >>> |> List.concat [3, 4]
|
||||||
concat : List a, List a -> List a
|
concat : List a, List a -> List a
|
||||||
|
|
||||||
## Returns the last element in the list, or `ListWasEmpty` if it was empty.
|
## Returns the last element in the list, or `ListWasEmpty` if it was empty.
|
||||||
|
@ -266,14 +266,14 @@ repeat : a, Nat -> List a
|
||||||
|
|
||||||
## Returns the list with its elements reversed.
|
## Returns the list with its elements reversed.
|
||||||
##
|
##
|
||||||
## >>> List.reverse [ 1, 2, 3 ]
|
## >>> List.reverse [1, 2, 3]
|
||||||
reverse : List a -> List a
|
reverse : List a -> List a
|
||||||
|
|
||||||
## Join the given lists together into one list.
|
## Join the given lists together into one list.
|
||||||
##
|
##
|
||||||
## >>> List.join [ [ 1, 2, 3 ], [ 4, 5 ], [], [ 6, 7 ] ]
|
## >>> List.join [[1, 2, 3], [4, 5], [], [6, 7]]
|
||||||
##
|
##
|
||||||
## >>> List.join [ [], [] ]
|
## >>> List.join [[], []]
|
||||||
##
|
##
|
||||||
## >>> List.join []
|
## >>> List.join []
|
||||||
join : List (List a) -> List a
|
join : List (List a) -> List a
|
||||||
|
@ -287,7 +287,7 @@ contains : List a, a -> Bool
|
||||||
##
|
##
|
||||||
## You can use it in a pipeline:
|
## You can use it in a pipeline:
|
||||||
##
|
##
|
||||||
## [ 2, 4, 8 ]
|
## [2, 4, 8]
|
||||||
## |> List.walk { start: 0, step: Num.add }
|
## |> List.walk { start: 0, step: Num.add }
|
||||||
##
|
##
|
||||||
## This returns 14 because:
|
## This returns 14 because:
|
||||||
|
@ -295,7 +295,7 @@ contains : List a, a -> Bool
|
||||||
## * Each `step` runs `Num.add state elem`, and the return value becomes the new `state`.
|
## * Each `step` runs `Num.add state elem`, and the return value becomes the new `state`.
|
||||||
##
|
##
|
||||||
## Here is a table of how `state` changes as [List.walk] walks over the elements
|
## Here is a table of how `state` changes as [List.walk] walks over the elements
|
||||||
## `[ 2, 4, 8 ]` using #Num.add as its `step` function to determine the next `state`.
|
## `[2, 4, 8]` using #Num.add as its `step` function to determine the next `state`.
|
||||||
##
|
##
|
||||||
## `state` | `elem` | `step state elem` (`Num.add state elem`)
|
## `state` | `elem` | `step state elem` (`Num.add state elem`)
|
||||||
## --------+--------+-----------------------------------------
|
## --------+--------+-----------------------------------------
|
||||||
|
@ -308,7 +308,7 @@ contains : List a, a -> Bool
|
||||||
## 1. `0` (because of `start: 0`)
|
## 1. `0` (because of `start: 0`)
|
||||||
## 2. `1` (because of `Num.add state elem` with `state` = 0 and `elem` = 1
|
## 2. `1` (because of `Num.add state elem` with `state` = 0 and `elem` = 1
|
||||||
##
|
##
|
||||||
## [ 1, 2, 3 ]
|
## [1, 2, 3]
|
||||||
## |> List.walk { start: 0, step: Num.sub }
|
## |> List.walk { start: 0, step: Num.sub }
|
||||||
##
|
##
|
||||||
## This returns -6 because
|
## This returns -6 because
|
||||||
|
@ -353,7 +353,7 @@ all : List a, (a -> Bool) -> Bool
|
||||||
## Run the given function on each element of a list, and return all the
|
## Run the given function on each element of a list, and return all the
|
||||||
## elements for which the function returned `True`.
|
## elements for which the function returned `True`.
|
||||||
##
|
##
|
||||||
## >>> List.keepIf [ 1, 2, 3, 4 ] (\num -> num > 2)
|
## >>> List.keepIf [1, 2, 3, 4] (\num -> num > 2)
|
||||||
##
|
##
|
||||||
## ## Performance Details
|
## ## Performance Details
|
||||||
##
|
##
|
||||||
|
@ -376,7 +376,7 @@ keepIf : List a, (a -> Bool) -> List a
|
||||||
## Run the given function on each element of a list, and return all the
|
## Run the given function on each element of a list, and return all the
|
||||||
## elements for which the function returned `False`.
|
## elements for which the function returned `False`.
|
||||||
##
|
##
|
||||||
## >>> List.dropIf [ 1, 2, 3, 4 ] (\num -> num > 2)
|
## >>> List.dropIf [1, 2, 3, 4] (\num -> num > 2)
|
||||||
##
|
##
|
||||||
## ## Performance Details
|
## ## Performance Details
|
||||||
##
|
##
|
||||||
|
@ -389,29 +389,29 @@ dropIf = \list, predicate ->
|
||||||
## This works like [List.map], except only the transformed values that are
|
## This works like [List.map], except only the transformed values that are
|
||||||
## wrapped in `Ok` are kept. Any that are wrapped in `Err` are dropped.
|
## wrapped in `Ok` are kept. Any that are wrapped in `Err` are dropped.
|
||||||
##
|
##
|
||||||
## >>> List.keepOks [ [ "a", "b" ], [], [], [ "c", "d", "e" ] ] List.last
|
## >>> List.keepOks [["a", "b"], [], [], ["c", "d", "e"]] List.last
|
||||||
##
|
##
|
||||||
## >>> fn = \str -> if Str.isEmpty str then Err StrWasEmpty else Ok (Str.len str)
|
## >>> fn = \str -> if Str.isEmpty str then Err StrWasEmpty else Ok (Str.len str)
|
||||||
## >>>
|
## >>>
|
||||||
## >>> List.keepOks [ "", "a", "bc", "", "d", "ef", "" ]
|
## >>> List.keepOks ["", "a", "bc", "", "d", "ef", ""]
|
||||||
keepOks : List before, (before -> Result after *) -> List after
|
keepOks : List before, (before -> Result after *) -> List after
|
||||||
|
|
||||||
## This works like [List.map], except only the transformed values that are
|
## This works like [List.map], except only the transformed values that are
|
||||||
## wrapped in `Err` are kept. Any that are wrapped in `Ok` are dropped.
|
## wrapped in `Err` are kept. Any that are wrapped in `Ok` are dropped.
|
||||||
##
|
##
|
||||||
## >>> List.keepErrs [ [ "a", "b" ], [], [], [ "c", "d", "e" ] ] List.last
|
## >>> List.keepErrs [["a", "b"], [], [], ["c", "d", "e"]] List.last
|
||||||
##
|
##
|
||||||
## >>> fn = \str -> if Str.isEmpty str then Err StrWasEmpty else Ok (Str.len str)
|
## >>> fn = \str -> if Str.isEmpty str then Err StrWasEmpty else Ok (Str.len str)
|
||||||
## >>>
|
## >>>
|
||||||
## >>> List.keepErrs [ "", "a", "bc", "", "d", "ef", "" ]
|
## >>> List.keepErrs ["", "a", "bc", "", "d", "ef", ""]
|
||||||
keepErrs : List before, (before -> Result * after) -> List after
|
keepErrs : List before, (before -> Result * after) -> List after
|
||||||
|
|
||||||
## Convert each element in the list to something new, by calling a conversion
|
## Convert each element in the list to something new, by calling a conversion
|
||||||
## function on each of them. Then return a new list of the converted values.
|
## function on each of them. Then return a new list of the converted values.
|
||||||
##
|
##
|
||||||
## > List.map [ 1, 2, 3 ] (\num -> num + 1)
|
## > List.map [1, 2, 3] (\num -> num + 1)
|
||||||
##
|
##
|
||||||
## > List.map [ "", "a", "bc" ] Str.isEmpty
|
## > List.map ["", "a", "bc"] Str.isEmpty
|
||||||
map : List a, (a -> b) -> List b
|
map : List a, (a -> b) -> List b
|
||||||
|
|
||||||
## Run a transformation function on the first element of each list,
|
## Run a transformation function on the first element of each list,
|
||||||
|
@ -421,7 +421,7 @@ map : List a, (a -> b) -> List b
|
||||||
## Some languages have a function named `zip`, which does something similar to
|
## Some languages have a function named `zip`, which does something similar to
|
||||||
## calling [List.map2] passing two lists and `Pair`:
|
## calling [List.map2] passing two lists and `Pair`:
|
||||||
##
|
##
|
||||||
## >>> zipped = List.map2 [ "a", "b", "c" ] [ 1, 2, 3 ] Pair
|
## >>> zipped = List.map2 ["a", "b", "c"] [1, 2, 3] Pair
|
||||||
map2 : List a, List b, (a, b -> c) -> List c
|
map2 : List a, List b, (a, b -> c) -> List c
|
||||||
|
|
||||||
## Run a transformation function on the first element of each list,
|
## Run a transformation function on the first element of each list,
|
||||||
|
@ -476,12 +476,12 @@ dropLast : List elem -> List elem
|
||||||
|
|
||||||
## Returns the given number of elements from the beginning of the list.
|
## Returns the given number of elements from the beginning of the list.
|
||||||
##
|
##
|
||||||
## >>> List.takeFirst 4 [ 1, 2, 3, 4, 5, 6, 7, 8 ]
|
## >>> List.takeFirst 4 [1, 2, 3, 4, 5, 6, 7, 8]
|
||||||
##
|
##
|
||||||
## If there are fewer elements in the list than the requested number,
|
## If there are fewer elements in the list than the requested number,
|
||||||
## returns the entire list.
|
## returns the entire list.
|
||||||
##
|
##
|
||||||
## >>> List.takeFirst 5 [ 1, 2 ]
|
## >>> List.takeFirst 5 [1, 2]
|
||||||
##
|
##
|
||||||
## To *remove* elements from the beginning of the list, use `List.takeLast`.
|
## To *remove* elements from the beginning of the list, use `List.takeLast`.
|
||||||
##
|
##
|
||||||
|
@ -503,12 +503,12 @@ takeFirst : List elem, Nat -> List elem
|
||||||
|
|
||||||
## Returns the given number of elements from the end of the list.
|
## Returns the given number of elements from the end of the list.
|
||||||
##
|
##
|
||||||
## >>> List.takeLast 4 [ 1, 2, 3, 4, 5, 6, 7, 8 ]
|
## >>> List.takeLast 4 [1, 2, 3, 4, 5, 6, 7, 8]
|
||||||
##
|
##
|
||||||
## If there are fewer elements in the list than the requested number,
|
## If there are fewer elements in the list than the requested number,
|
||||||
## returns the entire list.
|
## returns the entire list.
|
||||||
##
|
##
|
||||||
## >>> List.takeLast 5 [ 1, 2 ]
|
## >>> List.takeLast 5 [1, 2]
|
||||||
##
|
##
|
||||||
## To *remove* elements from the end of the list, use `List.takeFirst`.
|
## To *remove* elements from the end of the list, use `List.takeFirst`.
|
||||||
##
|
##
|
||||||
|
@ -588,11 +588,11 @@ find : List elem, (elem -> Bool) -> Result elem [NotFound]*
|
||||||
##
|
##
|
||||||
## If `start` is outside the bounds of the given list, returns the empty list.
|
## If `start` is outside the bounds of the given list, returns the empty list.
|
||||||
##
|
##
|
||||||
## >>> List.sublist { start: 4, len: 0 } [ 1, 2, 3 ]
|
## >>> List.sublist { start: 4, len: 0 } [1, 2, 3]
|
||||||
##
|
##
|
||||||
## If more elements are requested than exist in the list, returns as many as it can.
|
## If more elements are requested than exist in the list, returns as many as it can.
|
||||||
##
|
##
|
||||||
## >>> List.sublist { start: 2, len: 10 } [ 1, 2, 3, 4, 5 ]
|
## >>> List.sublist { start: 2, len: 10 } [1, 2, 3, 4, 5]
|
||||||
##
|
##
|
||||||
## > If you want a sublist which goes all the way to the end of the list, no
|
## > If you want a sublist which goes all the way to the end of the list, no
|
||||||
## > matter how long the list is, `List.takeLast` can do that more efficiently.
|
## > matter how long the list is, `List.takeLast` can do that more efficiently.
|
||||||
|
|
|
@ -1192,20 +1192,20 @@ toF64Checked : Num * -> Result F64 [OutOfBounds]*
|
||||||
##
|
##
|
||||||
## Although this can be passed to `List.sort`, you'll get better performance
|
## Although this can be passed to `List.sort`, you'll get better performance
|
||||||
## by using `List.sortAsc` or `List.sortDesc` instead.
|
## by using `List.sortAsc` or `List.sortDesc` instead.
|
||||||
# compare : Num a, Num a -> [ Lt, Eq, Gt ]
|
# compare : Num a, Num a -> [Lt, Eq, Gt]
|
||||||
## [Endianness](https://en.wikipedia.org/wiki/Endianness)
|
## [Endianness](https://en.wikipedia.org/wiki/Endianness)
|
||||||
# Endi : [ Big, Little, Native ]
|
# Endi : [Big, Little, Native]
|
||||||
## The `Endi` argument does not matter for [U8] and [I8], since they have
|
## The `Endi` argument does not matter for [U8] and [I8], since they have
|
||||||
## only one byte.
|
## only one byte.
|
||||||
# toBytes : Num *, Endi -> List U8
|
# toBytes : Num *, Endi -> List U8
|
||||||
## when Num.parseBytes bytes Big is
|
## when Num.parseBytes bytes Big is
|
||||||
## Ok { val: f64, rest } -> ...
|
## Ok { val: f64, rest } -> ...
|
||||||
## Err (ExpectedNum (Frac Binary64)) -> ...
|
## Err (ExpectedNum (Frac Binary64)) -> ...
|
||||||
# parseBytes : List U8, Endi -> Result { val : Num a, rest : List U8 } [ ExpectedNum a ]*
|
# parseBytes : List U8, Endi -> Result { val : Num a, rest : List U8 } [ExpectedNum a]*
|
||||||
## when Num.fromBytes bytes Big is
|
## when Num.fromBytes bytes Big is
|
||||||
## Ok f64 -> ...
|
## Ok f64 -> ...
|
||||||
## Err (ExpectedNum (Frac Binary64)) -> ...
|
## Err (ExpectedNum (Frac Binary64)) -> ...
|
||||||
# fromBytes : List U8, Endi -> Result (Num a) [ ExpectedNum a ]*
|
# fromBytes : List U8, Endi -> Result (Num a) [ExpectedNum a]*
|
||||||
# Bit shifts
|
# Bit shifts
|
||||||
## [Logical bit shift](https://en.wikipedia.org/wiki/Bitwise_operation#Logical_shift) left.
|
## [Logical bit shift](https://en.wikipedia.org/wiki/Bitwise_operation#Logical_shift) left.
|
||||||
##
|
##
|
||||||
|
@ -1280,10 +1280,10 @@ toF64Checked : Num * -> Result F64 [OutOfBounds]*
|
||||||
# format :
|
# format :
|
||||||
# Num *,
|
# Num *,
|
||||||
# {
|
# {
|
||||||
# base ? [ Decimal, Hexadecimal, Octal, Binary ],
|
# base ? [Decimal, Hexadecimal, Octal, Binary],
|
||||||
# notation ? [ Standard, Scientific ],
|
# notation ? [Standard, Scientific],
|
||||||
# decimalMark ? [ AlwaysShow Str, HideForIntegers ],
|
# decimalMark ? [AlwaysShow Str, HideForIntegers],
|
||||||
# decimalDigits ? { min : U16, max : [ All, Trunc U16, Round U16, Floor U16, Ceil U16 ] },
|
# decimalDigits ? { min : U16, max : [All, Trunc U16, Round U16, Floor U16, Ceil U16] },
|
||||||
# minWholeDigits ? U16,
|
# minWholeDigits ? U16,
|
||||||
# wholeSep ? { mark : Str, places : U64 }
|
# wholeSep ? { mark : Str, places : U64 }
|
||||||
# }
|
# }
|
||||||
|
|
|
@ -132,7 +132,7 @@ concat : Str, Str -> Str
|
||||||
## Combine a list of strings into a single string, with a separator
|
## Combine a list of strings into a single string, with a separator
|
||||||
## string in between each.
|
## string in between each.
|
||||||
##
|
##
|
||||||
## >>> Str.joinWith [ "one", "two", "three" ] ", "
|
## >>> Str.joinWith ["one", "two", "three"] ", "
|
||||||
joinWith : List Str, Str -> Str
|
joinWith : List Str, Str -> Str
|
||||||
|
|
||||||
## Split a string around a separator.
|
## Split a string around a separator.
|
||||||
|
@ -185,8 +185,8 @@ startsWithCodePt : Str, U32 -> Bool
|
||||||
## >>> Str.toUtf8 "🐦"
|
## >>> Str.toUtf8 "🐦"
|
||||||
toUtf8 : Str -> List U8
|
toUtf8 : Str -> List U8
|
||||||
|
|
||||||
# fromUtf8 : List U8 -> Result Str [ BadUtf8 Utf8Problem ]*
|
# fromUtf8 : List U8 -> Result Str [BadUtf8 Utf8Problem]*
|
||||||
# fromUtf8Range : List U8 -> Result Str [ BadUtf8 Utf8Problem Nat, OutOfBounds ]*
|
# fromUtf8Range : List U8 -> Result Str [BadUtf8 Utf8Problem Nat, OutOfBounds]*
|
||||||
fromUtf8 : List U8 -> Result Str [BadUtf8 Utf8ByteProblem Nat]*
|
fromUtf8 : List U8 -> Result Str [BadUtf8 Utf8ByteProblem Nat]*
|
||||||
fromUtf8Range : List U8, { start : Nat, count : Nat } -> Result Str [BadUtf8 Utf8ByteProblem Nat, OutOfBounds]*
|
fromUtf8Range : List U8, { start : Nat, count : Nat } -> Result Str [BadUtf8 Utf8ByteProblem Nat, OutOfBounds]*
|
||||||
|
|
||||||
|
|
|
@ -136,7 +136,7 @@ pub fn types() -> MutMap<Symbol, (SolvedType, Region)> {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// addChecked : Num a, Num a -> Result (Num a) [ Overflow ]*
|
// addChecked : Num a, Num a -> Result (Num a) [Overflow]*
|
||||||
add_top_level_function_type!(
|
add_top_level_function_type!(
|
||||||
Symbol::NUM_ADD_CHECKED,
|
Symbol::NUM_ADD_CHECKED,
|
||||||
vec![num_type(flex(TVAR1)), num_type(flex(TVAR1))],
|
vec![num_type(flex(TVAR1)), num_type(flex(TVAR1))],
|
||||||
|
@ -171,7 +171,7 @@ pub fn types() -> MutMap<Symbol, (SolvedType, Region)> {
|
||||||
Box::new(int_type(flex(TVAR1))),
|
Box::new(int_type(flex(TVAR1))),
|
||||||
);
|
);
|
||||||
|
|
||||||
// subChecked : Num a, Num a -> Result (Num a) [ Overflow ]*
|
// subChecked : Num a, Num a -> Result (Num a) [Overflow]*
|
||||||
add_top_level_function_type!(
|
add_top_level_function_type!(
|
||||||
Symbol::NUM_SUB_CHECKED,
|
Symbol::NUM_SUB_CHECKED,
|
||||||
vec![num_type(flex(TVAR1)), num_type(flex(TVAR1))],
|
vec![num_type(flex(TVAR1)), num_type(flex(TVAR1))],
|
||||||
|
@ -199,7 +199,7 @@ pub fn types() -> MutMap<Symbol, (SolvedType, Region)> {
|
||||||
Box::new(int_type(flex(TVAR1))),
|
Box::new(int_type(flex(TVAR1))),
|
||||||
);
|
);
|
||||||
|
|
||||||
// mulChecked : Num a, Num a -> Result (Num a) [ Overflow ]*
|
// mulChecked : Num a, Num a -> Result (Num a) [Overflow]*
|
||||||
add_top_level_function_type!(
|
add_top_level_function_type!(
|
||||||
Symbol::NUM_MUL_CHECKED,
|
Symbol::NUM_MUL_CHECKED,
|
||||||
vec![num_type(flex(TVAR1)), num_type(flex(TVAR1))],
|
vec![num_type(flex(TVAR1)), num_type(flex(TVAR1))],
|
||||||
|
@ -262,7 +262,7 @@ pub fn types() -> MutMap<Symbol, (SolvedType, Region)> {
|
||||||
Box::new(bool_type()),
|
Box::new(bool_type()),
|
||||||
);
|
);
|
||||||
|
|
||||||
// compare : Num a, Num a -> [ LT, EQ, GT ]
|
// compare : Num a, Num a -> [LT, EQ, GT]
|
||||||
add_top_level_function_type!(
|
add_top_level_function_type!(
|
||||||
Symbol::NUM_COMPARE,
|
Symbol::NUM_COMPARE,
|
||||||
vec![num_type(flex(TVAR1)), num_type(flex(TVAR1))],
|
vec![num_type(flex(TVAR1)), num_type(flex(TVAR1))],
|
||||||
|
@ -323,7 +323,7 @@ pub fn types() -> MutMap<Symbol, (SolvedType, Region)> {
|
||||||
Box::new(int_type(flex(TVAR1)))
|
Box::new(int_type(flex(TVAR1)))
|
||||||
);
|
);
|
||||||
|
|
||||||
// divTruncChecked : Int a, Int a -> Result (Int a) [ DivByZero ]*
|
// divTruncChecked : Int a, Int a -> Result (Int a) [DivByZero]*
|
||||||
add_top_level_function_type!(
|
add_top_level_function_type!(
|
||||||
Symbol::NUM_DIV_TRUNC_CHECKED,
|
Symbol::NUM_DIV_TRUNC_CHECKED,
|
||||||
vec![int_type(flex(TVAR1)), int_type(flex(TVAR1))],
|
vec![int_type(flex(TVAR1)), int_type(flex(TVAR1))],
|
||||||
|
@ -337,7 +337,7 @@ pub fn types() -> MutMap<Symbol, (SolvedType, Region)> {
|
||||||
Box::new(int_type(flex(TVAR1)))
|
Box::new(int_type(flex(TVAR1)))
|
||||||
);
|
);
|
||||||
|
|
||||||
// divCeilChecked : Int a, Int a -> Result (Int a) [ DivByZero ]*
|
// divCeilChecked : Int a, Int a -> Result (Int a) [DivByZero]*
|
||||||
add_top_level_function_type!(
|
add_top_level_function_type!(
|
||||||
Symbol::NUM_DIV_CEIL_CHECKED,
|
Symbol::NUM_DIV_CEIL_CHECKED,
|
||||||
vec![int_type(flex(TVAR1)), int_type(flex(TVAR1))],
|
vec![int_type(flex(TVAR1)), int_type(flex(TVAR1))],
|
||||||
|
@ -400,7 +400,7 @@ pub fn types() -> MutMap<Symbol, (SolvedType, Region)> {
|
||||||
Box::new(int_type(flex(TVAR1))),
|
Box::new(int_type(flex(TVAR1))),
|
||||||
);
|
);
|
||||||
|
|
||||||
// remChecked : Int a, Int a -> Result (Int a) [ DivByZero ]*
|
// remChecked : Int a, Int a -> Result (Int a) [DivByZero]*
|
||||||
add_top_level_function_type!(
|
add_top_level_function_type!(
|
||||||
Symbol::NUM_REM_CHECKED,
|
Symbol::NUM_REM_CHECKED,
|
||||||
vec![int_type(flex(TVAR1)), int_type(flex(TVAR1))],
|
vec![int_type(flex(TVAR1)), int_type(flex(TVAR1))],
|
||||||
|
@ -480,7 +480,7 @@ pub fn types() -> MutMap<Symbol, (SolvedType, Region)> {
|
||||||
Box::new(SolvedType::Wildcard),
|
Box::new(SolvedType::Wildcard),
|
||||||
);
|
);
|
||||||
|
|
||||||
// toI8Checked : Int * -> Result I8 [ OutOfBounds ]*
|
// toI8Checked : Int * -> Result I8 [OutOfBounds]*
|
||||||
add_top_level_function_type!(
|
add_top_level_function_type!(
|
||||||
Symbol::NUM_TO_I8_CHECKED,
|
Symbol::NUM_TO_I8_CHECKED,
|
||||||
vec![int_type(flex(TVAR1))],
|
vec![int_type(flex(TVAR1))],
|
||||||
|
@ -494,7 +494,7 @@ pub fn types() -> MutMap<Symbol, (SolvedType, Region)> {
|
||||||
Box::new(i16_type()),
|
Box::new(i16_type()),
|
||||||
);
|
);
|
||||||
|
|
||||||
// toI16Checked : Int * -> Result I16 [ OutOfBounds ]*
|
// toI16Checked : Int * -> Result I16 [OutOfBounds]*
|
||||||
add_top_level_function_type!(
|
add_top_level_function_type!(
|
||||||
Symbol::NUM_TO_I16_CHECKED,
|
Symbol::NUM_TO_I16_CHECKED,
|
||||||
vec![int_type(flex(TVAR1))],
|
vec![int_type(flex(TVAR1))],
|
||||||
|
@ -508,7 +508,7 @@ pub fn types() -> MutMap<Symbol, (SolvedType, Region)> {
|
||||||
Box::new(i32_type()),
|
Box::new(i32_type()),
|
||||||
);
|
);
|
||||||
|
|
||||||
// toI32Checked : Int * -> Result I32 [ OutOfBounds ]*
|
// toI32Checked : Int * -> Result I32 [OutOfBounds]*
|
||||||
add_top_level_function_type!(
|
add_top_level_function_type!(
|
||||||
Symbol::NUM_TO_I32_CHECKED,
|
Symbol::NUM_TO_I32_CHECKED,
|
||||||
vec![int_type(flex(TVAR1))],
|
vec![int_type(flex(TVAR1))],
|
||||||
|
@ -522,7 +522,7 @@ pub fn types() -> MutMap<Symbol, (SolvedType, Region)> {
|
||||||
Box::new(i64_type()),
|
Box::new(i64_type()),
|
||||||
);
|
);
|
||||||
|
|
||||||
// toI64Checked : Int * -> Result I64 [ OutOfBounds ]*
|
// toI64Checked : Int * -> Result I64 [OutOfBounds]*
|
||||||
add_top_level_function_type!(
|
add_top_level_function_type!(
|
||||||
Symbol::NUM_TO_I64_CHECKED,
|
Symbol::NUM_TO_I64_CHECKED,
|
||||||
vec![int_type(flex(TVAR1))],
|
vec![int_type(flex(TVAR1))],
|
||||||
|
@ -536,7 +536,7 @@ pub fn types() -> MutMap<Symbol, (SolvedType, Region)> {
|
||||||
Box::new(i128_type()),
|
Box::new(i128_type()),
|
||||||
);
|
);
|
||||||
|
|
||||||
// toI128Checked : Int * -> Result I128 [ OutOfBounds ]*
|
// toI128Checked : Int * -> Result I128 [OutOfBounds]*
|
||||||
add_top_level_function_type!(
|
add_top_level_function_type!(
|
||||||
Symbol::NUM_TO_I128_CHECKED,
|
Symbol::NUM_TO_I128_CHECKED,
|
||||||
vec![int_type(flex(TVAR1))],
|
vec![int_type(flex(TVAR1))],
|
||||||
|
@ -555,7 +555,7 @@ pub fn types() -> MutMap<Symbol, (SolvedType, Region)> {
|
||||||
Box::new(SolvedType::Wildcard),
|
Box::new(SolvedType::Wildcard),
|
||||||
);
|
);
|
||||||
|
|
||||||
// toU8Checked : Int * -> Result U8 [ OutOfBounds ]*
|
// toU8Checked : Int * -> Result U8 [OutOfBounds]*
|
||||||
add_top_level_function_type!(
|
add_top_level_function_type!(
|
||||||
Symbol::NUM_TO_U8_CHECKED,
|
Symbol::NUM_TO_U8_CHECKED,
|
||||||
vec![int_type(flex(TVAR1))],
|
vec![int_type(flex(TVAR1))],
|
||||||
|
@ -569,7 +569,7 @@ pub fn types() -> MutMap<Symbol, (SolvedType, Region)> {
|
||||||
Box::new(u16_type()),
|
Box::new(u16_type()),
|
||||||
);
|
);
|
||||||
|
|
||||||
// toU16Checked : Int * -> Result U16 [ OutOfBounds ]*
|
// toU16Checked : Int * -> Result U16 [OutOfBounds]*
|
||||||
add_top_level_function_type!(
|
add_top_level_function_type!(
|
||||||
Symbol::NUM_TO_U16_CHECKED,
|
Symbol::NUM_TO_U16_CHECKED,
|
||||||
vec![int_type(flex(TVAR1))],
|
vec![int_type(flex(TVAR1))],
|
||||||
|
@ -583,7 +583,7 @@ pub fn types() -> MutMap<Symbol, (SolvedType, Region)> {
|
||||||
Box::new(u32_type()),
|
Box::new(u32_type()),
|
||||||
);
|
);
|
||||||
|
|
||||||
// toU32Checked : Int * -> Result U32 [ OutOfBounds ]*
|
// toU32Checked : Int * -> Result U32 [OutOfBounds]*
|
||||||
add_top_level_function_type!(
|
add_top_level_function_type!(
|
||||||
Symbol::NUM_TO_U32_CHECKED,
|
Symbol::NUM_TO_U32_CHECKED,
|
||||||
vec![int_type(flex(TVAR1))],
|
vec![int_type(flex(TVAR1))],
|
||||||
|
@ -597,7 +597,7 @@ pub fn types() -> MutMap<Symbol, (SolvedType, Region)> {
|
||||||
Box::new(u64_type()),
|
Box::new(u64_type()),
|
||||||
);
|
);
|
||||||
|
|
||||||
// toU64Checked : Int * -> Result U64 [ OutOfBounds ]*
|
// toU64Checked : Int * -> Result U64 [OutOfBounds]*
|
||||||
add_top_level_function_type!(
|
add_top_level_function_type!(
|
||||||
Symbol::NUM_TO_U64_CHECKED,
|
Symbol::NUM_TO_U64_CHECKED,
|
||||||
vec![int_type(flex(TVAR1))],
|
vec![int_type(flex(TVAR1))],
|
||||||
|
@ -611,7 +611,7 @@ pub fn types() -> MutMap<Symbol, (SolvedType, Region)> {
|
||||||
Box::new(u128_type()),
|
Box::new(u128_type()),
|
||||||
);
|
);
|
||||||
|
|
||||||
// toU128Checked : Int * -> Result U128 [ OutOfBounds ]*
|
// toU128Checked : Int * -> Result U128 [OutOfBounds]*
|
||||||
add_top_level_function_type!(
|
add_top_level_function_type!(
|
||||||
Symbol::NUM_TO_U128_CHECKED,
|
Symbol::NUM_TO_U128_CHECKED,
|
||||||
vec![int_type(flex(TVAR1))],
|
vec![int_type(flex(TVAR1))],
|
||||||
|
@ -625,7 +625,7 @@ pub fn types() -> MutMap<Symbol, (SolvedType, Region)> {
|
||||||
Box::new(nat_type()),
|
Box::new(nat_type()),
|
||||||
);
|
);
|
||||||
|
|
||||||
// toNatChecked : Int * -> Result Nat [ OutOfBounds ]*
|
// toNatChecked : Int * -> Result Nat [OutOfBounds]*
|
||||||
add_top_level_function_type!(
|
add_top_level_function_type!(
|
||||||
Symbol::NUM_TO_NAT_CHECKED,
|
Symbol::NUM_TO_NAT_CHECKED,
|
||||||
vec![int_type(flex(TVAR1))],
|
vec![int_type(flex(TVAR1))],
|
||||||
|
@ -639,7 +639,7 @@ pub fn types() -> MutMap<Symbol, (SolvedType, Region)> {
|
||||||
Box::new(f32_type()),
|
Box::new(f32_type()),
|
||||||
);
|
);
|
||||||
|
|
||||||
// toF32Checked : Num * -> Result F32 [ OutOfBounds ]*
|
// toF32Checked : Num * -> Result F32 [OutOfBounds]*
|
||||||
add_top_level_function_type!(
|
add_top_level_function_type!(
|
||||||
Symbol::NUM_TO_F32_CHECKED,
|
Symbol::NUM_TO_F32_CHECKED,
|
||||||
vec![num_type(flex(TVAR1))],
|
vec![num_type(flex(TVAR1))],
|
||||||
|
@ -653,7 +653,7 @@ pub fn types() -> MutMap<Symbol, (SolvedType, Region)> {
|
||||||
Box::new(f64_type()),
|
Box::new(f64_type()),
|
||||||
);
|
);
|
||||||
|
|
||||||
// toF64Checked : Num * -> Result F64 [ OutOfBounds ]*
|
// toF64Checked : Num * -> Result F64 [OutOfBounds]*
|
||||||
add_top_level_function_type!(
|
add_top_level_function_type!(
|
||||||
Symbol::NUM_TO_F64_CHECKED,
|
Symbol::NUM_TO_F64_CHECKED,
|
||||||
vec![num_type(flex(TVAR1))],
|
vec![num_type(flex(TVAR1))],
|
||||||
|
@ -676,7 +676,7 @@ pub fn types() -> MutMap<Symbol, (SolvedType, Region)> {
|
||||||
Box::new(frac_type(flex(TVAR1)))
|
Box::new(frac_type(flex(TVAR1)))
|
||||||
);
|
);
|
||||||
|
|
||||||
// divChecked : Frac a, Frac a -> Result (Frac a) [ DivByZero ]*
|
// divChecked : Frac a, Frac a -> Result (Frac a) [DivByZero]*
|
||||||
add_top_level_function_type!(
|
add_top_level_function_type!(
|
||||||
Symbol::NUM_DIV_FRAC_CHECKED,
|
Symbol::NUM_DIV_FRAC_CHECKED,
|
||||||
vec![frac_type(flex(TVAR1)), frac_type(flex(TVAR1))],
|
vec![frac_type(flex(TVAR1)), frac_type(flex(TVAR1))],
|
||||||
|
@ -690,7 +690,7 @@ pub fn types() -> MutMap<Symbol, (SolvedType, Region)> {
|
||||||
Box::new(frac_type(flex(TVAR1))),
|
Box::new(frac_type(flex(TVAR1))),
|
||||||
);
|
);
|
||||||
|
|
||||||
// sqrtChecked : Frac a -> Result (Frac a) [ SqrtOfNegative ]*
|
// sqrtChecked : Frac a -> Result (Frac a) [SqrtOfNegative]*
|
||||||
let sqrt_of_negative = SolvedType::TagUnion(
|
let sqrt_of_negative = SolvedType::TagUnion(
|
||||||
vec![(TagName::Tag("SqrtOfNegative".into()), vec![])],
|
vec![(TagName::Tag("SqrtOfNegative".into()), vec![])],
|
||||||
Box::new(SolvedType::Wildcard),
|
Box::new(SolvedType::Wildcard),
|
||||||
|
@ -709,7 +709,7 @@ pub fn types() -> MutMap<Symbol, (SolvedType, Region)> {
|
||||||
Box::new(frac_type(flex(TVAR1))),
|
Box::new(frac_type(flex(TVAR1))),
|
||||||
);
|
);
|
||||||
|
|
||||||
// logChecked : Frac a -> Result (Frac a) [ LogNeedsPositive ]*
|
// logChecked : Frac a -> Result (Frac a) [LogNeedsPositive]*
|
||||||
let log_needs_positive = SolvedType::TagUnion(
|
let log_needs_positive = SolvedType::TagUnion(
|
||||||
vec![(TagName::Tag("LogNeedsPositive".into()), vec![])],
|
vec![(TagName::Tag("LogNeedsPositive".into()), vec![])],
|
||||||
Box::new(SolvedType::Wildcard),
|
Box::new(SolvedType::Wildcard),
|
||||||
|
@ -798,7 +798,7 @@ pub fn types() -> MutMap<Symbol, (SolvedType, Region)> {
|
||||||
Box::new(frac_type(flex(TVAR1))),
|
Box::new(frac_type(flex(TVAR1))),
|
||||||
);
|
);
|
||||||
|
|
||||||
// bytesToU16 : List U8, Nat -> Result U16 [ OutOfBounds ]
|
// bytesToU16 : List U8, Nat -> Result U16 [OutOfBounds]
|
||||||
{
|
{
|
||||||
let position_out_of_bounds = SolvedType::TagUnion(
|
let position_out_of_bounds = SolvedType::TagUnion(
|
||||||
vec![(TagName::Tag("OutOfBounds".into()), vec![])],
|
vec![(TagName::Tag("OutOfBounds".into()), vec![])],
|
||||||
|
@ -811,7 +811,7 @@ pub fn types() -> MutMap<Symbol, (SolvedType, Region)> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// bytesToU32 : List U8, Nat -> Result U32 [ OutOfBounds ]
|
// bytesToU32 : List U8, Nat -> Result U32 [OutOfBounds]
|
||||||
{
|
{
|
||||||
let position_out_of_bounds = SolvedType::TagUnion(
|
let position_out_of_bounds = SolvedType::TagUnion(
|
||||||
vec![(TagName::Tag("OutOfBounds".into()), vec![])],
|
vec![(TagName::Tag("OutOfBounds".into()), vec![])],
|
||||||
|
@ -932,7 +932,7 @@ pub fn types() -> MutMap<Symbol, (SolvedType, Region)> {
|
||||||
// trim : Str -> Str
|
// trim : Str -> Str
|
||||||
add_top_level_function_type!(Symbol::STR_TRIM, vec![str_type()], Box::new(str_type()));
|
add_top_level_function_type!(Symbol::STR_TRIM, vec![str_type()], Box::new(str_type()));
|
||||||
|
|
||||||
// fromUtf8 : List U8 -> Result Str [ BadUtf8 Utf8Problem ]*
|
// fromUtf8 : List U8 -> Result Str [BadUtf8 Utf8Problem]*
|
||||||
{
|
{
|
||||||
let bad_utf8 = SolvedType::TagUnion(
|
let bad_utf8 = SolvedType::TagUnion(
|
||||||
vec![(
|
vec![(
|
||||||
|
@ -949,7 +949,7 @@ pub fn types() -> MutMap<Symbol, (SolvedType, Region)> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// fromUtf8Range : List U8, { start : Nat, count : Nat } -> Result Str [ BadUtf8 Utf8Problem, OutOfBounds ]*
|
// fromUtf8Range : List U8, { start : Nat, count : Nat } -> Result Str [BadUtf8 Utf8Problem, OutOfBounds]*
|
||||||
{
|
{
|
||||||
let bad_utf8 = SolvedType::TagUnion(
|
let bad_utf8 = SolvedType::TagUnion(
|
||||||
vec![
|
vec![
|
||||||
|
@ -985,7 +985,7 @@ pub fn types() -> MutMap<Symbol, (SolvedType, Region)> {
|
||||||
Box::new(list_type(u8_type()))
|
Box::new(list_type(u8_type()))
|
||||||
);
|
);
|
||||||
|
|
||||||
// toNum : Str -> Result (Num a) [ InvalidNumStr ]
|
// toNum : Str -> Result (Num a) [InvalidNumStr]
|
||||||
// Because toNum doesn't work with floats & decimals by default without
|
// Because toNum doesn't work with floats & decimals by default without
|
||||||
// a point of usage to be able to infer the proper layout
|
// a point of usage to be able to infer the proper layout
|
||||||
// we decided that separate functions for each sub num type
|
// we decided that separate functions for each sub num type
|
||||||
|
@ -998,98 +998,98 @@ pub fn types() -> MutMap<Symbol, (SolvedType, Region)> {
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
// toDec : Str -> Result Dec [ InvalidNumStr ]
|
// toDec : Str -> Result Dec [InvalidNumStr]
|
||||||
add_top_level_function_type!(
|
add_top_level_function_type!(
|
||||||
Symbol::STR_TO_DEC,
|
Symbol::STR_TO_DEC,
|
||||||
vec![str_type()],
|
vec![str_type()],
|
||||||
Box::new(result_type(dec_type(), invalid_str()))
|
Box::new(result_type(dec_type(), invalid_str()))
|
||||||
);
|
);
|
||||||
|
|
||||||
// toF64 : Str -> Result F64 [ InvalidNumStr ]
|
// toF64 : Str -> Result F64 [InvalidNumStr]
|
||||||
add_top_level_function_type!(
|
add_top_level_function_type!(
|
||||||
Symbol::STR_TO_F64,
|
Symbol::STR_TO_F64,
|
||||||
vec![str_type()],
|
vec![str_type()],
|
||||||
Box::new(result_type(f64_type(), invalid_str()))
|
Box::new(result_type(f64_type(), invalid_str()))
|
||||||
);
|
);
|
||||||
|
|
||||||
// toF32 : Str -> Result F32 [ InvalidNumStr ]
|
// toF32 : Str -> Result F32 [InvalidNumStr]
|
||||||
add_top_level_function_type!(
|
add_top_level_function_type!(
|
||||||
Symbol::STR_TO_F32,
|
Symbol::STR_TO_F32,
|
||||||
vec![str_type()],
|
vec![str_type()],
|
||||||
Box::new(result_type(f32_type(), invalid_str()))
|
Box::new(result_type(f32_type(), invalid_str()))
|
||||||
);
|
);
|
||||||
|
|
||||||
// toNat : Str -> Result Nat [ InvalidNumStr ]
|
// toNat : Str -> Result Nat [InvalidNumStr]
|
||||||
add_top_level_function_type!(
|
add_top_level_function_type!(
|
||||||
Symbol::STR_TO_NAT,
|
Symbol::STR_TO_NAT,
|
||||||
vec![str_type()],
|
vec![str_type()],
|
||||||
Box::new(result_type(nat_type(), invalid_str()))
|
Box::new(result_type(nat_type(), invalid_str()))
|
||||||
);
|
);
|
||||||
|
|
||||||
// toU128 : Str -> Result U128 [ InvalidNumStr ]
|
// toU128 : Str -> Result U128 [InvalidNumStr]
|
||||||
add_top_level_function_type!(
|
add_top_level_function_type!(
|
||||||
Symbol::STR_TO_U128,
|
Symbol::STR_TO_U128,
|
||||||
vec![str_type()],
|
vec![str_type()],
|
||||||
Box::new(result_type(u128_type(), invalid_str()))
|
Box::new(result_type(u128_type(), invalid_str()))
|
||||||
);
|
);
|
||||||
|
|
||||||
// toI128 : Str -> Result I128 [ InvalidNumStr ]
|
// toI128 : Str -> Result I128 [InvalidNumStr]
|
||||||
add_top_level_function_type!(
|
add_top_level_function_type!(
|
||||||
Symbol::STR_TO_I128,
|
Symbol::STR_TO_I128,
|
||||||
vec![str_type()],
|
vec![str_type()],
|
||||||
Box::new(result_type(i128_type(), invalid_str()))
|
Box::new(result_type(i128_type(), invalid_str()))
|
||||||
);
|
);
|
||||||
|
|
||||||
// toU64 : Str -> Result U64 [ InvalidNumStr ]
|
// toU64 : Str -> Result U64 [InvalidNumStr]
|
||||||
add_top_level_function_type!(
|
add_top_level_function_type!(
|
||||||
Symbol::STR_TO_U64,
|
Symbol::STR_TO_U64,
|
||||||
vec![str_type()],
|
vec![str_type()],
|
||||||
Box::new(result_type(u64_type(), invalid_str()))
|
Box::new(result_type(u64_type(), invalid_str()))
|
||||||
);
|
);
|
||||||
|
|
||||||
// toI64 : Str -> Result I64 [ InvalidNumStr ]
|
// toI64 : Str -> Result I64 [InvalidNumStr]
|
||||||
add_top_level_function_type!(
|
add_top_level_function_type!(
|
||||||
Symbol::STR_TO_I64,
|
Symbol::STR_TO_I64,
|
||||||
vec![str_type()],
|
vec![str_type()],
|
||||||
Box::new(result_type(i64_type(), invalid_str()))
|
Box::new(result_type(i64_type(), invalid_str()))
|
||||||
);
|
);
|
||||||
|
|
||||||
// toU32 : Str -> Result U32 [ InvalidNumStr ]
|
// toU32 : Str -> Result U32 [InvalidNumStr]
|
||||||
add_top_level_function_type!(
|
add_top_level_function_type!(
|
||||||
Symbol::STR_TO_U32,
|
Symbol::STR_TO_U32,
|
||||||
vec![str_type()],
|
vec![str_type()],
|
||||||
Box::new(result_type(u32_type(), invalid_str()))
|
Box::new(result_type(u32_type(), invalid_str()))
|
||||||
);
|
);
|
||||||
|
|
||||||
// toI32 : Str -> Result I32 [ InvalidNumStr ]
|
// toI32 : Str -> Result I32 [InvalidNumStr]
|
||||||
add_top_level_function_type!(
|
add_top_level_function_type!(
|
||||||
Symbol::STR_TO_I32,
|
Symbol::STR_TO_I32,
|
||||||
vec![str_type()],
|
vec![str_type()],
|
||||||
Box::new(result_type(i32_type(), invalid_str()))
|
Box::new(result_type(i32_type(), invalid_str()))
|
||||||
);
|
);
|
||||||
|
|
||||||
// toU16 : Str -> Result U16 [ InvalidNumStr ]
|
// toU16 : Str -> Result U16 [InvalidNumStr]
|
||||||
add_top_level_function_type!(
|
add_top_level_function_type!(
|
||||||
Symbol::STR_TO_U16,
|
Symbol::STR_TO_U16,
|
||||||
vec![str_type()],
|
vec![str_type()],
|
||||||
Box::new(result_type(u16_type(), invalid_str()))
|
Box::new(result_type(u16_type(), invalid_str()))
|
||||||
);
|
);
|
||||||
|
|
||||||
// toI16 : Str -> Result I16 [ InvalidNumStr ]
|
// toI16 : Str -> Result I16 [InvalidNumStr]
|
||||||
add_top_level_function_type!(
|
add_top_level_function_type!(
|
||||||
Symbol::STR_TO_I16,
|
Symbol::STR_TO_I16,
|
||||||
vec![str_type()],
|
vec![str_type()],
|
||||||
Box::new(result_type(i16_type(), invalid_str()))
|
Box::new(result_type(i16_type(), invalid_str()))
|
||||||
);
|
);
|
||||||
|
|
||||||
// toU8 : Str -> Result U8 [ InvalidNumStr ]
|
// toU8 : Str -> Result U8 [InvalidNumStr]
|
||||||
add_top_level_function_type!(
|
add_top_level_function_type!(
|
||||||
Symbol::STR_TO_U8,
|
Symbol::STR_TO_U8,
|
||||||
vec![str_type()],
|
vec![str_type()],
|
||||||
Box::new(result_type(u8_type(), invalid_str()))
|
Box::new(result_type(u8_type(), invalid_str()))
|
||||||
);
|
);
|
||||||
|
|
||||||
// toI8 : Str -> Result I8 [ InvalidNumStr ]
|
// toI8 : Str -> Result I8 [InvalidNumStr]
|
||||||
add_top_level_function_type!(
|
add_top_level_function_type!(
|
||||||
Symbol::STR_TO_I8,
|
Symbol::STR_TO_I8,
|
||||||
vec![str_type()],
|
vec![str_type()],
|
||||||
|
@ -1098,7 +1098,7 @@ pub fn types() -> MutMap<Symbol, (SolvedType, Region)> {
|
||||||
|
|
||||||
// List module
|
// List module
|
||||||
|
|
||||||
// get : List elem, Nat -> Result elem [ OutOfBounds ]*
|
// get : List elem, Nat -> Result elem [OutOfBounds]*
|
||||||
let index_out_of_bounds = SolvedType::TagUnion(
|
let index_out_of_bounds = SolvedType::TagUnion(
|
||||||
vec![(TagName::Tag("OutOfBounds".into()), vec![])],
|
vec![(TagName::Tag("OutOfBounds".into()), vec![])],
|
||||||
Box::new(SolvedType::Wildcard),
|
Box::new(SolvedType::Wildcard),
|
||||||
|
@ -1110,7 +1110,7 @@ pub fn types() -> MutMap<Symbol, (SolvedType, Region)> {
|
||||||
Box::new(result_type(flex(TVAR1), index_out_of_bounds)),
|
Box::new(result_type(flex(TVAR1), index_out_of_bounds)),
|
||||||
);
|
);
|
||||||
|
|
||||||
// first : List elem -> Result elem [ ListWasEmpty ]*
|
// first : List elem -> Result elem [ListWasEmpty]*
|
||||||
let list_was_empty = SolvedType::TagUnion(
|
let list_was_empty = SolvedType::TagUnion(
|
||||||
vec![(TagName::Tag("ListWasEmpty".into()), vec![])],
|
vec![(TagName::Tag("ListWasEmpty".into()), vec![])],
|
||||||
Box::new(SolvedType::Wildcard),
|
Box::new(SolvedType::Wildcard),
|
||||||
|
@ -1122,7 +1122,7 @@ pub fn types() -> MutMap<Symbol, (SolvedType, Region)> {
|
||||||
Box::new(result_type(flex(TVAR1), list_was_empty.clone())),
|
Box::new(result_type(flex(TVAR1), list_was_empty.clone())),
|
||||||
);
|
);
|
||||||
|
|
||||||
// last : List elem -> Result elem [ ListWasEmpty ]*
|
// last : List elem -> Result elem [ListWasEmpty]*
|
||||||
add_top_level_function_type!(
|
add_top_level_function_type!(
|
||||||
Symbol::LIST_LAST,
|
Symbol::LIST_LAST,
|
||||||
vec![list_type(flex(TVAR1))],
|
vec![list_type(flex(TVAR1))],
|
||||||
|
@ -1163,14 +1163,14 @@ pub fn types() -> MutMap<Symbol, (SolvedType, Region)> {
|
||||||
Box::new(bool_type()),
|
Box::new(bool_type()),
|
||||||
);
|
);
|
||||||
|
|
||||||
// min : List (Num a) -> Result (Num a) [ ListWasEmpty ]*
|
// min : List (Num a) -> Result (Num a) [ListWasEmpty]*
|
||||||
add_top_level_function_type!(
|
add_top_level_function_type!(
|
||||||
Symbol::LIST_MIN,
|
Symbol::LIST_MIN,
|
||||||
vec![list_type(num_type(flex(TVAR1)))],
|
vec![list_type(num_type(flex(TVAR1)))],
|
||||||
Box::new(result_type(num_type(flex(TVAR1)), list_was_empty.clone())),
|
Box::new(result_type(num_type(flex(TVAR1)), list_was_empty.clone())),
|
||||||
);
|
);
|
||||||
|
|
||||||
// max : List (Num a) -> Result (Num a) [ ListWasEmpty ]*
|
// max : List (Num a) -> Result (Num a) [ListWasEmpty]*
|
||||||
add_top_level_function_type!(
|
add_top_level_function_type!(
|
||||||
Symbol::LIST_MAX,
|
Symbol::LIST_MAX,
|
||||||
vec![list_type(num_type(flex(TVAR1)))],
|
vec![list_type(num_type(flex(TVAR1)))],
|
||||||
|
@ -1214,7 +1214,7 @@ pub fn types() -> MutMap<Symbol, (SolvedType, Region)> {
|
||||||
);
|
);
|
||||||
|
|
||||||
fn until_type(content: SolvedType) -> SolvedType {
|
fn until_type(content: SolvedType) -> SolvedType {
|
||||||
// [ LT, EQ, GT ]
|
// [LT, EQ, GT]
|
||||||
SolvedType::TagUnion(
|
SolvedType::TagUnion(
|
||||||
vec![
|
vec![
|
||||||
(TagName::Tag("Continue".into()), vec![content.clone()]),
|
(TagName::Tag("Continue".into()), vec![content.clone()]),
|
||||||
|
@ -1224,7 +1224,7 @@ pub fn types() -> MutMap<Symbol, (SolvedType, Region)> {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// walkUntil : List elem, state, (state, elem -> [ Continue state, Stop state ]) -> state
|
// walkUntil : List elem, state, (state, elem -> [Continue state, Stop state]) -> state
|
||||||
add_top_level_function_type!(
|
add_top_level_function_type!(
|
||||||
Symbol::LIST_WALK_UNTIL,
|
Symbol::LIST_WALK_UNTIL,
|
||||||
vec![
|
vec![
|
||||||
|
@ -1576,7 +1576,7 @@ pub fn types() -> MutMap<Symbol, (SolvedType, Region)> {
|
||||||
Box::new(list_type(num_type(flex(TVAR1))))
|
Box::new(list_type(num_type(flex(TVAR1))))
|
||||||
);
|
);
|
||||||
|
|
||||||
// find : List elem, (elem -> Bool) -> Result elem [ NotFound ]*
|
// find : List elem, (elem -> Bool) -> Result elem [NotFound]*
|
||||||
{
|
{
|
||||||
let not_found = SolvedType::TagUnion(
|
let not_found = SolvedType::TagUnion(
|
||||||
vec![(TagName::Tag("NotFound".into()), vec![])],
|
vec![(TagName::Tag("NotFound".into()), vec![])],
|
||||||
|
@ -1619,7 +1619,7 @@ pub fn types() -> MutMap<Symbol, (SolvedType, Region)> {
|
||||||
Box::new(dict_type(flex(TVAR1), flex(TVAR2))),
|
Box::new(dict_type(flex(TVAR1), flex(TVAR2))),
|
||||||
);
|
);
|
||||||
|
|
||||||
// get : Dict k v, k -> Result v [ KeyNotFound ]*
|
// get : Dict k v, k -> Result v [KeyNotFound]*
|
||||||
let key_not_found = SolvedType::TagUnion(
|
let key_not_found = SolvedType::TagUnion(
|
||||||
vec![(TagName::Tag("KeyNotFound".into()), vec![])],
|
vec![(TagName::Tag("KeyNotFound".into()), vec![])],
|
||||||
Box::new(SolvedType::Wildcard),
|
Box::new(SolvedType::Wildcard),
|
||||||
|
|
|
@ -359,7 +359,7 @@ pub(crate) fn make_apply_symbol(
|
||||||
/// Retrieves all symbols in an annotations that reference a type definition, that is either an
|
/// Retrieves all symbols in an annotations that reference a type definition, that is either an
|
||||||
/// alias or an opaque type.
|
/// alias or an opaque type.
|
||||||
///
|
///
|
||||||
/// For example, in `[ A Age U8, B Str {} ]`, there are three type definition references - `Age`,
|
/// For example, in `[A Age U8, B Str {}]`, there are three type definition references - `Age`,
|
||||||
/// `U8`, and `Str`.
|
/// `U8`, and `Str`.
|
||||||
pub fn find_type_def_symbols(
|
pub fn find_type_def_symbols(
|
||||||
scope: &mut Scope,
|
scope: &mut Scope,
|
||||||
|
|
|
@ -31,13 +31,13 @@ macro_rules! macro_magic {
|
||||||
/// Some builtins cannot be constructed in code gen alone, and need to be defined
|
/// Some builtins cannot be constructed in code gen alone, and need to be defined
|
||||||
/// as separate Roc defs. For example, List.get has this type:
|
/// as separate Roc defs. For example, List.get has this type:
|
||||||
///
|
///
|
||||||
/// List.get : List elem, Nat -> Result elem [ OutOfBounds ]*
|
/// List.get : List elem, Nat -> Result elem [OutOfBounds]*
|
||||||
///
|
///
|
||||||
/// Because this returns an open tag union for its Err type, it's not possible
|
/// Because this returns an open tag union for its Err type, it's not possible
|
||||||
/// for code gen to return a hardcoded value for OutOfBounds. For example,
|
/// for code gen to return a hardcoded value for OutOfBounds. For example,
|
||||||
/// if this Result unifies to [ Foo, OutOfBounds ] then OutOfBOunds will
|
/// if this Result unifies to [Foo, OutOfBounds] then OutOfBOunds will
|
||||||
/// get assigned the number 1 (because Foo got 0 alphabetically), whereas
|
/// get assigned the number 1 (because Foo got 0 alphabetically), whereas
|
||||||
/// if it unifies to [ OutOfBounds, Qux ] then OutOfBounds will get the number 0.
|
/// if it unifies to [OutOfBounds, Qux] then OutOfBounds will get the number 0.
|
||||||
///
|
///
|
||||||
/// Getting these numbers right requires having List.get participate in the
|
/// Getting these numbers right requires having List.get participate in the
|
||||||
/// normal type-checking and monomorphization processes. As such, this function
|
/// normal type-checking and monomorphization processes. As such, this function
|
||||||
|
@ -574,7 +574,7 @@ fn to_num_checked(symbol: Symbol, var_store: &mut VarStore, lowlevel: LowLevel)
|
||||||
|
|
||||||
macro_rules! num_to_checked {
|
macro_rules! num_to_checked {
|
||||||
($($fn:ident)*) => {$(
|
($($fn:ident)*) => {$(
|
||||||
// Num.toXXXChecked : Int * -> Result XXX [ OutOfBounds ]*
|
// Num.toXXXChecked : Int * -> Result XXX [OutOfBounds]*
|
||||||
fn $fn(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
fn $fn(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||||
// Use the generic `NumToIntChecked`; we'll figure out exactly what layout(s) we need
|
// Use the generic `NumToIntChecked`; we'll figure out exactly what layout(s) we need
|
||||||
// during code generation after types are resolved.
|
// during code generation after types are resolved.
|
||||||
|
@ -869,7 +869,7 @@ fn num_overflow_checked(symbol: Symbol, var_store: &mut VarStore, lowlevel: LowL
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Num.addChecked : Num a, Num a -> Result (Num a) [ Overflow ]*
|
/// Num.addChecked : Num a, Num a -> Result (Num a) [Overflow]*
|
||||||
fn num_add_checked(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
fn num_add_checked(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||||
num_overflow_checked(symbol, var_store, LowLevel::NumAddChecked)
|
num_overflow_checked(symbol, var_store, LowLevel::NumAddChecked)
|
||||||
}
|
}
|
||||||
|
@ -889,7 +889,7 @@ fn num_sub_wrap(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||||
num_binop(symbol, var_store, LowLevel::NumSubWrap)
|
num_binop(symbol, var_store, LowLevel::NumSubWrap)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Num.subChecked : Num a, Num a -> Result (Num a) [ Overflow ]*
|
/// Num.subChecked : Num a, Num a -> Result (Num a) [Overflow]*
|
||||||
fn num_sub_checked(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
fn num_sub_checked(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||||
num_overflow_checked(symbol, var_store, LowLevel::NumSubChecked)
|
num_overflow_checked(symbol, var_store, LowLevel::NumSubChecked)
|
||||||
}
|
}
|
||||||
|
@ -909,7 +909,7 @@ fn num_mul_wrap(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||||
num_binop(symbol, var_store, LowLevel::NumMulWrap)
|
num_binop(symbol, var_store, LowLevel::NumMulWrap)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Num.mulChecked : Num a, Num a -> Result (Num a) [ Overflow ]*
|
/// Num.mulChecked : Num a, Num a -> Result (Num a) [Overflow]*
|
||||||
fn num_mul_checked(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
fn num_mul_checked(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||||
num_overflow_checked(symbol, var_store, LowLevel::NumMulChecked)
|
num_overflow_checked(symbol, var_store, LowLevel::NumMulChecked)
|
||||||
}
|
}
|
||||||
|
@ -934,7 +934,7 @@ fn num_lte(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||||
num_num_other_binop(symbol, var_store, LowLevel::NumLte)
|
num_num_other_binop(symbol, var_store, LowLevel::NumLte)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Num.compare : Num a, Num a -> [ LT, EQ, GT ]
|
/// Num.compare : Num a, Num a -> [LT, EQ, GT]
|
||||||
fn num_compare(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
fn num_compare(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||||
num_num_other_binop(symbol, var_store, LowLevel::NumCompare)
|
num_num_other_binop(symbol, var_store, LowLevel::NumCompare)
|
||||||
}
|
}
|
||||||
|
@ -1178,7 +1178,7 @@ fn num_sqrt(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||||
num_unaryop(symbol, var_store, LowLevel::NumSqrtUnchecked)
|
num_unaryop(symbol, var_store, LowLevel::NumSqrtUnchecked)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Num.sqrtChecked : Frac a -> Result (Frac a) [ SqrtOfNegative ]*
|
/// Num.sqrtChecked : Frac a -> Result (Frac a) [SqrtOfNegative]*
|
||||||
fn num_sqrt_checked(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
fn num_sqrt_checked(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||||
let bool_var = var_store.fresh();
|
let bool_var = var_store.fresh();
|
||||||
let frac_var = var_store.fresh();
|
let frac_var = var_store.fresh();
|
||||||
|
@ -1232,7 +1232,7 @@ fn num_log(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||||
num_unaryop(symbol, var_store, LowLevel::NumLogUnchecked)
|
num_unaryop(symbol, var_store, LowLevel::NumLogUnchecked)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Num.logChecked : Frac a -> Result (Frac a) [ LogNeedsPositive ]*
|
/// Num.logChecked : Frac a -> Result (Frac a) [LogNeedsPositive]*
|
||||||
fn num_log_checked(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
fn num_log_checked(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||||
let bool_var = var_store.fresh();
|
let bool_var = var_store.fresh();
|
||||||
let frac_var = var_store.fresh();
|
let frac_var = var_store.fresh();
|
||||||
|
@ -1442,12 +1442,12 @@ fn num_asin(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Num.bytesToU16 : List U8, Nat -> Result U16 [ OutOfBounds ]
|
/// Num.bytesToU16 : List U8, Nat -> Result U16 [OutOfBounds]
|
||||||
fn num_bytes_to_u16(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
fn num_bytes_to_u16(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||||
num_bytes_to(symbol, var_store, 1, LowLevel::NumBytesToU16)
|
num_bytes_to(symbol, var_store, 1, LowLevel::NumBytesToU16)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Num.bytesToU32 : List U8, Nat -> Result U32 [ OutOfBounds ]
|
/// Num.bytesToU32 : List U8, Nat -> Result U32 [OutOfBounds]
|
||||||
fn num_bytes_to_u32(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
fn num_bytes_to_u32(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||||
num_bytes_to(symbol, var_store, 3, LowLevel::NumBytesToU32)
|
num_bytes_to(symbol, var_store, 3, LowLevel::NumBytesToU32)
|
||||||
}
|
}
|
||||||
|
@ -1573,7 +1573,7 @@ fn str_trim_right(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||||
lowlevel_1(symbol, LowLevel::StrTrimRight, var_store)
|
lowlevel_1(symbol, LowLevel::StrTrimRight, var_store)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Str.toNum : Str -> Result (Num *) [ InvalidNumStr ]*
|
/// Str.toNum : Str -> Result (Num *) [InvalidNumStr]*
|
||||||
fn str_to_num(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
fn str_to_num(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||||
let bool_var = var_store.fresh();
|
let bool_var = var_store.fresh();
|
||||||
let str_var = var_store.fresh();
|
let str_var = var_store.fresh();
|
||||||
|
@ -1805,7 +1805,7 @@ fn str_count_graphemes(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Str.fromUtf8 : List U8 -> Result Str [ BadUtf8 { byteIndex : Nat, problem : Utf8Problem } } ]*
|
/// Str.fromUtf8 : List U8 -> Result Str [BadUtf8 { byteIndex : Nat, problem : Utf8Problem } }]*
|
||||||
fn str_from_utf8(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
fn str_from_utf8(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||||
let bytes_var = var_store.fresh();
|
let bytes_var = var_store.fresh();
|
||||||
let bool_var = var_store.fresh();
|
let bool_var = var_store.fresh();
|
||||||
|
@ -1908,7 +1908,7 @@ fn str_from_utf8(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||||
ret_var,
|
ret_var,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
/// Str.fromUtf8Range : List U8, { start : Nat, count : Nat } -> Result Str [ BadUtf8 { byteIndex : Nat, problem : Utf8Problem } } ]*
|
/// Str.fromUtf8Range : List U8, { start : Nat, count : Nat } -> Result Str [BadUtf8 { byteIndex : Nat, problem : Utf8Problem } }]*
|
||||||
fn str_from_utf8_range(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
fn str_from_utf8_range(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||||
let bytes_var = var_store.fresh();
|
let bytes_var = var_store.fresh();
|
||||||
let bool_var = var_store.fresh();
|
let bool_var = var_store.fresh();
|
||||||
|
@ -2173,12 +2173,12 @@ fn list_len(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// List.get : List elem, Int -> Result elem [ OutOfBounds ]*
|
/// List.get : List elem, Int -> Result elem [OutOfBounds]*
|
||||||
///
|
///
|
||||||
/// List.get :
|
/// List.get :
|
||||||
/// Attr (* | u) (List (Attr u a)),
|
/// Attr (* | u) (List (Attr u a)),
|
||||||
/// Attr * Int
|
/// Attr * Int
|
||||||
/// -> Attr * (Result (Attr u a) (Attr * [ OutOfBounds ]*))
|
/// -> Attr * (Result (Attr u a) (Attr * [OutOfBounds]*))
|
||||||
fn list_get(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
fn list_get(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||||
let arg_list = Symbol::ARG_1;
|
let arg_list = Symbol::ARG_1;
|
||||||
let arg_index = Symbol::ARG_2;
|
let arg_index = Symbol::ARG_2;
|
||||||
|
@ -2863,7 +2863,7 @@ fn list_drop_at(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// List.dropFirst : List elem -> Result { first: elem, others : List elem } [ ListWasEmpty ]*
|
/// List.dropFirst : List elem -> Result { first: elem, others : List elem } [ListWasEmpty]*
|
||||||
fn list_drop_first(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
fn list_drop_first(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||||
let list_var = var_store.fresh();
|
let list_var = var_store.fresh();
|
||||||
let index_var = var_store.fresh();
|
let index_var = var_store.fresh();
|
||||||
|
@ -3074,7 +3074,7 @@ fn list_walk_backwards(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||||
lowlevel_3(symbol, LowLevel::ListWalkBackwards, var_store)
|
lowlevel_3(symbol, LowLevel::ListWalkBackwards, var_store)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// List.walkUntil : List elem, state, (state, elem -> [ Continue state, Stop state ]) -> state
|
/// List.walkUntil : List elem, state, (state, elem -> [Continue state, Stop state]) -> state
|
||||||
fn list_walk_until(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
fn list_walk_until(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||||
lowlevel_3(symbol, LowLevel::ListWalkUntil, var_store)
|
lowlevel_3(symbol, LowLevel::ListWalkUntil, var_store)
|
||||||
}
|
}
|
||||||
|
@ -3164,7 +3164,7 @@ fn list_join_map(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// min : List (Num a) -> Result (Num a) [ ListWasEmpty ]*
|
// min : List (Num a) -> Result (Num a) [ListWasEmpty]*
|
||||||
fn list_min(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
fn list_min(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||||
let arg_var = var_store.fresh();
|
let arg_var = var_store.fresh();
|
||||||
let bool_var = var_store.fresh();
|
let bool_var = var_store.fresh();
|
||||||
|
@ -3305,7 +3305,7 @@ fn list_min_lt(list_elem_var: Variable, var_store: &mut VarStore) -> Expr {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// max : List (Num a) -> Result (Num a) [ ListWasEmpty ]*
|
// max : List (Num a) -> Result (Num a) [ListWasEmpty]*
|
||||||
fn list_max(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
fn list_max(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||||
let arg_var = var_store.fresh();
|
let arg_var = var_store.fresh();
|
||||||
let bool_var = var_store.fresh();
|
let bool_var = var_store.fresh();
|
||||||
|
@ -3693,7 +3693,7 @@ fn list_all(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||||
lowlevel_2(symbol, LowLevel::ListAll, var_store)
|
lowlevel_2(symbol, LowLevel::ListAll, var_store)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// List.find : List elem, (elem -> Bool) -> Result elem [ NotFound ]*
|
/// List.find : List elem, (elem -> Bool) -> Result elem [NotFound]*
|
||||||
fn list_find(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
fn list_find(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||||
let list = Symbol::ARG_1;
|
let list = Symbol::ARG_1;
|
||||||
let find_predicate = Symbol::ARG_2;
|
let find_predicate = Symbol::ARG_2;
|
||||||
|
@ -3859,7 +3859,7 @@ fn dict_contains(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||||
lowlevel_2(symbol, LowLevel::DictContains, var_store)
|
lowlevel_2(symbol, LowLevel::DictContains, var_store)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Dict.get : Dict k v, k -> Result v [ KeyNotFound ]*
|
/// Dict.get : Dict k v, k -> Result v [KeyNotFound]*
|
||||||
fn dict_get(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
fn dict_get(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||||
let arg_dict = Symbol::ARG_1;
|
let arg_dict = Symbol::ARG_1;
|
||||||
let arg_key = Symbol::ARG_2;
|
let arg_key = Symbol::ARG_2;
|
||||||
|
@ -4169,7 +4169,7 @@ fn num_rem(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||||
num_binop(symbol, var_store, LowLevel::NumRemUnchecked)
|
num_binop(symbol, var_store, LowLevel::NumRemUnchecked)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Num.remChecked : Int a, Int a -> Result (Int a) [ DivByZero ]*
|
/// Num.remChecked : Int a, Int a -> Result (Int a) [DivByZero]*
|
||||||
fn num_rem_checked(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
fn num_rem_checked(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||||
let num_var = var_store.fresh();
|
let num_var = var_store.fresh();
|
||||||
let unbound_zero_var = var_store.fresh();
|
let unbound_zero_var = var_store.fresh();
|
||||||
|
@ -4276,7 +4276,7 @@ fn num_div_frac(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||||
num_binop(symbol, var_store, LowLevel::NumDivUnchecked)
|
num_binop(symbol, var_store, LowLevel::NumDivUnchecked)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Num.divChecked : Frac, Frac -> Result Frac [ DivByZero ]*
|
/// Num.divChecked : Frac, Frac -> Result Frac [DivByZero]*
|
||||||
fn num_div_frac_checked(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
fn num_div_frac_checked(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||||
let bool_var = var_store.fresh();
|
let bool_var = var_store.fresh();
|
||||||
let num_var = var_store.fresh();
|
let num_var = var_store.fresh();
|
||||||
|
@ -4347,7 +4347,7 @@ fn num_div_trunc(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||||
num_binop(symbol, var_store, LowLevel::NumDivUnchecked)
|
num_binop(symbol, var_store, LowLevel::NumDivUnchecked)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Num.divTruncChecked : Int a , Int a -> Result (Int a) [ DivByZero ]*
|
/// Num.divTruncChecked : Int a , Int a -> Result (Int a) [DivByZero]*
|
||||||
fn num_div_trunc_checked(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
fn num_div_trunc_checked(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||||
let bool_var = var_store.fresh();
|
let bool_var = var_store.fresh();
|
||||||
let num_var = var_store.fresh();
|
let num_var = var_store.fresh();
|
||||||
|
@ -4423,7 +4423,7 @@ fn num_div_ceil(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||||
num_binop(symbol, var_store, LowLevel::NumDivCeilUnchecked)
|
num_binop(symbol, var_store, LowLevel::NumDivCeilUnchecked)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Num.divCeilChecked : Int a , Int a -> Result (Int a) [ DivByZero ]*
|
/// Num.divCeilChecked : Int a , Int a -> Result (Int a) [DivByZero]*
|
||||||
fn num_div_ceil_checked(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
fn num_div_ceil_checked(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||||
let bool_var = var_store.fresh();
|
let bool_var = var_store.fresh();
|
||||||
let num_var = var_store.fresh();
|
let num_var = var_store.fresh();
|
||||||
|
@ -4494,11 +4494,11 @@ fn num_div_ceil_checked(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// List.first : List elem -> Result elem [ ListWasEmpty ]*
|
/// List.first : List elem -> Result elem [ListWasEmpty]*
|
||||||
///
|
///
|
||||||
/// List.first :
|
/// List.first :
|
||||||
/// Attr (* | u) (List (Attr u a)),
|
/// Attr (* | u) (List (Attr u a)),
|
||||||
/// -> Attr * (Result (Attr u a) (Attr * [ OutOfBounds ]*))
|
/// -> Attr * (Result (Attr u a) (Attr * [OutOfBounds]*))
|
||||||
fn list_first(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
fn list_first(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||||
let bool_var = var_store.fresh();
|
let bool_var = var_store.fresh();
|
||||||
let list_var = var_store.fresh();
|
let list_var = var_store.fresh();
|
||||||
|
@ -4580,11 +4580,11 @@ fn list_first(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// List.last : List elem -> Result elem [ ListWasEmpty ]*
|
/// List.last : List elem -> Result elem [ListWasEmpty]*
|
||||||
///
|
///
|
||||||
/// List.last :
|
/// List.last :
|
||||||
/// Attr (* | u) (List (Attr u a)),
|
/// Attr (* | u) (List (Attr u a)),
|
||||||
/// -> Attr * (Result (Attr u a) (Attr * [ OutOfBounds ]*))
|
/// -> Attr * (Result (Attr u a) (Attr * [OutOfBounds]*))
|
||||||
fn list_last(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
fn list_last(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||||
let arg_var = var_store.fresh();
|
let arg_var = var_store.fresh();
|
||||||
let bool_var = var_store.fresh();
|
let bool_var = var_store.fresh();
|
||||||
|
|
|
@ -1810,19 +1810,19 @@ fn correct_mutual_recursive_type_alias<'a>(
|
||||||
// Within a recursive group, we must instantiate all aliases like how they came to the
|
// Within a recursive group, we must instantiate all aliases like how they came to the
|
||||||
// loop. e.g. given
|
// loop. e.g. given
|
||||||
//
|
//
|
||||||
// A : [ ConsA B, NilA ]
|
// A : [ConsA B, NilA]
|
||||||
// B : [ ConsB A, NilB ]
|
// B : [ConsB A, NilB]
|
||||||
//
|
//
|
||||||
// Our goal is
|
// Our goal is
|
||||||
//
|
//
|
||||||
// A : [ ConsA [ ConsB A, NilB ], NilA ]
|
// A : [ConsA [ConsB A, NilB], NilA]
|
||||||
// B : [ ConsB [ ConsA B, NilA ], NilB ]
|
// B : [ConsB [ConsA B, NilA], NilB]
|
||||||
//
|
//
|
||||||
// But if we would first instantiate B into A, then use the updated A to instantiate B,
|
// But if we would first instantiate B into A, then use the updated A to instantiate B,
|
||||||
// we get
|
// we get
|
||||||
//
|
//
|
||||||
// A : [ ConsA [ ConsB A, NilB ], NilA ]
|
// A : [ConsA [ConsB A, NilB], NilA]
|
||||||
// B : [ ConsB [ ConsA [ ConsB A, NilB ], NilA ], NilB ]
|
// B : [ConsB [ConsA [ConsB A, NilB], NilA], NilB]
|
||||||
//
|
//
|
||||||
// Which is incorrect. We do need the instantiated version however.
|
// Which is incorrect. We do need the instantiated version however.
|
||||||
// e.g. if in a next group we have:
|
// e.g. if in a next group we have:
|
||||||
|
@ -1831,7 +1831,7 @@ fn correct_mutual_recursive_type_alias<'a>(
|
||||||
//
|
//
|
||||||
// Then we must use the instantiated version
|
// Then we must use the instantiated version
|
||||||
//
|
//
|
||||||
// C : [ ConsA [ ConsB A, NilB ], NilA ]
|
// C : [ConsA [ConsB A, NilB], NilA]
|
||||||
//
|
//
|
||||||
// So, we cannot replace the original version of A with its instantiated version
|
// So, we cannot replace the original version of A with its instantiated version
|
||||||
// while we process A's group. We have to store the instantiated version until the
|
// while we process A's group. We have to store the instantiated version until the
|
||||||
|
@ -1997,21 +1997,21 @@ enum MakeTagUnionRecursive {
|
||||||
/// Attempt to make a tag union recursive at the position of `recursive_alias`; for example,
|
/// Attempt to make a tag union recursive at the position of `recursive_alias`; for example,
|
||||||
///
|
///
|
||||||
/// ```roc
|
/// ```roc
|
||||||
/// [ Cons a (ConsList a), Nil ] as ConsList a
|
/// [Cons a (ConsList a), Nil] as ConsList a
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// can be made recursive at the position "ConsList a" with a fresh recursive variable, say r1:
|
/// can be made recursive at the position "ConsList a" with a fresh recursive variable, say r1:
|
||||||
///
|
///
|
||||||
/// ```roc
|
/// ```roc
|
||||||
/// [ Cons a r1, Nil ] as r1
|
/// [Cons a r1, Nil] as r1
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// Returns `Err` if the tag union is recursive, but there is no structure-preserving recursion
|
/// Returns `Err` if the tag union is recursive, but there is no structure-preserving recursion
|
||||||
/// variable for it. This can happen when the type is a nested datatype, for example in either of
|
/// variable for it. This can happen when the type is a nested datatype, for example in either of
|
||||||
///
|
///
|
||||||
/// ```roc
|
/// ```roc
|
||||||
/// Nested a : [ Chain a (Nested (List a)), Term ]
|
/// Nested a : [Chain a (Nested (List a)), Term]
|
||||||
/// DuoList a b : [ Cons a (DuoList b a), Nil ]
|
/// DuoList a b : [Cons a (DuoList b a), Nil]
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// When `Err` is returned, a problem will be added to `env`.
|
/// When `Err` is returned, a problem will be added to `env`.
|
||||||
|
|
|
@ -78,7 +78,7 @@ pub(crate) fn build_effect_builtins(
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Effect.loop : a, (a -> Effect [ Step a, Done b ]) -> Effect b
|
// Effect.loop : a, (a -> Effect [Step a, Done b]) -> Effect b
|
||||||
if generated_functions.loop_ {
|
if generated_functions.loop_ {
|
||||||
let def = helper!(build_effect_loop);
|
let def = helper!(build_effect_loop);
|
||||||
declarations.push(Declaration::DeclareRec(
|
declarations.push(Declaration::DeclareRec(
|
||||||
|
@ -708,7 +708,7 @@ fn build_effect_forever(
|
||||||
// thunk2 = Effect.forever effect
|
// thunk2 = Effect.forever effect
|
||||||
// thunk2 {}
|
// thunk2 {}
|
||||||
//
|
//
|
||||||
// Effect.forever : [ C foreverInner { effect : T } ]
|
// Effect.forever : [C foreverInner { effect : T }]
|
||||||
// Effect.forever = \effect ->
|
// Effect.forever = \effect ->
|
||||||
// C { effect }
|
// C { effect }
|
||||||
//
|
//
|
||||||
|
|
|
@ -202,7 +202,7 @@ pub enum Expr {
|
||||||
// definition, which we then use during constraint generation. For example
|
// definition, which we then use during constraint generation. For example
|
||||||
// suppose we have
|
// suppose we have
|
||||||
//
|
//
|
||||||
// Id n := [ Id U64 n ]
|
// Id n := [Id U64 n]
|
||||||
// @Id "sasha"
|
// @Id "sasha"
|
||||||
//
|
//
|
||||||
// Then `opaque` is "Id", `argument` is "sasha", but this is not enough for us to
|
// Then `opaque` is "Id", `argument` is "sasha", but this is not enough for us to
|
||||||
|
@ -210,7 +210,7 @@ pub enum Expr {
|
||||||
// the variable "n".
|
// the variable "n".
|
||||||
// That's what `specialized_def_type` and `type_arguments` are for; they are specialized
|
// That's what `specialized_def_type` and `type_arguments` are for; they are specialized
|
||||||
// for the expression from the opaque definition. `type_arguments` is something like
|
// for the expression from the opaque definition. `type_arguments` is something like
|
||||||
// [(n, fresh1)], and `specialized_def_type` becomes "[ Id U64 fresh1 ]".
|
// [(n, fresh1)], and `specialized_def_type` becomes "[Id U64 fresh1]".
|
||||||
specialized_def_type: Box<Type>,
|
specialized_def_type: Box<Type>,
|
||||||
type_arguments: Vec<OptAbleVar>,
|
type_arguments: Vec<OptAbleVar>,
|
||||||
lambda_set_variables: Vec<LambdaSet>,
|
lambda_set_variables: Vec<LambdaSet>,
|
||||||
|
|
|
@ -213,7 +213,7 @@ pub fn canonicalize_module_defs<'a>(
|
||||||
|
|
||||||
// Exposed values are treated like defs that appear before any others, e.g.
|
// Exposed values are treated like defs that appear before any others, e.g.
|
||||||
//
|
//
|
||||||
// imports [ Foo.{ bar, baz } ]
|
// imports [Foo.{ bar, baz }]
|
||||||
//
|
//
|
||||||
// ...is basically the same as if we'd added these extra defs at the start of the module:
|
// ...is basically the same as if we'd added these extra defs at the start of the module:
|
||||||
//
|
//
|
||||||
|
@ -233,7 +233,7 @@ pub fn canonicalize_module_defs<'a>(
|
||||||
Ok(()) => {
|
Ok(()) => {
|
||||||
// Add an entry to exposed_imports using the current module's name
|
// Add an entry to exposed_imports using the current module's name
|
||||||
// as the key; e.g. if this is the Foo module and we have
|
// as the key; e.g. if this is the Foo module and we have
|
||||||
// exposes [ Bar.{ baz } ] then insert Foo.baz as the key, so when
|
// exposes [Bar.{ baz }] then insert Foo.baz as the key, so when
|
||||||
// anything references `baz` in this Foo module, it will resolve to Bar.baz.
|
// anything references `baz` in this Foo module, it will resolve to Bar.baz.
|
||||||
can_exposed_imports.insert(symbol, expr_var);
|
can_exposed_imports.insert(symbol, expr_var);
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,7 @@ pub enum Pattern {
|
||||||
// definition, which we then use during constraint generation. For example
|
// definition, which we then use during constraint generation. For example
|
||||||
// suppose we have
|
// suppose we have
|
||||||
//
|
//
|
||||||
// Id n := [ Id U64 n ]
|
// Id n := [Id U64 n]
|
||||||
// strToBool : Str -> Bool
|
// strToBool : Str -> Bool
|
||||||
//
|
//
|
||||||
// f = \@Id who -> strToBool who
|
// f = \@Id who -> strToBool who
|
||||||
|
@ -45,7 +45,7 @@ pub enum Pattern {
|
||||||
// the variable "n".
|
// the variable "n".
|
||||||
// That's what `specialized_def_type` and `type_arguments` are for; they are specialized
|
// That's what `specialized_def_type` and `type_arguments` are for; they are specialized
|
||||||
// for the expression from the opaque definition. `type_arguments` is something like
|
// for the expression from the opaque definition. `type_arguments` is something like
|
||||||
// [(n, fresh1)], and `specialized_def_type` becomes "[ Id U64 fresh1 ]".
|
// [(n, fresh1)], and `specialized_def_type` becomes "[Id U64 fresh1]".
|
||||||
specialized_def_type: Box<Type>,
|
specialized_def_type: Box<Type>,
|
||||||
type_arguments: Vec<OptAbleVar>,
|
type_arguments: Vec<OptAbleVar>,
|
||||||
lambda_set_variables: Vec<LambdaSet>,
|
lambda_set_variables: Vec<LambdaSet>,
|
||||||
|
|
|
@ -1015,7 +1015,7 @@ mod test_can {
|
||||||
fn unused_def_regression() {
|
fn unused_def_regression() {
|
||||||
let src = indoc!(
|
let src = indoc!(
|
||||||
r#"
|
r#"
|
||||||
Booly : [ Yes, No, Maybe ]
|
Booly : [Yes, No, Maybe]
|
||||||
|
|
||||||
y : Booly
|
y : Booly
|
||||||
y = No
|
y = No
|
||||||
|
@ -1025,7 +1025,7 @@ mod test_can {
|
||||||
#
|
#
|
||||||
# https://github.com/rtfeldman/roc/issues/298
|
# https://github.com/rtfeldman/roc/issues/298
|
||||||
x : List Booly
|
x : List Booly
|
||||||
x = [ y ]
|
x = [y]
|
||||||
|
|
||||||
x
|
x
|
||||||
"#
|
"#
|
||||||
|
|
|
@ -2138,10 +2138,10 @@ pub fn rec_defs_help(
|
||||||
// the let-generalization.
|
// the let-generalization.
|
||||||
// 2. Introduce all symbols of the untyped defs, but don't generalize them yet. Now, solve
|
// 2. Introduce all symbols of the untyped defs, but don't generalize them yet. Now, solve
|
||||||
// the untyped defs' bodies. This way, when checking something like
|
// the untyped defs' bodies. This way, when checking something like
|
||||||
// f = \x -> f [ x ]
|
// f = \x -> f [x]
|
||||||
// we introduce `f: b -> c`, then constrain the call `f [ x ]`,
|
// we introduce `f: b -> c`, then constrain the call `f [x]`,
|
||||||
// forcing `b -> c ~ List b -> c` and correctly picking up a recursion error.
|
// forcing `b -> c ~ List b -> c` and correctly picking up a recursion error.
|
||||||
// Had we generalized `b -> c`, the call `f [ x ]` would have been generalized, and this
|
// Had we generalized `b -> c`, the call `f [x]` would have been generalized, and this
|
||||||
// error would not be found.
|
// error would not be found.
|
||||||
// 3. Now properly let-generalize the untyped body defs, since we now know their types and
|
// 3. Now properly let-generalize the untyped body defs, since we now know their types and
|
||||||
// that they don't have circular type errors.
|
// that they don't have circular type errors.
|
||||||
|
|
|
@ -509,7 +509,7 @@ pub fn constrain_pattern(
|
||||||
type_arguments,
|
type_arguments,
|
||||||
lambda_set_variables,
|
lambda_set_variables,
|
||||||
} => {
|
} => {
|
||||||
// Suppose we are constraining the pattern \@Id who, where Id n := [ Id U64 n ]
|
// Suppose we are constraining the pattern \@Id who, where Id n := [Id U64 n]
|
||||||
let (arg_pattern_var, loc_arg_pattern) = &**argument;
|
let (arg_pattern_var, loc_arg_pattern) = &**argument;
|
||||||
let arg_pattern_type = Type::Variable(*arg_pattern_var);
|
let arg_pattern_type = Type::Variable(*arg_pattern_var);
|
||||||
|
|
||||||
|
@ -549,15 +549,15 @@ pub fn constrain_pattern(
|
||||||
// Link the entire wrapped opaque type (with the now-constrained argument) to the type
|
// Link the entire wrapped opaque type (with the now-constrained argument) to the type
|
||||||
// variables of the opaque type.
|
// variables of the opaque type.
|
||||||
//
|
//
|
||||||
// For example, suppose we have `O k := [ A k, B k ]`, and the pattern `@O (A s) -> s == ""`.
|
// For example, suppose we have `O k := [A k, B k]`, and the pattern `@O (A s) -> s == ""`.
|
||||||
// Previous constraints will have solved `typeof s ~ Str`, and we have the
|
// Previous constraints will have solved `typeof s ~ Str`, and we have the
|
||||||
// `specialized_def_type` being `[ A k1, B k1 ]`, specializing `k` as `k1` for this opaque
|
// `specialized_def_type` being `[A k1, B k1]`, specializing `k` as `k1` for this opaque
|
||||||
// usage.
|
// usage.
|
||||||
// We now want to link `typeof s ~ k1`, so to capture this relationship, we link
|
// We now want to link `typeof s ~ k1`, so to capture this relationship, we link
|
||||||
// the type of `A s` (the arg type) to `[ A k1, B k1 ]` (the specialized opaque type).
|
// the type of `A s` (the arg type) to `[A k1, B k1]` (the specialized opaque type).
|
||||||
//
|
//
|
||||||
// This must **always** be a presence constraint, that is enforcing
|
// This must **always** be a presence constraint, that is enforcing
|
||||||
// `[ A k1, B k1 ] += typeof (A s)`, because we are in a destructure position and not
|
// `[A k1, B k1] += typeof (A s)`, because we are in a destructure position and not
|
||||||
// all constructors are covered in this branch!
|
// all constructors are covered in this branch!
|
||||||
let link_type_variables_con = constraints.pattern_presence(
|
let link_type_variables_con = constraints.pattern_presence(
|
||||||
arg_pattern_type,
|
arg_pattern_type,
|
||||||
|
|
|
@ -380,7 +380,7 @@ fn build_transform_caller_help<'a, 'ctx, 'env>(
|
||||||
env,
|
env,
|
||||||
fn_name,
|
fn_name,
|
||||||
env.context.void_type().into(),
|
env.context.void_type().into(),
|
||||||
&(bumpalo::vec![ in env.arena; BasicTypeEnum::PointerType(arg_type); argument_layouts.len() + 2 ]),
|
&(bumpalo::vec![in env.arena; BasicTypeEnum::PointerType(arg_type); argument_layouts.len() + 2]),
|
||||||
);
|
);
|
||||||
|
|
||||||
// called from zig, must use C calling convention
|
// called from zig, must use C calling convention
|
||||||
|
|
|
@ -5652,7 +5652,7 @@ fn run_low_level<'a, 'ctx, 'env>(
|
||||||
list_join(env, list, element_layout)
|
list_join(env, list, element_layout)
|
||||||
}
|
}
|
||||||
ListGetUnsafe => {
|
ListGetUnsafe => {
|
||||||
// List.get : List elem, Nat -> [ Ok elem, OutOfBounds ]*
|
// List.get : List elem, Nat -> [Ok elem, OutOfBounds]*
|
||||||
debug_assert_eq!(args.len(), 2);
|
debug_assert_eq!(args.len(), 2);
|
||||||
|
|
||||||
let (wrapper_struct, list_layout) = load_symbol_and_layout(scope, &args[0]);
|
let (wrapper_struct, list_layout) = load_symbol_and_layout(scope, &args[0]);
|
||||||
|
@ -7258,7 +7258,7 @@ fn build_int_unary_op<'a, 'ctx, 'env>(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
NumToIntChecked => {
|
NumToIntChecked => {
|
||||||
// return_layout : Result N [ OutOfBounds ]* ~ { result: N, out_of_bounds: bool }
|
// return_layout : Result N [OutOfBounds]* ~ { result: N, out_of_bounds: bool }
|
||||||
|
|
||||||
let target_int_width = match return_layout {
|
let target_int_width = match return_layout {
|
||||||
Layout::Struct { field_layouts, .. } if field_layouts.len() == 2 => {
|
Layout::Struct { field_layouts, .. } if field_layouts.len() == 2 => {
|
||||||
|
|
|
@ -116,8 +116,8 @@ pub fn basic_type_from_builtin<'a, 'ctx, 'env>(
|
||||||
/// Current differences
|
/// Current differences
|
||||||
///
|
///
|
||||||
/// - tag unions are passed by-reference. That means that
|
/// - tag unions are passed by-reference. That means that
|
||||||
/// * `f : [ Some I64, None ] -> I64` is typed `{ { i64, i8 }, i64 }* -> i64`
|
/// * `f : [Some I64, None] -> I64` is typed `{ { i64, i8 }, i64 }* -> i64`
|
||||||
/// * `f : { x : [ Some I64, None ] } -> I64 is typed `{ { { i64, i8 }, i64 } } -> i64`
|
/// * `f : { x : [Some I64, None] } -> I64 is typed `{ { { i64, i8 }, i64 } } -> i64`
|
||||||
///
|
///
|
||||||
/// Ideas exist to have (bigger than 2 register) records also be passed by-reference, but this
|
/// Ideas exist to have (bigger than 2 register) records also be passed by-reference, but this
|
||||||
/// is not currently implemented
|
/// is not currently implemented
|
||||||
|
|
|
@ -82,7 +82,7 @@ In this backend, each symbol in the Mono IR gets one WebAssembly local. To illus
|
||||||
The WebAssembly code below is completely unoptimised and uses far more locals than necessary. But that does help to illustrate the concept of locals.
|
The WebAssembly code below is completely unoptimised and uses far more locals than necessary. But that does help to illustrate the concept of locals.
|
||||||
|
|
||||||
```
|
```
|
||||||
app "test" provides [ main ] to "./platform"
|
app "test" provides [main] to "./platform"
|
||||||
|
|
||||||
main =
|
main =
|
||||||
1 + 2 + 4
|
1 + 2 + 4
|
||||||
|
|
|
@ -222,7 +222,7 @@ impl From<String> for IdentStr {
|
||||||
|
|
||||||
impl fmt::Debug for IdentStr {
|
impl fmt::Debug for IdentStr {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
// IdentStr { is_small_str: false, storage: Refcounted(3), elements: [ 1,2,3,4] }
|
// IdentStr { is_small_str: false, storage: Refcounted(3), elements: [1,2,3,4] }
|
||||||
f.debug_struct("IdentStr")
|
f.debug_struct("IdentStr")
|
||||||
//.field("is_small_str", &self.is_small_str())
|
//.field("is_small_str", &self.is_small_str())
|
||||||
.field("string", &self.as_str())
|
.field("string", &self.as_str())
|
||||||
|
@ -233,7 +233,7 @@ impl fmt::Debug for IdentStr {
|
||||||
|
|
||||||
impl fmt::Display for IdentStr {
|
impl fmt::Display for IdentStr {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
// IdentStr { is_small_str: false, storage: Refcounted(3), elements: [ 1,2,3,4] }
|
// IdentStr { is_small_str: false, storage: Refcounted(3), elements: [1,2,3,4] }
|
||||||
f.write_str(self.as_str())
|
f.write_str(self.as_str())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3126,7 +3126,7 @@ fn send_header<'a>(
|
||||||
|
|
||||||
// For each of our imports, add an entry to deps_by_name
|
// For each of our imports, add an entry to deps_by_name
|
||||||
//
|
//
|
||||||
// e.g. for `imports [ pf.Foo.{ bar } ]`, add `Foo` to deps_by_name
|
// e.g. for `imports [pf.Foo.{ bar }]`, add `Foo` to deps_by_name
|
||||||
//
|
//
|
||||||
// Also build a list of imported_values_to_expose (like `bar` above.)
|
// Also build a list of imported_values_to_expose (like `bar` above.)
|
||||||
for (qualified_module_name, exposed_idents, region) in imported.into_iter() {
|
for (qualified_module_name, exposed_idents, region) in imported.into_iter() {
|
||||||
|
@ -3175,7 +3175,7 @@ fn send_header<'a>(
|
||||||
// created an IdentId for this, when it was imported exposed
|
// created an IdentId for this, when it was imported exposed
|
||||||
// in a dependent module.
|
// in a dependent module.
|
||||||
//
|
//
|
||||||
// For example, if module A has [ B.{ foo } ], then
|
// For example, if module A has [B.{ foo }], then
|
||||||
// when we get here for B, `foo` will already have
|
// when we get here for B, `foo` will already have
|
||||||
// an IdentId. We must reuse that!
|
// an IdentId. We must reuse that!
|
||||||
let ident_id = ident_ids.get_or_insert(&loc_exposed.value.as_str().into());
|
let ident_id = ident_ids.get_or_insert(&loc_exposed.value.as_str().into());
|
||||||
|
@ -3340,7 +3340,7 @@ fn send_header_two<'a>(
|
||||||
|
|
||||||
// For each of our imports, add an entry to deps_by_name
|
// For each of our imports, add an entry to deps_by_name
|
||||||
//
|
//
|
||||||
// e.g. for `imports [ pf.Foo.{ bar } ]`, add `Foo` to deps_by_name
|
// e.g. for `imports [pf.Foo.{ bar }]`, add `Foo` to deps_by_name
|
||||||
//
|
//
|
||||||
// Also build a list of imported_values_to_expose (like `bar` above.)
|
// Also build a list of imported_values_to_expose (like `bar` above.)
|
||||||
for (qualified_module_name, exposed_idents, region) in imported.into_iter() {
|
for (qualified_module_name, exposed_idents, region) in imported.into_iter() {
|
||||||
|
@ -3420,7 +3420,7 @@ fn send_header_two<'a>(
|
||||||
// created an IdentId for this, when it was imported exposed
|
// created an IdentId for this, when it was imported exposed
|
||||||
// in a dependent module.
|
// in a dependent module.
|
||||||
//
|
//
|
||||||
// For example, if module A has [ B.{ foo } ], then
|
// For example, if module A has [B.{ foo }], then
|
||||||
// when we get here for B, `foo` will already have
|
// when we get here for B, `foo` will already have
|
||||||
// an IdentId. We must reuse that!
|
// an IdentId. We must reuse that!
|
||||||
let ident_id = ident_ids.get_or_insert(&loc_exposed.value.as_str().into());
|
let ident_id = ident_ids.get_or_insert(&loc_exposed.value.as_str().into());
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
interface AStar
|
interface AStar
|
||||||
exposes [ initialModel, reconstructPath, updateCost, cheapestOpen, astar, findPath ]
|
exposes [initialModel, reconstructPath, updateCost, cheapestOpen, astar, findPath]
|
||||||
imports []
|
imports []
|
||||||
|
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@ initialModel = \start ->
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
cheapestOpen : (position -> F64), Model position -> Result position [ KeyNotFound ]*
|
cheapestOpen : (position -> F64), Model position -> Result position [KeyNotFound]*
|
||||||
cheapestOpen = \costFunction, model ->
|
cheapestOpen = \costFunction, model ->
|
||||||
|
|
||||||
folder = \resSmallestSoFar, position ->
|
folder = \resSmallestSoFar, position ->
|
||||||
|
@ -80,12 +80,12 @@ updateCost = \current, neighbour, model ->
|
||||||
model
|
model
|
||||||
|
|
||||||
|
|
||||||
findPath : { costFunction: (position, position -> F64), moveFunction: (position -> Set position), start : position, end : position } -> Result (List position) [ KeyNotFound ]*
|
findPath : { costFunction: (position, position -> F64), moveFunction: (position -> Set position), start : position, end : position } -> Result (List position) [KeyNotFound]*
|
||||||
findPath = \{ costFunction, moveFunction, start, end } ->
|
findPath = \{ costFunction, moveFunction, start, end } ->
|
||||||
astar costFunction moveFunction end (initialModel start)
|
astar costFunction moveFunction end (initialModel start)
|
||||||
|
|
||||||
|
|
||||||
astar : (position, position -> F64), (position -> Set position), position, Model position -> [ Err [ KeyNotFound ]*, Ok (List position) ]*
|
astar : (position, position -> F64), (position -> Set position), position, Model position -> [Err [KeyNotFound]*, Ok (List position)]*
|
||||||
astar = \costFn, moveFn, goal, model ->
|
astar = \costFn, moveFn, goal, model ->
|
||||||
when cheapestOpen (\position -> costFn goal position) model is
|
when cheapestOpen (\position -> costFn goal position) model is
|
||||||
Err _ ->
|
Err _ ->
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
interface Dep1
|
interface Dep1
|
||||||
exposes [ three, str, Unit, Identity, one, two ]
|
exposes [three, str, Unit, Identity, one, two]
|
||||||
imports [ Dep3.Blah.{ foo } ]
|
imports [Dep3.Blah.{ foo }]
|
||||||
|
|
||||||
one = 1
|
one = 1
|
||||||
|
|
||||||
|
@ -10,6 +10,6 @@ three = 3.0
|
||||||
|
|
||||||
str = "string!"
|
str = "string!"
|
||||||
|
|
||||||
Unit : [ Unit ]
|
Unit : [Unit]
|
||||||
|
|
||||||
Identity a : [ Identity a ]
|
Identity a : [Identity a]
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
interface Dep2
|
interface Dep2
|
||||||
exposes [ one, two, blah ]
|
exposes [one, two, blah]
|
||||||
imports [ Dep3.Blah.{ foo, bar } ]
|
imports [Dep3.Blah.{ foo, bar }]
|
||||||
|
|
||||||
one = 1
|
one = 1
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
interface Dep3.Blah
|
interface Dep3.Blah
|
||||||
exposes [ one, two, foo, bar ]
|
exposes [one, two, foo, bar]
|
||||||
imports []
|
imports []
|
||||||
|
|
||||||
one = 1
|
one = 1
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
interface ImportAlias
|
interface ImportAlias
|
||||||
exposes [ unit ]
|
exposes [unit]
|
||||||
imports [ Dep1 ]
|
imports [Dep1]
|
||||||
|
|
||||||
unit : Dep1.Unit
|
unit : Dep1.Unit
|
||||||
unit = Unit
|
unit = Unit
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
interface OneDep
|
interface OneDep
|
||||||
exposes [ str ]
|
exposes [str]
|
||||||
imports [ Dep3.Blah.{ foo } ]
|
imports [Dep3.Blah.{ foo }]
|
||||||
|
|
||||||
str = foo
|
str = foo
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
interface Primary
|
interface Primary
|
||||||
exposes [ blah2, blah3, str, alwaysThree, identity, z, w, succeed, withDefault, yay ]
|
exposes [blah2, blah3, str, alwaysThree, identity, z, w, succeed, withDefault, yay]
|
||||||
imports [ Dep1, Dep2.{ two, foo }, Dep3.Blah.{ bar }, Res ]
|
imports [Dep1, Dep2.{ two, foo }, Dep3.Blah.{ bar }, Res]
|
||||||
|
|
||||||
blah2 = Dep2.two
|
blah2 = Dep2.two
|
||||||
blah3 = bar
|
blah3 = bar
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
app "quicksort" provides [ swap, partition, partitionHelp, quicksort ] to "./platform"
|
app "quicksort" provides [swap, partition, partitionHelp, quicksort] to "./platform"
|
||||||
|
|
||||||
quicksort : List (Num a), Nat, Nat -> List (Num a)
|
quicksort : List (Num a), Nat, Nat -> List (Num a)
|
||||||
quicksort = \list, low, high ->
|
quicksort = \list, low, high ->
|
||||||
|
@ -21,7 +21,7 @@ swap = \i, j, list ->
|
||||||
[]
|
[]
|
||||||
|
|
||||||
|
|
||||||
partition : Nat, Nat, List (Num a) -> [ Pair Nat (List (Num a)) ]
|
partition : Nat, Nat, List (Num a) -> [Pair Nat (List (Num a))]
|
||||||
partition = \low, high, initialList ->
|
partition = \low, high, initialList ->
|
||||||
when List.get initialList high is
|
when List.get initialList high is
|
||||||
Ok pivot ->
|
Ok pivot ->
|
||||||
|
@ -33,7 +33,7 @@ partition = \low, high, initialList ->
|
||||||
Pair (low - 1) initialList
|
Pair (low - 1) initialList
|
||||||
|
|
||||||
|
|
||||||
partitionHelp : Nat, Nat, List (Num a), Nat, (Num a) -> [ Pair Nat (List (Num a)) ]
|
partitionHelp : Nat, Nat, List (Num a), Nat, (Num a) -> [Pair Nat (List (Num a))]
|
||||||
partitionHelp = \i, j, list, high, pivot ->
|
partitionHelp = \i, j, list, high, pivot ->
|
||||||
if j < high then
|
if j < high then
|
||||||
when List.get list j is
|
when List.get list j is
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
app "quicksort" provides [ quicksort ] to "./platform"
|
app "quicksort" provides [quicksort] to "./platform"
|
||||||
|
|
||||||
quicksort = \originalList ->
|
quicksort = \originalList ->
|
||||||
quicksortHelp : List (Num a), Nat, Nat -> List (Num a)
|
quicksortHelp : List (Num a), Nat, Nat -> List (Num a)
|
||||||
|
@ -24,7 +24,7 @@ quicksort = \originalList ->
|
||||||
_ ->
|
_ ->
|
||||||
[]
|
[]
|
||||||
|
|
||||||
partition : Nat, Nat, List (Num a) -> [ Pair Nat (List (Num a)) ]
|
partition : Nat, Nat, List (Num a) -> [Pair Nat (List (Num a))]
|
||||||
partition = \low, high, initialList ->
|
partition = \low, high, initialList ->
|
||||||
when List.get initialList high is
|
when List.get initialList high is
|
||||||
Ok pivot ->
|
Ok pivot ->
|
||||||
|
@ -36,7 +36,7 @@ quicksort = \originalList ->
|
||||||
Pair (low - 1) initialList
|
Pair (low - 1) initialList
|
||||||
|
|
||||||
|
|
||||||
partitionHelp : Nat, Nat, List (Num a), Nat, (Num a) -> [ Pair Nat (List (Num a)) ]
|
partitionHelp : Nat, Nat, List (Num a), Nat, (Num a) -> [Pair Nat (List (Num a))]
|
||||||
partitionHelp = \i, j, list, high, pivot ->
|
partitionHelp = \i, j, list, high, pivot ->
|
||||||
if j < high then
|
if j < high then
|
||||||
when List.get list j is
|
when List.get list j is
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
interface Records
|
interface Records
|
||||||
exposes [ intVal ]
|
exposes [intVal]
|
||||||
imports []
|
imports []
|
||||||
|
|
||||||
intVal =
|
intVal =
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
interface Res
|
interface Res
|
||||||
exposes [ Res, withDefault, map, andThen, ConsList ]
|
exposes [Res, withDefault, map, andThen, ConsList]
|
||||||
imports []
|
imports []
|
||||||
|
|
||||||
Res ok err : [ Ok ok, Err err ]
|
Res ok err : [Ok ok, Err err]
|
||||||
|
|
||||||
ConsList a : [ Cons a (ConsList a), Nil ]
|
ConsList a : [Cons a (ConsList a), Nil]
|
||||||
|
|
||||||
listMap : ConsList a, (a -> b) -> ConsList b
|
listMap : ConsList a, (a -> b) -> ConsList b
|
||||||
listMap = \list, f ->
|
listMap = \list, f ->
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
interface WithBuiltins
|
interface WithBuiltins
|
||||||
exposes [ floatTest, divisionFn, divisionTest, intTest, constantNum, fromDep2, divDep1ByDep2 ]
|
exposes [floatTest, divisionFn, divisionTest, intTest, constantNum, fromDep2, divDep1ByDep2]
|
||||||
imports [ Dep1, Dep2.{ two } ]
|
imports [Dep1, Dep2.{ two }]
|
||||||
|
|
||||||
floatTest = Num.maxF64
|
floatTest = Num.maxF64
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
interface AStar
|
interface AStar
|
||||||
exposes [ initialModel, reconstructPath, updateCost, cheapestOpen, astar, findPath ]
|
exposes [initialModel, reconstructPath, updateCost, cheapestOpen, astar, findPath]
|
||||||
imports []
|
imports []
|
||||||
|
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@ initialModel = \start ->
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
cheapestOpen : (position -> F64), Model position -> Result position [ KeyNotFound ]*
|
cheapestOpen : (position -> F64), Model position -> Result position [KeyNotFound]*
|
||||||
cheapestOpen = \costFunction, model ->
|
cheapestOpen = \costFunction, model ->
|
||||||
|
|
||||||
folder = \resSmallestSoFar, position ->
|
folder = \resSmallestSoFar, position ->
|
||||||
|
@ -80,12 +80,12 @@ updateCost = \current, neighbour, model ->
|
||||||
model
|
model
|
||||||
|
|
||||||
|
|
||||||
findPath : { costFunction: (position, position -> F64), moveFunction: (position -> Set position), start : position, end : position } -> Result (List position) [ KeyNotFound ]*
|
findPath : { costFunction: (position, position -> F64), moveFunction: (position -> Set position), start : position, end : position } -> Result (List position) [KeyNotFound]*
|
||||||
findPath = \{ costFunction, moveFunction, start, end } ->
|
findPath = \{ costFunction, moveFunction, start, end } ->
|
||||||
astar costFunction moveFunction end (initialModel start)
|
astar costFunction moveFunction end (initialModel start)
|
||||||
|
|
||||||
|
|
||||||
astar : (position, position -> F64), (position -> Set position), position, Model position -> [ Err [ KeyNotFound ]*, Ok (List position) ]*
|
astar : (position, position -> F64), (position -> Set position), position, Model position -> [Err [KeyNotFound]*, Ok (List position)]*
|
||||||
astar = \costFn, moveFn, goal, model ->
|
astar = \costFn, moveFn, goal, model ->
|
||||||
when cheapestOpen (\position -> costFn goal position) model is
|
when cheapestOpen (\position -> costFn goal position) model is
|
||||||
Err _ ->
|
Err _ ->
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
interface Dep1
|
interface Dep1
|
||||||
exposes [ three, str, Unit, Identity, one, two ]
|
exposes [three, str, Unit, Identity, one, two]
|
||||||
imports [ Dep3.Blah.{ foo } ]
|
imports [Dep3.Blah.{ foo }]
|
||||||
|
|
||||||
one = 1
|
one = 1
|
||||||
|
|
||||||
|
@ -10,6 +10,6 @@ three = 3.0
|
||||||
|
|
||||||
str = "string!"
|
str = "string!"
|
||||||
|
|
||||||
Unit : [ Unit ]
|
Unit : [Unit]
|
||||||
|
|
||||||
Identity a : [ Identity a ]
|
Identity a : [Identity a]
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
interface Dep2
|
interface Dep2
|
||||||
exposes [ one, two, blah ]
|
exposes [one, two, blah]
|
||||||
imports [ Dep3.Blah.{ foo, bar } ]
|
imports [Dep3.Blah.{ foo, bar }]
|
||||||
|
|
||||||
one = 1
|
one = 1
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
interface Dep3.Blah
|
interface Dep3.Blah
|
||||||
exposes [ one, two, foo, bar ]
|
exposes [one, two, foo, bar]
|
||||||
imports []
|
imports []
|
||||||
|
|
||||||
one = 1
|
one = 1
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
interface ImportAlias
|
interface ImportAlias
|
||||||
exposes [ unit ]
|
exposes [unit]
|
||||||
imports [ Dep1 ]
|
imports [Dep1]
|
||||||
|
|
||||||
unit : Dep1.Unit
|
unit : Dep1.Unit
|
||||||
unit = Unit
|
unit = Unit
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
interface OneDep
|
interface OneDep
|
||||||
exposes [ str ]
|
exposes [str]
|
||||||
imports [ Dep3.Blah.{ foo } ]
|
imports [Dep3.Blah.{ foo }]
|
||||||
|
|
||||||
str = foo
|
str = foo
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
interface Primary
|
interface Primary
|
||||||
exposes [ blah2, blah3, str, alwaysThree, identity, z, w, succeed, withDefault, yay ]
|
exposes [blah2, blah3, str, alwaysThree, identity, z, w, succeed, withDefault, yay]
|
||||||
imports [ Dep1, Dep2.{ two, foo }, Dep3.Blah.{ bar }, Res ]
|
imports [Dep1, Dep2.{ two, foo }, Dep3.Blah.{ bar }, Res]
|
||||||
|
|
||||||
blah2 = Dep2.two
|
blah2 = Dep2.two
|
||||||
blah3 = bar
|
blah3 = bar
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
interface Quicksort
|
interface Quicksort
|
||||||
exposes [ swap, partition, quicksort ]
|
exposes [swap, partition, quicksort]
|
||||||
imports []
|
imports []
|
||||||
|
|
||||||
quicksort : List (Num a), Nat, Nat -> List (Num a)
|
quicksort : List (Num a), Nat, Nat -> List (Num a)
|
||||||
|
@ -23,7 +23,7 @@ swap = \i, j, list ->
|
||||||
[]
|
[]
|
||||||
|
|
||||||
|
|
||||||
partition : Nat, Nat, List (Num a) -> [ Pair Nat (List (Num a)) ]
|
partition : Nat, Nat, List (Num a) -> [Pair Nat (List (Num a))]
|
||||||
partition = \low, high, initialList ->
|
partition = \low, high, initialList ->
|
||||||
when List.get initialList high is
|
when List.get initialList high is
|
||||||
Ok pivot ->
|
Ok pivot ->
|
||||||
|
@ -35,7 +35,7 @@ partition = \low, high, initialList ->
|
||||||
Pair (low - 1) initialList
|
Pair (low - 1) initialList
|
||||||
|
|
||||||
|
|
||||||
partitionHelp : Nat, Nat, List (Num a), Nat, (Num a) -> [ Pair Nat (List (Num a)) ]
|
partitionHelp : Nat, Nat, List (Num a), Nat, (Num a) -> [Pair Nat (List (Num a))]
|
||||||
partitionHelp = \i, j, list, high, pivot ->
|
partitionHelp = \i, j, list, high, pivot ->
|
||||||
if j < high then
|
if j < high then
|
||||||
when List.get list j is
|
when List.get list j is
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
interface Records
|
interface Records
|
||||||
exposes [ intVal ]
|
exposes [intVal]
|
||||||
imports []
|
imports []
|
||||||
|
|
||||||
intVal =
|
intVal =
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
interface Res
|
interface Res
|
||||||
exposes [ Res, withDefault, map, listMap, andThen, ConsList ]
|
exposes [Res, withDefault, map, listMap, andThen, ConsList]
|
||||||
imports []
|
imports []
|
||||||
|
|
||||||
Res ok err : [ Ok ok, Err err ]
|
Res ok err : [Ok ok, Err err]
|
||||||
|
|
||||||
ConsList a : [ Cons a (ConsList a), Nil ]
|
ConsList a : [Cons a (ConsList a), Nil]
|
||||||
|
|
||||||
listMap : ConsList a, (a -> b) -> ConsList b
|
listMap : ConsList a, (a -> b) -> ConsList b
|
||||||
listMap = \list, f ->
|
listMap = \list, f ->
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
interface WithBuiltins
|
interface WithBuiltins
|
||||||
exposes [ floatTest, divisionFn, divisionTest, intTest, constantNum, fromDep2, divDep1ByDep2 ]
|
exposes [floatTest, divisionFn, divisionTest, intTest, constantNum, fromDep2, divDep1ByDep2]
|
||||||
imports [ Dep1, Dep2.{ two } ]
|
imports [Dep1, Dep2.{ two }]
|
||||||
|
|
||||||
floatTest = Num.maxF64
|
floatTest = Num.maxF64
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
interface MissingDep
|
interface MissingDep
|
||||||
exposes [ unit ]
|
exposes [unit]
|
||||||
imports [ ThisFileIsMissing ]
|
imports [ThisFileIsMissing]
|
||||||
|
|
||||||
Unit : [ Unit ]
|
Unit : [Unit]
|
||||||
|
|
||||||
unit : Unit
|
unit : Unit
|
||||||
unit = Unit
|
unit = Unit
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
interface Principal
|
interface Principal
|
||||||
exposes [ identity, intVal ]
|
exposes [identity, intVal]
|
||||||
imports []
|
imports []
|
||||||
|
|
||||||
identity = \a -> a
|
identity = \a -> a
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
interface Unit
|
interface Unit
|
||||||
exposes [ unit ]
|
exposes [unit]
|
||||||
imports []
|
imports []
|
||||||
|
|
||||||
Unit : [ Unit ]
|
Unit : [Unit]
|
||||||
|
|
||||||
unit : Unit
|
unit : Unit
|
||||||
unit = Unit
|
unit = Unit
|
||||||
|
|
|
@ -309,12 +309,12 @@ mod test_load {
|
||||||
"RBTree",
|
"RBTree",
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
interface RBTree exposes [ RedBlackTree, empty ] imports []
|
interface RBTree exposes [RedBlackTree, empty] imports []
|
||||||
|
|
||||||
# The color of a node. Leaves are considered Black.
|
# The color of a node. Leaves are considered Black.
|
||||||
NodeColor : [ Red, Black ]
|
NodeColor : [Red, Black]
|
||||||
|
|
||||||
RedBlackTree k v : [ Node NodeColor k v (RedBlackTree k v) (RedBlackTree k v), Empty ]
|
RedBlackTree k v : [Node NodeColor k v (RedBlackTree k v) (RedBlackTree k v), Empty]
|
||||||
|
|
||||||
# Create an empty dictionary.
|
# Create an empty dictionary.
|
||||||
empty : RedBlackTree k v
|
empty : RedBlackTree k v
|
||||||
|
@ -327,7 +327,7 @@ mod test_load {
|
||||||
"Main",
|
"Main",
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
interface Other exposes [ empty ] imports [ RBTree ]
|
interface Other exposes [empty] imports [RBTree]
|
||||||
|
|
||||||
empty : RBTree.RedBlackTree I64 I64
|
empty : RBTree.RedBlackTree I64 I64
|
||||||
empty = RBTree.empty
|
empty = RBTree.empty
|
||||||
|
@ -440,8 +440,8 @@ mod test_load {
|
||||||
loaded_module,
|
loaded_module,
|
||||||
hashmap! {
|
hashmap! {
|
||||||
"swap" => "Nat, Nat, List a -> List a",
|
"swap" => "Nat, Nat, List a -> List a",
|
||||||
"partition" => "Nat, Nat, List (Num a) -> [ Pair Nat (List (Num a)) ]",
|
"partition" => "Nat, Nat, List (Num a) -> [Pair Nat (List (Num a))]",
|
||||||
"partitionHelp" => "Nat, Nat, List (Num a), Nat, Num a -> [ Pair Nat (List (Num a)) ]",
|
"partitionHelp" => "Nat, Nat, List (Num a), Nat, Num a -> [Pair Nat (List (Num a))]",
|
||||||
"quicksort" => "List (Num a), Nat, Nat -> List (Num a)",
|
"quicksort" => "List (Num a), Nat, Nat -> List (Num a)",
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
@ -469,8 +469,8 @@ mod test_load {
|
||||||
loaded_module,
|
loaded_module,
|
||||||
hashmap! {
|
hashmap! {
|
||||||
"swap" => "Nat, Nat, List a -> List a",
|
"swap" => "Nat, Nat, List a -> List a",
|
||||||
"partition" => "Nat, Nat, List (Num a) -> [ Pair Nat (List (Num a)) ]",
|
"partition" => "Nat, Nat, List (Num a) -> [Pair Nat (List (Num a))]",
|
||||||
"partitionHelp" => "Nat, Nat, List (Num a), Nat, Num a -> [ Pair Nat (List (Num a)) ]",
|
"partitionHelp" => "Nat, Nat, List (Num a), Nat, Num a -> [Pair Nat (List (Num a))]",
|
||||||
"quicksort" => "List (Num a), Nat, Nat -> List (Num a)",
|
"quicksort" => "List (Num a), Nat, Nat -> List (Num a)",
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
@ -484,12 +484,12 @@ mod test_load {
|
||||||
expect_types(
|
expect_types(
|
||||||
loaded_module,
|
loaded_module,
|
||||||
hashmap! {
|
hashmap! {
|
||||||
"findPath" => "{ costFunction : position, position -> F64, end : position, moveFunction : position -> Set position, start : position } -> Result (List position) [ KeyNotFound ]*",
|
"findPath" => "{ costFunction : position, position -> F64, end : position, moveFunction : position -> Set position, start : position } -> Result (List position) [KeyNotFound]*",
|
||||||
"initialModel" => "position -> Model position",
|
"initialModel" => "position -> Model position",
|
||||||
"reconstructPath" => "Dict position position, position -> List position",
|
"reconstructPath" => "Dict position position, position -> List position",
|
||||||
"updateCost" => "position, position, Model position -> Model position",
|
"updateCost" => "position, position, Model position -> Model position",
|
||||||
"cheapestOpen" => "(position -> F64), Model position -> Result position [ KeyNotFound ]*",
|
"cheapestOpen" => "(position -> F64), Model position -> Result position [KeyNotFound]*",
|
||||||
"astar" => "(position, position -> F64), (position -> Set position), position, Model position -> [ Err [ KeyNotFound ]*, Ok (List position) ]*",
|
"astar" => "(position, position -> F64), (position -> Set position), position, Model position -> [Err [KeyNotFound]*, Ok (List position)]*",
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -571,7 +571,7 @@ mod test_load {
|
||||||
"Main",
|
"Main",
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
interface Main exposes [ main ] imports []
|
interface Main exposes [main] imports []
|
||||||
|
|
||||||
main = [
|
main = [
|
||||||
"#
|
"#
|
||||||
|
@ -590,7 +590,7 @@ mod test_load {
|
||||||
3│ main = [
|
3│ main = [
|
||||||
^
|
^
|
||||||
|
|
||||||
You could change it to something like [ 1, 2, 3 ] or even just [].
|
You could change it to something like [1, 2, 3] or even just [].
|
||||||
Anything where there is an open and a close square bracket, and where
|
Anything where there is an open and a close square bracket, and where
|
||||||
the elements of the list are separated by commas.
|
the elements of the list are separated by commas.
|
||||||
|
|
||||||
|
@ -637,8 +637,8 @@ mod test_load {
|
||||||
r#"
|
r#"
|
||||||
app "example"
|
app "example"
|
||||||
packages { pf: "./zzz-does-not-exist" }
|
packages { pf: "./zzz-does-not-exist" }
|
||||||
imports [ ]
|
imports []
|
||||||
provides [ main ] to pf
|
provides [main] to pf
|
||||||
|
|
||||||
main = ""
|
main = ""
|
||||||
"#
|
"#
|
||||||
|
@ -670,7 +670,7 @@ mod test_load {
|
||||||
exposes []
|
exposes []
|
||||||
packages {}
|
packages {}
|
||||||
imports []
|
imports []
|
||||||
provides [ mainForHost ]
|
provides [mainForHost]
|
||||||
blah 1 2 3 # causing a parse error on purpose
|
blah 1 2 3 # causing a parse error on purpose
|
||||||
|
|
||||||
mainForHost : Str
|
mainForHost : Str
|
||||||
|
@ -684,7 +684,7 @@ mod test_load {
|
||||||
app "hello-world"
|
app "hello-world"
|
||||||
packages { pf: "platform" }
|
packages { pf: "platform" }
|
||||||
imports []
|
imports []
|
||||||
provides [ main ] to pf
|
provides [main] to pf
|
||||||
|
|
||||||
main = "Hello, World!\n"
|
main = "Hello, World!\n"
|
||||||
"#
|
"#
|
||||||
|
@ -714,7 +714,7 @@ mod test_load {
|
||||||
exposes []
|
exposes []
|
||||||
packages {}
|
packages {}
|
||||||
imports []
|
imports []
|
||||||
provides [ mainForHost ]
|
provides [mainForHost]
|
||||||
|
|
||||||
mainForHost : { content: Str, other: Str }
|
mainForHost : { content: Str, other: Str }
|
||||||
mainForHost = main
|
mainForHost = main
|
||||||
|
@ -728,7 +728,7 @@ mod test_load {
|
||||||
app "hello-world"
|
app "hello-world"
|
||||||
packages { pf: "platform" }
|
packages { pf: "platform" }
|
||||||
imports []
|
imports []
|
||||||
provides [ main ] to pf
|
provides [main] to pf
|
||||||
|
|
||||||
main = { content: "Hello, World!\n", other: "" }
|
main = { content: "Hello, World!\n", other: "" }
|
||||||
"#
|
"#
|
||||||
|
@ -746,7 +746,7 @@ mod test_load {
|
||||||
"Age",
|
"Age",
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
interface Age exposes [ Age ] imports []
|
interface Age exposes [Age] imports []
|
||||||
|
|
||||||
Age := U32
|
Age := U32
|
||||||
"#
|
"#
|
||||||
|
@ -756,7 +756,7 @@ mod test_load {
|
||||||
"Main",
|
"Main",
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
interface Main exposes [ twenty, readAge ] imports [ Age.{ Age } ]
|
interface Main exposes [twenty, readAge] imports [Age.{ Age }]
|
||||||
|
|
||||||
twenty = @Age 20
|
twenty = @Age 20
|
||||||
|
|
||||||
|
@ -781,7 +781,7 @@ mod test_load {
|
||||||
|
|
||||||
is imported from another module:
|
is imported from another module:
|
||||||
|
|
||||||
1│ interface Main exposes [ twenty, readAge ] imports [ Age.{ Age } ]
|
1│ interface Main exposes [twenty, readAge] imports [Age.{ Age }]
|
||||||
^^^^^^^^^^^
|
^^^^^^^^^^^
|
||||||
|
|
||||||
Note: Opaque types can only be wrapped and unwrapped in the module they are defined in!
|
Note: Opaque types can only be wrapped and unwrapped in the module they are defined in!
|
||||||
|
@ -795,7 +795,7 @@ mod test_load {
|
||||||
|
|
||||||
is imported from another module:
|
is imported from another module:
|
||||||
|
|
||||||
1│ interface Main exposes [ twenty, readAge ] imports [ Age.{ Age } ]
|
1│ interface Main exposes [twenty, readAge] imports [Age.{ Age }]
|
||||||
^^^^^^^^^^^
|
^^^^^^^^^^^
|
||||||
|
|
||||||
Note: Opaque types can only be wrapped and unwrapped in the module they are defined in!
|
Note: Opaque types can only be wrapped and unwrapped in the module they are defined in!
|
||||||
|
@ -804,7 +804,7 @@ mod test_load {
|
||||||
|
|
||||||
Nothing from Age is used in this module.
|
Nothing from Age is used in this module.
|
||||||
|
|
||||||
1│ interface Main exposes [ twenty, readAge ] imports [ Age.{ Age } ]
|
1│ interface Main exposes [twenty, readAge] imports [Age.{ Age }]
|
||||||
^^^^^^^^^^^
|
^^^^^^^^^^^
|
||||||
|
|
||||||
Since Age isn't used, you don't need to import it.
|
Since Age isn't used, you don't need to import it.
|
||||||
|
@ -827,7 +827,7 @@ mod test_load {
|
||||||
exposes []
|
exposes []
|
||||||
packages {}
|
packages {}
|
||||||
imports []
|
imports []
|
||||||
provides [ mainForHost ]
|
provides [mainForHost]
|
||||||
|
|
||||||
mainForHost : Str
|
mainForHost : Str
|
||||||
mainForHost = main
|
mainForHost = main
|
||||||
|
@ -840,7 +840,7 @@ mod test_load {
|
||||||
r#"
|
r#"
|
||||||
app "test"
|
app "test"
|
||||||
packages { pf: "platform" }
|
packages { pf: "platform" }
|
||||||
provides [ main ] to pf
|
provides [main] to pf
|
||||||
|
|
||||||
main : DoesNotExist
|
main : DoesNotExist
|
||||||
main = 1
|
main = 1
|
||||||
|
|
|
@ -1154,9 +1154,9 @@ define_builtins! {
|
||||||
}
|
}
|
||||||
2 BOOL: "Bool" => {
|
2 BOOL: "Bool" => {
|
||||||
0 BOOL_BOOL: "Bool" // the Bool.Bool type alias
|
0 BOOL_BOOL: "Bool" // the Bool.Bool type alias
|
||||||
1 BOOL_FALSE: "False" imported // Bool.Bool = [ False, True ]
|
1 BOOL_FALSE: "False" imported // Bool.Bool = [False, True]
|
||||||
// NB: not strictly needed; used for finding tag names in error suggestions
|
// NB: not strictly needed; used for finding tag names in error suggestions
|
||||||
2 BOOL_TRUE: "True" imported // Bool.Bool = [ False, True ]
|
2 BOOL_TRUE: "True" imported // Bool.Bool = [False, True]
|
||||||
// NB: not strictly needed; used for finding tag names in error suggestions
|
// NB: not strictly needed; used for finding tag names in error suggestions
|
||||||
3 BOOL_AND: "and"
|
3 BOOL_AND: "and"
|
||||||
4 BOOL_OR: "or"
|
4 BOOL_OR: "or"
|
||||||
|
@ -1264,9 +1264,9 @@ define_builtins! {
|
||||||
}
|
}
|
||||||
5 RESULT: "Result" => {
|
5 RESULT: "Result" => {
|
||||||
0 RESULT_RESULT: "Result" // the Result.Result type alias
|
0 RESULT_RESULT: "Result" // the Result.Result type alias
|
||||||
1 RESULT_OK: "Ok" imported // Result.Result a e = [ Ok a, Err e ]
|
1 RESULT_OK: "Ok" imported // Result.Result a e = [Ok a, Err e]
|
||||||
// NB: not strictly needed; used for finding tag names in error suggestions
|
// NB: not strictly needed; used for finding tag names in error suggestions
|
||||||
2 RESULT_ERR: "Err" imported // Result.Result a e = [ Ok a, Err e ]
|
2 RESULT_ERR: "Err" imported // Result.Result a e = [Ok a, Err e]
|
||||||
// NB: not strictly needed; used for finding tag names in error suggestions
|
// NB: not strictly needed; used for finding tag names in error suggestions
|
||||||
3 RESULT_MAP: "map"
|
3 RESULT_MAP: "map"
|
||||||
4 RESULT_MAP_ERR: "mapErr"
|
4 RESULT_MAP_ERR: "mapErr"
|
||||||
|
|
|
@ -288,7 +288,7 @@ impl<'a> ParamMap<'a> {
|
||||||
fn visit_stmt(&mut self, arena: &'a Bump, _fnid: Symbol, stmt: &Stmt<'a>) {
|
fn visit_stmt(&mut self, arena: &'a Bump, _fnid: Symbol, stmt: &Stmt<'a>) {
|
||||||
use Stmt::*;
|
use Stmt::*;
|
||||||
|
|
||||||
let mut stack = bumpalo::vec![ in arena; stmt ];
|
let mut stack = bumpalo::vec![in arena; stmt];
|
||||||
|
|
||||||
while let Some(stmt) = stack.pop() {
|
while let Some(stmt) = stack.pop() {
|
||||||
match stmt {
|
match stmt {
|
||||||
|
@ -1001,7 +1001,7 @@ fn call_info_call<'a>(call: &crate::ir::Call<'a>, info: &mut CallInfo<'a>) {
|
||||||
fn call_info_stmt<'a>(arena: &'a Bump, stmt: &Stmt<'a>, info: &mut CallInfo<'a>) {
|
fn call_info_stmt<'a>(arena: &'a Bump, stmt: &Stmt<'a>, info: &mut CallInfo<'a>) {
|
||||||
use Stmt::*;
|
use Stmt::*;
|
||||||
|
|
||||||
let mut stack = bumpalo::vec![ in arena; stmt ];
|
let mut stack = bumpalo::vec![in arena; stmt];
|
||||||
|
|
||||||
while let Some(stmt) = stack.pop() {
|
while let Some(stmt) = stack.pop() {
|
||||||
match stmt {
|
match stmt {
|
||||||
|
|
|
@ -401,7 +401,7 @@ impl<'a> CodeGenHelp<'a> {
|
||||||
|
|
||||||
// When creating or looking up Specializations, we need to replace RecursivePointer
|
// When creating or looking up Specializations, we need to replace RecursivePointer
|
||||||
// with the particular Union layout it represents at this point in the tree.
|
// with the particular Union layout it represents at this point in the tree.
|
||||||
// For example if a program uses `RoseTree a : [ Tree a (List (RoseTree a)) ]`
|
// For example if a program uses `RoseTree a : [Tree a (List (RoseTree a))]`
|
||||||
// then it could have both `RoseTree I64` and `RoseTree Str`. In this case it
|
// then it could have both `RoseTree I64` and `RoseTree Str`. In this case it
|
||||||
// needs *two* specializations for `List(RecursivePointer)`, not just one.
|
// needs *two* specializations for `List(RecursivePointer)`, not just one.
|
||||||
fn replace_rec_ptr(&self, ctx: &Context<'a>, layout: Layout<'a>) -> Layout<'a> {
|
fn replace_rec_ptr(&self, ctx: &Context<'a>, layout: Layout<'a>) -> Layout<'a> {
|
||||||
|
|
|
@ -1455,11 +1455,11 @@ pub enum Literal<'a> {
|
||||||
/// Closed tag unions containing exactly two (0-arity) tags compile to Expr::Bool,
|
/// Closed tag unions containing exactly two (0-arity) tags compile to Expr::Bool,
|
||||||
/// so they can (at least potentially) be emitted as 1-bit machine bools.
|
/// so they can (at least potentially) be emitted as 1-bit machine bools.
|
||||||
///
|
///
|
||||||
/// So [ True, False ] compiles to this, and so do [ A, B ] and [ Foo, Bar ].
|
/// So [True, False] compiles to this, and so do [A, B] and [Foo, Bar].
|
||||||
/// However, a union like [ True, False, Other Int ] would not.
|
/// However, a union like [True, False, Other Int] would not.
|
||||||
Bool(bool),
|
Bool(bool),
|
||||||
/// Closed tag unions containing between 3 and 256 tags (all of 0 arity)
|
/// Closed tag unions containing between 3 and 256 tags (all of 0 arity)
|
||||||
/// compile to bytes, e.g. [ Blue, Black, Red, Green, White ]
|
/// compile to bytes, e.g. [Blue, Black, Red, Green, White]
|
||||||
Byte(u8),
|
Byte(u8),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -262,23 +262,23 @@ pub enum Layout<'a> {
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
||||||
pub enum UnionLayout<'a> {
|
pub enum UnionLayout<'a> {
|
||||||
/// A non-recursive tag union
|
/// A non-recursive tag union
|
||||||
/// e.g. `Result a e : [ Ok a, Err e ]`
|
/// e.g. `Result a e : [Ok a, Err e]`
|
||||||
NonRecursive(&'a [&'a [Layout<'a>]]),
|
NonRecursive(&'a [&'a [Layout<'a>]]),
|
||||||
/// A recursive tag union (general case)
|
/// A recursive tag union (general case)
|
||||||
/// e.g. `Expr : [ Sym Str, Add Expr Expr ]`
|
/// e.g. `Expr : [Sym Str, Add Expr Expr]`
|
||||||
Recursive(&'a [&'a [Layout<'a>]]),
|
Recursive(&'a [&'a [Layout<'a>]]),
|
||||||
/// A recursive tag union with just one constructor
|
/// A recursive tag union with just one constructor
|
||||||
/// Optimization: No need to store a tag ID (the payload is "unwrapped")
|
/// Optimization: No need to store a tag ID (the payload is "unwrapped")
|
||||||
/// e.g. `RoseTree a : [ Tree a (List (RoseTree a)) ]`
|
/// e.g. `RoseTree a : [Tree a (List (RoseTree a))]`
|
||||||
NonNullableUnwrapped(&'a [Layout<'a>]),
|
NonNullableUnwrapped(&'a [Layout<'a>]),
|
||||||
/// A recursive tag union that has an empty variant
|
/// A recursive tag union that has an empty variant
|
||||||
/// Optimization: Represent the empty variant as null pointer => no memory usage & fast comparison
|
/// Optimization: Represent the empty variant as null pointer => no memory usage & fast comparison
|
||||||
/// It has more than one other variant, so they need tag IDs (payloads are "wrapped")
|
/// It has more than one other variant, so they need tag IDs (payloads are "wrapped")
|
||||||
/// e.g. `FingerTree a : [ Empty, Single a, More (Some a) (FingerTree (Tuple a)) (Some a) ]`
|
/// e.g. `FingerTree a : [Empty, Single a, More (Some a) (FingerTree (Tuple a)) (Some a)]`
|
||||||
/// see also: https://youtu.be/ip92VMpf_-A?t=164
|
/// see also: https://youtu.be/ip92VMpf_-A?t=164
|
||||||
///
|
///
|
||||||
/// nullable_id refers to the index of the tag that is represented at runtime as NULL.
|
/// nullable_id refers to the index of the tag that is represented at runtime as NULL.
|
||||||
/// For example, in `FingerTree a : [ Empty, Single a, More (Some a) (FingerTree (Tuple a)) (Some a) ]`,
|
/// For example, in `FingerTree a : [Empty, Single a, More (Some a) (FingerTree (Tuple a)) (Some a)]`,
|
||||||
/// the ids would be Empty = 0, More = 1, Single = 2, because that's how those tags are
|
/// the ids would be Empty = 0, More = 1, Single = 2, because that's how those tags are
|
||||||
/// ordered alphabetically. Since the Empty tag will be represented at runtime as NULL,
|
/// ordered alphabetically. Since the Empty tag will be represented at runtime as NULL,
|
||||||
/// and since Empty's tag id is 0, here nullable_id would be 0.
|
/// and since Empty's tag id is 0, here nullable_id would be 0.
|
||||||
|
@ -288,12 +288,12 @@ pub enum UnionLayout<'a> {
|
||||||
},
|
},
|
||||||
/// A recursive tag union with only two variants, where one is empty.
|
/// A recursive tag union with only two variants, where one is empty.
|
||||||
/// Optimizations: Use null for the empty variant AND don't store a tag ID for the other variant.
|
/// Optimizations: Use null for the empty variant AND don't store a tag ID for the other variant.
|
||||||
/// e.g. `ConsList a : [ Nil, Cons a (ConsList a) ]`
|
/// e.g. `ConsList a : [Nil, Cons a (ConsList a)]`
|
||||||
///
|
///
|
||||||
/// nullable_id is a bool because it's only ever 0 or 1, but (as with the NullableWrapped
|
/// nullable_id is a bool because it's only ever 0 or 1, but (as with the NullableWrapped
|
||||||
/// variant), it reprsents the index of the tag that will be represented at runtime as NULL.
|
/// variant), it reprsents the index of the tag that will be represented at runtime as NULL.
|
||||||
///
|
///
|
||||||
/// So for example, in `ConsList a : [ Nil, Cons a (ConsList a) ]`, Nil is tag id 1 and
|
/// So for example, in `ConsList a : [Nil, Cons a (ConsList a)]`, Nil is tag id 1 and
|
||||||
/// Cons is tag id 0 because Nil comes alphabetically after Cons. Here, Nil will be
|
/// Cons is tag id 0 because Nil comes alphabetically after Cons. Here, Nil will be
|
||||||
/// represented as NULL at runtime, so nullable_id is 1 - which is to say, `true`, because
|
/// represented as NULL at runtime, so nullable_id is 1 - which is to say, `true`, because
|
||||||
/// `(1 as bool)` is `true`.
|
/// `(1 as bool)` is `true`.
|
||||||
|
@ -2145,7 +2145,7 @@ pub fn union_sorted_tags<'a>(
|
||||||
Ok(())
|
Ok(())
|
||||||
// Admit type variables in the extension for now. This may come from things that never got
|
// Admit type variables in the extension for now. This may come from things that never got
|
||||||
// monomorphized, like in
|
// monomorphized, like in
|
||||||
// x : [ A ]*
|
// x : [A]*
|
||||||
// x = A
|
// x = A
|
||||||
// x
|
// x
|
||||||
// In such cases it's fine to drop the variable. We may be proven wrong in the future...
|
// In such cases it's fine to drop the variable. We may be proven wrong in the future...
|
||||||
|
|
|
@ -392,7 +392,7 @@ pub struct HasClause<'a> {
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, PartialEq)]
|
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||||
pub enum Derived<'a> {
|
pub enum Derived<'a> {
|
||||||
/// `has [ Eq, Hash ]`
|
/// `has [Eq, Hash]`
|
||||||
Has(Collection<'a, AbilityName<'a>>),
|
Has(Collection<'a, AbilityName<'a>>),
|
||||||
|
|
||||||
// We preserve this for the formatter; canonicalization ignores it.
|
// We preserve this for the formatter; canonicalization ignores it.
|
||||||
|
@ -429,7 +429,7 @@ pub enum TypeAnnotation<'a> {
|
||||||
/// A bound type variable, e.g. `a` in `(a -> a)`
|
/// A bound type variable, e.g. `a` in `(a -> a)`
|
||||||
BoundVariable(&'a str),
|
BoundVariable(&'a str),
|
||||||
|
|
||||||
/// Inline type alias, e.g. `as List a` in `[ Cons a (List a), Nil ] as List a`
|
/// Inline type alias, e.g. `as List a` in `[Cons a (List a), Nil] as List a`
|
||||||
As(
|
As(
|
||||||
&'a Loc<TypeAnnotation<'a>>,
|
&'a Loc<TypeAnnotation<'a>>,
|
||||||
&'a [CommentOrNewline<'a>],
|
&'a [CommentOrNewline<'a>],
|
||||||
|
@ -445,8 +445,8 @@ pub enum TypeAnnotation<'a> {
|
||||||
|
|
||||||
/// A tag union, e.g. `[
|
/// A tag union, e.g. `[
|
||||||
TagUnion {
|
TagUnion {
|
||||||
/// The row type variable in an open tag union, e.g. the `a` in `[ Foo, Bar ]a`.
|
/// The row type variable in an open tag union, e.g. the `a` in `[Foo, Bar]a`.
|
||||||
/// This is None if it's a closed tag union like `[ Foo, Bar]`.
|
/// This is None if it's a closed tag union like `[Foo, Bar]`.
|
||||||
ext: Option<&'a Loc<TypeAnnotation<'a>>>,
|
ext: Option<&'a Loc<TypeAnnotation<'a>>>,
|
||||||
tags: Collection<'a, Loc<Tag<'a>>>,
|
tags: Collection<'a, Loc<Tag<'a>>>,
|
||||||
},
|
},
|
||||||
|
|
|
@ -600,7 +600,7 @@ fn append_body_definition<'a>(
|
||||||
}),
|
}),
|
||||||
)) => {
|
)) => {
|
||||||
// This is a case like
|
// This is a case like
|
||||||
// UserId x : [ UserId Int ]
|
// UserId x : [UserId Int]
|
||||||
// UserId x = UserId 42
|
// UserId x = UserId 42
|
||||||
// We optimistically parsed the first line as an alias; we now turn it
|
// We optimistically parsed the first line as an alias; we now turn it
|
||||||
// into an annotation.
|
// into an annotation.
|
||||||
|
|
|
@ -48,7 +48,7 @@ fn tag_union_type<'a>(
|
||||||
)
|
)
|
||||||
.parse(arena, state)?;
|
.parse(arena, state)?;
|
||||||
|
|
||||||
// This could be an open tag union, e.g. `[ Foo, Bar ]a`
|
// This could be an open tag union, e.g. `[Foo, Bar]a`
|
||||||
let (_, ext, state) = optional(allocated(specialize_ref(
|
let (_, ext, state) = optional(allocated(specialize_ref(
|
||||||
ETypeTagUnion::Type,
|
ETypeTagUnion::Type,
|
||||||
term(min_indent, stop_at_surface_has),
|
term(min_indent, stop_at_surface_has),
|
||||||
|
@ -135,7 +135,7 @@ fn term<'a>(
|
||||||
loc!(parse_type_variable(stop_at_surface_has)),
|
loc!(parse_type_variable(stop_at_surface_has)),
|
||||||
fail_type_start(),
|
fail_type_start(),
|
||||||
),
|
),
|
||||||
// Inline alias notation, e.g. [ Nil, Cons a (List a) ] as List a
|
// Inline alias notation, e.g. [Nil, Cons a (List a)] as List a
|
||||||
one_of![
|
one_of![
|
||||||
map!(
|
map!(
|
||||||
and!(
|
and!(
|
||||||
|
@ -478,7 +478,7 @@ fn has_clause_chain<'a>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parse a has-derived clause, e.g. `has [ Eq, Hash ]`.
|
/// Parse a has-derived clause, e.g. `has [Eq, Hash]`.
|
||||||
pub fn has_derived<'a>(min_indent: u32) -> impl Parser<'a, Loc<Derived<'a>>, EType<'a>> {
|
pub fn has_derived<'a>(min_indent: u32) -> impl Parser<'a, Loc<Derived<'a>>, EType<'a>> {
|
||||||
skip_first!(
|
skip_first!(
|
||||||
// Parse "has"; we don't care about this keyword
|
// Parse "has"; we don't care about this keyword
|
||||||
|
|
|
@ -704,7 +704,7 @@ mod test_parse {
|
||||||
// assert_parses_to(
|
// assert_parses_to(
|
||||||
// indoc!(
|
// indoc!(
|
||||||
// r#"
|
// r#"
|
||||||
// foo : [ True, Perhaps Thing ]*
|
// foo : [True, Perhaps Thing]*
|
||||||
// foo = True
|
// foo = True
|
||||||
|
|
||||||
// 42
|
// 42
|
||||||
|
@ -757,7 +757,7 @@ mod test_parse {
|
||||||
// assert_parses_to(
|
// assert_parses_to(
|
||||||
// indoc!(
|
// indoc!(
|
||||||
// r#"
|
// r#"
|
||||||
// foo : [ True, Perhaps Thing ]
|
// foo : [True, Perhaps Thing]
|
||||||
// foo = True
|
// foo = True
|
||||||
|
|
||||||
// 42
|
// 42
|
||||||
|
|
|
@ -233,8 +233,8 @@ pub enum RuntimeError {
|
||||||
/// ```roc
|
/// ```roc
|
||||||
/// app "hello"
|
/// app "hello"
|
||||||
/// packages { pf: "platform" }
|
/// packages { pf: "platform" }
|
||||||
/// imports [ pf.Stdout]
|
/// imports [pf.Stdout]
|
||||||
/// provides [ main ] to pf
|
/// provides [main] to pf
|
||||||
///
|
///
|
||||||
/// main : Task.Task {} [] // Task isn't imported!
|
/// main : Task.Task {} [] // Task isn't imported!
|
||||||
/// main = Stdout.line "I'm a Roc application!"
|
/// main = Stdout.line "I'm a Roc application!"
|
||||||
|
|
|
@ -2751,12 +2751,12 @@ fn adjust_rank_content(
|
||||||
// Normally this is not a problem because of the loop below that maximizes the
|
// Normally this is not a problem because of the loop below that maximizes the
|
||||||
// rank from nested types in the union. But suppose we have the simple tag
|
// rank from nested types in the union. But suppose we have the simple tag
|
||||||
// union
|
// union
|
||||||
// [ Z ]{}
|
// [Z]{}
|
||||||
// there are no nested types in the tags, and the empty tag union is at rank 0,
|
// there are no nested types in the tags, and the empty tag union is at rank 0,
|
||||||
// so we promote the tag union to rank 0. Now if we introduce the presence
|
// so we promote the tag union to rank 0. Now if we introduce the presence
|
||||||
// constraint
|
// constraint
|
||||||
// [ Z ]{} += [ S a ]
|
// [Z]{} += [S a]
|
||||||
// we'll wind up with [ Z, S a ]{}, but it will be at rank 0, and "a" will get
|
// we'll wind up with [Z, S a]{}, but it will be at rank 0, and "a" will get
|
||||||
// over-generalized. Really, the empty tag union should be introduced at
|
// over-generalized. Really, the empty tag union should be introduced at
|
||||||
// whatever current group rank we're at, and so that's how we encode it here.
|
// whatever current group rank we're at, and so that's how we encode it here.
|
||||||
if *ext_var == Variable::EMPTY_TAG_UNION && rank.is_none() {
|
if *ext_var == Variable::EMPTY_TAG_UNION && rank.is_none() {
|
||||||
|
@ -2798,7 +2798,7 @@ fn adjust_rank_content(
|
||||||
// For example, see the `recursion_var_specialization_error` reporting test -
|
// For example, see the `recursion_var_specialization_error` reporting test -
|
||||||
// there, we have
|
// there, we have
|
||||||
//
|
//
|
||||||
// Job a : [ Job (List (Job a)) a ]
|
// Job a : [Job (List (Job a)) a]
|
||||||
//
|
//
|
||||||
// job : Job Str
|
// job : Job Str
|
||||||
//
|
//
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -22,7 +22,7 @@ Here's what the fields mean:
|
||||||
|
|
||||||
## Nonempty list
|
## Nonempty list
|
||||||
|
|
||||||
Now let's say we define a `List Str` with two elements in it, like so: `[ "foo", "bar" ]`.
|
Now let's say we define a `List Str` with two elements in it, like so: `["foo", "bar"]`.
|
||||||
|
|
||||||
First we'd have the `struct` above, with both `length` and `capacity` set to 2. Then, we'd have some memory allocated on the heap, and `pointer` would store that memory's address.
|
First we'd have the `struct` above, with both `length` and `capacity` set to 2. Then, we'd have some memory allocated on the heap, and `pointer` would store that memory's address.
|
||||||
|
|
||||||
|
@ -49,7 +49,7 @@ This is memory-inefficient, but it's the price we pay for having all the 16B str
|
||||||
|
|
||||||
Let's go back to the refcount - short for "reference count."
|
Let's go back to the refcount - short for "reference count."
|
||||||
|
|
||||||
The refcount is a `usize` integer which counts how many times this `List` has been shared. For example, if we named this list `myList` and then wrote `[ myList, myList, myList ]` then we'd increment that refcount 3 times because `myList` is now being shared three more times.
|
The refcount is a `usize` integer which counts how many times this `List` has been shared. For example, if we named this list `myList` and then wrote `[myList, myList, myList]` then we'd increment that refcount 3 times because `myList` is now being shared three more times.
|
||||||
|
|
||||||
If we were to later call `List.pop` on that list, and the result was an in-place mutation that removed one of the `myList` entries, we'd decrement the refcount. If we did that again and again until the refcount got all the way down to 0, meaning nothing is using it anymore, then we'd deallocate these 48B of heap memory because nobody is using them anymore.
|
If we were to later call `List.pop` on that list, and the result was an in-place mutation that removed one of the `myList` entries, we'd decrement the refcount. If we did that again and again until the refcount got all the way down to 0, meaning nothing is using it anymore, then we'd deallocate these 48B of heap memory because nobody is using them anymore.
|
||||||
|
|
||||||
|
@ -94,7 +94,7 @@ When you have a way to anticipate that a list will want to grow incrementally to
|
||||||
|
|
||||||
Some lists may end up beginning with excess capacity due to memory alignment requirements. Since the refcount is `usize`, all lists need a minimum of that alignment. For example, on a 64-bit system, a `List Bool` has an alignment of 8B even though bools can fit in 1B.
|
Some lists may end up beginning with excess capacity due to memory alignment requirements. Since the refcount is `usize`, all lists need a minimum of that alignment. For example, on a 64-bit system, a `List Bool` has an alignment of 8B even though bools can fit in 1B.
|
||||||
|
|
||||||
This means the list `[ True, True, False ]` would have a memory layout like this):
|
This means the list `[True, True, False]` would have a memory layout like this):
|
||||||
|
|
||||||
```
|
```
|
||||||
|--------------8B--------------|--1B--|--1B--|--1B--|-----5B-----|
|
|--------------8B--------------|--1B--|--1B--|--1B--|-----5B-----|
|
||||||
|
|
|
@ -19,7 +19,7 @@ fn hash_specialization() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
app "test" provides [ main ] to "./platform"
|
app "test" provides [main] to "./platform"
|
||||||
|
|
||||||
Hash has
|
Hash has
|
||||||
hash : a -> U64 | a has Hash
|
hash : a -> U64 | a has Hash
|
||||||
|
@ -42,7 +42,7 @@ fn hash_specialization_multiple_add() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
app "test" provides [ main ] to "./platform"
|
app "test" provides [main] to "./platform"
|
||||||
|
|
||||||
Hash has
|
Hash has
|
||||||
hash : a -> U64 | a has Hash
|
hash : a -> U64 | a has Hash
|
||||||
|
@ -69,7 +69,7 @@ fn alias_member_specialization() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
app "test" provides [ main ] to "./platform"
|
app "test" provides [main] to "./platform"
|
||||||
|
|
||||||
Hash has
|
Hash has
|
||||||
hash : a -> U64 | a has Hash
|
hash : a -> U64 | a has Hash
|
||||||
|
@ -94,7 +94,7 @@ fn ability_constrained_in_non_member_usage() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
app "test" provides [ result ] to "./platform"
|
app "test" provides [result] to "./platform"
|
||||||
|
|
||||||
Hash has
|
Hash has
|
||||||
hash : a -> U64 | a has Hash
|
hash : a -> U64 | a has Hash
|
||||||
|
@ -119,7 +119,7 @@ fn ability_constrained_in_non_member_usage_inferred() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
app "test" provides [ result ] to "./platform"
|
app "test" provides [result] to "./platform"
|
||||||
|
|
||||||
Hash has
|
Hash has
|
||||||
hash : a -> U64 | a has Hash
|
hash : a -> U64 | a has Hash
|
||||||
|
@ -143,7 +143,7 @@ fn ability_constrained_in_non_member_multiple_specializations() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
app "test" provides [ result ] to "./platform"
|
app "test" provides [result] to "./platform"
|
||||||
|
|
||||||
Hash has
|
Hash has
|
||||||
hash : a -> U64 | a has Hash
|
hash : a -> U64 | a has Hash
|
||||||
|
@ -171,7 +171,7 @@ fn ability_constrained_in_non_member_multiple_specializations_inferred() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
app "test" provides [ result ] to "./platform"
|
app "test" provides [result] to "./platform"
|
||||||
|
|
||||||
Hash has
|
Hash has
|
||||||
hash : a -> U64 | a has Hash
|
hash : a -> U64 | a has Hash
|
||||||
|
@ -198,7 +198,7 @@ fn ability_used_as_type_still_compiles() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
app "test" provides [ result ] to "./platform"
|
app "test" provides [result] to "./platform"
|
||||||
|
|
||||||
Hash has
|
Hash has
|
||||||
hash : a -> U64 | a has Hash
|
hash : a -> U64 | a has Hash
|
||||||
|
@ -226,7 +226,7 @@ fn encode() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
app "test" provides [ myU8Bytes ] to "./platform"
|
app "test" provides [myU8Bytes] to "./platform"
|
||||||
|
|
||||||
Encoder fmt := List U8, fmt -> List U8 | fmt has Format
|
Encoder fmt := List U8, fmt -> List U8 | fmt has Format
|
||||||
|
|
||||||
|
@ -272,9 +272,9 @@ fn decode() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
app "test" provides [ myU8 ] to "./platform"
|
app "test" provides [myU8] to "./platform"
|
||||||
|
|
||||||
DecodeError : [ TooShort, Leftover (List U8) ]
|
DecodeError : [TooShort, Leftover (List U8)]
|
||||||
|
|
||||||
Decoder val fmt := List U8, fmt -> { result: Result val DecodeError, rest: List U8 } | fmt has DecoderFormatting
|
Decoder val fmt := List U8, fmt -> { result: Result val DecodeError, rest: List U8 } | fmt has DecoderFormatting
|
||||||
|
|
||||||
|
@ -314,7 +314,7 @@ fn decode() {
|
||||||
{ result: Result.map result (\n -> @MyU8 n), rest }
|
{ result: Result.map result (\n -> @MyU8 n), rest }
|
||||||
|
|
||||||
myU8 =
|
myU8 =
|
||||||
when fromBytes [ 15 ] (@Linear {}) is
|
when fromBytes [15] (@Linear {}) is
|
||||||
Ok (@MyU8 n) -> n
|
Ok (@MyU8 n) -> n
|
||||||
_ -> 27u8
|
_ -> 27u8
|
||||||
"#
|
"#
|
||||||
|
|
|
@ -276,7 +276,7 @@ fn eq_expr() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
Expr : [ Add Expr Expr, Mul Expr Expr, Val I64, Var I64 ]
|
Expr : [Add Expr Expr, Mul Expr Expr, Val I64, Var I64]
|
||||||
|
|
||||||
x : Expr
|
x : Expr
|
||||||
x = Val 0
|
x = Val 0
|
||||||
|
@ -298,7 +298,7 @@ fn eq_linked_list() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
LinkedList a : [ Nil, Cons a (LinkedList a) ]
|
LinkedList a : [Nil, Cons a (LinkedList a)]
|
||||||
|
|
||||||
x : LinkedList I64
|
x : LinkedList I64
|
||||||
x = Nil
|
x = Nil
|
||||||
|
@ -316,7 +316,7 @@ fn eq_linked_list() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
LinkedList a : [ Nil, Cons a (LinkedList a) ]
|
LinkedList a : [Nil, Cons a (LinkedList a)]
|
||||||
|
|
||||||
x : LinkedList I64
|
x : LinkedList I64
|
||||||
x = Cons 1 Nil
|
x = Cons 1 Nil
|
||||||
|
@ -334,7 +334,7 @@ fn eq_linked_list() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
LinkedList a : [ Nil, Cons a (LinkedList a) ]
|
LinkedList a : [Nil, Cons a (LinkedList a)]
|
||||||
|
|
||||||
x : LinkedList I64
|
x : LinkedList I64
|
||||||
x = Cons 1 (Cons 2 Nil)
|
x = Cons 1 (Cons 2 Nil)
|
||||||
|
@ -356,7 +356,7 @@ fn eq_linked_list_false() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
LinkedList a : [ Nil, Cons a (LinkedList a) ]
|
LinkedList a : [Nil, Cons a (LinkedList a)]
|
||||||
|
|
||||||
x : LinkedList I64
|
x : LinkedList I64
|
||||||
x = Cons 1 Nil
|
x = Cons 1 Nil
|
||||||
|
@ -378,9 +378,9 @@ fn eq_linked_list_long() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
app "test" provides [ main ] to "./platform"
|
app "test" provides [main] to "./platform"
|
||||||
|
|
||||||
LinkedList a : [ Nil, Cons a (LinkedList a) ]
|
LinkedList a : [Nil, Cons a (LinkedList a)]
|
||||||
|
|
||||||
prependOnes = \n, tail ->
|
prependOnes = \n, tail ->
|
||||||
if n == 0 then
|
if n == 0 then
|
||||||
|
@ -411,7 +411,7 @@ fn eq_nullable_expr() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
Expr : [ Add Expr Expr, Mul Expr Expr, Val I64, Empty ]
|
Expr : [Add Expr Expr, Mul Expr Expr, Val I64, Empty]
|
||||||
|
|
||||||
x : Expr
|
x : Expr
|
||||||
x = Val 0
|
x = Val 0
|
||||||
|
@ -434,7 +434,7 @@ fn eq_rosetree() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
Rose a : [ Rose a (List (Rose a)) ]
|
Rose a : [Rose a (List (Rose a))]
|
||||||
|
|
||||||
x : Rose I64
|
x : Rose I64
|
||||||
x = Rose 0 []
|
x = Rose 0 []
|
||||||
|
@ -452,7 +452,7 @@ fn eq_rosetree() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
Rose a : [ Rose a (List (Rose a)) ]
|
Rose a : [Rose a (List (Rose a))]
|
||||||
|
|
||||||
x : Rose I64
|
x : Rose I64
|
||||||
x = Rose 0 []
|
x = Rose 0 []
|
||||||
|
@ -470,7 +470,7 @@ fn eq_rosetree() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
Rose a : [ Rose a (List (Rose a)) ]
|
Rose a : [Rose a (List (Rose a))]
|
||||||
|
|
||||||
a1 : Rose I64
|
a1 : Rose I64
|
||||||
a1 = Rose 999 []
|
a1 = Rose 999 []
|
||||||
|
@ -506,7 +506,7 @@ fn eq_different_rosetrees() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
Rose a : [ Rose a (List (Rose a)) ]
|
Rose a : [Rose a (List (Rose a))]
|
||||||
|
|
||||||
a1 : Rose I64
|
a1 : Rose I64
|
||||||
a1 = Rose 999 []
|
a1 = Rose 999 []
|
||||||
|
@ -549,7 +549,7 @@ fn rosetree_with_tag() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
Rose a : [ Rose (Result (List (Rose a)) I64) ]
|
Rose a : [Rose (Result (List (Rose a)) I64)]
|
||||||
|
|
||||||
x : Rose I64
|
x : Rose I64
|
||||||
x = (Rose (Ok []))
|
x = (Rose (Ok []))
|
||||||
|
@ -613,7 +613,7 @@ fn compare_union_same_content() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
Foo : [ A I64, B I64 ]
|
Foo : [A I64, B I64]
|
||||||
|
|
||||||
a : Foo
|
a : Foo
|
||||||
a = A 42
|
a = A 42
|
||||||
|
@ -635,7 +635,7 @@ fn compare_recursive_union_same_content() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
Expr : [ Add Expr Expr, Mul Expr Expr, Val1 I64, Val2 I64 ]
|
Expr : [Add Expr Expr, Mul Expr Expr, Val1 I64, Val2 I64]
|
||||||
|
|
||||||
v1 : Expr
|
v1 : Expr
|
||||||
v1 = Val1 42
|
v1 = Val1 42
|
||||||
|
@ -657,7 +657,7 @@ fn compare_nullable_recursive_union_same_content() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
Expr : [ Add Expr Expr, Mul Expr Expr, Val1 I64, Val2 I64, Empty ]
|
Expr : [Add Expr Expr, Mul Expr Expr, Val1 I64, Val2 I64, Empty]
|
||||||
|
|
||||||
v1 : Expr
|
v1 : Expr
|
||||||
v1 = Val1 42
|
v1 = Val1 42
|
||||||
|
|
|
@ -46,9 +46,9 @@ fn int_singleton_list_literal() {
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))]
|
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))]
|
||||||
fn int_list_literal() {
|
fn int_list_literal() {
|
||||||
assert_evals_to!("[ 12, 9 ]", RocList::from_slice(&[12, 9]), RocList<i64>);
|
assert_evals_to!("[12, 9]", RocList::from_slice(&[12, 9]), RocList<i64>);
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
"[ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 ]",
|
"[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]",
|
||||||
RocList::from_slice(&[1i64; 23]),
|
RocList::from_slice(&[1i64; 23]),
|
||||||
RocList<i64>
|
RocList<i64>
|
||||||
);
|
);
|
||||||
|
@ -59,7 +59,7 @@ fn int_list_literal() {
|
||||||
fn bool_list_literal() {
|
fn bool_list_literal() {
|
||||||
// NOTE: make sure to explicitly declare the elements to be of type bool, or
|
// NOTE: make sure to explicitly declare the elements to be of type bool, or
|
||||||
// use both True and False; only using one of them causes the list to in practice be
|
// use both True and False; only using one of them causes the list to in practice be
|
||||||
// of type `List [ True ]` or `List [ False ]`, those are tag unions with one constructor
|
// of type `List [True]` or `List [False]`, those are tag unions with one constructor
|
||||||
// and not fields, and don't have a runtime representation.
|
// and not fields, and don't have a runtime representation.
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
|
@ -67,7 +67,7 @@ fn bool_list_literal() {
|
||||||
false : Bool
|
false : Bool
|
||||||
false = False
|
false = False
|
||||||
|
|
||||||
[ false ]
|
[false]
|
||||||
"#
|
"#
|
||||||
),
|
),
|
||||||
RocList::from_slice(&[false; 1]),
|
RocList::from_slice(&[false; 1]),
|
||||||
|
@ -75,7 +75,7 @@ fn bool_list_literal() {
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
"[ True, False, True ]",
|
"[True, False, True]",
|
||||||
RocList::from_slice(&[true, false, true]),
|
RocList::from_slice(&[true, false, true]),
|
||||||
RocList<bool>
|
RocList<bool>
|
||||||
);
|
);
|
||||||
|
@ -86,7 +86,7 @@ fn bool_list_literal() {
|
||||||
false : Bool
|
false : Bool
|
||||||
false = False
|
false = False
|
||||||
|
|
||||||
[false ]
|
[false]
|
||||||
"#
|
"#
|
||||||
),
|
),
|
||||||
RocList::from_slice(&[false; 1]),
|
RocList::from_slice(&[false; 1]),
|
||||||
|
@ -382,7 +382,7 @@ fn list_drop_at_shared() {
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
list : List I64
|
list : List I64
|
||||||
list = [ if True then 4 else 4, 5, 6 ]
|
list = [if True then 4 else 4, 5, 6]
|
||||||
|
|
||||||
{ newList: List.dropAt list 0, original: list }
|
{ newList: List.dropAt list 0, original: list }
|
||||||
"#
|
"#
|
||||||
|
@ -514,7 +514,7 @@ fn list_drop_last_mutable() {
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
list : List I64
|
list : List I64
|
||||||
list = [ if True then 4 else 4, 5, 6 ]
|
list = [if True then 4 else 4, 5, 6]
|
||||||
|
|
||||||
{ newList: List.dropLast list, original: list }
|
{ newList: List.dropLast list, original: list }
|
||||||
"#
|
"#
|
||||||
|
@ -557,33 +557,29 @@ fn list_swap() {
|
||||||
RocList::<i64>::from_slice(&[]),
|
RocList::<i64>::from_slice(&[]),
|
||||||
RocList<i64>
|
RocList<i64>
|
||||||
);
|
);
|
||||||
|
assert_evals_to!("List.swap [0] 1 2", RocList::from_slice(&[0]), RocList<i64>);
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
"List.swap [ 0 ] 1 2",
|
"List.swap [1, 2] 0 1",
|
||||||
RocList::from_slice(&[0]),
|
|
||||||
RocList<i64>
|
|
||||||
);
|
|
||||||
assert_evals_to!(
|
|
||||||
"List.swap [ 1, 2 ] 0 1",
|
|
||||||
RocList::from_slice(&[2, 1]),
|
RocList::from_slice(&[2, 1]),
|
||||||
RocList<i64>
|
RocList<i64>
|
||||||
);
|
);
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
"List.swap [ 1, 2 ] 1 0",
|
"List.swap [1, 2] 1 0",
|
||||||
RocList::from_slice(&[2, 1]),
|
RocList::from_slice(&[2, 1]),
|
||||||
RocList<i64>
|
RocList<i64>
|
||||||
);
|
);
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
"List.swap [ 0, 1, 2, 3, 4, 5 ] 2 4",
|
"List.swap [0, 1, 2, 3, 4, 5] 2 4",
|
||||||
RocList::from_slice(&[0, 1, 4, 3, 2, 5]),
|
RocList::from_slice(&[0, 1, 4, 3, 2, 5]),
|
||||||
RocList<i64>
|
RocList<i64>
|
||||||
);
|
);
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
"List.swap [ 0, 1, 2 ] 1 3",
|
"List.swap [0, 1, 2] 1 3",
|
||||||
RocList::from_slice(&[0, 1, 2]),
|
RocList::from_slice(&[0, 1, 2]),
|
||||||
RocList<i64>
|
RocList<i64>
|
||||||
);
|
);
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
"List.swap [ 1, 2, 3 ] 1 1",
|
"List.swap [1, 2, 3] 1 1",
|
||||||
RocList::from_slice(&[1, 2, 3]),
|
RocList::from_slice(&[1, 2, 3]),
|
||||||
RocList<i64>
|
RocList<i64>
|
||||||
);
|
);
|
||||||
|
@ -617,7 +613,7 @@ fn list_append_to_empty_list_of_int() {
|
||||||
#[cfg(any(feature = "gen-llvm"))]
|
#[cfg(any(feature = "gen-llvm"))]
|
||||||
fn list_append_bools() {
|
fn list_append_bools() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
"List.append [ True, False ] True",
|
"List.append [True, False] True",
|
||||||
RocList::from_slice(&[true, false, true]),
|
RocList::from_slice(&[true, false, true]),
|
||||||
RocList<bool>
|
RocList<bool>
|
||||||
);
|
);
|
||||||
|
@ -627,7 +623,7 @@ fn list_append_bools() {
|
||||||
#[cfg(any(feature = "gen-llvm"))]
|
#[cfg(any(feature = "gen-llvm"))]
|
||||||
fn list_append_longer_list() {
|
fn list_append_longer_list() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
"List.append [ 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22 ] 23",
|
"List.append [11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22] 23",
|
||||||
RocList::from_slice(&[11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23]),
|
RocList::from_slice(&[11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23]),
|
||||||
RocList<i64>
|
RocList<i64>
|
||||||
);
|
);
|
||||||
|
@ -676,7 +672,7 @@ fn list_prepend() {
|
||||||
#[cfg(any(feature = "gen-llvm"))]
|
#[cfg(any(feature = "gen-llvm"))]
|
||||||
fn list_prepend_bools() {
|
fn list_prepend_bools() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
"List.prepend [ True, False ] True",
|
"List.prepend [True, False] True",
|
||||||
RocList::from_slice(&[true, true, false]),
|
RocList::from_slice(&[true, true, false]),
|
||||||
RocList<bool>
|
RocList<bool>
|
||||||
);
|
);
|
||||||
|
@ -686,7 +682,7 @@ fn list_prepend_bools() {
|
||||||
#[cfg(any(feature = "gen-llvm"))]
|
#[cfg(any(feature = "gen-llvm"))]
|
||||||
fn list_prepend_big_list() {
|
fn list_prepend_big_list() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
"List.prepend [ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 100, 100, 100, 100 ] 9",
|
"List.prepend [10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 100, 100, 100, 100] 9",
|
||||||
RocList::from_slice(&[
|
RocList::from_slice(&[
|
||||||
9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 100, 100, 100, 100
|
9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 100, 100, 100, 100
|
||||||
]),
|
]),
|
||||||
|
@ -726,13 +722,13 @@ fn list_walk_backwards_empty_all_inline() {
|
||||||
#[cfg(any(feature = "gen-llvm"))]
|
#[cfg(any(feature = "gen-llvm"))]
|
||||||
fn list_walk_backwards_with_str() {
|
fn list_walk_backwards_with_str() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
r#"List.walkBackwards [ "x", "y", "z" ] "<" Str.concat"#,
|
r#"List.walkBackwards ["x", "y", "z"] "<" Str.concat"#,
|
||||||
RocStr::from("<zyx"),
|
RocStr::from("<zyx"),
|
||||||
RocStr
|
RocStr
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
r#"List.walkBackwards [ "Second", "Third", "Fourth" ] "First" Str.concat"#,
|
r#"List.walkBackwards ["Second", "Third", "Fourth"] "First" Str.concat"#,
|
||||||
RocStr::from("FirstFourthThirdSecond"),
|
RocStr::from("FirstFourthThirdSecond"),
|
||||||
RocStr
|
RocStr
|
||||||
);
|
);
|
||||||
|
@ -744,10 +740,10 @@ fn list_walk_backwards_with_record() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
Bit : [ Zero, One ]
|
Bit : [Zero, One]
|
||||||
|
|
||||||
byte : List Bit
|
byte : List Bit
|
||||||
byte = [ Zero, One, Zero, One, Zero, Zero, One, Zero ]
|
byte = [Zero, One, Zero, One, Zero, Zero, One, Zero]
|
||||||
|
|
||||||
initialCounts = { zeroes: 0, ones: 0 }
|
initialCounts = { zeroes: 0, ones: 0 }
|
||||||
|
|
||||||
|
@ -770,13 +766,13 @@ fn list_walk_backwards_with_record() {
|
||||||
#[cfg(any(feature = "gen-llvm"))]
|
#[cfg(any(feature = "gen-llvm"))]
|
||||||
fn list_walk_with_str() {
|
fn list_walk_with_str() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
r#"List.walk [ "x", "y", "z" ] "<" Str.concat"#,
|
r#"List.walk ["x", "y", "z"] "<" Str.concat"#,
|
||||||
RocStr::from("<xyz"),
|
RocStr::from("<xyz"),
|
||||||
RocStr
|
RocStr
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
r#"List.walk [ "Second", "Third", "Fourth" ] "First" Str.concat"#,
|
r#"List.walk ["Second", "Third", "Fourth"] "First" Str.concat"#,
|
||||||
RocStr::from("FirstSecondThirdFourth"),
|
RocStr::from("FirstSecondThirdFourth"),
|
||||||
RocStr
|
RocStr
|
||||||
);
|
);
|
||||||
|
@ -785,14 +781,14 @@ fn list_walk_with_str() {
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg(any(feature = "gen-llvm"))]
|
#[cfg(any(feature = "gen-llvm"))]
|
||||||
fn list_walk_subtraction() {
|
fn list_walk_subtraction() {
|
||||||
assert_evals_to!(r#"List.walk [ 1, 2 ] 1 Num.sub"#, (1 - 1) - 2, i64);
|
assert_evals_to!(r#"List.walk [1, 2] 1 Num.sub"#, (1 - 1) - 2, i64);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg(any(feature = "gen-llvm"))]
|
#[cfg(any(feature = "gen-llvm"))]
|
||||||
fn list_walk_until_sum() {
|
fn list_walk_until_sum() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
r#"List.walkUntil [ 1, 2 ] 0 \a,b -> Continue (a + b)"#,
|
r#"List.walkUntil [1, 2] 0 \a,b -> Continue (a + b)"#,
|
||||||
3,
|
3,
|
||||||
i64
|
i64
|
||||||
);
|
);
|
||||||
|
@ -803,7 +799,7 @@ fn list_walk_until_sum() {
|
||||||
fn list_walk_implements_position() {
|
fn list_walk_implements_position() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
r#"
|
r#"
|
||||||
Option a : [ Some a, None ]
|
Option a : [Some a, None]
|
||||||
|
|
||||||
find : List a, a -> Option Nat
|
find : List a, a -> Option Nat
|
||||||
find = \list, needle ->
|
find = \list, needle ->
|
||||||
|
@ -817,7 +813,7 @@ fn list_walk_implements_position() {
|
||||||
else
|
else
|
||||||
Continue { n: n + 1, v }
|
Continue { n: n + 1, v }
|
||||||
|
|
||||||
when find [ 1, 2, 3 ] 3 is
|
when find [1, 2, 3] 3 is
|
||||||
None -> 0
|
None -> 0
|
||||||
Some v -> v
|
Some v -> v
|
||||||
"#,
|
"#,
|
||||||
|
@ -838,7 +834,7 @@ fn list_walk_until_even_prefix_sum() {
|
||||||
else
|
else
|
||||||
Stop a
|
Stop a
|
||||||
|
|
||||||
List.walkUntil [ 2, 4, 8, 9 ] 0 helper"#,
|
List.walkUntil [2, 4, 8, 9] 0 helper"#,
|
||||||
2 + 4 + 8,
|
2 + 4 + 8,
|
||||||
i64
|
i64
|
||||||
);
|
);
|
||||||
|
@ -979,7 +975,7 @@ fn list_map_on_non_empty_list() {
|
||||||
r#"
|
r#"
|
||||||
nonEmpty : List I64
|
nonEmpty : List I64
|
||||||
nonEmpty =
|
nonEmpty =
|
||||||
[ 1 ]
|
[1]
|
||||||
|
|
||||||
List.map nonEmpty (\x -> x)
|
List.map nonEmpty (\x -> x)
|
||||||
"#
|
"#
|
||||||
|
@ -997,7 +993,7 @@ fn list_map_changes_input() {
|
||||||
r#"
|
r#"
|
||||||
nonEmpty : List I64
|
nonEmpty : List I64
|
||||||
nonEmpty =
|
nonEmpty =
|
||||||
[ 1 ]
|
[1]
|
||||||
|
|
||||||
List.map nonEmpty (\x -> x + 1)
|
List.map nonEmpty (\x -> x + 1)
|
||||||
"#
|
"#
|
||||||
|
@ -1015,7 +1011,7 @@ fn list_map_on_big_list() {
|
||||||
r#"
|
r#"
|
||||||
nonEmpty : List I64
|
nonEmpty : List I64
|
||||||
nonEmpty =
|
nonEmpty =
|
||||||
[ 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5 ]
|
[1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5]
|
||||||
|
|
||||||
List.map nonEmpty (\x -> x * 2)
|
List.map nonEmpty (\x -> x * 2)
|
||||||
"#
|
"#
|
||||||
|
@ -1035,7 +1031,7 @@ fn list_map_with_type_change() {
|
||||||
r#"
|
r#"
|
||||||
nonEmpty : List I64
|
nonEmpty : List I64
|
||||||
nonEmpty =
|
nonEmpty =
|
||||||
[ 1, 1, -4, 1, 2 ]
|
[1, 1, -4, 1, 2]
|
||||||
|
|
||||||
|
|
||||||
List.map nonEmpty (\x -> x > 0)
|
List.map nonEmpty (\x -> x > 0)
|
||||||
|
@ -1054,7 +1050,7 @@ fn list_map_using_defined_function() {
|
||||||
r#"
|
r#"
|
||||||
nonEmpty : List I64
|
nonEmpty : List I64
|
||||||
nonEmpty =
|
nonEmpty =
|
||||||
[ 2, 2, -4, 2, 3 ]
|
[2, 2, -4, 2, 3]
|
||||||
|
|
||||||
greaterThanOne : I64 -> Bool
|
greaterThanOne : I64 -> Bool
|
||||||
greaterThanOne = \i ->
|
greaterThanOne = \i ->
|
||||||
|
@ -1093,7 +1089,7 @@ fn list_map_closure() {
|
||||||
|
|
||||||
single : List F64
|
single : List F64
|
||||||
single =
|
single =
|
||||||
[ 0 ]
|
[0]
|
||||||
|
|
||||||
List.map single (\x -> x + float)
|
List.map single (\x -> x + float)
|
||||||
"#
|
"#
|
||||||
|
@ -1190,7 +1186,7 @@ fn list_map2_different_lengths() {
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
List.map2
|
List.map2
|
||||||
["a", "b", "lllllllllllllooooooooongnggg" ]
|
["a", "b", "lllllllllllllooooooooongnggg"]
|
||||||
["b"]
|
["b"]
|
||||||
(\a, b -> Str.concat a b)
|
(\a, b -> Str.concat a b)
|
||||||
"#
|
"#
|
||||||
|
@ -1214,7 +1210,7 @@ fn list_join_empty_list() {
|
||||||
#[cfg(any(feature = "gen-llvm"))]
|
#[cfg(any(feature = "gen-llvm"))]
|
||||||
fn list_join_one_list() {
|
fn list_join_one_list() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
"List.join [ [1, 2, 3 ] ]",
|
"List.join [[1, 2, 3]]",
|
||||||
RocList::from_slice(&[1, 2, 3]),
|
RocList::from_slice(&[1, 2, 3]),
|
||||||
RocList<i64>
|
RocList<i64>
|
||||||
);
|
);
|
||||||
|
@ -1224,7 +1220,7 @@ fn list_join_one_list() {
|
||||||
#[cfg(any(feature = "gen-llvm"))]
|
#[cfg(any(feature = "gen-llvm"))]
|
||||||
fn list_join_two_non_empty_lists() {
|
fn list_join_two_non_empty_lists() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
"List.join [ [1, 2, 3 ] , [4 ,5, 6] ]",
|
"List.join [[1, 2, 3] , [4 ,5, 6]]",
|
||||||
RocList::from_slice(&[1, 2, 3, 4, 5, 6]),
|
RocList::from_slice(&[1, 2, 3, 4, 5, 6]),
|
||||||
RocList<i64>
|
RocList<i64>
|
||||||
);
|
);
|
||||||
|
@ -1234,7 +1230,7 @@ fn list_join_two_non_empty_lists() {
|
||||||
#[cfg(any(feature = "gen-llvm"))]
|
#[cfg(any(feature = "gen-llvm"))]
|
||||||
fn list_join_two_non_empty_lists_of_float() {
|
fn list_join_two_non_empty_lists_of_float() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
"List.join [ [ 1.2, 1.1 ], [ 2.1, 2.2 ] ]",
|
"List.join [[1.2, 1.1], [2.1, 2.2]]",
|
||||||
RocList::from_slice(&[1.2, 1.1, 2.1, 2.2]),
|
RocList::from_slice(&[1.2, 1.1, 2.1, 2.2]),
|
||||||
RocList<f64>
|
RocList<f64>
|
||||||
);
|
);
|
||||||
|
@ -1248,13 +1244,13 @@ fn list_join_to_big_list() {
|
||||||
r#"
|
r#"
|
||||||
List.join
|
List.join
|
||||||
[
|
[
|
||||||
[ 1.2, 1.1 ],
|
[1.2, 1.1],
|
||||||
[ 2.1, 2.2 ],
|
[2.1, 2.2],
|
||||||
[ 3.0, 4.0, 5.0, 6.1, 9.0 ],
|
[3.0, 4.0, 5.0, 6.1, 9.0],
|
||||||
[ 3.0, 4.0, 5.0, 6.1, 9.0 ],
|
[3.0, 4.0, 5.0, 6.1, 9.0],
|
||||||
[ 3.0, 4.0, 5.0, 6.1, 9.0 ],
|
[3.0, 4.0, 5.0, 6.1, 9.0],
|
||||||
[ 3.0, 4.0, 5.0, 6.1, 9.0 ],
|
[3.0, 4.0, 5.0, 6.1, 9.0],
|
||||||
[ 3.0, 4.0, 5.0, 6.1, 9.0 ]
|
[3.0, 4.0, 5.0, 6.1, 9.0]
|
||||||
]
|
]
|
||||||
"#
|
"#
|
||||||
),
|
),
|
||||||
|
@ -1276,7 +1272,7 @@ fn list_join_defined_empty_list() {
|
||||||
empty =
|
empty =
|
||||||
[]
|
[]
|
||||||
|
|
||||||
List.join [ [ 0.2, 11.11 ], empty ]
|
List.join [[0.2, 11.11], empty]
|
||||||
"#
|
"#
|
||||||
),
|
),
|
||||||
RocList::from_slice(&[0.2, 11.11]),
|
RocList::from_slice(&[0.2, 11.11]),
|
||||||
|
@ -1288,7 +1284,7 @@ fn list_join_defined_empty_list() {
|
||||||
#[cfg(any(feature = "gen-llvm"))]
|
#[cfg(any(feature = "gen-llvm"))]
|
||||||
fn list_join_all_empty_lists() {
|
fn list_join_all_empty_lists() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
"List.join [ [], [], [] ]",
|
"List.join [[], [], []]",
|
||||||
RocList::<f64>::from_slice(&[]),
|
RocList::<f64>::from_slice(&[]),
|
||||||
RocList<f64>
|
RocList<f64>
|
||||||
);
|
);
|
||||||
|
@ -1298,7 +1294,7 @@ fn list_join_all_empty_lists() {
|
||||||
#[cfg(any(feature = "gen-llvm"))]
|
#[cfg(any(feature = "gen-llvm"))]
|
||||||
fn list_join_one_empty_list() {
|
fn list_join_one_empty_list() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
"List.join [ [ 1.2, 1.1 ], [] ]",
|
"List.join [[1.2, 1.1], []]",
|
||||||
RocList::from_slice(&[1.2, 1.1]),
|
RocList::from_slice(&[1.2, 1.1]),
|
||||||
RocList<f64>
|
RocList<f64>
|
||||||
);
|
);
|
||||||
|
@ -1356,7 +1352,7 @@ fn list_repeat() {
|
||||||
#[cfg(any(feature = "gen-llvm"))]
|
#[cfg(any(feature = "gen-llvm"))]
|
||||||
fn list_reverse() {
|
fn list_reverse() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
"List.reverse [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 ]",
|
"List.reverse [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]",
|
||||||
RocList::from_slice(&[12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1]),
|
RocList::from_slice(&[12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1]),
|
||||||
RocList<i64>
|
RocList<i64>
|
||||||
);
|
);
|
||||||
|
@ -1454,12 +1450,12 @@ fn list_concat_two_empty_lists_of_int() {
|
||||||
#[cfg(any(feature = "gen-llvm"))]
|
#[cfg(any(feature = "gen-llvm"))]
|
||||||
fn list_concat_second_list_is_empty() {
|
fn list_concat_second_list_is_empty() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
"List.concat [ 12, 13 ] []",
|
"List.concat [12, 13] []",
|
||||||
RocList::from_slice(&[12, 13]),
|
RocList::from_slice(&[12, 13]),
|
||||||
RocList<i64>
|
RocList<i64>
|
||||||
);
|
);
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
"List.concat [ 34, 43 ] [ 64, 55, 66 ]",
|
"List.concat [34, 43] [64, 55, 66]",
|
||||||
RocList::from_slice(&[34, 43, 64, 55, 66]),
|
RocList::from_slice(&[34, 43, 64, 55, 66]),
|
||||||
RocList<i64>
|
RocList<i64>
|
||||||
);
|
);
|
||||||
|
@ -1469,7 +1465,7 @@ fn list_concat_second_list_is_empty() {
|
||||||
#[cfg(any(feature = "gen-llvm"))]
|
#[cfg(any(feature = "gen-llvm"))]
|
||||||
fn list_concat_first_list_is_empty() {
|
fn list_concat_first_list_is_empty() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
"List.concat [] [ 23, 24 ]",
|
"List.concat [] [23, 24]",
|
||||||
RocList::from_slice(&[23, 24]),
|
RocList::from_slice(&[23, 24]),
|
||||||
RocList<i64>
|
RocList<i64>
|
||||||
);
|
);
|
||||||
|
@ -1479,7 +1475,7 @@ fn list_concat_first_list_is_empty() {
|
||||||
#[cfg(any(feature = "gen-llvm"))]
|
#[cfg(any(feature = "gen-llvm"))]
|
||||||
fn list_concat_two_non_empty_lists() {
|
fn list_concat_two_non_empty_lists() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
"List.concat [1, 2 ] [ 3, 4 ]",
|
"List.concat [1, 2] [3, 4]",
|
||||||
RocList::from_slice(&[1, 2, 3, 4]),
|
RocList::from_slice(&[1, 2, 3, 4]),
|
||||||
RocList<i64>
|
RocList<i64>
|
||||||
);
|
);
|
||||||
|
@ -1489,7 +1485,7 @@ fn list_concat_two_non_empty_lists() {
|
||||||
#[cfg(any(feature = "gen-llvm"))]
|
#[cfg(any(feature = "gen-llvm"))]
|
||||||
fn list_concat_two_bigger_non_empty_lists() {
|
fn list_concat_two_bigger_non_empty_lists() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
"List.concat [ 1.1, 2.2 ] [ 3.3, 4.4, 5.5 ]",
|
"List.concat [1.1, 2.2] [3.3, 4.4, 5.5]",
|
||||||
RocList::from_slice(&[1.1, 2.2, 3.3, 4.4, 5.5]),
|
RocList::from_slice(&[1.1, 2.2, 3.3, 4.4, 5.5]),
|
||||||
RocList<f64>
|
RocList<f64>
|
||||||
);
|
);
|
||||||
|
@ -1579,7 +1575,7 @@ fn empty_list_len() {
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))]
|
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))]
|
||||||
fn basic_int_list_len() {
|
fn basic_int_list_len() {
|
||||||
assert_evals_to!("List.len [ 12, 9, 6, 3 ]", 4, usize);
|
assert_evals_to!("List.len [12, 9, 6, 3]", 4, usize);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -1588,7 +1584,7 @@ fn loaded_int_list_len() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
nums = [ 2, 4, 6 ]
|
nums = [2, 4, 6]
|
||||||
|
|
||||||
List.len nums
|
List.len nums
|
||||||
"#
|
"#
|
||||||
|
@ -1606,7 +1602,7 @@ fn fn_int_list_len() {
|
||||||
r#"
|
r#"
|
||||||
getLen = \list -> List.len list
|
getLen = \list -> List.len list
|
||||||
|
|
||||||
nums = [ 2, 4, 6, 8 ]
|
nums = [2, 4, 6, 8]
|
||||||
|
|
||||||
getLen nums
|
getLen nums
|
||||||
"#
|
"#
|
||||||
|
@ -1619,7 +1615,7 @@ fn fn_int_list_len() {
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))]
|
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))]
|
||||||
fn int_list_is_empty() {
|
fn int_list_is_empty() {
|
||||||
assert_evals_to!("List.isEmpty [ 12, 9, 6, 3 ]", false, bool);
|
assert_evals_to!("List.isEmpty [12, 9, 6, 3]", false, bool);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -1634,7 +1630,7 @@ fn first_int_list() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
when List.first [ 12, 9, 6, 3 ] is
|
when List.first [12, 9, 6, 3] is
|
||||||
Ok val -> val
|
Ok val -> val
|
||||||
Err _ -> -1
|
Err _ -> -1
|
||||||
"#
|
"#
|
||||||
|
@ -1683,7 +1679,7 @@ fn last_int_list() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
when List.last [ 12, 9, 6, 3 ] is
|
when List.last [12, 9, 6, 3] is
|
||||||
Ok val -> val
|
Ok val -> val
|
||||||
Err _ -> -1
|
Err _ -> -1
|
||||||
"#
|
"#
|
||||||
|
@ -1765,7 +1761,7 @@ fn get_int_list_ok() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
when List.get [ 12, 9, 6 ] 1 is
|
when List.get [12, 9, 6] 1 is
|
||||||
Ok val -> val
|
Ok val -> val
|
||||||
Err _ -> -1
|
Err _ -> -1
|
||||||
"#
|
"#
|
||||||
|
@ -1781,7 +1777,7 @@ fn get_int_list_oob() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
when List.get [ 12, 9, 6 ] 1000 is
|
when List.get [12, 9, 6] 1000 is
|
||||||
Ok val -> val
|
Ok val -> val
|
||||||
Err _ -> -1
|
Err _ -> -1
|
||||||
"#
|
"#
|
||||||
|
@ -1797,7 +1793,7 @@ fn replace_unique_int_list() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
record = List.replace [ 12, 9, 7, 1, 5 ] 2 33
|
record = List.replace [12, 9, 7, 1, 5] 2 33
|
||||||
record.list
|
record.list
|
||||||
"#
|
"#
|
||||||
),
|
),
|
||||||
|
@ -1812,7 +1808,7 @@ fn replace_unique_int_list_out_of_bounds() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
record = List.replace [ 12, 9, 7, 1, 5 ] 5 33
|
record = List.replace [12, 9, 7, 1, 5] 5 33
|
||||||
record.value
|
record.value
|
||||||
"#
|
"#
|
||||||
),
|
),
|
||||||
|
@ -1827,7 +1823,7 @@ fn replace_unique_int_list_get_old_value() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
record = List.replace [ 12, 9, 7, 1, 5 ] 2 33
|
record = List.replace [12, 9, 7, 1, 5] 2 33
|
||||||
record.value
|
record.value
|
||||||
"#
|
"#
|
||||||
),
|
),
|
||||||
|
@ -1843,7 +1839,7 @@ fn replace_unique_get_large_value() {
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
list : List { a : U64, b: U64, c: U64, d: U64 }
|
list : List { a : U64, b: U64, c: U64, d: U64 }
|
||||||
list = [ { a: 1, b: 2, c: 3, d: 4 }, { a: 5, b: 6, c: 7, d: 8 }, { a: 9, b: 10, c: 11, d: 12 } ]
|
list = [{ a: 1, b: 2, c: 3, d: 4 }, { a: 5, b: 6, c: 7, d: 8 }, { a: 9, b: 10, c: 11, d: 12 }]
|
||||||
record = List.replace list 1 { a: 13, b: 14, c: 15, d: 16 }
|
record = List.replace list 1 { a: 13, b: 14, c: 15, d: 16 }
|
||||||
record.value
|
record.value
|
||||||
"#
|
"#
|
||||||
|
@ -1874,7 +1870,7 @@ fn replace_shared_int_list() {
|
||||||
|
|
||||||
{ x, y }
|
{ x, y }
|
||||||
|
|
||||||
wrapper [ 2.1, 4.3 ]
|
wrapper [2.1, 4.3]
|
||||||
"#
|
"#
|
||||||
),
|
),
|
||||||
(7.7, 4.3),
|
(7.7, 4.3),
|
||||||
|
@ -1888,7 +1884,7 @@ fn get_set_unique_int_list() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
when List.get (List.set [ 12, 9, 7, 3 ] 1 42) 1 is
|
when List.get (List.set [12, 9, 7, 3] 1 42) 1 is
|
||||||
Ok val -> val
|
Ok val -> val
|
||||||
Err _ -> -1
|
Err _ -> -1
|
||||||
"#
|
"#
|
||||||
|
@ -1902,7 +1898,7 @@ fn get_set_unique_int_list() {
|
||||||
#[cfg(any(feature = "gen-llvm"))]
|
#[cfg(any(feature = "gen-llvm"))]
|
||||||
fn set_unique_int_list() {
|
fn set_unique_int_list() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
"List.set [ 12, 9, 7, 1, 5 ] 2 33",
|
"List.set [12, 9, 7, 1, 5] 2 33",
|
||||||
RocList::from_slice(&[12, 9, 33, 1, 5]),
|
RocList::from_slice(&[12, 9, 33, 1, 5]),
|
||||||
RocList<i64>
|
RocList<i64>
|
||||||
);
|
);
|
||||||
|
@ -1912,7 +1908,7 @@ fn set_unique_int_list() {
|
||||||
#[cfg(any(feature = "gen-llvm"))]
|
#[cfg(any(feature = "gen-llvm"))]
|
||||||
fn set_unique_list_oob() {
|
fn set_unique_list_oob() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
"List.set [ 3, 17, 4.1 ] 1337 9.25",
|
"List.set [3, 17, 4.1] 1337 9.25",
|
||||||
RocList::from_slice(&[3.0, 17.0, 4.1]),
|
RocList::from_slice(&[3.0, 17.0, 4.1]),
|
||||||
RocList<f64>
|
RocList<f64>
|
||||||
);
|
);
|
||||||
|
@ -1938,7 +1934,7 @@ fn set_shared_int_list() {
|
||||||
|
|
||||||
{ x, y }
|
{ x, y }
|
||||||
|
|
||||||
wrapper [ 2.1, 4.3 ]
|
wrapper [2.1, 4.3]
|
||||||
"#
|
"#
|
||||||
),
|
),
|
||||||
(7.7, 4.3),
|
(7.7, 4.3),
|
||||||
|
@ -1952,7 +1948,7 @@ fn set_shared_list_oob() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
shared = [ 2, 4 ]
|
shared = [2, 4]
|
||||||
|
|
||||||
# This List.set is out of bounds, and should have no effect
|
# This List.set is out of bounds, and should have no effect
|
||||||
x =
|
x =
|
||||||
|
@ -1979,7 +1975,7 @@ fn get_unique_int_list() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
unique = [ 2, 4 ]
|
unique = [2, 4]
|
||||||
|
|
||||||
when List.get unique 1 is
|
when List.get unique 1 is
|
||||||
Ok num -> num
|
Ok num -> num
|
||||||
|
@ -1998,9 +1994,9 @@ fn gen_wrap_len() {
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
wrapLen = \list ->
|
wrapLen = \list ->
|
||||||
[ List.len list ]
|
[List.len list]
|
||||||
|
|
||||||
wrapLen [ 1, 7, 9 ]
|
wrapLen [1, 7, 9]
|
||||||
"#
|
"#
|
||||||
),
|
),
|
||||||
RocList::from_slice(&[3]),
|
RocList::from_slice(&[3]),
|
||||||
|
@ -2015,9 +2011,9 @@ fn gen_wrap_first() {
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
wrapFirst = \list ->
|
wrapFirst = \list ->
|
||||||
[ List.first list ]
|
[List.first list]
|
||||||
|
|
||||||
wrapFirst [ 1, 2 ]
|
wrapFirst [1, 2]
|
||||||
"#
|
"#
|
||||||
),
|
),
|
||||||
RocList::from_slice(&[1]),
|
RocList::from_slice(&[1]),
|
||||||
|
@ -2040,7 +2036,7 @@ fn gen_duplicate() {
|
||||||
_ ->
|
_ ->
|
||||||
[]
|
[]
|
||||||
|
|
||||||
dupe [ 1, 2 ]
|
dupe [1, 2]
|
||||||
"#
|
"#
|
||||||
),
|
),
|
||||||
RocList::from_slice(&[1, 1]),
|
RocList::from_slice(&[1, 1]),
|
||||||
|
@ -2054,7 +2050,7 @@ fn gen_swap() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
app "quicksort" provides [ main ] to "./platform"
|
app "quicksort" provides [main] to "./platform"
|
||||||
|
|
||||||
|
|
||||||
swap : Nat, Nat, List a -> List a
|
swap : Nat, Nat, List a -> List a
|
||||||
|
@ -2069,7 +2065,7 @@ fn gen_swap() {
|
||||||
[]
|
[]
|
||||||
|
|
||||||
main =
|
main =
|
||||||
swap 0 1 [ 1, 2 ]
|
swap 0 1 [1, 2]
|
||||||
"#
|
"#
|
||||||
),
|
),
|
||||||
RocList::from_slice(&[2, 1]),
|
RocList::from_slice(&[2, 1]),
|
||||||
|
@ -2113,7 +2109,7 @@ fn gen_quicksort() {
|
||||||
_ ->
|
_ ->
|
||||||
[]
|
[]
|
||||||
|
|
||||||
partition : Nat, Nat, List (Num a) -> [ Pair Nat (List (Num a)) ]
|
partition : Nat, Nat, List (Num a) -> [Pair Nat (List (Num a))]
|
||||||
partition = \low, high, initialList ->
|
partition = \low, high, initialList ->
|
||||||
when List.get initialList high is
|
when List.get initialList high is
|
||||||
Ok pivot ->
|
Ok pivot ->
|
||||||
|
@ -2125,7 +2121,7 @@ fn gen_quicksort() {
|
||||||
Pair low initialList
|
Pair low initialList
|
||||||
|
|
||||||
|
|
||||||
partitionHelp : Nat, Nat, List (Num a), Nat, (Num a) -> [ Pair Nat (List (Num a)) ]
|
partitionHelp : Nat, Nat, List (Num a), Nat, (Num a) -> [Pair Nat (List (Num a))]
|
||||||
partitionHelp = \i, j, list, high, pivot ->
|
partitionHelp = \i, j, list, high, pivot ->
|
||||||
if j < high then
|
if j < high then
|
||||||
when List.get list j is
|
when List.get list j is
|
||||||
|
@ -2140,7 +2136,7 @@ fn gen_quicksort() {
|
||||||
else
|
else
|
||||||
Pair i list
|
Pair i list
|
||||||
|
|
||||||
quicksort [ 7, 4, 21, 19 ]
|
quicksort [7, 4, 21, 19]
|
||||||
"#
|
"#
|
||||||
),
|
),
|
||||||
RocList::from_slice(&[4, 7, 19, 21]),
|
RocList::from_slice(&[4, 7, 19, 21]),
|
||||||
|
@ -2184,7 +2180,7 @@ fn quicksort() {
|
||||||
_ ->
|
_ ->
|
||||||
[]
|
[]
|
||||||
|
|
||||||
partition : Nat, Nat, List (Num a) -> [ Pair Nat (List (Num a)) ]
|
partition : Nat, Nat, List (Num a) -> [Pair Nat (List (Num a))]
|
||||||
partition = \low, high, initialList ->
|
partition = \low, high, initialList ->
|
||||||
when List.get initialList high is
|
when List.get initialList high is
|
||||||
Ok pivot ->
|
Ok pivot ->
|
||||||
|
@ -2196,7 +2192,7 @@ fn quicksort() {
|
||||||
Pair low initialList
|
Pair low initialList
|
||||||
|
|
||||||
|
|
||||||
partitionHelp : Nat, Nat, List (Num a), Nat, Num a -> [ Pair Nat (List (Num a)) ]
|
partitionHelp : Nat, Nat, List (Num a), Nat, Num a -> [Pair Nat (List (Num a))]
|
||||||
partitionHelp = \i, j, list, high, pivot ->
|
partitionHelp = \i, j, list, high, pivot ->
|
||||||
# if j < high then
|
# if j < high then
|
||||||
if False then
|
if False then
|
||||||
|
@ -2214,7 +2210,7 @@ fn quicksort() {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
quicksort [ 7, 4, 21, 19 ]
|
quicksort [7, 4, 21, 19]
|
||||||
"#
|
"#
|
||||||
),
|
),
|
||||||
RocList::from_slice(&[19, 7, 4, 21]),
|
RocList::from_slice(&[19, 7, 4, 21]),
|
||||||
|
@ -2258,7 +2254,7 @@ fn quicksort_singleton() {
|
||||||
_ ->
|
_ ->
|
||||||
[]
|
[]
|
||||||
|
|
||||||
partition : Nat, Nat, List (Num a) -> [ Pair Nat (List (Num a)) ]
|
partition : Nat, Nat, List (Num a) -> [Pair Nat (List (Num a))]
|
||||||
partition = \low, high, initialList ->
|
partition = \low, high, initialList ->
|
||||||
when List.get initialList high is
|
when List.get initialList high is
|
||||||
Ok pivot ->
|
Ok pivot ->
|
||||||
|
@ -2270,7 +2266,7 @@ fn quicksort_singleton() {
|
||||||
Pair low initialList
|
Pair low initialList
|
||||||
|
|
||||||
|
|
||||||
partitionHelp : Nat, Nat, List (Num a), Nat, Num a -> [ Pair Nat (List (Num a)) ]
|
partitionHelp : Nat, Nat, List (Num a), Nat, Num a -> [Pair Nat (List (Num a))]
|
||||||
partitionHelp = \i, j, list, high, pivot ->
|
partitionHelp = \i, j, list, high, pivot ->
|
||||||
if j < high then
|
if j < high then
|
||||||
when List.get list j is
|
when List.get list j is
|
||||||
|
@ -2377,7 +2373,7 @@ fn list_wrap_in_tag() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
id : List I64 -> [ Pair (List I64) I64 ]
|
id : List I64 -> [Pair (List I64) I64]
|
||||||
id = \y -> Pair y 4
|
id = \y -> Pair y 4
|
||||||
|
|
||||||
when id [1,2,3] is
|
when id [1,2,3] is
|
||||||
|
@ -2426,7 +2422,7 @@ fn list_manual_range() {
|
||||||
else
|
else
|
||||||
accum
|
accum
|
||||||
|
|
||||||
range 0 5 [ 42 ]
|
range 0 5 [42]
|
||||||
"#
|
"#
|
||||||
),
|
),
|
||||||
RocList::from_slice(&[42, 0, 1, 2, 3, 4]),
|
RocList::from_slice(&[42, 0, 1, 2, 3, 4]),
|
||||||
|
@ -2492,16 +2488,16 @@ fn list_max() {
|
||||||
#[cfg(any(feature = "gen-llvm"))]
|
#[cfg(any(feature = "gen-llvm"))]
|
||||||
fn list_sum() {
|
fn list_sum() {
|
||||||
assert_evals_to!("List.sum []", 0, i64);
|
assert_evals_to!("List.sum []", 0, i64);
|
||||||
assert_evals_to!("List.sum [ 1, 2, 3 ]", 6, i64);
|
assert_evals_to!("List.sum [1, 2, 3]", 6, i64);
|
||||||
assert_evals_to!("List.sum [ 1.1, 2.2, 3.3 ]", 6.6, f64);
|
assert_evals_to!("List.sum [1.1, 2.2, 3.3]", 6.6, f64);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg(any(feature = "gen-llvm"))]
|
#[cfg(any(feature = "gen-llvm"))]
|
||||||
fn list_product() {
|
fn list_product() {
|
||||||
assert_evals_to!("List.product []", 1, i64);
|
assert_evals_to!("List.product []", 1, i64);
|
||||||
assert_evals_to!("List.product [ 1, 2, 3 ]", 6, i64);
|
assert_evals_to!("List.product [1, 2, 3]", 6, i64);
|
||||||
assert_evals_to!("List.product [ 1.1, 2.2, 3.3 ]", 1.1 * 2.2 * 3.3, f64);
|
assert_evals_to!("List.product [1.1, 2.2, 3.3]", 1.1 * 2.2 * 3.3, f64);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -2592,7 +2588,7 @@ fn cleanup_because_exception() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
x = [ 1,2 ]
|
x = [1,2]
|
||||||
|
|
||||||
five : I64
|
five : I64
|
||||||
five = 5
|
five = 5
|
||||||
|
@ -2630,12 +2626,12 @@ fn list_sort_with() {
|
||||||
RocList<i64>
|
RocList<i64>
|
||||||
);
|
);
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
"List.sortWith [ 4,3,2,1 ] Num.compare",
|
"List.sortWith [4,3,2,1] Num.compare",
|
||||||
RocList::from_slice(&[1, 2, 3, 4]),
|
RocList::from_slice(&[1, 2, 3, 4]),
|
||||||
RocList<i64>
|
RocList<i64>
|
||||||
);
|
);
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
"List.sortWith [ 1,2,3,4] (\\a,b -> Num.compare b a)",
|
"List.sortWith [1,2,3,4] (\\a,b -> Num.compare b a)",
|
||||||
RocList::from_slice(&[4, 3, 2, 1]),
|
RocList::from_slice(&[4, 3, 2, 1]),
|
||||||
RocList<i64>
|
RocList<i64>
|
||||||
);
|
);
|
||||||
|
@ -2650,7 +2646,7 @@ fn list_sort_asc() {
|
||||||
RocList<i64>
|
RocList<i64>
|
||||||
);
|
);
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
"List.sortAsc [ 4,3,2,1 ]",
|
"List.sortAsc [4,3,2,1]",
|
||||||
RocList::from_slice(&[1, 2, 3, 4]),
|
RocList::from_slice(&[1, 2, 3, 4]),
|
||||||
RocList<i64>
|
RocList<i64>
|
||||||
);
|
);
|
||||||
|
@ -2665,7 +2661,7 @@ fn list_sort_desc() {
|
||||||
RocList<i64>
|
RocList<i64>
|
||||||
);
|
);
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
"List.sortDesc [ 1,2,3,4 ]",
|
"List.sortDesc [1,2,3,4]",
|
||||||
RocList::from_slice(&[4, 3, 2, 1]),
|
RocList::from_slice(&[4, 3, 2, 1]),
|
||||||
RocList<i64>
|
RocList<i64>
|
||||||
);
|
);
|
||||||
|
@ -2675,8 +2671,8 @@ fn list_sort_desc() {
|
||||||
#[cfg(any(feature = "gen-llvm"))]
|
#[cfg(any(feature = "gen-llvm"))]
|
||||||
fn list_any() {
|
fn list_any() {
|
||||||
assert_evals_to!("List.any [] (\\e -> e > 3)", false, bool);
|
assert_evals_to!("List.any [] (\\e -> e > 3)", false, bool);
|
||||||
assert_evals_to!("List.any [ 1, 2, 3 ] (\\e -> e > 3)", false, bool);
|
assert_evals_to!("List.any [1, 2, 3] (\\e -> e > 3)", false, bool);
|
||||||
assert_evals_to!("List.any [ 1, 2, 4 ] (\\e -> e > 3)", true, bool);
|
assert_evals_to!("List.any [1, 2, 4] (\\e -> e > 3)", true, bool);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -2699,9 +2695,9 @@ fn list_any_empty_with_unknown_element_type() {
|
||||||
#[cfg(any(feature = "gen-llvm"))]
|
#[cfg(any(feature = "gen-llvm"))]
|
||||||
fn list_all() {
|
fn list_all() {
|
||||||
assert_evals_to!("List.all [] (\\e -> e > 3)", true, bool);
|
assert_evals_to!("List.all [] (\\e -> e > 3)", true, bool);
|
||||||
assert_evals_to!("List.all [ 1, 2, 3 ] (\\e -> e > 3)", false, bool);
|
assert_evals_to!("List.all [1, 2, 3] (\\e -> e > 3)", false, bool);
|
||||||
assert_evals_to!("List.all [ 1, 2, 4 ] (\\e -> e > 3)", false, bool);
|
assert_evals_to!("List.all [1, 2, 4] (\\e -> e > 3)", false, bool);
|
||||||
assert_evals_to!("List.all [ 1, 2, 3 ] (\\e -> e >= 1)", true, bool);
|
assert_evals_to!("List.all [1, 2, 3] (\\e -> e >= 1)", true, bool);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -2727,9 +2723,9 @@ fn lists_with_incompatible_type_param_in_if() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
list1 = [ {} ]
|
list1 = [{}]
|
||||||
|
|
||||||
list2 = [ "" ]
|
list2 = [""]
|
||||||
|
|
||||||
x = if True then list1 else list2
|
x = if True then list1 else list2
|
||||||
|
|
||||||
|
@ -2748,7 +2744,7 @@ fn map_with_index_multi_record() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
List.mapWithIndex [ { x: {}, y: {} } ] \_, _ -> {}
|
List.mapWithIndex [{ x: {}, y: {} }] \_, _ -> {}
|
||||||
"#
|
"#
|
||||||
),
|
),
|
||||||
RocList::from_slice(&[((), ())]),
|
RocList::from_slice(&[((), ())]),
|
||||||
|
@ -2773,7 +2769,7 @@ fn empty_list_of_function_type() {
|
||||||
if False then
|
if False then
|
||||||
myList
|
myList
|
||||||
else
|
else
|
||||||
[ myClosure ]
|
[myClosure]
|
||||||
|
|
||||||
when List.get choose 0 is
|
when List.get choose 0 is
|
||||||
Ok f -> f "foo"
|
Ok f -> f "foo"
|
||||||
|
|
|
@ -52,7 +52,7 @@ fn i64_signed_int_alias() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
app "test" provides [ main ] to "./platform"
|
app "test" provides [main] to "./platform"
|
||||||
|
|
||||||
main =
|
main =
|
||||||
i : I64
|
i : I64
|
||||||
|
@ -2381,7 +2381,7 @@ fn min_f32() {
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! num_conversion_tests {
|
macro_rules! num_conversion_tests {
|
||||||
($($fn:expr, $typ:ty, ($($test_name:ident, $input:expr, $output:expr $(, [ $($support_gen:literal),* ])? )*))*) => {$($(
|
($($fn:expr, $typ:ty, ($($test_name:ident, $input:expr, $output:expr $(, [$($support_gen:literal),*])? )*))*) => {$($(
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg(any(feature = "gen-llvm", $($(feature = $support_gen)*)?))]
|
#[cfg(any(feature = "gen-llvm", $($(feature = $support_gen)*)?))]
|
||||||
fn $test_name() {
|
fn $test_name() {
|
||||||
|
@ -2816,7 +2816,7 @@ fn when_on_i32() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
app "test" provides [ main ] to "./platform"
|
app "test" provides [main] to "./platform"
|
||||||
|
|
||||||
x : I32
|
x : I32
|
||||||
x = 0
|
x = 0
|
||||||
|
@ -2839,7 +2839,7 @@ fn when_on_i16() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
app "test" provides [ main ] to "./platform"
|
app "test" provides [main] to "./platform"
|
||||||
|
|
||||||
x : I16
|
x : I16
|
||||||
x = 0
|
x = 0
|
||||||
|
|
|
@ -161,7 +161,7 @@ fn when_one_element_tag() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
x : [ Pair (Int a) (Int a) ]
|
x : [Pair (Int a) (Int a)]
|
||||||
x = Pair 0x2 0x3
|
x = Pair 0x2 0x3
|
||||||
|
|
||||||
when x is
|
when x is
|
||||||
|
@ -537,7 +537,7 @@ fn peano1() {
|
||||||
assert_non_opt_evals_to!(
|
assert_non_opt_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
Peano : [ S Peano, Z ]
|
Peano : [S Peano, Z]
|
||||||
|
|
||||||
three : Peano
|
three : Peano
|
||||||
three = S (S (S Z))
|
three = S (S (S Z))
|
||||||
|
@ -558,7 +558,7 @@ fn peano2() {
|
||||||
assert_non_opt_evals_to!(
|
assert_non_opt_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
Peano : [ S Peano, Z ]
|
Peano : [S Peano, Z]
|
||||||
|
|
||||||
three : Peano
|
three : Peano
|
||||||
three = S (S (S Z))
|
three = S (S (S Z))
|
||||||
|
@ -580,7 +580,7 @@ fn top_level_constant() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
app "test" provides [ main ] to "./platform"
|
app "test" provides [main] to "./platform"
|
||||||
|
|
||||||
float = 1.2315
|
float = 1.2315
|
||||||
|
|
||||||
|
@ -600,7 +600,7 @@ fn top_level_destructure() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
app "test" provides [ main ] to "./platform"
|
app "test" provides [main] to "./platform"
|
||||||
|
|
||||||
{a, b} = { a: 1, b: 2 }
|
{a, b} = { a: 1, b: 2 }
|
||||||
|
|
||||||
|
@ -620,9 +620,9 @@ fn linked_list_len_0() {
|
||||||
assert_non_opt_evals_to!(
|
assert_non_opt_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
app "test" provides [ main ] to "./platform"
|
app "test" provides [main] to "./platform"
|
||||||
|
|
||||||
LinkedList a : [ Nil, Cons a (LinkedList a) ]
|
LinkedList a : [Nil, Cons a (LinkedList a)]
|
||||||
|
|
||||||
len : LinkedList a -> Int *
|
len : LinkedList a -> Int *
|
||||||
len = \list ->
|
len = \list ->
|
||||||
|
@ -648,9 +648,9 @@ fn linked_list_len_twice_0() {
|
||||||
assert_non_opt_evals_to!(
|
assert_non_opt_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
app "test" provides [ main ] to "./platform"
|
app "test" provides [main] to "./platform"
|
||||||
|
|
||||||
LinkedList a : [ Nil, Cons a (LinkedList a) ]
|
LinkedList a : [Nil, Cons a (LinkedList a)]
|
||||||
|
|
||||||
nil : LinkedList I64
|
nil : LinkedList I64
|
||||||
nil = Nil
|
nil = Nil
|
||||||
|
@ -676,9 +676,9 @@ fn linked_list_len_1() {
|
||||||
assert_non_opt_evals_to!(
|
assert_non_opt_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
app "test" provides [ main ] to "./platform"
|
app "test" provides [main] to "./platform"
|
||||||
|
|
||||||
LinkedList a : [ Nil, Cons a (LinkedList a) ]
|
LinkedList a : [Nil, Cons a (LinkedList a)]
|
||||||
|
|
||||||
one : LinkedList (Int *)
|
one : LinkedList (Int *)
|
||||||
one = Cons 1 Nil
|
one = Cons 1 Nil
|
||||||
|
@ -704,9 +704,9 @@ fn linked_list_len_twice_1() {
|
||||||
assert_non_opt_evals_to!(
|
assert_non_opt_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
app "test" provides [ main ] to "./platform"
|
app "test" provides [main] to "./platform"
|
||||||
|
|
||||||
LinkedList a : [ Nil, Cons a (LinkedList a) ]
|
LinkedList a : [Nil, Cons a (LinkedList a)]
|
||||||
|
|
||||||
one : LinkedList (Int *)
|
one : LinkedList (Int *)
|
||||||
one = Cons 1 Nil
|
one = Cons 1 Nil
|
||||||
|
@ -732,9 +732,9 @@ fn linked_list_len_3() {
|
||||||
assert_non_opt_evals_to!(
|
assert_non_opt_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
app "test" provides [ main ] to "./platform"
|
app "test" provides [main] to "./platform"
|
||||||
|
|
||||||
LinkedList a : [ Nil, Cons a (LinkedList a) ]
|
LinkedList a : [Nil, Cons a (LinkedList a)]
|
||||||
|
|
||||||
three : LinkedList (Int *)
|
three : LinkedList (Int *)
|
||||||
three = Cons 3 (Cons 2 (Cons 1 Nil))
|
three = Cons 3 (Cons 2 (Cons 1 Nil))
|
||||||
|
@ -761,9 +761,9 @@ fn linked_list_sum_num_a() {
|
||||||
assert_non_opt_evals_to!(
|
assert_non_opt_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
app "test" provides [ main ] to "./platform"
|
app "test" provides [main] to "./platform"
|
||||||
|
|
||||||
LinkedList a : [ Nil, Cons a (LinkedList a) ]
|
LinkedList a : [Nil, Cons a (LinkedList a)]
|
||||||
|
|
||||||
three : LinkedList (Int *)
|
three : LinkedList (Int *)
|
||||||
three = Cons 3 (Cons 2 (Cons 1 Nil))
|
three = Cons 3 (Cons 2 (Cons 1 Nil))
|
||||||
|
@ -790,9 +790,9 @@ fn linked_list_sum_int() {
|
||||||
assert_non_opt_evals_to!(
|
assert_non_opt_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
app "test" provides [ main ] to "./platform"
|
app "test" provides [main] to "./platform"
|
||||||
|
|
||||||
LinkedList a : [ Nil, Cons a (LinkedList a) ]
|
LinkedList a : [Nil, Cons a (LinkedList a)]
|
||||||
|
|
||||||
zero : LinkedList (Int *)
|
zero : LinkedList (Int *)
|
||||||
zero = Nil
|
zero = Nil
|
||||||
|
@ -818,9 +818,9 @@ fn linked_list_map() {
|
||||||
assert_non_opt_evals_to!(
|
assert_non_opt_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
app "test" provides [ main ] to "./platform"
|
app "test" provides [main] to "./platform"
|
||||||
|
|
||||||
LinkedList a : [ Nil, Cons a (LinkedList a) ]
|
LinkedList a : [Nil, Cons a (LinkedList a)]
|
||||||
|
|
||||||
three : LinkedList (Int *)
|
three : LinkedList (Int *)
|
||||||
three = Cons 3 (Cons 2 (Cons 1 Nil))
|
three = Cons 3 (Cons 2 (Cons 1 Nil))
|
||||||
|
@ -852,7 +852,7 @@ fn when_nested_maybe() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
Maybe a : [ Nothing, Just a ]
|
Maybe a : [Nothing, Just a]
|
||||||
|
|
||||||
x : Maybe (Maybe (Int a))
|
x : Maybe (Maybe (Int a))
|
||||||
x = Just (Just 41)
|
x = Just (Just 41)
|
||||||
|
@ -869,7 +869,7 @@ fn when_nested_maybe() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
Maybe a : [ Nothing, Just a ]
|
Maybe a : [Nothing, Just a]
|
||||||
|
|
||||||
x : Maybe (Maybe (Int *))
|
x : Maybe (Maybe (Int *))
|
||||||
x = Just Nothing
|
x = Just Nothing
|
||||||
|
@ -887,7 +887,7 @@ fn when_nested_maybe() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
Maybe a : [ Nothing, Just a ]
|
Maybe a : [Nothing, Just a]
|
||||||
|
|
||||||
x : Maybe (Maybe (Int *))
|
x : Maybe (Maybe (Int *))
|
||||||
x = Nothing
|
x = Nothing
|
||||||
|
@ -909,7 +909,7 @@ fn when_peano() {
|
||||||
assert_non_opt_evals_to!(
|
assert_non_opt_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
Peano : [ S Peano, Z ]
|
Peano : [S Peano, Z]
|
||||||
|
|
||||||
three : Peano
|
three : Peano
|
||||||
three = S (S (S Z))
|
three = S (S (S Z))
|
||||||
|
@ -927,7 +927,7 @@ fn when_peano() {
|
||||||
assert_non_opt_evals_to!(
|
assert_non_opt_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
Peano : [ S Peano, Z ]
|
Peano : [S Peano, Z]
|
||||||
|
|
||||||
three : Peano
|
three : Peano
|
||||||
three = S Z
|
three = S Z
|
||||||
|
@ -945,7 +945,7 @@ fn when_peano() {
|
||||||
assert_non_opt_evals_to!(
|
assert_non_opt_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
Peano : [ S Peano, Z ]
|
Peano : [S Peano, Z]
|
||||||
|
|
||||||
three : Peano
|
three : Peano
|
||||||
three = Z
|
three = Z
|
||||||
|
@ -1028,7 +1028,7 @@ fn simple_closure() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
app "test" provides [ main ] to "./platform"
|
app "test" provides [main] to "./platform"
|
||||||
|
|
||||||
x = 42
|
x = 42
|
||||||
|
|
||||||
|
@ -1050,7 +1050,7 @@ fn nested_closure() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
app "test" provides [ main ] to "./platform"
|
app "test" provides [main] to "./platform"
|
||||||
|
|
||||||
foo = \{} ->
|
foo = \{} ->
|
||||||
x = 41
|
x = 41
|
||||||
|
@ -1074,14 +1074,14 @@ fn closure_in_list() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
app "test" provides [ main ] to "./platform"
|
app "test" provides [main] to "./platform"
|
||||||
|
|
||||||
foo = \{} ->
|
foo = \{} ->
|
||||||
x = 41
|
x = 41
|
||||||
|
|
||||||
f = \{} -> x
|
f = \{} -> x
|
||||||
|
|
||||||
[ f ]
|
[f]
|
||||||
|
|
||||||
main =
|
main =
|
||||||
items = foo {}
|
items = foo {}
|
||||||
|
@ -1102,7 +1102,7 @@ fn specialize_closure() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
app "test" provides [ main ] to "./platform"
|
app "test" provides [main] to "./platform"
|
||||||
|
|
||||||
foo = \{} ->
|
foo = \{} ->
|
||||||
x = 41
|
x = 41
|
||||||
|
@ -1111,7 +1111,7 @@ fn specialize_closure() {
|
||||||
f = \{} -> x
|
f = \{} -> x
|
||||||
g = \{} -> x + Num.intCast (List.len y)
|
g = \{} -> x + Num.intCast (List.len y)
|
||||||
|
|
||||||
[ f, g ]
|
[f, g]
|
||||||
|
|
||||||
apply = \f -> f {}
|
apply = \f -> f {}
|
||||||
|
|
||||||
|
@ -1132,7 +1132,7 @@ fn io_poc_effect() {
|
||||||
assert_non_opt_evals_to!(
|
assert_non_opt_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
app "test" provides [ main ] to "./platform"
|
app "test" provides [main] to "./platform"
|
||||||
|
|
||||||
Effect a := {} -> a
|
Effect a := {} -> a
|
||||||
|
|
||||||
|
@ -1163,7 +1163,7 @@ fn io_poc_desugared() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
app "test" provides [ main ] to "./platform"
|
app "test" provides [main] to "./platform"
|
||||||
|
|
||||||
# succeed : a -> ({} -> a)
|
# succeed : a -> ({} -> a)
|
||||||
succeed = \x -> \_ -> x
|
succeed = \x -> \_ -> x
|
||||||
|
@ -1191,7 +1191,7 @@ fn return_wrapped_function_pointer() {
|
||||||
assert_non_opt_evals_to!(
|
assert_non_opt_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
app "test" provides [ main ] to "./platform"
|
app "test" provides [main] to "./platform"
|
||||||
|
|
||||||
Effect a := {} -> a
|
Effect a := {} -> a
|
||||||
|
|
||||||
|
@ -1214,7 +1214,7 @@ fn return_wrapped_function_pointer_b() {
|
||||||
assert_non_opt_evals_to!(
|
assert_non_opt_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
app "test" provides [ main ] to "./platform"
|
app "test" provides [main] to "./platform"
|
||||||
|
|
||||||
|
|
||||||
foo : { x: (I64 -> Str) }
|
foo : { x: (I64 -> Str) }
|
||||||
|
@ -1236,7 +1236,7 @@ fn return_wrapped_closure() {
|
||||||
assert_non_opt_evals_to!(
|
assert_non_opt_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
app "test" provides [ main ] to "./platform"
|
app "test" provides [main] to "./platform"
|
||||||
|
|
||||||
Effect a := {} -> a
|
Effect a := {} -> a
|
||||||
|
|
||||||
|
@ -1262,9 +1262,9 @@ fn linked_list_is_singleton() {
|
||||||
assert_non_opt_evals_to!(
|
assert_non_opt_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
app "test" provides [ main ] to "./platform"
|
app "test" provides [main] to "./platform"
|
||||||
|
|
||||||
ConsList a : [ Cons a (ConsList a), Nil ]
|
ConsList a : [Cons a (ConsList a), Nil]
|
||||||
|
|
||||||
empty : ConsList a
|
empty : ConsList a
|
||||||
empty = Nil
|
empty = Nil
|
||||||
|
@ -1297,9 +1297,9 @@ fn linked_list_is_empty_1() {
|
||||||
assert_non_opt_evals_to!(
|
assert_non_opt_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
app "test" provides [ main ] to "./platform"
|
app "test" provides [main] to "./platform"
|
||||||
|
|
||||||
ConsList a : [ Cons a (ConsList a), Nil ]
|
ConsList a : [Cons a (ConsList a), Nil]
|
||||||
|
|
||||||
empty : ConsList a
|
empty : ConsList a
|
||||||
empty = Nil
|
empty = Nil
|
||||||
|
@ -1332,9 +1332,9 @@ fn linked_list_is_empty_2() {
|
||||||
assert_non_opt_evals_to!(
|
assert_non_opt_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
app "test" provides [ main ] to "./platform"
|
app "test" provides [main] to "./platform"
|
||||||
|
|
||||||
ConsList a : [ Cons a (ConsList a), Nil ]
|
ConsList a : [Cons a (ConsList a), Nil]
|
||||||
|
|
||||||
isEmpty : ConsList a -> Bool
|
isEmpty : ConsList a -> Bool
|
||||||
isEmpty = \list ->
|
isEmpty = \list ->
|
||||||
|
@ -1365,9 +1365,9 @@ fn linked_list_singleton() {
|
||||||
assert_non_opt_evals_to!(
|
assert_non_opt_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
app "test" provides [ main ] to "./platform"
|
app "test" provides [main] to "./platform"
|
||||||
|
|
||||||
ConsList a : [ Cons a (ConsList a), Nil ]
|
ConsList a : [Cons a (ConsList a), Nil]
|
||||||
|
|
||||||
main : ConsList I64
|
main : ConsList I64
|
||||||
main = Cons 0x1 Nil
|
main = Cons 0x1 Nil
|
||||||
|
@ -1385,7 +1385,7 @@ fn recursive_function_with_rigid() {
|
||||||
assert_non_opt_evals_to!(
|
assert_non_opt_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
app "test" provides [ main ] to "./platform"
|
app "test" provides [main] to "./platform"
|
||||||
|
|
||||||
State a : { count : I64, x : a }
|
State a : { count : I64, x : a }
|
||||||
|
|
||||||
|
@ -1412,11 +1412,11 @@ fn rbtree_insert() {
|
||||||
assert_non_opt_evals_to!(
|
assert_non_opt_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
app "test" provides [ main ] to "./platform"
|
app "test" provides [main] to "./platform"
|
||||||
|
|
||||||
NodeColor : [ Red, Black ]
|
NodeColor : [Red, Black]
|
||||||
|
|
||||||
RedBlackTree k v : [ Node NodeColor k v (RedBlackTree k v) (RedBlackTree k v), Empty ]
|
RedBlackTree k v : [Node NodeColor k v (RedBlackTree k v) (RedBlackTree k v), Empty]
|
||||||
|
|
||||||
Key k : Num k
|
Key k : Num k
|
||||||
|
|
||||||
|
@ -1500,9 +1500,9 @@ fn rbtree_balance_3() {
|
||||||
assert_non_opt_evals_to!(
|
assert_non_opt_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
app "test" provides [ main ] to "./platform"
|
app "test" provides [main] to "./platform"
|
||||||
|
|
||||||
RedBlackTree k : [ Node k (RedBlackTree k) (RedBlackTree k), Empty ]
|
RedBlackTree k : [Node k (RedBlackTree k) (RedBlackTree k), Empty]
|
||||||
|
|
||||||
balance : k, RedBlackTree k -> RedBlackTree k
|
balance : k, RedBlackTree k -> RedBlackTree k
|
||||||
balance = \key, left ->
|
balance = \key, left ->
|
||||||
|
@ -1527,11 +1527,11 @@ fn rbtree_layout_issue() {
|
||||||
assert_non_opt_evals_to!(
|
assert_non_opt_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
app "test" provides [ main ] to "./platform"
|
app "test" provides [main] to "./platform"
|
||||||
|
|
||||||
NodeColor : [ Red, Black ]
|
NodeColor : [Red, Black]
|
||||||
|
|
||||||
RedBlackTree k v : [ Node NodeColor k v (RedBlackTree k v) (RedBlackTree k v), Empty ]
|
RedBlackTree k v : [Node NodeColor k v (RedBlackTree k v) (RedBlackTree k v), Empty]
|
||||||
|
|
||||||
# balance : NodeColor, k, v, RedBlackTree k v -> RedBlackTree k v
|
# balance : NodeColor, k, v, RedBlackTree k v -> RedBlackTree k v
|
||||||
balance = \color, key, value, right ->
|
balance = \color, key, value, right ->
|
||||||
|
@ -1574,11 +1574,11 @@ fn rbtree_balance_mono_problem() {
|
||||||
assert_non_opt_evals_to!(
|
assert_non_opt_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
app "test" provides [ main ] to "./platform"
|
app "test" provides [main] to "./platform"
|
||||||
|
|
||||||
NodeColor : [ Red, Black ]
|
NodeColor : [Red, Black]
|
||||||
|
|
||||||
RedBlackTree k v : [ Node NodeColor k v (RedBlackTree k v) (RedBlackTree k v), Empty ]
|
RedBlackTree k v : [Node NodeColor k v (RedBlackTree k v) (RedBlackTree k v), Empty]
|
||||||
|
|
||||||
# balance : NodeColor, k, v, RedBlackTree k v, RedBlackTree k v -> RedBlackTree k v
|
# balance : NodeColor, k, v, RedBlackTree k v, RedBlackTree k v -> RedBlackTree k v
|
||||||
balance = \color, key, value, left, right ->
|
balance = \color, key, value, left, right ->
|
||||||
|
@ -1621,11 +1621,11 @@ fn rbtree_balance_full() {
|
||||||
assert_non_opt_evals_to!(
|
assert_non_opt_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
app "test" provides [ main ] to "./platform"
|
app "test" provides [main] to "./platform"
|
||||||
|
|
||||||
NodeColor : [ Red, Black ]
|
NodeColor : [Red, Black]
|
||||||
|
|
||||||
RedBlackTree k v : [ Node NodeColor k v (RedBlackTree k v) (RedBlackTree k v), Empty ]
|
RedBlackTree k v : [Node NodeColor k v (RedBlackTree k v) (RedBlackTree k v), Empty]
|
||||||
|
|
||||||
balance : NodeColor, k, v, RedBlackTree k v, RedBlackTree k v -> RedBlackTree k v
|
balance : NodeColor, k, v, RedBlackTree k v, RedBlackTree k v -> RedBlackTree k v
|
||||||
balance = \color, key, value, left, right ->
|
balance = \color, key, value, left, right ->
|
||||||
|
@ -1674,9 +1674,9 @@ fn nested_pattern_match_two_ways() {
|
||||||
assert_non_opt_evals_to!(
|
assert_non_opt_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
app "test" provides [ main ] to "./platform"
|
app "test" provides [main] to "./platform"
|
||||||
|
|
||||||
ConsList a : [ Cons a (ConsList a), Nil ]
|
ConsList a : [Cons a (ConsList a), Nil]
|
||||||
|
|
||||||
balance : ConsList (Int *) -> Int *
|
balance : ConsList (Int *) -> Int *
|
||||||
balance = \right ->
|
balance = \right ->
|
||||||
|
@ -1700,9 +1700,9 @@ fn nested_pattern_match_two_ways() {
|
||||||
assert_non_opt_evals_to!(
|
assert_non_opt_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
app "test" provides [ main ] to "./platform"
|
app "test" provides [main] to "./platform"
|
||||||
|
|
||||||
ConsList a : [ Cons a (ConsList a), Nil ]
|
ConsList a : [Cons a (ConsList a), Nil]
|
||||||
|
|
||||||
balance : ConsList (Int *) -> Int *
|
balance : ConsList (Int *) -> Int *
|
||||||
balance = \right ->
|
balance = \right ->
|
||||||
|
@ -1729,9 +1729,9 @@ fn linked_list_guarded_double_pattern_match() {
|
||||||
assert_non_opt_evals_to!(
|
assert_non_opt_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
app "test" provides [ main ] to "./platform"
|
app "test" provides [main] to "./platform"
|
||||||
|
|
||||||
ConsList a : [ Cons a (ConsList a), Nil ]
|
ConsList a : [Cons a (ConsList a), Nil]
|
||||||
|
|
||||||
balance : ConsList (Int *) -> Int *
|
balance : ConsList (Int *) -> Int *
|
||||||
balance = \right ->
|
balance = \right ->
|
||||||
|
@ -1759,9 +1759,9 @@ fn linked_list_double_pattern_match() {
|
||||||
assert_non_opt_evals_to!(
|
assert_non_opt_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
app "test" provides [ main ] to "./platform"
|
app "test" provides [main] to "./platform"
|
||||||
|
|
||||||
ConsList a : [ Cons a (ConsList a), Nil ]
|
ConsList a : [Cons a (ConsList a), Nil]
|
||||||
|
|
||||||
foo : ConsList (Int a) -> Int a
|
foo : ConsList (Int a) -> Int a
|
||||||
foo = \list ->
|
foo = \list ->
|
||||||
|
@ -1785,9 +1785,9 @@ fn binary_tree_double_pattern_match() {
|
||||||
assert_non_opt_evals_to!(
|
assert_non_opt_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
app "test" provides [ main ] to "./platform"
|
app "test" provides [main] to "./platform"
|
||||||
|
|
||||||
BTree : [ Node BTree BTree, Leaf I64 ]
|
BTree : [Node BTree BTree, Leaf I64]
|
||||||
|
|
||||||
foo : BTree -> I64
|
foo : BTree -> I64
|
||||||
foo = \btree ->
|
foo = \btree ->
|
||||||
|
@ -1813,7 +1813,7 @@ fn unified_empty_closure_bool() {
|
||||||
assert_non_opt_evals_to!(
|
assert_non_opt_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
app "test" provides [ main ] to "./platform"
|
app "test" provides [main] to "./platform"
|
||||||
|
|
||||||
foo = \{} ->
|
foo = \{} ->
|
||||||
when A is
|
when A is
|
||||||
|
@ -1838,7 +1838,7 @@ fn unified_empty_closure_byte() {
|
||||||
assert_non_opt_evals_to!(
|
assert_non_opt_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
app "test" provides [ main ] to "./platform"
|
app "test" provides [main] to "./platform"
|
||||||
|
|
||||||
foo = \{} ->
|
foo = \{} ->
|
||||||
when A is
|
when A is
|
||||||
|
@ -1862,7 +1862,7 @@ fn task_always_twice() {
|
||||||
assert_non_opt_evals_to!(
|
assert_non_opt_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
app "test" provides [ main ] to "./platform"
|
app "test" provides [main] to "./platform"
|
||||||
|
|
||||||
Effect a := {} -> a
|
Effect a := {} -> a
|
||||||
|
|
||||||
|
@ -1907,7 +1907,7 @@ fn wildcard_rigid() {
|
||||||
assert_non_opt_evals_to!(
|
assert_non_opt_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
app "test" provides [ main ] to "./platform"
|
app "test" provides [main] to "./platform"
|
||||||
|
|
||||||
Effect a := {} -> a
|
Effect a := {} -> a
|
||||||
|
|
||||||
|
@ -1937,7 +1937,7 @@ fn alias_of_alias_with_type_arguments() {
|
||||||
assert_non_opt_evals_to!(
|
assert_non_opt_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
app "test" provides [ main ] to "./platform"
|
app "test" provides [main] to "./platform"
|
||||||
|
|
||||||
Effect a := a
|
Effect a := a
|
||||||
|
|
||||||
|
@ -1967,7 +1967,7 @@ fn todo_bad_error_message() {
|
||||||
assert_non_opt_evals_to!(
|
assert_non_opt_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
app "test" provides [ main ] to "./platform"
|
app "test" provides [main] to "./platform"
|
||||||
|
|
||||||
Effect a := {} -> a
|
Effect a := {} -> a
|
||||||
|
|
||||||
|
@ -2028,7 +2028,7 @@ fn hof_conditional() {
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg(any(feature = "gen-llvm"))]
|
#[cfg(any(feature = "gen-llvm"))]
|
||||||
#[should_panic(
|
#[should_panic(
|
||||||
expected = "Roc failed with message: \"Shadowing { original_region: @57-58, shadow: @90-91 Ident"
|
expected = "Roc failed with message: \"Shadowing { original_region: @55-56, shadow: @88-89 Ident"
|
||||||
)]
|
)]
|
||||||
fn pattern_shadowing() {
|
fn pattern_shadowing() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
|
@ -2070,14 +2070,14 @@ fn fingertree_basic() {
|
||||||
assert_non_opt_evals_to!(
|
assert_non_opt_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
app "test" provides [ main ] to "./platform"
|
app "test" provides [main] to "./platform"
|
||||||
|
|
||||||
Some a : [ One a, Two a a, Three a a a ]
|
Some a : [One a, Two a a, Three a a a]
|
||||||
|
|
||||||
Tuple a : [ Pair a a, Triple a a a ]
|
Tuple a : [Pair a a, Triple a a a]
|
||||||
|
|
||||||
# a FingerTree implementation
|
# a FingerTree implementation
|
||||||
Seq a : [ Nil, Unit a, More (Some a) (Seq (Tuple a)) (Some a) ]
|
Seq a : [Nil, Unit a, More (Some a) (Seq (Tuple a)) (Some a)]
|
||||||
|
|
||||||
# cons : a, Seq a -> Seq a
|
# cons : a, Seq a -> Seq a
|
||||||
cons = \x, s ->
|
cons = \x, s ->
|
||||||
|
@ -2113,7 +2113,7 @@ fn case_or_pattern() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
x : [ Red, Green, Blue ]
|
x : [Red, Green, Blue]
|
||||||
x = Red
|
x = Red
|
||||||
|
|
||||||
when x is
|
when x is
|
||||||
|
@ -2133,9 +2133,9 @@ fn rosetree_basic() {
|
||||||
assert_non_opt_evals_to!(
|
assert_non_opt_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
app "test" provides [ main ] to "./platform"
|
app "test" provides [main] to "./platform"
|
||||||
|
|
||||||
Tree a : [ Tree a (List (Tree a)) ]
|
Tree a : [Tree a (List (Tree a))]
|
||||||
|
|
||||||
singleton : a -> Tree a
|
singleton : a -> Tree a
|
||||||
singleton = \x -> Tree x []
|
singleton = \x -> Tree x []
|
||||||
|
@ -2161,9 +2161,9 @@ fn case_jump() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
app "test" provides [ main ] to "./platform"
|
app "test" provides [main] to "./platform"
|
||||||
|
|
||||||
ConsList a : [ Cons a (ConsList a), Nil ]
|
ConsList a : [Cons a (ConsList a), Nil]
|
||||||
|
|
||||||
x : ConsList I64
|
x : ConsList I64
|
||||||
x = Nil
|
x = Nil
|
||||||
|
@ -2187,9 +2187,9 @@ fn nullable_eval_cfold() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
app "test" provides [ main ] to "./platform"
|
app "test" provides [main] to "./platform"
|
||||||
|
|
||||||
Expr : [ Var, Val I64, Add Expr Expr, Mul Expr Expr ]
|
Expr : [Var, Val I64, Add Expr Expr, Mul Expr Expr]
|
||||||
|
|
||||||
mkExpr : I64, I64 -> Expr
|
mkExpr : I64, I64 -> Expr
|
||||||
mkExpr = \n , v ->
|
mkExpr = \n , v ->
|
||||||
|
@ -2224,9 +2224,9 @@ fn nested_switch() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
app "test" provides [ main ] to "./platform"
|
app "test" provides [main] to "./platform"
|
||||||
|
|
||||||
Expr : [ ZAdd Expr Expr, Val I64, Var I64 ]
|
Expr : [ZAdd Expr Expr, Val I64, Var I64]
|
||||||
|
|
||||||
eval : Expr -> I64
|
eval : Expr -> I64
|
||||||
eval = \e ->
|
eval = \e ->
|
||||||
|
@ -2267,9 +2267,9 @@ fn count_deriv_x() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
app "test" provides [ main ] to "./platform"
|
app "test" provides [main] to "./platform"
|
||||||
|
|
||||||
Expr : [ Ln Expr, Pow Expr Expr, Var Str ]
|
Expr : [Ln Expr, Pow Expr Expr, Var Str]
|
||||||
|
|
||||||
count : Expr -> I64
|
count : Expr -> I64
|
||||||
count = \expr ->
|
count = \expr ->
|
||||||
|
@ -2294,9 +2294,9 @@ fn deriv_pow() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
app "test" provides [ main ] to "./platform"
|
app "test" provides [main] to "./platform"
|
||||||
|
|
||||||
Expr : [ Ln Expr, Pow Expr Expr, Var Str, Val I64 ]
|
Expr : [Ln Expr, Pow Expr Expr, Var Str, Val I64]
|
||||||
|
|
||||||
count : Expr -> I64
|
count : Expr -> I64
|
||||||
count = \expr ->
|
count = \expr ->
|
||||||
|
@ -2331,12 +2331,12 @@ fn multiple_increment() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
app "test" provides [ main ] to "./platform"
|
app "test" provides [main] to "./platform"
|
||||||
|
|
||||||
|
|
||||||
Color : [ Red, Black ]
|
Color : [Red, Black]
|
||||||
|
|
||||||
Tree a b : [ Leaf, Node Color (Tree a b) a b (Tree a b) ]
|
Tree a b : [Leaf, Node Color (Tree a b) a b (Tree a b)]
|
||||||
|
|
||||||
Map : Tree I64 Bool
|
Map : Tree I64 Bool
|
||||||
|
|
||||||
|
@ -2364,9 +2364,9 @@ fn switch_fuse_rc_non_exhaustive() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
app "test" provides [ main ] to "./platform"
|
app "test" provides [main] to "./platform"
|
||||||
|
|
||||||
Foo : [ A I64 Foo, B I64 Foo, C I64 Foo, Empty ]
|
Foo : [A I64 Foo, B I64 Foo, C I64 Foo, Empty]
|
||||||
|
|
||||||
sum : Foo, I64 -> I64
|
sum : Foo, I64 -> I64
|
||||||
sum = \foo, accum ->
|
sum = \foo, accum ->
|
||||||
|
@ -2394,9 +2394,9 @@ fn switch_fuse_rc_exhaustive() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
app "test" provides [ main ] to "./platform"
|
app "test" provides [main] to "./platform"
|
||||||
|
|
||||||
Foo : [ A I64 Foo, B I64 Foo, C I64 Foo, Empty ]
|
Foo : [A I64 Foo, B I64 Foo, C I64 Foo, Empty]
|
||||||
|
|
||||||
sum : Foo, I64 -> I64
|
sum : Foo, I64 -> I64
|
||||||
sum = \foo, accum ->
|
sum = \foo, accum ->
|
||||||
|
@ -2423,7 +2423,7 @@ fn build_then_apply_closure() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
app "test" provides [ main ] to "./platform"
|
app "test" provides [main] to "./platform"
|
||||||
|
|
||||||
main : Str
|
main : Str
|
||||||
main =
|
main =
|
||||||
|
@ -2443,7 +2443,7 @@ fn expanded_result() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
app "test" provides [ main ] to "./platform"
|
app "test" provides [main] to "./platform"
|
||||||
|
|
||||||
a : Result I64 Str
|
a : Result I64 Str
|
||||||
a = Ok 4
|
a = Ok 4
|
||||||
|
@ -2475,7 +2475,7 @@ fn backpassing_result() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
app "test" provides [ main ] to "./platform"
|
app "test" provides [main] to "./platform"
|
||||||
|
|
||||||
a : Result I64 Str
|
a : Result I64 Str
|
||||||
a = Ok 1
|
a = Ok 1
|
||||||
|
@ -2504,7 +2504,7 @@ fn backpassing_result() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg(any(feature = "gen-llvm"))]
|
#[cfg(any(feature = "gen-llvm"))]
|
||||||
#[should_panic(expected = "Shadowing { original_region: @57-58, shadow: @74-75 Ident")]
|
#[should_panic(expected = "Shadowing { original_region: @55-56, shadow: @72-73 Ident")]
|
||||||
fn function_malformed_pattern() {
|
fn function_malformed_pattern() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
|
@ -2562,7 +2562,7 @@ fn increment_or_double_closure() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
app "test" provides [ main ] to "./platform"
|
app "test" provides [main] to "./platform"
|
||||||
|
|
||||||
|
|
||||||
apply : (a -> a), a -> a
|
apply : (a -> a), a -> a
|
||||||
|
@ -2600,7 +2600,7 @@ fn module_thunk_is_function() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
app "test" provides [ main ] to "./platform"
|
app "test" provides [main] to "./platform"
|
||||||
|
|
||||||
main = helper "foo" "bar"
|
main = helper "foo" "bar"
|
||||||
helper = Str.concat
|
helper = Str.concat
|
||||||
|
@ -2618,7 +2618,7 @@ fn hit_unresolved_type_variable() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
app "test" provides [ main ] to "./platform"
|
app "test" provides [main] to "./platform"
|
||||||
|
|
||||||
main : Str
|
main : Str
|
||||||
main =
|
main =
|
||||||
|
@ -2641,7 +2641,7 @@ fn pattern_match_empty_record() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
app "test" provides [ main ] to "./platform"
|
app "test" provides [main] to "./platform"
|
||||||
|
|
||||||
main : I64
|
main : I64
|
||||||
main =
|
main =
|
||||||
|
@ -2661,9 +2661,9 @@ fn pattern_match_unit_tag() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
app "test" provides [ main ] to "./platform"
|
app "test" provides [main] to "./platform"
|
||||||
|
|
||||||
unit : [ Unit ]
|
unit : [Unit]
|
||||||
unit = Unit
|
unit = Unit
|
||||||
|
|
||||||
main : I64
|
main : I64
|
||||||
|
@ -2687,13 +2687,13 @@ fn mirror_llvm_alignment_padding() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
app "test" provides [ main ] to "./platform"
|
app "test" provides [main] to "./platform"
|
||||||
|
|
||||||
main : Str
|
main : Str
|
||||||
main =
|
main =
|
||||||
p1 = {name : "test1", test: 1 == 1 }
|
p1 = {name : "test1", test: 1 == 1 }
|
||||||
|
|
||||||
List.map [p1, p1 ] (\{ test } -> if test then "pass" else "fail")
|
List.map [p1, p1] (\{ test } -> if test then "pass" else "fail")
|
||||||
|> Str.joinWith "\n"
|
|> Str.joinWith "\n"
|
||||||
|
|
||||||
"#
|
"#
|
||||||
|
@ -2709,7 +2709,7 @@ fn lambda_set_bool() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
app "test" provides [ main ] to "./platform"
|
app "test" provides [main] to "./platform"
|
||||||
|
|
||||||
p1 = (\u -> u == 97)
|
p1 = (\u -> u == 97)
|
||||||
p2 = (\u -> u == 98)
|
p2 = (\u -> u == 98)
|
||||||
|
@ -2734,7 +2734,7 @@ fn lambda_set_byte() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
app "test" provides [ main ] to "./platform"
|
app "test" provides [main] to "./platform"
|
||||||
|
|
||||||
p1 = (\u -> u == 97)
|
p1 = (\u -> u == 97)
|
||||||
p2 = (\u -> u == 98)
|
p2 = (\u -> u == 98)
|
||||||
|
@ -2760,12 +2760,12 @@ fn lambda_set_struct_byte() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
app "test" provides [ main ] to "./platform"
|
app "test" provides [main] to "./platform"
|
||||||
|
|
||||||
|
|
||||||
main : I64
|
main : I64
|
||||||
main =
|
main =
|
||||||
r : [ Red, Green, Blue ]
|
r : [Red, Green, Blue]
|
||||||
r = Red
|
r = Red
|
||||||
|
|
||||||
p1 = (\u -> r == u)
|
p1 = (\u -> r == u)
|
||||||
|
@ -2788,15 +2788,15 @@ fn lambda_set_enum_byte_byte() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
app "test" provides [ main ] to "./platform"
|
app "test" provides [main] to "./platform"
|
||||||
|
|
||||||
|
|
||||||
main : I64
|
main : I64
|
||||||
main =
|
main =
|
||||||
r : [ Red, Green, Blue ]
|
r : [Red, Green, Blue]
|
||||||
r = Red
|
r = Red
|
||||||
|
|
||||||
g : [ Red, Green, Blue ]
|
g : [Red, Green, Blue]
|
||||||
g = Green
|
g = Green
|
||||||
|
|
||||||
p1 = (\u -> r == u)
|
p1 = (\u -> r == u)
|
||||||
|
@ -2820,14 +2820,14 @@ fn list_walk_until() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
app "test" provides [ main ] to "./platform"
|
app "test" provides [main] to "./platform"
|
||||||
|
|
||||||
|
|
||||||
satisfyA : {} -> List {}
|
satisfyA : {} -> List {}
|
||||||
satisfyA = \_ -> []
|
satisfyA = \_ -> []
|
||||||
|
|
||||||
oneOfResult =
|
oneOfResult =
|
||||||
List.walkUntil [ satisfyA ] [] \_, _ -> Stop []
|
List.walkUntil [satisfyA] [] \_, _ -> Stop []
|
||||||
|
|
||||||
main =
|
main =
|
||||||
when oneOfResult is
|
when oneOfResult is
|
||||||
|
@ -2846,7 +2846,7 @@ fn int_literal_not_specialized_with_annotation() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
app "test" provides [ main ] to "./platform"
|
app "test" provides [main] to "./platform"
|
||||||
|
|
||||||
main =
|
main =
|
||||||
satisfy : (U8 -> Str) -> Str
|
satisfy : (U8 -> Str) -> Str
|
||||||
|
@ -2874,7 +2874,7 @@ fn int_literal_not_specialized_no_annotation() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
app "test" provides [ main ] to "./platform"
|
app "test" provides [main] to "./platform"
|
||||||
|
|
||||||
main =
|
main =
|
||||||
satisfy : (U8 -> Str) -> Str
|
satisfy : (U8 -> Str) -> Str
|
||||||
|
@ -2901,7 +2901,7 @@ fn unresolved_tvar_when_capture_is_unused() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
app "test" provides [ main ] to "./platform"
|
app "test" provides [main] to "./platform"
|
||||||
|
|
||||||
main : I64
|
main : I64
|
||||||
main =
|
main =
|
||||||
|
@ -2928,7 +2928,7 @@ fn value_not_exposed_hits_panic() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
app "test" provides [ main ] to "./platform"
|
app "test" provides [main] to "./platform"
|
||||||
|
|
||||||
main : I64
|
main : I64
|
||||||
main =
|
main =
|
||||||
|
@ -2947,7 +2947,7 @@ fn mix_function_and_closure() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
app "test" provides [ main ] to "./platform"
|
app "test" provides [main] to "./platform"
|
||||||
|
|
||||||
# foo does not capture any variables
|
# foo does not capture any variables
|
||||||
# but through unification will get a lambda set that does store information
|
# but through unification will get a lambda set that does store information
|
||||||
|
@ -2973,7 +2973,7 @@ fn mix_function_and_closure_level_of_indirection() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
app "test" provides [ main ] to "./platform"
|
app "test" provides [main] to "./platform"
|
||||||
|
|
||||||
foo = \x -> x
|
foo = \x -> x
|
||||||
|
|
||||||
|
@ -3001,7 +3001,7 @@ fn do_pass_bool_byte_closure_layout() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
app "test" provides [ main ] to "./platform"
|
app "test" provides [main] to "./platform"
|
||||||
|
|
||||||
## PARSER
|
## PARSER
|
||||||
|
|
||||||
|
@ -3016,7 +3016,7 @@ fn do_pass_bool_byte_closure_layout() {
|
||||||
any = \inp ->
|
any = \inp ->
|
||||||
when List.first inp is
|
when List.first inp is
|
||||||
Ok u -> [Pair u (List.drop inp 1)]
|
Ok u -> [Pair u (List.drop inp 1)]
|
||||||
_ -> [ ]
|
_ -> []
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -3027,7 +3027,7 @@ fn do_pass_bool_byte_closure_layout() {
|
||||||
\input ->
|
\input ->
|
||||||
walker = \accum, (Pair u rest) ->
|
walker = \accum, (Pair u rest) ->
|
||||||
if predicate u then
|
if predicate u then
|
||||||
Stop [ Pair u rest ]
|
Stop [Pair u rest]
|
||||||
|
|
||||||
else
|
else
|
||||||
Stop accum
|
Stop accum
|
||||||
|
@ -3074,7 +3074,7 @@ fn nested_rigid_list() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
app "test" provides [ main ] to "./platform"
|
app "test" provides [main] to "./platform"
|
||||||
|
|
||||||
foo : List a -> List a
|
foo : List a -> List a
|
||||||
foo = \list ->
|
foo = \list ->
|
||||||
|
@ -3099,7 +3099,7 @@ fn nested_rigid_alias() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
app "test" provides [ main ] to "./platform"
|
app "test" provides [main] to "./platform"
|
||||||
|
|
||||||
Identity a := a
|
Identity a := a
|
||||||
|
|
||||||
|
@ -3126,11 +3126,11 @@ fn nested_rigid_tag_union() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
app "test" provides [ main ] to "./platform"
|
app "test" provides [main] to "./platform"
|
||||||
|
|
||||||
foo : [ Identity a ] -> [ Identity a ]
|
foo : [Identity a] -> [Identity a]
|
||||||
foo = \list ->
|
foo = \list ->
|
||||||
p2 : [ Identity a ]
|
p2 : [Identity a]
|
||||||
p2 = list
|
p2 = list
|
||||||
|
|
||||||
p2
|
p2
|
||||||
|
@ -3153,15 +3153,15 @@ fn call_that_needs_closure_parameter() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
Step state a : [ Loop state, Done a ]
|
Step state a : [Loop state, Done a]
|
||||||
|
|
||||||
manyAux : List a -> [ Pair (Step (List a) (List a))]
|
manyAux : List a -> [Pair (Step (List a) (List a))]
|
||||||
manyAux = \list ->
|
manyAux = \list ->
|
||||||
p2 = \_ -> Pair (Done list)
|
p2 = \_ -> Pair (Done list)
|
||||||
|
|
||||||
p2 "foo"
|
p2 "foo"
|
||||||
|
|
||||||
manyAuxTest = (manyAux [ ]) == Pair (Loop [97])
|
manyAuxTest = (manyAux []) == Pair (Loop [97])
|
||||||
|
|
||||||
runTest = \t -> if t then "PASS" else "FAIL"
|
runTest = \t -> if t then "PASS" else "FAIL"
|
||||||
|
|
||||||
|
@ -3179,7 +3179,7 @@ fn alias_defined_out_of_order() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
app "test" provides [ main ] to "./platform"
|
app "test" provides [main] to "./platform"
|
||||||
|
|
||||||
main : Foo
|
main : Foo
|
||||||
main = "foo"
|
main = "foo"
|
||||||
|
@ -3200,7 +3200,7 @@ fn recursively_build_effect() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
app "test" provides [ main ] to "./platform"
|
app "test" provides [main] to "./platform"
|
||||||
|
|
||||||
greeting =
|
greeting =
|
||||||
hi = "Hello"
|
hi = "Hello"
|
||||||
|
@ -3247,7 +3247,7 @@ fn polymophic_expression_captured_inside_closure() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
app "test" provides [ main ] to "./platform"
|
app "test" provides [main] to "./platform"
|
||||||
|
|
||||||
asU8 : U8 -> U8
|
asU8 : U8 -> U8
|
||||||
asU8 = \_ -> 30
|
asU8 = \_ -> 30
|
||||||
|
@ -3334,7 +3334,7 @@ fn box_and_unbox_tag_union() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
v : [ A U8, B U8 ] # usually stack allocated
|
v : [A U8, B U8] # usually stack allocated
|
||||||
v = B 27u8
|
v = B 27u8
|
||||||
|
|
||||||
Box.unbox (Box.box v)
|
Box.unbox (Box.box v)
|
||||||
|
@ -3351,7 +3351,7 @@ fn closure_called_in_its_defining_scope() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
app "test" provides [ main ] to "./platform"
|
app "test" provides [main] to "./platform"
|
||||||
|
|
||||||
main : Str
|
main : Str
|
||||||
main =
|
main =
|
||||||
|
@ -3376,7 +3376,7 @@ fn issue_2894() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
app "test" provides [ main ] to "./platform"
|
app "test" provides [main] to "./platform"
|
||||||
|
|
||||||
main : U32
|
main : U32
|
||||||
main =
|
main =
|
||||||
|
@ -3461,10 +3461,10 @@ fn list_map2_conslist() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
ConsList a : [ Nil, Cons a (ConsList a) ]
|
ConsList a : [Nil, Cons a (ConsList a)]
|
||||||
|
|
||||||
x : List (ConsList Str)
|
x : List (ConsList Str)
|
||||||
x = List.map2 [ ] [ Nil ] Cons
|
x = List.map2 [] [Nil] Cons
|
||||||
|
|
||||||
when List.first x is
|
when List.first x is
|
||||||
_ -> ""
|
_ -> ""
|
||||||
|
|
|
@ -423,7 +423,7 @@ fn optional_field_when_use_default() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
app "test" provides [ main ] to "./platform"
|
app "test" provides [main] to "./platform"
|
||||||
|
|
||||||
f = \r ->
|
f = \r ->
|
||||||
when r is
|
when r is
|
||||||
|
@ -475,7 +475,7 @@ fn optional_field_when_no_use_default() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
app "test" provides [ main ] to "./platform"
|
app "test" provides [main] to "./platform"
|
||||||
|
|
||||||
f = \r ->
|
f = \r ->
|
||||||
{ x ? 10, y } = r
|
{ x ? 10, y } = r
|
||||||
|
@ -514,7 +514,7 @@ fn optional_field_let_use_default() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
app "test" provides [ main ] to "./platform"
|
app "test" provides [main] to "./platform"
|
||||||
|
|
||||||
f = \r ->
|
f = \r ->
|
||||||
{ x ? 10, y } = r
|
{ x ? 10, y } = r
|
||||||
|
@ -535,7 +535,7 @@ fn optional_field_let_no_use_default() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
app "test" provides [ main ] to "./platform"
|
app "test" provides [main] to "./platform"
|
||||||
|
|
||||||
f = \r ->
|
f = \r ->
|
||||||
{ x ? 10, y } = r
|
{ x ? 10, y } = r
|
||||||
|
@ -591,7 +591,7 @@ fn optional_field_function_no_use_default() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
app "test" provides [ main ] to "./platform"
|
app "test" provides [main] to "./platform"
|
||||||
|
|
||||||
f = \{ x ? 10, y } -> x + y
|
f = \{ x ? 10, y } -> x + y
|
||||||
|
|
||||||
|
@ -1014,7 +1014,7 @@ fn different_proc_types_specialized_to_same_layout() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
app "test" provides [ nums ] to "./platform"
|
app "test" provides [nums] to "./platform"
|
||||||
|
|
||||||
# Top-level values compile to procedure calls with no args
|
# Top-level values compile to procedure calls with no args
|
||||||
# alpha has the generic type { a: Num *, b: Num * }
|
# alpha has the generic type { a: Num *, b: Num * }
|
||||||
|
@ -1047,7 +1047,7 @@ fn different_proc_types_specialized_to_same_layout() {
|
||||||
fn call_with_bad_record_runtime_error() {
|
fn call_with_bad_record_runtime_error() {
|
||||||
expect_runtime_error_panic!(indoc!(
|
expect_runtime_error_panic!(indoc!(
|
||||||
r#"
|
r#"
|
||||||
app "test" provides [ main ] to "./platform"
|
app "test" provides [main] to "./platform"
|
||||||
|
|
||||||
main =
|
main =
|
||||||
get : {a: Bool} -> Bool
|
get : {a: Bool} -> Bool
|
||||||
|
@ -1063,7 +1063,7 @@ fn call_with_bad_record_runtime_error() {
|
||||||
fn call_with_bad_record_runtime_error() {
|
fn call_with_bad_record_runtime_error() {
|
||||||
expect_runtime_error_panic!(indoc!(
|
expect_runtime_error_panic!(indoc!(
|
||||||
r#"
|
r#"
|
||||||
app "test" provides [ main ] to "./platform"
|
app "test" provides [main] to "./platform"
|
||||||
|
|
||||||
main =
|
main =
|
||||||
get : {a: Bool} -> Bool
|
get : {a: Bool} -> Bool
|
||||||
|
|
|
@ -166,7 +166,7 @@ fn union_nonrecursive_inc() {
|
||||||
assert_refcounts!(
|
assert_refcounts!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
TwoOrNone a: [ Two a a, None ]
|
TwoOrNone a: [Two a a, None]
|
||||||
|
|
||||||
s = Str.concat "A long enough string " "to be heap-allocated"
|
s = Str.concat "A long enough string " "to be heap-allocated"
|
||||||
|
|
||||||
|
@ -190,7 +190,7 @@ fn union_nonrecursive_dec() {
|
||||||
assert_refcounts!(
|
assert_refcounts!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
TwoOrNone a: [ Two a a, None ]
|
TwoOrNone a: [Two a a, None]
|
||||||
|
|
||||||
s = Str.concat "A long enough string " "to be heap-allocated"
|
s = Str.concat "A long enough string " "to be heap-allocated"
|
||||||
|
|
||||||
|
@ -213,7 +213,7 @@ fn union_recursive_inc() {
|
||||||
assert_refcounts!(
|
assert_refcounts!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
Expr : [ Sym Str, Add Expr Expr ]
|
Expr : [Sym Str, Add Expr Expr]
|
||||||
|
|
||||||
s = Str.concat "heap_allocated" "_symbol_name"
|
s = Str.concat "heap_allocated" "_symbol_name"
|
||||||
|
|
||||||
|
@ -241,7 +241,7 @@ fn union_recursive_dec() {
|
||||||
assert_refcounts!(
|
assert_refcounts!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
Expr : [ Sym Str, Add Expr Expr ]
|
Expr : [Sym Str, Add Expr Expr]
|
||||||
|
|
||||||
s = Str.concat "heap_allocated" "_symbol_name"
|
s = Str.concat "heap_allocated" "_symbol_name"
|
||||||
|
|
||||||
|
@ -273,7 +273,7 @@ fn refcount_different_rosetrees_inc() {
|
||||||
assert_refcounts!(
|
assert_refcounts!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
Rose a : [ Rose a (List (Rose a)) ]
|
Rose a : [Rose a (List (Rose a))]
|
||||||
|
|
||||||
s = Str.concat "A long enough string " "to be heap-allocated"
|
s = Str.concat "A long enough string " "to be heap-allocated"
|
||||||
|
|
||||||
|
@ -313,7 +313,7 @@ fn refcount_different_rosetrees_dec() {
|
||||||
assert_refcounts!(
|
assert_refcounts!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
Rose a : [ Rose a (List (Rose a)) ]
|
Rose a : [Rose a (List (Rose a))]
|
||||||
|
|
||||||
s = Str.concat "A long enough string " "to be heap-allocated"
|
s = Str.concat "A long enough string " "to be heap-allocated"
|
||||||
|
|
||||||
|
@ -352,7 +352,7 @@ fn union_linked_list_inc() {
|
||||||
assert_refcounts!(
|
assert_refcounts!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
LinkedList a : [ Nil, Cons a (LinkedList a) ]
|
LinkedList a : [Nil, Cons a (LinkedList a)]
|
||||||
|
|
||||||
s = Str.concat "A long enough string " "to be heap-allocated"
|
s = Str.concat "A long enough string " "to be heap-allocated"
|
||||||
|
|
||||||
|
@ -378,7 +378,7 @@ fn union_linked_list_dec() {
|
||||||
assert_refcounts!(
|
assert_refcounts!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
LinkedList a : [ Nil, Cons a (LinkedList a) ]
|
LinkedList a : [Nil, Cons a (LinkedList a)]
|
||||||
|
|
||||||
s = Str.concat "A long enough string " "to be heap-allocated"
|
s = Str.concat "A long enough string " "to be heap-allocated"
|
||||||
|
|
||||||
|
@ -406,9 +406,9 @@ fn union_linked_list_long_dec() {
|
||||||
assert_refcounts!(
|
assert_refcounts!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
app "test" provides [ main ] to "./platform"
|
app "test" provides [main] to "./platform"
|
||||||
|
|
||||||
LinkedList a : [ Nil, Cons a (LinkedList a) ]
|
LinkedList a : [Nil, Cons a (LinkedList a)]
|
||||||
|
|
||||||
prependOnes = \n, tail ->
|
prependOnes = \n, tail ->
|
||||||
if n == 0 then
|
if n == 0 then
|
||||||
|
|
|
@ -268,7 +268,7 @@ fn from_list_result() {
|
||||||
x : Result Str {}
|
x : Result Str {}
|
||||||
x = Ok "foo"
|
x = Ok "foo"
|
||||||
|
|
||||||
[ x ]
|
[x]
|
||||||
|> Set.fromList
|
|> Set.fromList
|
||||||
|> Set.toList
|
|> Set.toList
|
||||||
|> List.len
|
|> List.len
|
||||||
|
|
|
@ -582,7 +582,7 @@ fn str_from_utf8_pass_single_ascii() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
when Str.fromUtf8 [ 97 ] is
|
when Str.fromUtf8 [97] is
|
||||||
Ok val -> val
|
Ok val -> val
|
||||||
Err _ -> ""
|
Err _ -> ""
|
||||||
"#
|
"#
|
||||||
|
@ -598,7 +598,7 @@ fn str_from_utf8_pass_many_ascii() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
when Str.fromUtf8 [ 97, 98, 99, 0x7E ] is
|
when Str.fromUtf8 [97, 98, 99, 0x7E] is
|
||||||
Ok val -> val
|
Ok val -> val
|
||||||
Err _ -> ""
|
Err _ -> ""
|
||||||
"#
|
"#
|
||||||
|
@ -614,7 +614,7 @@ fn str_from_utf8_pass_single_unicode() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
when Str.fromUtf8 [ 0xE2, 0x88, 0x86 ] is
|
when Str.fromUtf8 [0xE2, 0x88, 0x86] is
|
||||||
Ok val -> val
|
Ok val -> val
|
||||||
Err _ -> ""
|
Err _ -> ""
|
||||||
"#
|
"#
|
||||||
|
@ -630,7 +630,7 @@ fn str_from_utf8_pass_many_unicode() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
when Str.fromUtf8 [ 0xE2, 0x88, 0x86, 0xC5, 0x93, 0xC2, 0xAC ] is
|
when Str.fromUtf8 [0xE2, 0x88, 0x86, 0xC5, 0x93, 0xC2, 0xAC] is
|
||||||
Ok val -> val
|
Ok val -> val
|
||||||
Err _ -> ""
|
Err _ -> ""
|
||||||
"#
|
"#
|
||||||
|
@ -646,7 +646,7 @@ fn str_from_utf8_pass_single_grapheme() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
when Str.fromUtf8 [ 0xF0, 0x9F, 0x92, 0x96 ] is
|
when Str.fromUtf8 [0xF0, 0x9F, 0x92, 0x96] is
|
||||||
Ok val -> val
|
Ok val -> val
|
||||||
Err _ -> ""
|
Err _ -> ""
|
||||||
"#
|
"#
|
||||||
|
@ -662,7 +662,7 @@ fn str_from_utf8_pass_many_grapheme() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
when Str.fromUtf8 [ 0xF0, 0x9F, 0x92, 0x96, 0xF0, 0x9F, 0xA4, 0xA0, 0xF0, 0x9F, 0x9A, 0x80 ] is
|
when Str.fromUtf8 [0xF0, 0x9F, 0x92, 0x96, 0xF0, 0x9F, 0xA4, 0xA0, 0xF0, 0x9F, 0x9A, 0x80] is
|
||||||
Ok val -> val
|
Ok val -> val
|
||||||
Err _ -> ""
|
Err _ -> ""
|
||||||
"#
|
"#
|
||||||
|
@ -678,7 +678,7 @@ fn str_from_utf8_pass_all() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
when Str.fromUtf8 [ 0xF0, 0x9F, 0x92, 0x96, 98, 0xE2, 0x88, 0x86 ] is
|
when Str.fromUtf8 [0xF0, 0x9F, 0x92, 0x96, 98, 0xE2, 0x88, 0x86] is
|
||||||
Ok val -> val
|
Ok val -> val
|
||||||
Err _ -> ""
|
Err _ -> ""
|
||||||
"#
|
"#
|
||||||
|
@ -694,7 +694,7 @@ fn str_from_utf8_fail_invalid_start_byte() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
when Str.fromUtf8 [ 97, 98, 0x80, 99 ] is
|
when Str.fromUtf8 [97, 98, 0x80, 99] is
|
||||||
Err (BadUtf8 InvalidStartByte byteIndex) ->
|
Err (BadUtf8 InvalidStartByte byteIndex) ->
|
||||||
if byteIndex == 2 then
|
if byteIndex == 2 then
|
||||||
"a"
|
"a"
|
||||||
|
@ -714,7 +714,7 @@ fn str_from_utf8_fail_unexpected_end_of_sequence() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
when Str.fromUtf8 [ 97, 98, 99, 0xC2 ] is
|
when Str.fromUtf8 [97, 98, 99, 0xC2] is
|
||||||
Err (BadUtf8 UnexpectedEndOfSequence byteIndex) ->
|
Err (BadUtf8 UnexpectedEndOfSequence byteIndex) ->
|
||||||
if byteIndex == 3 then
|
if byteIndex == 3 then
|
||||||
"a"
|
"a"
|
||||||
|
@ -734,7 +734,7 @@ fn str_from_utf8_fail_expected_continuation() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
when Str.fromUtf8 [ 97, 98, 99, 0xC2, 0x00 ] is
|
when Str.fromUtf8 [97, 98, 99, 0xC2, 0x00] is
|
||||||
Err (BadUtf8 ExpectedContinuation byteIndex) ->
|
Err (BadUtf8 ExpectedContinuation byteIndex) ->
|
||||||
if byteIndex == 3 then
|
if byteIndex == 3 then
|
||||||
"a"
|
"a"
|
||||||
|
@ -754,7 +754,7 @@ fn str_from_utf8_fail_overlong_encoding() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
when Str.fromUtf8 [ 97, 0xF0, 0x80, 0x80, 0x80 ] is
|
when Str.fromUtf8 [97, 0xF0, 0x80, 0x80, 0x80] is
|
||||||
Err (BadUtf8 OverlongEncoding byteIndex) ->
|
Err (BadUtf8 OverlongEncoding byteIndex) ->
|
||||||
if byteIndex == 1 then
|
if byteIndex == 1 then
|
||||||
"a"
|
"a"
|
||||||
|
@ -774,7 +774,7 @@ fn str_from_utf8_fail_codepoint_too_large() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
when Str.fromUtf8 [ 97, 0xF4, 0x90, 0x80, 0x80 ] is
|
when Str.fromUtf8 [97, 0xF4, 0x90, 0x80, 0x80] is
|
||||||
Err (BadUtf8 CodepointTooLarge byteIndex) ->
|
Err (BadUtf8 CodepointTooLarge byteIndex) ->
|
||||||
if byteIndex == 1 then
|
if byteIndex == 1 then
|
||||||
"a"
|
"a"
|
||||||
|
@ -794,7 +794,7 @@ fn str_from_utf8_fail_surrogate_half() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
when Str.fromUtf8 [ 97, 98, 0xED, 0xA0, 0x80 ] is
|
when Str.fromUtf8 [97, 98, 0xED, 0xA0, 0x80] is
|
||||||
Err (BadUtf8 EncodesSurrogateHalf byteIndex) ->
|
Err (BadUtf8 EncodesSurrogateHalf byteIndex) ->
|
||||||
if byteIndex == 2 then
|
if byteIndex == 2 then
|
||||||
"a"
|
"a"
|
||||||
|
@ -839,7 +839,7 @@ fn nested_recursive_literal() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
Expr : [ Add Expr Expr, Val I64, Var I64 ]
|
Expr : [Add Expr Expr, Val I64, Var I64]
|
||||||
|
|
||||||
expr : Expr
|
expr : Expr
|
||||||
expr = Add (Add (Val 3) (Val 1)) (Add (Val 1) (Var 1))
|
expr = Add (Add (Val 3) (Val 1)) (Add (Val 1) (Var 1))
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue