mirror of
https://github.com/roc-lang/roc.git
synced 2025-07-24 06:55:15 +00:00
Merge remote-tracking branch 'origin/main' into expect-fx-codegen
This commit is contained in:
commit
a22e04361c
222 changed files with 10039 additions and 1945 deletions
|
@ -1,4 +1,4 @@
|
|||
#!/bin/bash
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -euxo pipefail
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 }
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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 ->
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue