Merge remote-tracking branch 'origin/main' into expect-fx-codegen

This commit is contained in:
Folkert 2022-08-23 16:28:21 +02:00
commit a22e04361c
No known key found for this signature in database
GPG key ID: 1F17F6FFD112B97C
222 changed files with 10039 additions and 1945 deletions

View file

@ -1,4 +1,4 @@
#!/bin/bash
#!/usr/bin/env bash
set -euxo pipefail

View file

@ -1,9 +1,10 @@
#!/bin/bash
#!/usr/bin/env bash
# https://vaneyckt.io/posts/safer_bash_scripts_with_set_euxo_pipefail/
set -euxo pipefail
# Test every zig
# Execute zig tests (see build.zig)
zig build test
# fmt every zig
# check formatting of zig files
find src/*.zig -type f -print0 | xargs -n 1 -0 zig fmt --check || (echo "zig fmt --check FAILED! Check the previous lines to see which files were improperly formatted." && exit 1)

View file

@ -1,5 +1,6 @@
#!/bin/bash
#!/usr/bin/env bash
# https://vaneyckt.io/posts/safer_bash_scripts_with_set_euxo_pipefail/
set -euxo pipefail
# Test failures will always point at the _start function

View file

@ -181,7 +181,7 @@ comptime {
// Utils continued - SJLJ
// For tests (in particular test_gen), roc_panic is implemented in terms of
// setjmp/longjmp. LLVM is unable to generate code for longjmp on AArch64 (https://github.com/rtfeldman/roc/issues/2965),
// setjmp/longjmp. LLVM is unable to generate code for longjmp on AArch64 (https://github.com/roc-lang/roc/issues/2965),
// so instead we ask Zig to please provide implementations for us, which is does
// (seemingly via musl).
pub extern fn setjmp([*c]c_int) c_int;

View file

@ -22,6 +22,7 @@ interface Decode
bool,
string,
list,
record,
custom,
decodeWith,
fromBytesPartial,
@ -57,6 +58,7 @@ DecoderFormatting has
bool : Decoder Bool fmt | fmt has DecoderFormatting
string : Decoder Str fmt | fmt has DecoderFormatting
list : Decoder elem fmt -> Decoder (List elem) fmt | fmt has DecoderFormatting
record : state, (state, Str -> [Keep (Decoder state fmt), Skip]), (state -> Result val DecodeError) -> Decoder val fmt | fmt has DecoderFormatting
custom : (List U8, fmt -> DecodeResult val) -> Decoder val fmt | fmt has DecoderFormatting
custom = \decode -> @Decoder decode

View file

@ -16,6 +16,7 @@ interface Json
Decode,
Decode.{
DecoderFormatting,
DecodeResult,
},
]
@ -57,6 +58,7 @@ Json := {} has [
bool: decodeBool,
string: decodeString,
list: decodeList,
record: decodeRecord,
},
]
@ -316,7 +318,8 @@ decodeBool = Decode.custom \bytes, @Json {} ->
else
{ result: Err TooShort, rest: bytes }
decodeString = Decode.custom \bytes, @Json {} ->
jsonString : List U8 -> DecodeResult Str
jsonString = \bytes ->
{ before, others: afterStartingQuote } = List.split bytes 1
if
@ -335,6 +338,9 @@ decodeString = Decode.custom \bytes, @Json {} ->
else
{ result: Err TooShort, rest: bytes }
decodeString = Decode.custom \bytes, @Json {} ->
jsonString bytes
decodeList = \decodeElem -> Decode.custom \bytes, @Json {} ->
decodeElems = \chunk, accum ->
when Decode.decodeWith chunk decodeElem (@Json {}) is
@ -372,3 +378,72 @@ decodeList = \decodeElem -> Decode.custom \bytes, @Json {} ->
{ result: Err TooShort, rest }
else
{ result: Err TooShort, rest: bytes }
parseExactChar : List U8, U8 -> DecodeResult {}
parseExactChar = \bytes, char ->
when List.get bytes 0 is
Ok c ->
if
c == char
then
{ result: Ok {}, rest: (List.split bytes 1).others }
else
{ result: Err TooShort, rest: bytes }
Err _ -> { result: Err TooShort, rest: bytes }
openBrace : List U8 -> DecodeResult {}
openBrace = \bytes -> parseExactChar bytes (asciiByte '{')
closingBrace : List U8 -> DecodeResult {}
closingBrace = \bytes -> parseExactChar bytes (asciiByte '}')
recordKey : List U8 -> DecodeResult Str
recordKey = \bytes -> jsonString bytes
anything : List U8 -> DecodeResult {}
anything = \bytes -> { result: Err TooShort, rest: bytes }
colon : List U8 -> DecodeResult {}
colon = \bytes -> parseExactChar bytes (asciiByte ':')
comma : List U8 -> DecodeResult {}
comma = \bytes -> parseExactChar bytes (asciiByte ',')
tryDecode : DecodeResult a, ({ val : a, rest : List U8 } -> DecodeResult b) -> DecodeResult b
tryDecode = \{ result, rest }, mapper ->
when result is
Ok val -> mapper { val, rest }
Err e -> { result: Err e, rest }
decodeRecord = \initialState, stepField, finalizer -> Decode.custom \bytes, @Json {} ->
# NB: the stepper function must be passed explicitly until #2894 is resolved.
decodeFields = \stepper, state, kvBytes ->
{ val: key, rest } <- recordKey kvBytes |> tryDecode
{ rest: afterColonBytes } <- colon rest |> tryDecode
{ val: newState, rest: beforeCommaOrBreak } <- tryDecode
(
when stepper state key is
Skip ->
{ rest: beforeCommaOrBreak } <- afterColonBytes |> anything |> tryDecode
{ result: Ok state, rest: beforeCommaOrBreak }
Keep decoder ->
Decode.decodeWith afterColonBytes decoder (@Json {})
)
{ result: commaResult, rest: nextBytes } = comma beforeCommaOrBreak
when commaResult is
Ok {} -> decodeFields stepField newState nextBytes
Err _ -> { result: Ok newState, rest: nextBytes }
{ rest: afterBraceBytes } <- bytes |> openBrace |> tryDecode
{ val: endStateResult, rest: beforeClosingBraceBytes } <- decodeFields stepField initialState afterBraceBytes |> tryDecode
{ rest: afterRecordBytes } <- beforeClosingBraceBytes |> closingBrace |> tryDecode
when finalizer endStateResult is
Ok val -> { result: Ok val, rest: afterRecordBytes }
Err e -> { result: Err e, rest: afterRecordBytes }

View file

@ -857,8 +857,44 @@ isMultipleOf : Int a, Int a -> Bool
bitwiseAnd : Int a, Int a -> Int a
bitwiseXor : Int a, Int a -> Int a
bitwiseOr : Int a, Int a -> Int a
## Bitwise left shift of a number by another
##
## The least significant bits always become 0. This means that shifting left is
## like multiplying by factors of two for unsigned integers.
##
## >>> shiftLeftBy 0b0000_0011 2 == 0b0000_1100
##
## >>> 0b0000_0101 |> shiftLeftBy 2 == 0b0000_1100
##
## In some languages `shiftLeftBy` is implemented as a binary operator `<<`.
shiftLeftBy : Int a, Int a -> Int a
## Bitwise arithmetic shift of a number by another
##
## The most significant bits are copied from the current.
##
## >>> shiftRightBy 0b0000_0011 2 == 0b0000_1100
##
## >>> 0b0001_0100 |> shiftRightBy 2 == 0b0000_0101
##
## >>> 0b1001_0000 |> shiftRightBy 2 == 0b1110_0100
##
## In some languages `shiftRightBy` is implemented as a binary operator `>>>`.
shiftRightBy : Int a, Int a -> Int a
## Bitwise logical right shift of a number by another
##
## The most significant bits always become 0. This means that shifting left is
## like dividing by factors of two for unsigned integers.
##
## >>> shiftRightBy 0b0010_1000 2 == 0b0000_1010
##
## >>> 0b0010_1000 |> shiftRightBy 2 == 0b0000_1010
##
## >>> 0b1001_0000 |> shiftRightBy 2 == 0b0010_0100
##
## In some languages `shiftRightBy` is implemented as a binary operator `>>`.
shiftRightZfBy : Int a, Int a -> Int a
## Round off the given fraction to the nearest integer.

View file

@ -41,10 +41,39 @@ insert = \@Set dict, key ->
|> Dict.insert key {}
|> @Set
# Inserting a duplicate key has no effect.
expect
actual =
Set.empty
|> Set.insert "foo"
|> Set.insert "bar"
|> Set.insert "foo"
|> Set.insert "baz"
expected =
Set.empty
|> Set.insert "foo"
|> Set.insert "bar"
|> Set.insert "baz"
expected == actual
len : Set k -> Nat
len = \@Set dict ->
Dict.len dict
# Inserting a duplicate key has no effect on length.
expect
actual =
Set.empty
|> Set.insert "foo"
|> Set.insert "bar"
|> Set.insert "foo"
|> Set.insert "baz"
|> Set.len
actual == 3
## Drops the given element from the set.
remove : Set k, k -> Set k
remove = \@Set dict, key ->

View file

@ -1,5 +1,5 @@
#![warn(clippy::dbg_macro)]
// See github.com/rtfeldman/roc/issues/800 for discussion of the large_enum_variant check.
// See github.com/roc-lang/roc/issues/800 for discussion of the large_enum_variant check.
#![allow(clippy::large_enum_variant)]
pub mod bitcode;
pub mod roc;