Skip to content

Commit

Permalink
Merge pull request #6422 from roc-lang/remove-nat
Browse files Browse the repository at this point in the history
Remove `Nat`
  • Loading branch information
rtfeldman authored Feb 20, 2024
2 parents 943d7a3 + 12aa775 commit 3b3a330
Show file tree
Hide file tree
Showing 216 changed files with 5,322 additions and 6,448 deletions.
4 changes: 3 additions & 1 deletion .gitattributes
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
# Require roc files to be checlked out with Unix line endings, even on windows
# Require roc files to be checked out with Unix line endings, even on windows
*.roc text eol=lf

crates/compiler/test_mono/generated/* linguist-generated=true
4 changes: 2 additions & 2 deletions crates/cli/tests/cli_run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -900,7 +900,7 @@ mod cli_run {
&[],
indoc!(
r#"
This roc file can print it's own source code. The source is:
This roc file can print its own source code. The source is:
app "ingested-file"
packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.8.1/x8URkvfyi9I0QhmVG98roKBUs_AZRkLFwFJVJ3942YA.tar.br" }
Expand All @@ -911,7 +911,7 @@ mod cli_run {
provides [main] to pf
main =
Stdout.line "\nThis roc file can print it's own source code. The source is:\n\n$(ownCode)"
Stdout.line "\nThis roc file can print its own source code. The source is:\n\n$(ownCode)"
"#
),
Expand Down
8 changes: 4 additions & 4 deletions crates/cli_testing_examples/algorithms/quicksort.roc
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ quicksort = \originalList ->

quicksortHelp originalList 0 (n - 1)

quicksortHelp : List (Num a), Nat, Nat -> List (Num a)
quicksortHelp : List (Num a), U64, U64 -> List (Num a)
quicksortHelp = \list, low, high ->
if low < high then
when partition low high list is
Expand All @@ -19,7 +19,7 @@ quicksortHelp = \list, low, high ->
else
list

partition : Nat, Nat, List (Num a) -> [Pair Nat (List (Num a))]
partition : U64, U64, List (Num a) -> [Pair U64 (List (Num a))]
partition = \low, high, initialList ->
when List.get initialList high is
Ok pivot ->
Expand All @@ -30,7 +30,7 @@ partition = \low, high, initialList ->
Err _ ->
Pair low initialList

partitionHelp : Nat, Nat, List (Num c), Nat, Num c -> [Pair Nat (List (Num c))]
partitionHelp : U64, U64, List (Num c), U64, Num c -> [Pair U64 (List (Num c))]
partitionHelp = \i, j, list, high, pivot ->
if j < high then
when List.get list j is
Expand All @@ -45,7 +45,7 @@ partitionHelp = \i, j, list, high, pivot ->
else
Pair i list

swap : Nat, Nat, List a -> List a
swap : U64, U64, List a -> List a
swap = \i, j, list ->
when Pair (List.get list i) (List.get list j) is
Pair (Ok atI) (Ok atJ) ->
Expand Down
4 changes: 2 additions & 2 deletions crates/cli_testing_examples/benchmarks/Base64/Decode.roc
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ fromBytes : List U8 -> Result Str DecodeProblem
fromBytes = \bytes ->
Bytes.Decode.decode bytes (decodeBase64 (List.len bytes))

decodeBase64 : Nat -> ByteDecoder Str
decodeBase64 : U64 -> ByteDecoder Str
decodeBase64 = \width -> Bytes.Decode.loop loopHelp { remaining: width, string: "" }

loopHelp : { remaining : Nat, string : Str } -> ByteDecoder (Bytes.Decode.Step { remaining : Nat, string : Str } Str)
loopHelp : { remaining : U64, string : Str } -> ByteDecoder (Bytes.Decode.Step { remaining : U64, string : Str } Str)
loopHelp = \{ remaining, string } ->
if remaining >= 3 then
x, y, z <- Bytes.Decode.map3 Bytes.Decode.u8 Bytes.Decode.u8 Bytes.Decode.u8
Expand Down
2 changes: 1 addition & 1 deletion crates/cli_testing_examples/benchmarks/Base64/Encode.roc
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ encodeChunks = \bytes ->
List.walk bytes { output: [], accum: None } folder
|> encodeResidual

coerce : Nat, a -> a
coerce : U64, a -> a
coerce = \_, x -> x

# folder : { output : List ByteEncoder, accum : State }, U8 -> { output : List ByteEncoder, accum : State }
Expand Down
2 changes: 1 addition & 1 deletion crates/cli_testing_examples/benchmarks/Bytes/Decode.roc
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
interface Bytes.Decode exposes [ByteDecoder, decode, map, map2, u8, loop, Step, succeed, DecodeProblem, after, map3] imports []

State : { bytes : List U8, cursor : Nat }
State : { bytes : List U8, cursor : U64 }

DecodeProblem : [OutOfBytes]

Expand Down
8 changes: 4 additions & 4 deletions crates/cli_testing_examples/benchmarks/Bytes/Encode.roc
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ interface Bytes.Encode exposes [ByteEncoder, sequence, u8, u16, bytes, empty, en

Endianness : [BE, LE]

ByteEncoder : [Signed8 I8, Unsigned8 U8, Signed16 Endianness I16, Unsigned16 Endianness U16, Sequence Nat (List ByteEncoder), Bytes (List U8)]
ByteEncoder : [Signed8 I8, Unsigned8 U8, Signed16 Endianness I16, Unsigned16 Endianness U16, Sequence U64 (List ByteEncoder), Bytes (List U8)]

u8 : U8 -> ByteEncoder
u8 = \value -> Unsigned8 value
Expand All @@ -24,7 +24,7 @@ sequence : List ByteEncoder -> ByteEncoder
sequence = \encoders ->
Sequence (getWidths encoders 0) encoders

getWidth : ByteEncoder -> Nat
getWidth : ByteEncoder -> U64
getWidth = \encoder ->
when encoder is
Signed8 _ -> 1
Expand All @@ -40,7 +40,7 @@ getWidth = \encoder ->
Sequence w _ -> w
Bytes bs -> List.len bs

getWidths : List ByteEncoder, Nat -> Nat
getWidths : List ByteEncoder, U64 -> U64
getWidths = \encoders, initial ->
List.walk encoders initial \accum, encoder -> accum + getWidth encoder

Expand All @@ -51,7 +51,7 @@ encode = \encoder ->
encodeHelp encoder 0 output
|> .output

encodeHelp : ByteEncoder, Nat, List U8 -> { output : List U8, offset : Nat }
encodeHelp : ByteEncoder, U64, List U8 -> { output : List U8, offset : U64 }
encodeHelp = \encoder, offset, output ->
when encoder is
Unsigned8 value ->
Expand Down
8 changes: 4 additions & 4 deletions crates/cli_testing_examples/benchmarks/Quicksort.roc
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ sortWith = \list, order ->

quicksortHelp list order 0 (n - 1)

quicksortHelp : List a, Order a, Nat, Nat -> List a
quicksortHelp : List a, Order a, U64, U64 -> List a
quicksortHelp = \list, order, low, high ->
if low < high then
when partition low high list order is
Expand All @@ -35,7 +35,7 @@ quicksortHelp = \list, order, low, high ->
else
list

partition : Nat, Nat, List a, Order a -> [Pair Nat (List a)]
partition : U64, U64, List a, Order a -> [Pair U64 (List a)]
partition = \low, high, initialList, order ->
when List.get initialList high is
Ok pivot ->
Expand All @@ -46,7 +46,7 @@ partition = \low, high, initialList, order ->
Err _ ->
Pair low initialList

partitionHelp : Nat, Nat, List c, Order c, Nat, c -> [Pair Nat (List c)]
partitionHelp : U64, U64, List c, Order c, U64, c -> [Pair U64 (List c)]
partitionHelp = \i, j, list, order, high, pivot ->
if j < high then
when List.get list j is
Expand All @@ -63,7 +63,7 @@ partitionHelp = \i, j, list, order, high, pivot ->
else
Pair i list

swap : Nat, Nat, List a -> List a
swap : U64, U64, List a -> List a
swap = \i, j, list ->
when Pair (List.get list i) (List.get list j) is
Pair (Ok atI) (Ok atJ) ->
Expand Down
4 changes: 2 additions & 2 deletions crates/compiler/alias_analysis/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1121,7 +1121,7 @@ fn lowlevel_spec<'a>(
// just dream up a unit value
builder.add_make_tuple(block, &[])
}
ListLen => {
ListLenUsize | ListLenU64 => {
// TODO should this touch the heap cell?
// just dream up a unit value
builder.add_make_tuple(block, &[])
Expand Down Expand Up @@ -1230,7 +1230,7 @@ fn lowlevel_spec<'a>(

builder.add_make_tuple(block, &[cell, bag])
}
StrFromUtf8Range => {
StrFromUtf8 => {
let list = env.symbols[&arguments[0]];

let cell = builder.add_get_tuple_field(block, list, LIST_CELL_INDEX)?;
Expand Down
16 changes: 8 additions & 8 deletions crates/compiler/builtins/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Builtins are the functions and modules that are implicitly imported into every m

Edit the appropriate `roc/*.roc` file with your new implementation. All normal rules for writing Roc code apply. Be sure to add a declaration, definition, some documentation and add it to the exposes list it in the module head.

Next, look towards the bottom of the `compiler/module/src/symbol.rs` file. Inside the `define_builtins!` macro, there is a list for each of the builtin modules and the function or value names it contains. Add a new entry to the appropriate list for your new function.
Next, look towards the bottom of the `compiler/module/src/symbol.rs` file. Inside the `define_builtins!` macro, there is a list for each of the builtin modules and the function or value names it contains. Add a new entry to the appropriate list for your new function.

For each of the builtin modules, there is a file in `compiler/test_gen/src/` like `gen_num.rs`, `gen_str.rs` etc. Add new tests for the module you are changing to the appropriate file here. You can look at the existing test cases for examples and inspiration.

Expand All @@ -22,14 +22,14 @@ 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:

- ..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.#getUnsafe` that has the dangerous signature of `List elem, U64 -> elem` in LLVM
- ..writing `List elem, U64 -> Result elem [OutOfBounds]*` in a type safe way that uses `getUnsafe` internally, only after it checks if the `elem` at `U64` index exists.

### can/src/builtins.rs

Right at the top of this module is a function called `builtin_defs`. All this is doing is mapping the `Symbol` defined in `module/src/symbol.rs` to its implementation. Some of the builtins are quite complex, such as `list_get`. What makes `list_get` is that it returns tags, and in order to return tags it first has to defer to lower-level functions via an if statement.
Right at the top of this module is a function called `builtin_defs`. All this is doing is mapping the `Symbol` defined in `module/src/symbol.rs` to its implementation. Some of the builtins are quite complex, such as `list_get`. What makes `list_get` is that it returns tags, and in order to return tags it first has to defer to lower-level functions via an if statement.

Lets look at `List.repeat : elem, Nat -> List elem`, which is more straight-forward, and points directly to its lower level implementation:
Lets look at `List.repeat : elem, U64 -> List elem`, which is more straightforward, and points directly to its lower level implementation:

```rust
fn list_repeat(symbol: Symbol, var_store: &mut VarStore) -> Def {
Expand Down Expand Up @@ -106,7 +106,7 @@ fn atan() {

But replace `Num.atan` and the type signature with the new builtin.

### test_gen/test/*.rs
### test_gen/test/\*.rs

In this directory, there are a couple files like `gen_num.rs`, `gen_str.rs`, etc. For the `Str` module builtins, put the test in `gen_str.rs`, etc. Find the one for the new builtin, and add a test like:

Expand All @@ -123,5 +123,5 @@ But replace `Num.atan`, the return value, and the return type with your new buil

When implementing a new builtin, it is often easy to copy and paste the implementation for an existing builtin. This can take you quite far since many builtins are very similar, but it also risks forgetting to change one small part of what you copy and pasted and losing a lot of time later on when you cant figure out why things don't work. So, speaking from experience, even if you are copying an existing builtin, try and implement it manually without copying and pasting. Two recent instances of this (as of September 7th, 2020):

- `List.keepIf` did not work for a long time because in builtins its `LowLevel` was `ListMap`. This was because I copy and pasted the `List.map` implementation in `builtins.rs
- `List.walkBackwards` had mysterious memory bugs for a little while because in `unique.rs` its return type was `list_type(flex(b))` instead of `flex(b)` since it was copy and pasted from `List.keepIf`.
- `List.keepIf` did not work for a long time because in builtins its `LowLevel` was `ListMap`. This was because I copy and pasted the `List.map` implementation in `builtins.rs
- `List.walkBackwards` had mysterious memory bugs for a little while because in `unique.rs` its return type was `list_type(flex(b))` instead of `flex(b)` since it was copy and pasted from `List.keepIf`.
Loading

0 comments on commit 3b3a330

Please sign in to comment.