mirror of
https://github.com/roc-lang/roc.git
synced 2025-08-03 03:42:17 +00:00
Merge pull request #5179 from roc-lang/i5143-tuple-abilities
Implement ability obligation checking and derivation for tuples
This commit is contained in:
commit
61dd5cc8c7
36 changed files with 4225 additions and 2296 deletions
|
@ -23,6 +23,7 @@ interface Decode
|
||||||
string,
|
string,
|
||||||
list,
|
list,
|
||||||
record,
|
record,
|
||||||
|
tuple,
|
||||||
custom,
|
custom,
|
||||||
decodeWith,
|
decodeWith,
|
||||||
fromBytesPartial,
|
fromBytesPartial,
|
||||||
|
@ -43,6 +44,7 @@ interface Decode
|
||||||
I32,
|
I32,
|
||||||
I64,
|
I64,
|
||||||
I128,
|
I128,
|
||||||
|
Nat,
|
||||||
F32,
|
F32,
|
||||||
F64,
|
F64,
|
||||||
Dec,
|
Dec,
|
||||||
|
@ -76,8 +78,24 @@ DecoderFormatting has
|
||||||
bool : Decoder Bool fmt | fmt has DecoderFormatting
|
bool : Decoder Bool fmt | fmt has DecoderFormatting
|
||||||
string : Decoder Str fmt | fmt has DecoderFormatting
|
string : Decoder Str fmt | fmt has DecoderFormatting
|
||||||
list : Decoder elem fmt -> Decoder (List elem) fmt | fmt has DecoderFormatting
|
list : Decoder elem fmt -> Decoder (List elem) fmt | fmt has DecoderFormatting
|
||||||
|
|
||||||
|
## `record state stepField finalizer` decodes a record field-by-field.
|
||||||
|
##
|
||||||
|
## `stepField` returns a decoder for the given field in the record, or
|
||||||
|
## `Skip` if the field is not a part of the decoded record.
|
||||||
|
##
|
||||||
|
## `finalizer` should produce the record value from the decoded `state`.
|
||||||
record : state, (state, Str -> [Keep (Decoder state fmt), Skip]), (state -> Result val DecodeError) -> Decoder val fmt | fmt has DecoderFormatting
|
record : state, (state, Str -> [Keep (Decoder state fmt), Skip]), (state -> Result val DecodeError) -> Decoder val fmt | fmt has DecoderFormatting
|
||||||
|
|
||||||
|
## `tuple state stepElem finalizer` decodes a tuple element-by-element.
|
||||||
|
##
|
||||||
|
## `stepElem` returns a decoder for the nth index in the tuple, or
|
||||||
|
## `TooLong` if the index is larger than the expected size of the tuple. The
|
||||||
|
## index passed to `stepElem` is 0-indexed.
|
||||||
|
##
|
||||||
|
## `finalizer` should produce the tuple value from the decoded `state`.
|
||||||
|
tuple : state, (state, Nat -> [Next (Decoder state fmt), TooLong]), (state -> Result val DecodeError) -> Decoder val fmt | fmt has DecoderFormatting
|
||||||
|
|
||||||
custom : (List U8, fmt -> DecodeResult val) -> Decoder val fmt | fmt has DecoderFormatting
|
custom : (List U8, fmt -> DecodeResult val) -> Decoder val fmt | fmt has DecoderFormatting
|
||||||
custom = \decode -> @Decoder decode
|
custom = \decode -> @Decoder decode
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,7 @@ interface Encode
|
||||||
list,
|
list,
|
||||||
record,
|
record,
|
||||||
tag,
|
tag,
|
||||||
|
tuple,
|
||||||
custom,
|
custom,
|
||||||
appendWith,
|
appendWith,
|
||||||
append,
|
append,
|
||||||
|
@ -69,6 +70,7 @@ EncoderFormatting has
|
||||||
string : Str -> Encoder fmt | fmt has EncoderFormatting
|
string : Str -> Encoder fmt | fmt has EncoderFormatting
|
||||||
list : List elem, (elem -> Encoder fmt) -> Encoder fmt | fmt has EncoderFormatting
|
list : List elem, (elem -> Encoder fmt) -> Encoder fmt | fmt has EncoderFormatting
|
||||||
record : List { key : Str, value : Encoder fmt } -> Encoder fmt | fmt has EncoderFormatting
|
record : List { key : Str, value : Encoder fmt } -> Encoder fmt | fmt has EncoderFormatting
|
||||||
|
tuple : List (Encoder fmt) -> Encoder fmt | fmt has EncoderFormatting
|
||||||
tag : Str, List (Encoder fmt) -> Encoder fmt | fmt has EncoderFormatting
|
tag : Str, List (Encoder fmt) -> Encoder fmt | fmt has EncoderFormatting
|
||||||
|
|
||||||
custom : (List U8, fmt -> List U8) -> Encoder fmt | fmt has EncoderFormatting
|
custom : (List U8, fmt -> List U8) -> Encoder fmt | fmt has EncoderFormatting
|
||||||
|
|
|
@ -96,6 +96,7 @@ Json := {} has [
|
||||||
string: encodeString,
|
string: encodeString,
|
||||||
list: encodeList,
|
list: encodeList,
|
||||||
record: encodeRecord,
|
record: encodeRecord,
|
||||||
|
tuple: encodeTuple,
|
||||||
tag: encodeTag,
|
tag: encodeTag,
|
||||||
},
|
},
|
||||||
DecoderFormatting {
|
DecoderFormatting {
|
||||||
|
@ -116,6 +117,7 @@ Json := {} has [
|
||||||
string: decodeString,
|
string: decodeString,
|
||||||
list: decodeList,
|
list: decodeList,
|
||||||
record: decodeRecord,
|
record: decodeRecord,
|
||||||
|
tuple: decodeTuple,
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -207,6 +209,25 @@ encodeRecord = \fields ->
|
||||||
|
|
||||||
List.append bytesWithRecord (Num.toU8 '}')
|
List.append bytesWithRecord (Num.toU8 '}')
|
||||||
|
|
||||||
|
encodeTuple = \elems ->
|
||||||
|
Encode.custom \bytes, @Json {} ->
|
||||||
|
writeTuple = \{ buffer, elemsLeft }, elemEncoder ->
|
||||||
|
bufferWithElem =
|
||||||
|
appendWith buffer elemEncoder (@Json {})
|
||||||
|
|
||||||
|
bufferWithSuffix =
|
||||||
|
if elemsLeft > 1 then
|
||||||
|
List.append bufferWithElem (Num.toU8 ',')
|
||||||
|
else
|
||||||
|
bufferWithElem
|
||||||
|
|
||||||
|
{ buffer: bufferWithSuffix, elemsLeft: elemsLeft - 1 }
|
||||||
|
|
||||||
|
bytesHead = List.append bytes (Num.toU8 '[')
|
||||||
|
{ buffer: bytesWithRecord } = List.walk elems { buffer: bytesHead, elemsLeft: List.len elems } writeTuple
|
||||||
|
|
||||||
|
List.append bytesWithRecord (Num.toU8 ']')
|
||||||
|
|
||||||
encodeTag = \name, payload ->
|
encodeTag = \name, payload ->
|
||||||
Encode.custom \bytes, @Json {} ->
|
Encode.custom \bytes, @Json {} ->
|
||||||
# Idea: encode `A v1 v2` as `{"A": [v1, v2]}`
|
# Idea: encode `A v1 v2` as `{"A": [v1, v2]}`
|
||||||
|
@ -477,6 +498,12 @@ openBrace = \bytes -> parseExactChar bytes '{'
|
||||||
closingBrace : List U8 -> DecodeResult {}
|
closingBrace : List U8 -> DecodeResult {}
|
||||||
closingBrace = \bytes -> parseExactChar bytes '}'
|
closingBrace = \bytes -> parseExactChar bytes '}'
|
||||||
|
|
||||||
|
openBracket : List U8 -> DecodeResult {}
|
||||||
|
openBracket = \bytes -> parseExactChar bytes '['
|
||||||
|
|
||||||
|
closingBracket : List U8 -> DecodeResult {}
|
||||||
|
closingBracket = \bytes -> parseExactChar bytes ']'
|
||||||
|
|
||||||
recordKey : List U8 -> DecodeResult Str
|
recordKey : List U8 -> DecodeResult Str
|
||||||
recordKey = \bytes -> jsonString bytes
|
recordKey = \bytes -> jsonString bytes
|
||||||
|
|
||||||
|
@ -527,6 +554,36 @@ decodeRecord = \initialState, stepField, finalizer -> Decode.custom \bytes, @Jso
|
||||||
Ok val -> { result: Ok val, rest: afterRecordBytes }
|
Ok val -> { result: Ok val, rest: afterRecordBytes }
|
||||||
Err e -> { result: Err e, rest: afterRecordBytes }
|
Err e -> { result: Err e, rest: afterRecordBytes }
|
||||||
|
|
||||||
|
decodeTuple = \initialState, stepElem, finalizer -> Decode.custom \initialBytes, @Json {} ->
|
||||||
|
# NB: the stepper function must be passed explicitly until #2894 is resolved.
|
||||||
|
decodeElems = \stepper, state, index, bytes ->
|
||||||
|
{ val: newState, rest: beforeCommaOrBreak } <- tryDecode
|
||||||
|
(
|
||||||
|
when stepper state index is
|
||||||
|
TooLong ->
|
||||||
|
{ rest: beforeCommaOrBreak } <- bytes |> anything |> tryDecode
|
||||||
|
{ result: Ok state, rest: beforeCommaOrBreak }
|
||||||
|
|
||||||
|
Next decoder ->
|
||||||
|
Decode.decodeWith bytes decoder (@Json {})
|
||||||
|
)
|
||||||
|
|
||||||
|
{ result: commaResult, rest: nextBytes } = comma beforeCommaOrBreak
|
||||||
|
|
||||||
|
when commaResult is
|
||||||
|
Ok {} -> decodeElems stepElem newState (index + 1) nextBytes
|
||||||
|
Err _ -> { result: Ok newState, rest: nextBytes }
|
||||||
|
|
||||||
|
{ rest: afterBracketBytes } <- initialBytes |> openBracket |> tryDecode
|
||||||
|
|
||||||
|
{ val: endStateResult, rest: beforeClosingBracketBytes } <- decodeElems stepElem initialState 0 afterBracketBytes |> tryDecode
|
||||||
|
|
||||||
|
{ rest: afterTupleBytes } <- beforeClosingBracketBytes |> closingBracket |> tryDecode
|
||||||
|
|
||||||
|
when finalizer endStateResult is
|
||||||
|
Ok val -> { result: Ok val, rest: afterTupleBytes }
|
||||||
|
Err e -> { result: Err e, rest: afterTupleBytes }
|
||||||
|
|
||||||
# Helper to eat leading Json whitespace characters
|
# Helper to eat leading Json whitespace characters
|
||||||
eatWhitespace = \input ->
|
eatWhitespace = \input ->
|
||||||
when input is
|
when input is
|
||||||
|
|
|
@ -330,7 +330,11 @@ fn expr<'a>(c: &Ctx, p: EPrec, f: &'a Arena<'a>, e: &'a Expr) -> DocBuilder<'a,
|
||||||
} => expr(c, AppArg, f, &loc_expr.value)
|
} => expr(c, AppArg, f, &loc_expr.value)
|
||||||
.append(f.text(format!(".{}", field.as_str())))
|
.append(f.text(format!(".{}", field.as_str())))
|
||||||
.group(),
|
.group(),
|
||||||
TupleAccess { .. } => todo!(),
|
TupleAccess {
|
||||||
|
loc_expr, index, ..
|
||||||
|
} => expr(c, AppArg, f, &loc_expr.value)
|
||||||
|
.append(f.text(format!(".{index}")))
|
||||||
|
.group(),
|
||||||
OpaqueWrapFunction(OpaqueWrapFunctionData { opaque_name, .. }) => {
|
OpaqueWrapFunction(OpaqueWrapFunctionData { opaque_name, .. }) => {
|
||||||
f.text(format!("@{}", opaque_name.as_str(c.interns)))
|
f.text(format!("@{}", opaque_name.as_str(c.interns)))
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load diff
104
crates/compiler/derive/src/decoding/list.rs
Normal file
104
crates/compiler/derive/src/decoding/list.rs
Normal file
|
@ -0,0 +1,104 @@
|
||||||
|
use roc_can::expr::Expr;
|
||||||
|
|
||||||
|
use roc_error_macros::internal_error;
|
||||||
|
use roc_module::called_via::CalledVia;
|
||||||
|
|
||||||
|
use roc_module::symbol::Symbol;
|
||||||
|
use roc_region::all::Loc;
|
||||||
|
use roc_types::subs::{Content, FlatType, GetSubsSlice, SubsSlice, Variable};
|
||||||
|
use roc_types::types::AliasKind;
|
||||||
|
|
||||||
|
use crate::decoding::wrap_in_decode_custom_decode_with;
|
||||||
|
use crate::synth_var;
|
||||||
|
use crate::util::Env;
|
||||||
|
|
||||||
|
pub(crate) fn decoder(env: &mut Env<'_>, _def_symbol: Symbol) -> (Expr, Variable) {
|
||||||
|
// Build
|
||||||
|
//
|
||||||
|
// def_symbol : Decoder (List elem) fmt | elem has Decoding, fmt has DecoderFormatting
|
||||||
|
// def_symbol = Decode.custom \bytes, fmt -> Decode.decodeWith bytes (Decode.list Decode.decoder) fmt
|
||||||
|
//
|
||||||
|
// NB: reduction to `Decode.list Decode.decoder` is not possible to the HRR.
|
||||||
|
|
||||||
|
use Expr::*;
|
||||||
|
|
||||||
|
// Decode.list Decode.decoder : Decoder (List elem) fmt
|
||||||
|
let (decode_list_call, this_decode_list_ret_var) = {
|
||||||
|
// List elem
|
||||||
|
let elem_var = env.subs.fresh_unnamed_flex_var();
|
||||||
|
|
||||||
|
// Decode.decoder : Decoder elem fmt | elem has Decoding, fmt has EncoderFormatting
|
||||||
|
let (elem_decoder, elem_decoder_var) = {
|
||||||
|
// build `Decode.decoder : Decoder elem fmt` type
|
||||||
|
// Decoder val fmt | val has Decoding, fmt has EncoderFormatting
|
||||||
|
let elem_decoder_var = env.import_builtin_symbol_var(Symbol::DECODE_DECODER);
|
||||||
|
|
||||||
|
// set val ~ elem
|
||||||
|
let val_var = match env.subs.get_content_without_compacting(elem_decoder_var) {
|
||||||
|
Content::Alias(Symbol::DECODE_DECODER_OPAQUE, vars, _, AliasKind::Opaque)
|
||||||
|
if vars.type_variables_len == 2 =>
|
||||||
|
{
|
||||||
|
env.subs.get_subs_slice(vars.type_variables())[0]
|
||||||
|
}
|
||||||
|
_ => internal_error!("Decode.decode not an opaque type"),
|
||||||
|
};
|
||||||
|
|
||||||
|
env.unify(val_var, elem_var);
|
||||||
|
|
||||||
|
(
|
||||||
|
AbilityMember(Symbol::DECODE_DECODER, None, elem_decoder_var),
|
||||||
|
elem_decoder_var,
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
// Build `Decode.list Decode.decoder` type
|
||||||
|
// Decoder val fmt -[uls]-> Decoder (List val) fmt | fmt has DecoderFormatting
|
||||||
|
let decode_list_fn_var = env.import_builtin_symbol_var(Symbol::DECODE_LIST);
|
||||||
|
|
||||||
|
// Decoder elem fmt -a-> b
|
||||||
|
let elem_decoder_var_slice = SubsSlice::insert_into_subs(env.subs, [elem_decoder_var]);
|
||||||
|
let this_decode_list_clos_var = env.subs.fresh_unnamed_flex_var();
|
||||||
|
let this_decode_list_ret_var = env.subs.fresh_unnamed_flex_var();
|
||||||
|
let this_decode_list_fn_var = synth_var(
|
||||||
|
env.subs,
|
||||||
|
Content::Structure(FlatType::Func(
|
||||||
|
elem_decoder_var_slice,
|
||||||
|
this_decode_list_clos_var,
|
||||||
|
this_decode_list_ret_var,
|
||||||
|
)),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Decoder val fmt -[uls]-> Decoder (List val) fmt | fmt has DecoderFormatting
|
||||||
|
// ~ Decoder elem fmt -a -> b
|
||||||
|
env.unify(decode_list_fn_var, this_decode_list_fn_var);
|
||||||
|
|
||||||
|
let decode_list_member = AbilityMember(Symbol::DECODE_LIST, None, this_decode_list_fn_var);
|
||||||
|
let decode_list_fn = Box::new((
|
||||||
|
decode_list_fn_var,
|
||||||
|
Loc::at_zero(decode_list_member),
|
||||||
|
this_decode_list_clos_var,
|
||||||
|
this_decode_list_ret_var,
|
||||||
|
));
|
||||||
|
|
||||||
|
let decode_list_call = Call(
|
||||||
|
decode_list_fn,
|
||||||
|
vec![(elem_decoder_var, Loc::at_zero(elem_decoder))],
|
||||||
|
CalledVia::Space,
|
||||||
|
);
|
||||||
|
|
||||||
|
(decode_list_call, this_decode_list_ret_var)
|
||||||
|
};
|
||||||
|
|
||||||
|
let bytes_sym = env.new_symbol("bytes");
|
||||||
|
let fmt_sym = env.new_symbol("fmt");
|
||||||
|
let fmt_var = env.subs.fresh_unnamed_flex_var();
|
||||||
|
let captures = vec![];
|
||||||
|
|
||||||
|
wrap_in_decode_custom_decode_with(
|
||||||
|
env,
|
||||||
|
bytes_sym,
|
||||||
|
(fmt_sym, fmt_var),
|
||||||
|
captures,
|
||||||
|
(decode_list_call, this_decode_list_ret_var),
|
||||||
|
)
|
||||||
|
}
|
990
crates/compiler/derive/src/decoding/record.rs
Normal file
990
crates/compiler/derive/src/decoding/record.rs
Normal file
|
@ -0,0 +1,990 @@
|
||||||
|
use roc_can::expr::{
|
||||||
|
AnnotatedMark, ClosureData, Expr, Field, Recursive, WhenBranch, WhenBranchPattern,
|
||||||
|
};
|
||||||
|
use roc_can::pattern::Pattern;
|
||||||
|
use roc_collections::SendMap;
|
||||||
|
use roc_module::called_via::CalledVia;
|
||||||
|
use roc_module::ident::Lowercase;
|
||||||
|
use roc_module::symbol::Symbol;
|
||||||
|
use roc_region::all::{Loc, Region};
|
||||||
|
use roc_types::subs::{
|
||||||
|
Content, ExhaustiveMark, FlatType, LambdaSet, OptVariable, RecordFields, RedundantMark,
|
||||||
|
SubsSlice, TagExt, UnionLambdas, UnionTags, Variable,
|
||||||
|
};
|
||||||
|
use roc_types::types::RecordField;
|
||||||
|
|
||||||
|
use crate::synth_var;
|
||||||
|
use crate::util::{Env, ExtensionKind};
|
||||||
|
|
||||||
|
use super::wrap_in_decode_custom_decode_with;
|
||||||
|
|
||||||
|
/// Implements decoding of a record. For example, for
|
||||||
|
///
|
||||||
|
/// ```text
|
||||||
|
/// {first: a, second: b}
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// we'd like to generate an impl like
|
||||||
|
///
|
||||||
|
/// ```roc
|
||||||
|
/// decoder : Decoder {first: a, second: b} fmt | a has Decoding, b has Decoding, fmt has DecoderFormatting
|
||||||
|
/// decoder =
|
||||||
|
/// initialState : {f0: Result a [NoField], f1: Result b [NoField]}
|
||||||
|
/// initialState = {f0: Err NoField, f1: Err NoField}
|
||||||
|
///
|
||||||
|
/// stepField = \state, field ->
|
||||||
|
/// when field is
|
||||||
|
/// "first" ->
|
||||||
|
/// Keep (Decode.custom \bytes, fmt ->
|
||||||
|
/// when Decode.decodeWith bytes Decode.decoder fmt is
|
||||||
|
/// {result, rest} ->
|
||||||
|
/// {result: Result.map result \val -> {state & f0: Ok val}, rest})
|
||||||
|
/// "second" ->
|
||||||
|
/// Keep (Decode.custom \bytes, fmt ->
|
||||||
|
/// when Decode.decodeWith bytes Decode.decoder fmt is
|
||||||
|
/// {result, rest} ->
|
||||||
|
/// {result: Result.map result \val -> {state & f1: Ok val}, rest})
|
||||||
|
/// _ -> Skip
|
||||||
|
///
|
||||||
|
/// finalizer = \{f0, f1} ->
|
||||||
|
/// when f0 is
|
||||||
|
/// Ok first ->
|
||||||
|
/// when f1 is
|
||||||
|
/// Ok second -> Ok {first, second}
|
||||||
|
/// Err NoField -> Err TooShort
|
||||||
|
/// Err NoField -> Err TooShort
|
||||||
|
///
|
||||||
|
/// Decode.custom \bytes, fmt -> Decode.decodeWith bytes (Decode.record initialState stepField finalizer) fmt
|
||||||
|
/// ```
|
||||||
|
pub(crate) fn decoder(
|
||||||
|
env: &mut Env,
|
||||||
|
_def_symbol: Symbol,
|
||||||
|
fields: Vec<Lowercase>,
|
||||||
|
) -> (Expr, Variable) {
|
||||||
|
// The decoded type of each field in the record, e.g. {first: a, second: b}.
|
||||||
|
let mut field_vars = Vec::with_capacity(fields.len());
|
||||||
|
// The type of each field in the decoding state, e.g. {first: Result a [NoField], second: Result b [NoField]}
|
||||||
|
let mut result_field_vars = Vec::with_capacity(fields.len());
|
||||||
|
|
||||||
|
// initialState = ...
|
||||||
|
let (initial_state_var, initial_state) =
|
||||||
|
initial_state(env, &fields, &mut field_vars, &mut result_field_vars);
|
||||||
|
|
||||||
|
// finalizer = ...
|
||||||
|
let (finalizer, finalizer_var, decode_err_var) = finalizer(
|
||||||
|
env,
|
||||||
|
initial_state_var,
|
||||||
|
&fields,
|
||||||
|
&field_vars,
|
||||||
|
&result_field_vars,
|
||||||
|
);
|
||||||
|
|
||||||
|
// stepField = ...
|
||||||
|
let (step_field, step_var) = step_field(
|
||||||
|
env,
|
||||||
|
fields,
|
||||||
|
&field_vars,
|
||||||
|
&result_field_vars,
|
||||||
|
initial_state_var,
|
||||||
|
decode_err_var,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Build up the type of `Decode.record` we expect
|
||||||
|
let record_decoder_var = env.subs.fresh_unnamed_flex_var();
|
||||||
|
let decode_record_lambda_set = env.subs.fresh_unnamed_flex_var();
|
||||||
|
let decode_record_var = env.import_builtin_symbol_var(Symbol::DECODE_RECORD);
|
||||||
|
let this_decode_record_var = {
|
||||||
|
let flat_type = FlatType::Func(
|
||||||
|
SubsSlice::insert_into_subs(env.subs, [initial_state_var, step_var, finalizer_var]),
|
||||||
|
decode_record_lambda_set,
|
||||||
|
record_decoder_var,
|
||||||
|
);
|
||||||
|
|
||||||
|
synth_var(env.subs, Content::Structure(flat_type))
|
||||||
|
};
|
||||||
|
|
||||||
|
env.unify(decode_record_var, this_decode_record_var);
|
||||||
|
|
||||||
|
// Decode.record initialState stepField finalizer
|
||||||
|
let call_decode_record = Expr::Call(
|
||||||
|
Box::new((
|
||||||
|
this_decode_record_var,
|
||||||
|
Loc::at_zero(Expr::AbilityMember(
|
||||||
|
Symbol::DECODE_RECORD,
|
||||||
|
None,
|
||||||
|
this_decode_record_var,
|
||||||
|
)),
|
||||||
|
decode_record_lambda_set,
|
||||||
|
record_decoder_var,
|
||||||
|
)),
|
||||||
|
vec![
|
||||||
|
(initial_state_var, Loc::at_zero(initial_state)),
|
||||||
|
(step_var, Loc::at_zero(step_field)),
|
||||||
|
(finalizer_var, Loc::at_zero(finalizer)),
|
||||||
|
],
|
||||||
|
CalledVia::Space,
|
||||||
|
);
|
||||||
|
|
||||||
|
let (call_decode_custom, decode_custom_ret_var) = {
|
||||||
|
let bytes_sym = env.new_symbol("bytes");
|
||||||
|
let fmt_sym = env.new_symbol("fmt");
|
||||||
|
let fmt_var = env.subs.fresh_unnamed_flex_var();
|
||||||
|
|
||||||
|
let (decode_custom, decode_custom_var) = wrap_in_decode_custom_decode_with(
|
||||||
|
env,
|
||||||
|
bytes_sym,
|
||||||
|
(fmt_sym, fmt_var),
|
||||||
|
vec![],
|
||||||
|
(call_decode_record, record_decoder_var),
|
||||||
|
);
|
||||||
|
|
||||||
|
(decode_custom, decode_custom_var)
|
||||||
|
};
|
||||||
|
|
||||||
|
(call_decode_custom, decode_custom_ret_var)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Example:
|
||||||
|
// stepField = \state, field ->
|
||||||
|
// when field is
|
||||||
|
// "first" ->
|
||||||
|
// Keep (Decode.custom \bytes, fmt ->
|
||||||
|
// # Uses a single-branch `when` because `let` is more expensive to monomorphize
|
||||||
|
// # due to checks for polymorphic expressions, and `rec` would be polymorphic.
|
||||||
|
// when Decode.decodeWith bytes Decode.decoder fmt is
|
||||||
|
// rec ->
|
||||||
|
// {
|
||||||
|
// rest: rec.rest,
|
||||||
|
// result: when rec.result is
|
||||||
|
// Ok val -> Ok {state & first: Ok val},
|
||||||
|
// Err err -> Err err
|
||||||
|
// })
|
||||||
|
//
|
||||||
|
// "second" ->
|
||||||
|
// Keep (Decode.custom \bytes, fmt ->
|
||||||
|
// when Decode.decodeWith bytes Decode.decoder fmt is
|
||||||
|
// rec ->
|
||||||
|
// {
|
||||||
|
// rest: rec.rest,
|
||||||
|
// result: when rec.result is
|
||||||
|
// Ok val -> Ok {state & second: Ok val},
|
||||||
|
// Err err -> Err err
|
||||||
|
// })
|
||||||
|
//
|
||||||
|
// _ -> Skip
|
||||||
|
fn step_field(
|
||||||
|
env: &mut Env,
|
||||||
|
fields: Vec<Lowercase>,
|
||||||
|
field_vars: &[Variable],
|
||||||
|
result_field_vars: &[Variable],
|
||||||
|
state_record_var: Variable,
|
||||||
|
decode_err_var: Variable,
|
||||||
|
) -> (Expr, Variable) {
|
||||||
|
let state_arg_symbol = env.new_symbol("stateRecord");
|
||||||
|
let field_arg_symbol = env.new_symbol("field");
|
||||||
|
|
||||||
|
// +1 because of the default branch.
|
||||||
|
let mut branches = Vec::with_capacity(fields.len() + 1);
|
||||||
|
let keep_payload_var = env.subs.fresh_unnamed_flex_var();
|
||||||
|
let keep_or_skip_var = {
|
||||||
|
let keep_payload_subs_slice = SubsSlice::insert_into_subs(env.subs, [keep_payload_var]);
|
||||||
|
let flat_type = FlatType::TagUnion(
|
||||||
|
UnionTags::insert_slices_into_subs(
|
||||||
|
env.subs,
|
||||||
|
[
|
||||||
|
("Keep".into(), keep_payload_subs_slice),
|
||||||
|
("Skip".into(), Default::default()),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
TagExt::Any(Variable::EMPTY_TAG_UNION),
|
||||||
|
);
|
||||||
|
|
||||||
|
synth_var(env.subs, Content::Structure(flat_type))
|
||||||
|
};
|
||||||
|
|
||||||
|
for ((field_name, &field_var), &result_field_var) in fields
|
||||||
|
.into_iter()
|
||||||
|
.zip(field_vars.iter())
|
||||||
|
.zip(result_field_vars.iter())
|
||||||
|
{
|
||||||
|
// Example:
|
||||||
|
// "first" ->
|
||||||
|
// Keep (Decode.custom \bytes, fmt ->
|
||||||
|
// # Uses a single-branch `when` because `let` is more expensive to monomorphize
|
||||||
|
// # due to checks for polymorphic expressions, and `rec` would be polymorphic.
|
||||||
|
// when Decode.decodeWith bytes Decode.decoder fmt is
|
||||||
|
// rec ->
|
||||||
|
// {
|
||||||
|
// rest: rec.rest,
|
||||||
|
// result: when rec.result is
|
||||||
|
// Ok val -> Ok {state & first: Ok val},
|
||||||
|
// Err err -> Err err
|
||||||
|
// }
|
||||||
|
// )
|
||||||
|
|
||||||
|
let this_custom_callback_var;
|
||||||
|
let custom_callback_ret_var;
|
||||||
|
let custom_callback = {
|
||||||
|
// \bytes, fmt ->
|
||||||
|
// when Decode.decodeWith bytes Decode.decoder fmt is
|
||||||
|
// rec ->
|
||||||
|
// {
|
||||||
|
// rest: rec.rest,
|
||||||
|
// result: when rec.result is
|
||||||
|
// Ok val -> Ok {state & first: Ok val},
|
||||||
|
// Err err -> Err err
|
||||||
|
// }
|
||||||
|
let bytes_arg_symbol = env.new_symbol("bytes");
|
||||||
|
let fmt_arg_symbol = env.new_symbol("fmt");
|
||||||
|
let bytes_arg_var = env.subs.fresh_unnamed_flex_var();
|
||||||
|
let fmt_arg_var = env.subs.fresh_unnamed_flex_var();
|
||||||
|
|
||||||
|
// rec.result : [Ok field_var, Err DecodeError]
|
||||||
|
let rec_dot_result = {
|
||||||
|
let tag_union = FlatType::TagUnion(
|
||||||
|
UnionTags::for_result(env.subs, field_var, decode_err_var),
|
||||||
|
TagExt::Any(Variable::EMPTY_TAG_UNION),
|
||||||
|
);
|
||||||
|
|
||||||
|
synth_var(env.subs, Content::Structure(tag_union))
|
||||||
|
};
|
||||||
|
|
||||||
|
// rec : { rest: List U8, result: (typeof rec.result) }
|
||||||
|
let rec_var = {
|
||||||
|
let fields = RecordFields::insert_into_subs(
|
||||||
|
env.subs,
|
||||||
|
[
|
||||||
|
("rest".into(), RecordField::Required(Variable::LIST_U8)),
|
||||||
|
("result".into(), RecordField::Required(rec_dot_result)),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
let record = FlatType::Record(fields, Variable::EMPTY_RECORD);
|
||||||
|
|
||||||
|
synth_var(env.subs, Content::Structure(record))
|
||||||
|
};
|
||||||
|
|
||||||
|
// `Decode.decoder` for the field's value
|
||||||
|
let decoder_var = env.import_builtin_symbol_var(Symbol::DECODE_DECODER);
|
||||||
|
let decode_with_var = env.import_builtin_symbol_var(Symbol::DECODE_DECODE_WITH);
|
||||||
|
let lambda_set_var = env.subs.fresh_unnamed_flex_var();
|
||||||
|
let this_decode_with_var = {
|
||||||
|
let subs_slice = SubsSlice::insert_into_subs(
|
||||||
|
env.subs,
|
||||||
|
[bytes_arg_var, decoder_var, fmt_arg_var],
|
||||||
|
);
|
||||||
|
let this_decode_with_var = synth_var(
|
||||||
|
env.subs,
|
||||||
|
Content::Structure(FlatType::Func(subs_slice, lambda_set_var, rec_var)),
|
||||||
|
);
|
||||||
|
|
||||||
|
env.unify(decode_with_var, this_decode_with_var);
|
||||||
|
|
||||||
|
this_decode_with_var
|
||||||
|
};
|
||||||
|
|
||||||
|
// The result of decoding this field's value - either the updated state, or a decoding error.
|
||||||
|
let when_expr_var = {
|
||||||
|
let flat_type = FlatType::TagUnion(
|
||||||
|
UnionTags::for_result(env.subs, state_record_var, decode_err_var),
|
||||||
|
TagExt::Any(Variable::EMPTY_TAG_UNION),
|
||||||
|
);
|
||||||
|
|
||||||
|
synth_var(env.subs, Content::Structure(flat_type))
|
||||||
|
};
|
||||||
|
|
||||||
|
// What our decoder passed to `Decode.custom` returns - the result of decoding the
|
||||||
|
// field's value, and the remaining bytes.
|
||||||
|
custom_callback_ret_var = {
|
||||||
|
let rest_field = RecordField::Required(Variable::LIST_U8);
|
||||||
|
let result_field = RecordField::Required(when_expr_var);
|
||||||
|
let flat_type = FlatType::Record(
|
||||||
|
RecordFields::insert_into_subs(
|
||||||
|
env.subs,
|
||||||
|
[("rest".into(), rest_field), ("result".into(), result_field)],
|
||||||
|
),
|
||||||
|
Variable::EMPTY_RECORD,
|
||||||
|
);
|
||||||
|
|
||||||
|
synth_var(env.subs, Content::Structure(flat_type))
|
||||||
|
};
|
||||||
|
|
||||||
|
let custom_callback_body = {
|
||||||
|
let rec_symbol = env.new_symbol("rec");
|
||||||
|
|
||||||
|
// # Uses a single-branch `when` because `let` is more expensive to monomorphize
|
||||||
|
// # due to checks for polymorphic expressions, and `rec` would be polymorphic.
|
||||||
|
// when Decode.decodeWith bytes Decode.decoder fmt is
|
||||||
|
// rec ->
|
||||||
|
// {
|
||||||
|
// rest: rec.rest,
|
||||||
|
// result: when rec.result is
|
||||||
|
// Ok val -> Ok {state & first: Ok val},
|
||||||
|
// Err err -> Err err
|
||||||
|
// }
|
||||||
|
let branch_body = {
|
||||||
|
let result_val = {
|
||||||
|
// result: when rec.result is
|
||||||
|
// Ok val -> Ok {state & first: Ok val},
|
||||||
|
// Err err -> Err err
|
||||||
|
let ok_val_symbol = env.new_symbol("val");
|
||||||
|
let err_val_symbol = env.new_symbol("err");
|
||||||
|
let ok_branch_expr = {
|
||||||
|
// Ok {state & first: Ok val},
|
||||||
|
let mut updates = SendMap::default();
|
||||||
|
|
||||||
|
updates.insert(
|
||||||
|
field_name.clone(),
|
||||||
|
Field {
|
||||||
|
var: result_field_var,
|
||||||
|
region: Region::zero(),
|
||||||
|
loc_expr: Box::new(Loc::at_zero(Expr::Tag {
|
||||||
|
tag_union_var: result_field_var,
|
||||||
|
ext_var: env.new_ext_var(ExtensionKind::TagUnion),
|
||||||
|
name: "Ok".into(),
|
||||||
|
arguments: vec![(
|
||||||
|
field_var,
|
||||||
|
Loc::at_zero(Expr::Var(ok_val_symbol, field_var)),
|
||||||
|
)],
|
||||||
|
})),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
let updated_record = Expr::RecordUpdate {
|
||||||
|
record_var: state_record_var,
|
||||||
|
ext_var: env.new_ext_var(ExtensionKind::Record),
|
||||||
|
symbol: state_arg_symbol,
|
||||||
|
updates,
|
||||||
|
};
|
||||||
|
|
||||||
|
Expr::Tag {
|
||||||
|
tag_union_var: when_expr_var,
|
||||||
|
ext_var: env.new_ext_var(ExtensionKind::TagUnion),
|
||||||
|
name: "Ok".into(),
|
||||||
|
arguments: vec![(state_record_var, Loc::at_zero(updated_record))],
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let branches = vec![
|
||||||
|
// Ok val -> Ok {state & first: Ok val},
|
||||||
|
WhenBranch {
|
||||||
|
patterns: vec![WhenBranchPattern {
|
||||||
|
pattern: Loc::at_zero(Pattern::AppliedTag {
|
||||||
|
whole_var: rec_dot_result,
|
||||||
|
ext_var: Variable::EMPTY_TAG_UNION,
|
||||||
|
tag_name: "Ok".into(),
|
||||||
|
arguments: vec![(
|
||||||
|
field_var,
|
||||||
|
Loc::at_zero(Pattern::Identifier(ok_val_symbol)),
|
||||||
|
)],
|
||||||
|
}),
|
||||||
|
degenerate: false,
|
||||||
|
}],
|
||||||
|
value: Loc::at_zero(ok_branch_expr),
|
||||||
|
guard: None,
|
||||||
|
redundant: RedundantMark::known_non_redundant(),
|
||||||
|
},
|
||||||
|
// Err err -> Err err
|
||||||
|
WhenBranch {
|
||||||
|
patterns: vec![WhenBranchPattern {
|
||||||
|
pattern: Loc::at_zero(Pattern::AppliedTag {
|
||||||
|
whole_var: rec_dot_result,
|
||||||
|
ext_var: Variable::EMPTY_TAG_UNION,
|
||||||
|
tag_name: "Err".into(),
|
||||||
|
arguments: vec![(
|
||||||
|
decode_err_var,
|
||||||
|
Loc::at_zero(Pattern::Identifier(err_val_symbol)),
|
||||||
|
)],
|
||||||
|
}),
|
||||||
|
degenerate: false,
|
||||||
|
}],
|
||||||
|
value: Loc::at_zero(Expr::Tag {
|
||||||
|
tag_union_var: when_expr_var,
|
||||||
|
ext_var: env.new_ext_var(ExtensionKind::TagUnion),
|
||||||
|
name: "Err".into(),
|
||||||
|
arguments: vec![(
|
||||||
|
decode_err_var,
|
||||||
|
Loc::at_zero(Expr::Var(err_val_symbol, decode_err_var)),
|
||||||
|
)],
|
||||||
|
}),
|
||||||
|
guard: None,
|
||||||
|
redundant: RedundantMark::known_non_redundant(),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
// when rec.result is
|
||||||
|
// Ok val -> Ok {state & first: Ok val},
|
||||||
|
// Err err -> Err err
|
||||||
|
Expr::When {
|
||||||
|
loc_cond: Box::new(Loc::at_zero(Expr::RecordAccess {
|
||||||
|
record_var: rec_var,
|
||||||
|
ext_var: env.new_ext_var(ExtensionKind::Record),
|
||||||
|
field_var: rec_dot_result,
|
||||||
|
loc_expr: Box::new(Loc::at_zero(Expr::Var(rec_symbol, rec_var))),
|
||||||
|
field: "result".into(),
|
||||||
|
})),
|
||||||
|
cond_var: rec_dot_result,
|
||||||
|
expr_var: when_expr_var,
|
||||||
|
region: Region::zero(),
|
||||||
|
branches,
|
||||||
|
branches_cond_var: rec_dot_result,
|
||||||
|
exhaustive: ExhaustiveMark::known_exhaustive(),
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// {
|
||||||
|
// rest: rec.rest,
|
||||||
|
// result: when rec.result is
|
||||||
|
// Ok val -> Ok {state & first: Ok val},
|
||||||
|
// Err err -> Err err
|
||||||
|
// }
|
||||||
|
let mut fields_map = SendMap::default();
|
||||||
|
|
||||||
|
fields_map.insert(
|
||||||
|
"rest".into(),
|
||||||
|
Field {
|
||||||
|
var: Variable::LIST_U8,
|
||||||
|
region: Region::zero(),
|
||||||
|
loc_expr: Box::new(Loc::at_zero(Expr::RecordAccess {
|
||||||
|
record_var: rec_var,
|
||||||
|
ext_var: env.new_ext_var(ExtensionKind::Record),
|
||||||
|
field_var: Variable::LIST_U8,
|
||||||
|
loc_expr: Box::new(Loc::at_zero(Expr::Var(rec_symbol, rec_var))),
|
||||||
|
field: "rest".into(),
|
||||||
|
})),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
// result: when rec.result is
|
||||||
|
// Ok val -> Ok {state & first: Ok val},
|
||||||
|
// Err err -> Err err
|
||||||
|
fields_map.insert(
|
||||||
|
"result".into(),
|
||||||
|
Field {
|
||||||
|
var: when_expr_var,
|
||||||
|
region: Region::zero(),
|
||||||
|
loc_expr: Box::new(Loc::at_zero(result_val)),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
Expr::Record {
|
||||||
|
record_var: custom_callback_ret_var,
|
||||||
|
fields: fields_map,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let branch = WhenBranch {
|
||||||
|
patterns: vec![WhenBranchPattern {
|
||||||
|
pattern: Loc::at_zero(Pattern::Identifier(rec_symbol)),
|
||||||
|
degenerate: false,
|
||||||
|
}],
|
||||||
|
value: Loc::at_zero(branch_body),
|
||||||
|
guard: None,
|
||||||
|
redundant: RedundantMark::known_non_redundant(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let condition_expr = Expr::Call(
|
||||||
|
Box::new((
|
||||||
|
this_decode_with_var,
|
||||||
|
Loc::at_zero(Expr::Var(Symbol::DECODE_DECODE_WITH, this_decode_with_var)),
|
||||||
|
lambda_set_var,
|
||||||
|
rec_var,
|
||||||
|
)),
|
||||||
|
vec![
|
||||||
|
(
|
||||||
|
Variable::LIST_U8,
|
||||||
|
Loc::at_zero(Expr::Var(bytes_arg_symbol, Variable::LIST_U8)),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
decoder_var,
|
||||||
|
Loc::at_zero(Expr::AbilityMember(
|
||||||
|
Symbol::DECODE_DECODER,
|
||||||
|
None,
|
||||||
|
decoder_var,
|
||||||
|
)),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
fmt_arg_var,
|
||||||
|
Loc::at_zero(Expr::Var(fmt_arg_symbol, fmt_arg_var)),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
CalledVia::Space,
|
||||||
|
);
|
||||||
|
|
||||||
|
// when Decode.decodeWith bytes Decode.decoder fmt is
|
||||||
|
Expr::When {
|
||||||
|
loc_cond: Box::new(Loc::at_zero(condition_expr)),
|
||||||
|
cond_var: rec_var,
|
||||||
|
expr_var: custom_callback_ret_var,
|
||||||
|
region: Region::zero(),
|
||||||
|
branches: vec![branch],
|
||||||
|
branches_cond_var: rec_var,
|
||||||
|
exhaustive: ExhaustiveMark::known_exhaustive(),
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let custom_closure_symbol = env.new_symbol("customCallback");
|
||||||
|
this_custom_callback_var = env.subs.fresh_unnamed_flex_var();
|
||||||
|
let custom_callback_lambda_set_var = {
|
||||||
|
let content = Content::LambdaSet(LambdaSet {
|
||||||
|
solved: UnionLambdas::insert_into_subs(
|
||||||
|
env.subs,
|
||||||
|
[(custom_closure_symbol, [state_record_var])],
|
||||||
|
),
|
||||||
|
recursion_var: OptVariable::NONE,
|
||||||
|
unspecialized: Default::default(),
|
||||||
|
ambient_function: this_custom_callback_var,
|
||||||
|
});
|
||||||
|
let custom_callback_lambda_set_var = synth_var(env.subs, content);
|
||||||
|
let subs_slice =
|
||||||
|
SubsSlice::insert_into_subs(env.subs, [bytes_arg_var, fmt_arg_var]);
|
||||||
|
|
||||||
|
env.subs.set_content(
|
||||||
|
this_custom_callback_var,
|
||||||
|
Content::Structure(FlatType::Func(
|
||||||
|
subs_slice,
|
||||||
|
custom_callback_lambda_set_var,
|
||||||
|
custom_callback_ret_var,
|
||||||
|
)),
|
||||||
|
);
|
||||||
|
|
||||||
|
custom_callback_lambda_set_var
|
||||||
|
};
|
||||||
|
|
||||||
|
// \bytes, fmt -> …
|
||||||
|
Expr::Closure(ClosureData {
|
||||||
|
function_type: this_custom_callback_var,
|
||||||
|
closure_type: custom_callback_lambda_set_var,
|
||||||
|
return_type: custom_callback_ret_var,
|
||||||
|
name: custom_closure_symbol,
|
||||||
|
captured_symbols: vec![(state_arg_symbol, state_record_var)],
|
||||||
|
recursive: Recursive::NotRecursive,
|
||||||
|
arguments: vec![
|
||||||
|
(
|
||||||
|
bytes_arg_var,
|
||||||
|
AnnotatedMark::known_exhaustive(),
|
||||||
|
Loc::at_zero(Pattern::Identifier(bytes_arg_symbol)),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
fmt_arg_var,
|
||||||
|
AnnotatedMark::known_exhaustive(),
|
||||||
|
Loc::at_zero(Pattern::Identifier(fmt_arg_symbol)),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
loc_body: Box::new(Loc::at_zero(custom_callback_body)),
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
let decode_custom_ret_var = env.subs.fresh_unnamed_flex_var();
|
||||||
|
let decode_custom = {
|
||||||
|
let decode_custom_var = env.import_builtin_symbol_var(Symbol::DECODE_CUSTOM);
|
||||||
|
let decode_custom_closure_var = env.subs.fresh_unnamed_flex_var();
|
||||||
|
let this_decode_custom_var = {
|
||||||
|
let subs_slice = SubsSlice::insert_into_subs(env.subs, [this_custom_callback_var]);
|
||||||
|
let flat_type =
|
||||||
|
FlatType::Func(subs_slice, decode_custom_closure_var, decode_custom_ret_var);
|
||||||
|
|
||||||
|
synth_var(env.subs, Content::Structure(flat_type))
|
||||||
|
};
|
||||||
|
|
||||||
|
env.unify(decode_custom_var, this_decode_custom_var);
|
||||||
|
|
||||||
|
// Decode.custom \bytes, fmt -> …
|
||||||
|
Expr::Call(
|
||||||
|
Box::new((
|
||||||
|
this_decode_custom_var,
|
||||||
|
Loc::at_zero(Expr::Var(Symbol::DECODE_CUSTOM, this_decode_custom_var)),
|
||||||
|
decode_custom_closure_var,
|
||||||
|
decode_custom_ret_var,
|
||||||
|
)),
|
||||||
|
vec![(this_custom_callback_var, Loc::at_zero(custom_callback))],
|
||||||
|
CalledVia::Space,
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
env.unify(keep_payload_var, decode_custom_ret_var);
|
||||||
|
|
||||||
|
let keep = {
|
||||||
|
// Keep (Decode.custom \bytes, fmt ->
|
||||||
|
// when Decode.decodeWith bytes Decode.decoder fmt is
|
||||||
|
// rec ->
|
||||||
|
// {
|
||||||
|
// rest: rec.rest,
|
||||||
|
// result: when rec.result is
|
||||||
|
// Ok val -> Ok {state & first: Ok val},
|
||||||
|
// Err err -> Err err
|
||||||
|
// }
|
||||||
|
// )
|
||||||
|
Expr::Tag {
|
||||||
|
tag_union_var: keep_or_skip_var,
|
||||||
|
ext_var: env.new_ext_var(ExtensionKind::TagUnion),
|
||||||
|
name: "Keep".into(),
|
||||||
|
arguments: vec![(decode_custom_ret_var, Loc::at_zero(decode_custom))],
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let branch = {
|
||||||
|
// "first" ->
|
||||||
|
// Keep (Decode.custom \bytes, fmt ->
|
||||||
|
// when Decode.decodeWith bytes Decode.decoder fmt is
|
||||||
|
// rec ->
|
||||||
|
// {
|
||||||
|
// rest: rec.rest,
|
||||||
|
// result: when rec.result is
|
||||||
|
// Ok val -> Ok {state & first: Ok val},
|
||||||
|
// Err err -> Err err
|
||||||
|
// }
|
||||||
|
// )
|
||||||
|
WhenBranch {
|
||||||
|
patterns: vec![WhenBranchPattern {
|
||||||
|
pattern: Loc::at_zero(Pattern::StrLiteral(field_name.into())),
|
||||||
|
degenerate: false,
|
||||||
|
}],
|
||||||
|
value: Loc::at_zero(keep),
|
||||||
|
guard: None,
|
||||||
|
redundant: RedundantMark::known_non_redundant(),
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
branches.push(branch);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Example: `_ -> Skip`
|
||||||
|
let default_branch = WhenBranch {
|
||||||
|
patterns: vec![WhenBranchPattern {
|
||||||
|
pattern: Loc::at_zero(Pattern::Underscore),
|
||||||
|
degenerate: false,
|
||||||
|
}],
|
||||||
|
value: Loc::at_zero(Expr::Tag {
|
||||||
|
tag_union_var: keep_or_skip_var,
|
||||||
|
ext_var: env.new_ext_var(ExtensionKind::TagUnion),
|
||||||
|
name: "Skip".into(),
|
||||||
|
arguments: Vec::new(),
|
||||||
|
}),
|
||||||
|
guard: None,
|
||||||
|
redundant: RedundantMark::known_non_redundant(),
|
||||||
|
};
|
||||||
|
|
||||||
|
branches.push(default_branch);
|
||||||
|
|
||||||
|
// when field is
|
||||||
|
let body = Expr::When {
|
||||||
|
loc_cond: Box::new(Loc::at_zero(Expr::Var(field_arg_symbol, Variable::STR))),
|
||||||
|
cond_var: Variable::STR,
|
||||||
|
expr_var: keep_or_skip_var,
|
||||||
|
region: Region::zero(),
|
||||||
|
branches,
|
||||||
|
branches_cond_var: Variable::STR,
|
||||||
|
exhaustive: ExhaustiveMark::known_exhaustive(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let step_field_closure = env.new_symbol("stepField");
|
||||||
|
let function_type = env.subs.fresh_unnamed_flex_var();
|
||||||
|
let closure_type = {
|
||||||
|
let lambda_set = LambdaSet {
|
||||||
|
solved: UnionLambdas::tag_without_arguments(env.subs, step_field_closure),
|
||||||
|
recursion_var: OptVariable::NONE,
|
||||||
|
unspecialized: Default::default(),
|
||||||
|
ambient_function: function_type,
|
||||||
|
};
|
||||||
|
|
||||||
|
synth_var(env.subs, Content::LambdaSet(lambda_set))
|
||||||
|
};
|
||||||
|
|
||||||
|
{
|
||||||
|
let args_slice = SubsSlice::insert_into_subs(env.subs, [state_record_var, Variable::STR]);
|
||||||
|
|
||||||
|
env.subs.set_content(
|
||||||
|
function_type,
|
||||||
|
Content::Structure(FlatType::Func(args_slice, closure_type, keep_or_skip_var)),
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
let expr = Expr::Closure(ClosureData {
|
||||||
|
function_type,
|
||||||
|
closure_type,
|
||||||
|
return_type: keep_or_skip_var,
|
||||||
|
name: step_field_closure,
|
||||||
|
captured_symbols: Vec::new(),
|
||||||
|
recursive: Recursive::NotRecursive,
|
||||||
|
arguments: vec![
|
||||||
|
(
|
||||||
|
state_record_var,
|
||||||
|
AnnotatedMark::known_exhaustive(),
|
||||||
|
Loc::at_zero(Pattern::Identifier(state_arg_symbol)),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
Variable::STR,
|
||||||
|
AnnotatedMark::known_exhaustive(),
|
||||||
|
Loc::at_zero(Pattern::Identifier(field_arg_symbol)),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
loc_body: Box::new(Loc::at_zero(body)),
|
||||||
|
});
|
||||||
|
|
||||||
|
(expr, function_type)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Example:
|
||||||
|
// finalizer = \rec ->
|
||||||
|
// when rec.first is
|
||||||
|
// Ok first ->
|
||||||
|
// when rec.second is
|
||||||
|
// Ok second -> Ok {first, second}
|
||||||
|
// Err NoField -> Err TooShort
|
||||||
|
// Err NoField -> Err TooShort
|
||||||
|
fn finalizer(
|
||||||
|
env: &mut Env,
|
||||||
|
state_record_var: Variable,
|
||||||
|
fields: &[Lowercase],
|
||||||
|
field_vars: &[Variable],
|
||||||
|
result_field_vars: &[Variable],
|
||||||
|
) -> (Expr, Variable, Variable) {
|
||||||
|
let state_arg_symbol = env.new_symbol("stateRecord");
|
||||||
|
let mut fields_map = SendMap::default();
|
||||||
|
let mut pattern_symbols = Vec::with_capacity(fields.len());
|
||||||
|
let decode_err_var = {
|
||||||
|
let flat_type = FlatType::TagUnion(
|
||||||
|
UnionTags::tag_without_arguments(env.subs, "TooShort".into()),
|
||||||
|
TagExt::Any(Variable::EMPTY_TAG_UNION),
|
||||||
|
);
|
||||||
|
|
||||||
|
synth_var(env.subs, Content::Structure(flat_type))
|
||||||
|
};
|
||||||
|
|
||||||
|
for (field_name, &field_var) in fields.iter().zip(field_vars.iter()) {
|
||||||
|
let symbol = env.new_symbol(field_name.as_str());
|
||||||
|
|
||||||
|
pattern_symbols.push(symbol);
|
||||||
|
|
||||||
|
let field_expr = Expr::Var(symbol, field_var);
|
||||||
|
let field = Field {
|
||||||
|
var: field_var,
|
||||||
|
region: Region::zero(),
|
||||||
|
loc_expr: Box::new(Loc::at_zero(field_expr)),
|
||||||
|
};
|
||||||
|
|
||||||
|
fields_map.insert(field_name.clone(), field);
|
||||||
|
}
|
||||||
|
|
||||||
|
// The bottom of the happy path - return the decoded record {first: a, second: b} wrapped with
|
||||||
|
// "Ok".
|
||||||
|
let return_type_var;
|
||||||
|
let mut body = {
|
||||||
|
let subs = &mut env.subs;
|
||||||
|
let record_field_iter = fields
|
||||||
|
.iter()
|
||||||
|
.zip(field_vars.iter())
|
||||||
|
.map(|(field_name, &field_var)| (field_name.clone(), RecordField::Required(field_var)));
|
||||||
|
let flat_type = FlatType::Record(
|
||||||
|
RecordFields::insert_into_subs(subs, record_field_iter),
|
||||||
|
Variable::EMPTY_RECORD,
|
||||||
|
);
|
||||||
|
let done_record_var = synth_var(subs, Content::Structure(flat_type));
|
||||||
|
let done_record = Expr::Record {
|
||||||
|
record_var: done_record_var,
|
||||||
|
fields: fields_map,
|
||||||
|
};
|
||||||
|
|
||||||
|
return_type_var = {
|
||||||
|
let flat_type = FlatType::TagUnion(
|
||||||
|
UnionTags::for_result(subs, done_record_var, decode_err_var),
|
||||||
|
TagExt::Any(Variable::EMPTY_TAG_UNION),
|
||||||
|
);
|
||||||
|
|
||||||
|
synth_var(subs, Content::Structure(flat_type))
|
||||||
|
};
|
||||||
|
|
||||||
|
Expr::Tag {
|
||||||
|
tag_union_var: return_type_var,
|
||||||
|
ext_var: env.new_ext_var(ExtensionKind::TagUnion),
|
||||||
|
name: "Ok".into(),
|
||||||
|
arguments: vec![(done_record_var, Loc::at_zero(done_record))],
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Unwrap each result in the decoded state
|
||||||
|
//
|
||||||
|
// when rec.first is
|
||||||
|
// Ok first -> ...happy path...
|
||||||
|
// Err NoField -> Err TooShort
|
||||||
|
for (((symbol, field_name), &field_var), &result_field_var) in pattern_symbols
|
||||||
|
.iter()
|
||||||
|
.rev()
|
||||||
|
.zip(fields.iter().rev())
|
||||||
|
.zip(field_vars.iter().rev())
|
||||||
|
.zip(result_field_vars.iter().rev())
|
||||||
|
{
|
||||||
|
// when rec.first is
|
||||||
|
let cond_expr = Expr::RecordAccess {
|
||||||
|
record_var: state_record_var,
|
||||||
|
ext_var: env.new_ext_var(ExtensionKind::Record),
|
||||||
|
field_var: result_field_var,
|
||||||
|
loc_expr: Box::new(Loc::at_zero(Expr::Var(state_arg_symbol, state_record_var))),
|
||||||
|
field: field_name.clone(),
|
||||||
|
};
|
||||||
|
|
||||||
|
// Example: `Ok x -> expr`
|
||||||
|
let ok_branch = WhenBranch {
|
||||||
|
patterns: vec![WhenBranchPattern {
|
||||||
|
pattern: Loc::at_zero(Pattern::AppliedTag {
|
||||||
|
whole_var: result_field_var,
|
||||||
|
ext_var: Variable::EMPTY_TAG_UNION,
|
||||||
|
tag_name: "Ok".into(),
|
||||||
|
arguments: vec![(field_var, Loc::at_zero(Pattern::Identifier(*symbol)))],
|
||||||
|
}),
|
||||||
|
degenerate: false,
|
||||||
|
}],
|
||||||
|
value: Loc::at_zero(body),
|
||||||
|
guard: None,
|
||||||
|
redundant: RedundantMark::known_non_redundant(),
|
||||||
|
};
|
||||||
|
|
||||||
|
// Example: `_ -> Err TooShort`
|
||||||
|
let err_branch = WhenBranch {
|
||||||
|
patterns: vec![WhenBranchPattern {
|
||||||
|
pattern: Loc::at_zero(Pattern::Underscore),
|
||||||
|
degenerate: false,
|
||||||
|
}],
|
||||||
|
value: Loc::at_zero(Expr::Tag {
|
||||||
|
tag_union_var: return_type_var,
|
||||||
|
ext_var: env.new_ext_var(ExtensionKind::TagUnion),
|
||||||
|
name: "Err".into(),
|
||||||
|
arguments: vec![(
|
||||||
|
decode_err_var,
|
||||||
|
Loc::at_zero(Expr::Tag {
|
||||||
|
tag_union_var: decode_err_var,
|
||||||
|
ext_var: Variable::EMPTY_TAG_UNION,
|
||||||
|
name: "TooShort".into(),
|
||||||
|
arguments: Vec::new(),
|
||||||
|
}),
|
||||||
|
)],
|
||||||
|
}),
|
||||||
|
guard: None,
|
||||||
|
redundant: RedundantMark::known_non_redundant(),
|
||||||
|
};
|
||||||
|
|
||||||
|
body = Expr::When {
|
||||||
|
loc_cond: Box::new(Loc::at_zero(cond_expr)),
|
||||||
|
cond_var: result_field_var,
|
||||||
|
expr_var: return_type_var,
|
||||||
|
region: Region::zero(),
|
||||||
|
branches: vec![ok_branch, err_branch],
|
||||||
|
branches_cond_var: result_field_var,
|
||||||
|
exhaustive: ExhaustiveMark::known_exhaustive(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
let function_var = synth_var(env.subs, Content::Error); // We'll fix this up in subs later.
|
||||||
|
let function_symbol = env.new_symbol("finalizer");
|
||||||
|
let lambda_set = LambdaSet {
|
||||||
|
solved: UnionLambdas::tag_without_arguments(env.subs, function_symbol),
|
||||||
|
recursion_var: OptVariable::NONE,
|
||||||
|
unspecialized: Default::default(),
|
||||||
|
ambient_function: function_var,
|
||||||
|
};
|
||||||
|
let closure_type = synth_var(env.subs, Content::LambdaSet(lambda_set));
|
||||||
|
let flat_type = FlatType::Func(
|
||||||
|
SubsSlice::insert_into_subs(env.subs, [state_record_var]),
|
||||||
|
closure_type,
|
||||||
|
return_type_var,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Fix up function_var so it's not Content::Error anymore
|
||||||
|
env.subs
|
||||||
|
.set_content(function_var, Content::Structure(flat_type));
|
||||||
|
|
||||||
|
let finalizer = Expr::Closure(ClosureData {
|
||||||
|
function_type: function_var,
|
||||||
|
closure_type,
|
||||||
|
return_type: return_type_var,
|
||||||
|
name: function_symbol,
|
||||||
|
captured_symbols: Vec::new(),
|
||||||
|
recursive: Recursive::NotRecursive,
|
||||||
|
arguments: vec![(
|
||||||
|
state_record_var,
|
||||||
|
AnnotatedMark::known_exhaustive(),
|
||||||
|
Loc::at_zero(Pattern::Identifier(state_arg_symbol)),
|
||||||
|
)],
|
||||||
|
loc_body: Box::new(Loc::at_zero(body)),
|
||||||
|
});
|
||||||
|
|
||||||
|
(finalizer, function_var, decode_err_var)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Example:
|
||||||
|
// initialState : {first: Result a [NoField], second: Result b [NoField]}
|
||||||
|
// initialState = {first: Err NoField, second: Err NoField}
|
||||||
|
fn initial_state(
|
||||||
|
env: &mut Env<'_>,
|
||||||
|
field_names: &[Lowercase],
|
||||||
|
field_vars: &mut Vec<Variable>,
|
||||||
|
result_field_vars: &mut Vec<Variable>,
|
||||||
|
) -> (Variable, Expr) {
|
||||||
|
let mut initial_state_fields = SendMap::default();
|
||||||
|
|
||||||
|
for field_name in field_names {
|
||||||
|
let subs = &mut env.subs;
|
||||||
|
let field_var = subs.fresh_unnamed_flex_var();
|
||||||
|
|
||||||
|
field_vars.push(field_var);
|
||||||
|
|
||||||
|
let no_field_label = "NoField";
|
||||||
|
let union_tags = UnionTags::tag_without_arguments(subs, no_field_label.into());
|
||||||
|
let no_field_var = synth_var(
|
||||||
|
subs,
|
||||||
|
Content::Structure(FlatType::TagUnion(
|
||||||
|
union_tags,
|
||||||
|
TagExt::Any(Variable::EMPTY_TAG_UNION),
|
||||||
|
)),
|
||||||
|
);
|
||||||
|
let no_field = Expr::Tag {
|
||||||
|
tag_union_var: no_field_var,
|
||||||
|
ext_var: Variable::EMPTY_TAG_UNION,
|
||||||
|
name: no_field_label.into(),
|
||||||
|
arguments: Vec::new(),
|
||||||
|
};
|
||||||
|
let err_label = "Err";
|
||||||
|
let union_tags = UnionTags::for_result(subs, field_var, no_field_var);
|
||||||
|
let result_var = synth_var(
|
||||||
|
subs,
|
||||||
|
Content::Structure(FlatType::TagUnion(
|
||||||
|
union_tags,
|
||||||
|
TagExt::Any(Variable::EMPTY_TAG_UNION),
|
||||||
|
)),
|
||||||
|
);
|
||||||
|
let field_expr = Expr::Tag {
|
||||||
|
tag_union_var: result_var,
|
||||||
|
ext_var: env.new_ext_var(ExtensionKind::TagUnion),
|
||||||
|
name: err_label.into(),
|
||||||
|
arguments: vec![(no_field_var, Loc::at_zero(no_field))],
|
||||||
|
};
|
||||||
|
result_field_vars.push(result_var);
|
||||||
|
let field = Field {
|
||||||
|
var: result_var,
|
||||||
|
region: Region::zero(),
|
||||||
|
loc_expr: Box::new(Loc::at_zero(field_expr)),
|
||||||
|
};
|
||||||
|
|
||||||
|
initial_state_fields.insert(field_name.clone(), field);
|
||||||
|
}
|
||||||
|
|
||||||
|
let subs = &mut env.subs;
|
||||||
|
let record_field_iter = field_names
|
||||||
|
.iter()
|
||||||
|
.zip(result_field_vars.iter())
|
||||||
|
.map(|(field_name, &var)| (field_name.clone(), RecordField::Required(var)));
|
||||||
|
let flat_type = FlatType::Record(
|
||||||
|
RecordFields::insert_into_subs(subs, record_field_iter),
|
||||||
|
Variable::EMPTY_RECORD,
|
||||||
|
);
|
||||||
|
|
||||||
|
let state_record_var = synth_var(subs, Content::Structure(flat_type));
|
||||||
|
|
||||||
|
(
|
||||||
|
state_record_var,
|
||||||
|
Expr::Record {
|
||||||
|
record_var: state_record_var,
|
||||||
|
fields: initial_state_fields,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
994
crates/compiler/derive/src/decoding/tuple.rs
Normal file
994
crates/compiler/derive/src/decoding/tuple.rs
Normal file
|
@ -0,0 +1,994 @@
|
||||||
|
use roc_can::expr::{
|
||||||
|
AnnotatedMark, ClosureData, Expr, Field, IntValue, Recursive, WhenBranch, WhenBranchPattern,
|
||||||
|
};
|
||||||
|
use roc_can::num::{IntBound, IntLitWidth};
|
||||||
|
use roc_can::pattern::Pattern;
|
||||||
|
use roc_collections::SendMap;
|
||||||
|
use roc_module::called_via::CalledVia;
|
||||||
|
use roc_module::ident::Lowercase;
|
||||||
|
use roc_module::symbol::Symbol;
|
||||||
|
use roc_region::all::{Loc, Region};
|
||||||
|
use roc_types::subs::{
|
||||||
|
Content, ExhaustiveMark, FlatType, LambdaSet, OptVariable, RecordFields, RedundantMark,
|
||||||
|
SubsSlice, TagExt, TupleElems, UnionLambdas, UnionTags, Variable,
|
||||||
|
};
|
||||||
|
use roc_types::types::RecordField;
|
||||||
|
|
||||||
|
use crate::synth_var;
|
||||||
|
use crate::util::{Env, ExtensionKind};
|
||||||
|
|
||||||
|
use super::wrap_in_decode_custom_decode_with;
|
||||||
|
|
||||||
|
/// Implements decoding of a tuple. For example, for
|
||||||
|
///
|
||||||
|
/// ```text
|
||||||
|
/// (a, b)
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// we'd like to generate an impl like
|
||||||
|
///
|
||||||
|
/// ```roc
|
||||||
|
/// decoder : Decoder (a, b) fmt | a has Decoding, b has Decoding, fmt has DecoderFormatting
|
||||||
|
/// decoder =
|
||||||
|
/// initialState : {e0: Result a [NoElem], e1: Result b [NoElem]}
|
||||||
|
/// initialState = {e0: Err NoElem, e1: Err NoElem}
|
||||||
|
///
|
||||||
|
/// stepElem = \state, index ->
|
||||||
|
/// when index is
|
||||||
|
/// 0 ->
|
||||||
|
/// Next (Decode.custom \bytes, fmt ->
|
||||||
|
/// when Decode.decodeWith bytes Decode.decoder fmt is
|
||||||
|
/// {result, rest} ->
|
||||||
|
/// {result: Result.map result \val -> {state & e0: Ok val}, rest})
|
||||||
|
/// 1 ->
|
||||||
|
/// Next (Decode.custom \bytes, fmt ->
|
||||||
|
/// when Decode.decodeWith bytes Decode.decoder fmt is
|
||||||
|
/// {result, rest} ->
|
||||||
|
/// {result: Result.map result \val -> {state & e1: Ok val}, rest})
|
||||||
|
/// _ -> TooLong
|
||||||
|
///
|
||||||
|
/// finalizer = \st ->
|
||||||
|
/// when st.e0 is
|
||||||
|
/// Ok e0 ->
|
||||||
|
/// when st.e1 is
|
||||||
|
/// Ok e1 -> Ok (e0, e1)
|
||||||
|
/// Err NoElem -> Err TooShort
|
||||||
|
/// Err NoElem -> Err TooShort
|
||||||
|
///
|
||||||
|
/// Decode.custom \bytes, fmt -> Decode.decodeWith bytes (Decode.tuple initialState stepElem finalizer) fmt
|
||||||
|
/// ```
|
||||||
|
pub(crate) fn decoder(env: &mut Env, _def_symbol: Symbol, arity: u32) -> (Expr, Variable) {
|
||||||
|
// The decoded type of each index in the tuple, e.g. (a, b).
|
||||||
|
let mut index_vars = Vec::with_capacity(arity as _);
|
||||||
|
// The type of each index in the decoding state, e.g. {e0: Result a [NoElem], e1: Result b [NoElem]}
|
||||||
|
let mut state_fields = Vec::with_capacity(arity as _);
|
||||||
|
let mut state_field_vars = Vec::with_capacity(arity as _);
|
||||||
|
|
||||||
|
// initialState = ...
|
||||||
|
let (state_var, initial_state) = initial_state(
|
||||||
|
env,
|
||||||
|
arity,
|
||||||
|
&mut index_vars,
|
||||||
|
&mut state_fields,
|
||||||
|
&mut state_field_vars,
|
||||||
|
);
|
||||||
|
|
||||||
|
// finalizer = ...
|
||||||
|
let (finalizer, finalizer_var, decode_err_var) = finalizer(
|
||||||
|
env,
|
||||||
|
&index_vars,
|
||||||
|
state_var,
|
||||||
|
&state_fields,
|
||||||
|
&state_field_vars,
|
||||||
|
);
|
||||||
|
|
||||||
|
// stepElem = ...
|
||||||
|
let (step_elem, step_var) = step_elem(
|
||||||
|
env,
|
||||||
|
&index_vars,
|
||||||
|
state_var,
|
||||||
|
&state_fields,
|
||||||
|
&state_field_vars,
|
||||||
|
decode_err_var,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Build up the type of `Decode.tuple` we expect
|
||||||
|
let tuple_decoder_var = env.subs.fresh_unnamed_flex_var();
|
||||||
|
let decode_record_lambda_set = env.subs.fresh_unnamed_flex_var();
|
||||||
|
let decode_record_var = env.import_builtin_symbol_var(Symbol::DECODE_TUPLE);
|
||||||
|
let this_decode_record_var = {
|
||||||
|
let flat_type = FlatType::Func(
|
||||||
|
SubsSlice::insert_into_subs(env.subs, [state_var, step_var, finalizer_var]),
|
||||||
|
decode_record_lambda_set,
|
||||||
|
tuple_decoder_var,
|
||||||
|
);
|
||||||
|
|
||||||
|
synth_var(env.subs, Content::Structure(flat_type))
|
||||||
|
};
|
||||||
|
|
||||||
|
env.unify(decode_record_var, this_decode_record_var);
|
||||||
|
|
||||||
|
// Decode.tuple initialState stepElem finalizer
|
||||||
|
let call_decode_record = Expr::Call(
|
||||||
|
Box::new((
|
||||||
|
this_decode_record_var,
|
||||||
|
Loc::at_zero(Expr::AbilityMember(
|
||||||
|
Symbol::DECODE_TUPLE,
|
||||||
|
None,
|
||||||
|
this_decode_record_var,
|
||||||
|
)),
|
||||||
|
decode_record_lambda_set,
|
||||||
|
tuple_decoder_var,
|
||||||
|
)),
|
||||||
|
vec![
|
||||||
|
(state_var, Loc::at_zero(initial_state)),
|
||||||
|
(step_var, Loc::at_zero(step_elem)),
|
||||||
|
(finalizer_var, Loc::at_zero(finalizer)),
|
||||||
|
],
|
||||||
|
CalledVia::Space,
|
||||||
|
);
|
||||||
|
|
||||||
|
let (call_decode_custom, decode_custom_ret_var) = {
|
||||||
|
let bytes_sym = env.new_symbol("bytes");
|
||||||
|
let fmt_sym = env.new_symbol("fmt");
|
||||||
|
let fmt_var = env.subs.fresh_unnamed_flex_var();
|
||||||
|
|
||||||
|
let (decode_custom, decode_custom_var) = wrap_in_decode_custom_decode_with(
|
||||||
|
env,
|
||||||
|
bytes_sym,
|
||||||
|
(fmt_sym, fmt_var),
|
||||||
|
vec![],
|
||||||
|
(call_decode_record, tuple_decoder_var),
|
||||||
|
);
|
||||||
|
|
||||||
|
(decode_custom, decode_custom_var)
|
||||||
|
};
|
||||||
|
|
||||||
|
(call_decode_custom, decode_custom_ret_var)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Example:
|
||||||
|
// stepElem = \state, index ->
|
||||||
|
// when index is
|
||||||
|
// 0 ->
|
||||||
|
// Next (Decode.custom \bytes, fmt ->
|
||||||
|
// # Uses a single-branch `when` because `let` is more expensive to monomorphize
|
||||||
|
// # due to checks for polymorphic expressions, and `rec` would be polymorphic.
|
||||||
|
// when Decode.decodeWith bytes Decode.decoder fmt is
|
||||||
|
// rec ->
|
||||||
|
// {
|
||||||
|
// rest: rec.rest,
|
||||||
|
// result: when rec.result is
|
||||||
|
// Ok val -> Ok {state & e0: Ok val},
|
||||||
|
// Err err -> Err err
|
||||||
|
// })
|
||||||
|
//
|
||||||
|
// "e1" ->
|
||||||
|
// Next (Decode.custom \bytes, fmt ->
|
||||||
|
// when Decode.decodeWith bytes Decode.decoder fmt is
|
||||||
|
// rec ->
|
||||||
|
// {
|
||||||
|
// rest: rec.rest,
|
||||||
|
// result: when rec.result is
|
||||||
|
// Ok val -> Ok {state & e1: Ok val},
|
||||||
|
// Err err -> Err err
|
||||||
|
// })
|
||||||
|
//
|
||||||
|
// _ -> TooLong
|
||||||
|
fn step_elem(
|
||||||
|
env: &mut Env,
|
||||||
|
index_vars: &[Variable],
|
||||||
|
state_record_var: Variable,
|
||||||
|
state_fields: &[Lowercase],
|
||||||
|
state_field_vars: &[Variable],
|
||||||
|
decode_err_var: Variable,
|
||||||
|
) -> (Expr, Variable) {
|
||||||
|
let state_arg_symbol = env.new_symbol("stateRecord");
|
||||||
|
let index_arg_symbol = env.new_symbol("index");
|
||||||
|
|
||||||
|
// +1 because of the default branch.
|
||||||
|
let mut branches = Vec::with_capacity(index_vars.len() + 1);
|
||||||
|
let keep_payload_var = env.subs.fresh_unnamed_flex_var();
|
||||||
|
let keep_or_skip_var = {
|
||||||
|
let keep_payload_subs_slice = SubsSlice::insert_into_subs(env.subs, [keep_payload_var]);
|
||||||
|
let flat_type = FlatType::TagUnion(
|
||||||
|
UnionTags::insert_slices_into_subs(
|
||||||
|
env.subs,
|
||||||
|
[
|
||||||
|
("Next".into(), keep_payload_subs_slice),
|
||||||
|
("TooLong".into(), Default::default()),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
TagExt::Any(Variable::EMPTY_TAG_UNION),
|
||||||
|
);
|
||||||
|
|
||||||
|
synth_var(env.subs, Content::Structure(flat_type))
|
||||||
|
};
|
||||||
|
|
||||||
|
for (((index, state_field), &index_var), &result_index_var) in state_fields
|
||||||
|
.iter()
|
||||||
|
.enumerate()
|
||||||
|
.zip(index_vars)
|
||||||
|
.zip(state_field_vars)
|
||||||
|
{
|
||||||
|
// Example:
|
||||||
|
// 0 ->
|
||||||
|
// Next (Decode.custom \bytes, fmt ->
|
||||||
|
// when Decode.decodeWith bytes Decode.decoder fmt is
|
||||||
|
// rec ->
|
||||||
|
// {
|
||||||
|
// rest: rec.rest,
|
||||||
|
// result: when rec.result is
|
||||||
|
// Ok val -> Ok {state & e0: Ok val},
|
||||||
|
// Err err -> Err err
|
||||||
|
// }
|
||||||
|
// )
|
||||||
|
|
||||||
|
let this_custom_callback_var;
|
||||||
|
let custom_callback_ret_var;
|
||||||
|
let custom_callback = {
|
||||||
|
// \bytes, fmt ->
|
||||||
|
// when Decode.decodeWith bytes Decode.decoder fmt is
|
||||||
|
// rec ->
|
||||||
|
// {
|
||||||
|
// rest: rec.rest,
|
||||||
|
// result: when rec.result is
|
||||||
|
// Ok val -> Ok {state & e0: Ok val},
|
||||||
|
// Err err -> Err err
|
||||||
|
// }
|
||||||
|
let bytes_arg_symbol = env.new_symbol("bytes");
|
||||||
|
let fmt_arg_symbol = env.new_symbol("fmt");
|
||||||
|
let bytes_arg_var = env.subs.fresh_unnamed_flex_var();
|
||||||
|
let fmt_arg_var = env.subs.fresh_unnamed_flex_var();
|
||||||
|
|
||||||
|
// rec.result : [Ok index_var, Err DecodeError]
|
||||||
|
let rec_dot_result = {
|
||||||
|
let tag_union = FlatType::TagUnion(
|
||||||
|
UnionTags::for_result(env.subs, index_var, decode_err_var),
|
||||||
|
TagExt::Any(Variable::EMPTY_TAG_UNION),
|
||||||
|
);
|
||||||
|
|
||||||
|
synth_var(env.subs, Content::Structure(tag_union))
|
||||||
|
};
|
||||||
|
|
||||||
|
// rec : { rest: List U8, result: (typeof rec.result) }
|
||||||
|
let rec_var = {
|
||||||
|
let indexs = RecordFields::insert_into_subs(
|
||||||
|
env.subs,
|
||||||
|
[
|
||||||
|
("rest".into(), RecordField::Required(Variable::LIST_U8)),
|
||||||
|
("result".into(), RecordField::Required(rec_dot_result)),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
let record = FlatType::Record(indexs, Variable::EMPTY_RECORD);
|
||||||
|
|
||||||
|
synth_var(env.subs, Content::Structure(record))
|
||||||
|
};
|
||||||
|
|
||||||
|
// `Decode.decoder` for the index's value
|
||||||
|
let decoder_var = env.import_builtin_symbol_var(Symbol::DECODE_DECODER);
|
||||||
|
let decode_with_var = env.import_builtin_symbol_var(Symbol::DECODE_DECODE_WITH);
|
||||||
|
let lambda_set_var = env.subs.fresh_unnamed_flex_var();
|
||||||
|
let this_decode_with_var = {
|
||||||
|
let subs_slice = SubsSlice::insert_into_subs(
|
||||||
|
env.subs,
|
||||||
|
[bytes_arg_var, decoder_var, fmt_arg_var],
|
||||||
|
);
|
||||||
|
let this_decode_with_var = synth_var(
|
||||||
|
env.subs,
|
||||||
|
Content::Structure(FlatType::Func(subs_slice, lambda_set_var, rec_var)),
|
||||||
|
);
|
||||||
|
|
||||||
|
env.unify(decode_with_var, this_decode_with_var);
|
||||||
|
|
||||||
|
this_decode_with_var
|
||||||
|
};
|
||||||
|
|
||||||
|
// The result of decoding this index's value - either the updated state, or a decoding error.
|
||||||
|
let when_expr_var = {
|
||||||
|
let flat_type = FlatType::TagUnion(
|
||||||
|
UnionTags::for_result(env.subs, state_record_var, decode_err_var),
|
||||||
|
TagExt::Any(Variable::EMPTY_TAG_UNION),
|
||||||
|
);
|
||||||
|
|
||||||
|
synth_var(env.subs, Content::Structure(flat_type))
|
||||||
|
};
|
||||||
|
|
||||||
|
// What our decoder passed to `Decode.custom` returns - the result of decoding the
|
||||||
|
// index's value, and the remaining bytes.
|
||||||
|
custom_callback_ret_var = {
|
||||||
|
let rest_index = RecordField::Required(Variable::LIST_U8);
|
||||||
|
let result_index = RecordField::Required(when_expr_var);
|
||||||
|
let flat_type = FlatType::Record(
|
||||||
|
RecordFields::insert_into_subs(
|
||||||
|
env.subs,
|
||||||
|
[("rest".into(), rest_index), ("result".into(), result_index)],
|
||||||
|
),
|
||||||
|
Variable::EMPTY_RECORD,
|
||||||
|
);
|
||||||
|
|
||||||
|
synth_var(env.subs, Content::Structure(flat_type))
|
||||||
|
};
|
||||||
|
|
||||||
|
let custom_callback_body = {
|
||||||
|
let rec_symbol = env.new_symbol("rec");
|
||||||
|
|
||||||
|
// # Uses a single-branch `when` because `let` is more expensive to monomorphize
|
||||||
|
// # due to checks for polymorphic expressions, and `rec` would be polymorphic.
|
||||||
|
// when Decode.decodeWith bytes Decode.decoder fmt is
|
||||||
|
// rec ->
|
||||||
|
// {
|
||||||
|
// rest: rec.rest,
|
||||||
|
// result: when rec.result is
|
||||||
|
// Ok val -> Ok {state & e0: Ok val},
|
||||||
|
// Err err -> Err err
|
||||||
|
// }
|
||||||
|
let branch_body = {
|
||||||
|
let result_val = {
|
||||||
|
// result: when rec.result is
|
||||||
|
// Ok val -> Ok {state & e0: Ok val},
|
||||||
|
// Err err -> Err err
|
||||||
|
let ok_val_symbol = env.new_symbol("val");
|
||||||
|
let err_val_symbol = env.new_symbol("err");
|
||||||
|
let ok_branch_expr = {
|
||||||
|
// Ok {state & e0: Ok val},
|
||||||
|
let mut updates = SendMap::default();
|
||||||
|
|
||||||
|
updates.insert(
|
||||||
|
state_field.clone(),
|
||||||
|
Field {
|
||||||
|
var: result_index_var,
|
||||||
|
region: Region::zero(),
|
||||||
|
loc_expr: Box::new(Loc::at_zero(Expr::Tag {
|
||||||
|
tag_union_var: result_index_var,
|
||||||
|
ext_var: env.new_ext_var(ExtensionKind::TagUnion),
|
||||||
|
name: "Ok".into(),
|
||||||
|
arguments: vec![(
|
||||||
|
index_var,
|
||||||
|
Loc::at_zero(Expr::Var(ok_val_symbol, index_var)),
|
||||||
|
)],
|
||||||
|
})),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
let updated_record = Expr::RecordUpdate {
|
||||||
|
record_var: state_record_var,
|
||||||
|
ext_var: env.new_ext_var(ExtensionKind::Record),
|
||||||
|
symbol: state_arg_symbol,
|
||||||
|
updates,
|
||||||
|
};
|
||||||
|
|
||||||
|
Expr::Tag {
|
||||||
|
tag_union_var: when_expr_var,
|
||||||
|
ext_var: env.new_ext_var(ExtensionKind::TagUnion),
|
||||||
|
name: "Ok".into(),
|
||||||
|
arguments: vec![(state_record_var, Loc::at_zero(updated_record))],
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let branches = vec![
|
||||||
|
// Ok val -> Ok {state & e0: Ok val},
|
||||||
|
WhenBranch {
|
||||||
|
patterns: vec![WhenBranchPattern {
|
||||||
|
pattern: Loc::at_zero(Pattern::AppliedTag {
|
||||||
|
whole_var: rec_dot_result,
|
||||||
|
ext_var: Variable::EMPTY_TAG_UNION,
|
||||||
|
tag_name: "Ok".into(),
|
||||||
|
arguments: vec![(
|
||||||
|
index_var,
|
||||||
|
Loc::at_zero(Pattern::Identifier(ok_val_symbol)),
|
||||||
|
)],
|
||||||
|
}),
|
||||||
|
degenerate: false,
|
||||||
|
}],
|
||||||
|
value: Loc::at_zero(ok_branch_expr),
|
||||||
|
guard: None,
|
||||||
|
redundant: RedundantMark::known_non_redundant(),
|
||||||
|
},
|
||||||
|
// Err err -> Err err
|
||||||
|
WhenBranch {
|
||||||
|
patterns: vec![WhenBranchPattern {
|
||||||
|
pattern: Loc::at_zero(Pattern::AppliedTag {
|
||||||
|
whole_var: rec_dot_result,
|
||||||
|
ext_var: Variable::EMPTY_TAG_UNION,
|
||||||
|
tag_name: "Err".into(),
|
||||||
|
arguments: vec![(
|
||||||
|
decode_err_var,
|
||||||
|
Loc::at_zero(Pattern::Identifier(err_val_symbol)),
|
||||||
|
)],
|
||||||
|
}),
|
||||||
|
degenerate: false,
|
||||||
|
}],
|
||||||
|
value: Loc::at_zero(Expr::Tag {
|
||||||
|
tag_union_var: when_expr_var,
|
||||||
|
ext_var: env.new_ext_var(ExtensionKind::TagUnion),
|
||||||
|
name: "Err".into(),
|
||||||
|
arguments: vec![(
|
||||||
|
decode_err_var,
|
||||||
|
Loc::at_zero(Expr::Var(err_val_symbol, decode_err_var)),
|
||||||
|
)],
|
||||||
|
}),
|
||||||
|
guard: None,
|
||||||
|
redundant: RedundantMark::known_non_redundant(),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
// when rec.result is
|
||||||
|
// Ok val -> Ok {state & e0: Ok val},
|
||||||
|
// Err err -> Err err
|
||||||
|
Expr::When {
|
||||||
|
loc_cond: Box::new(Loc::at_zero(Expr::RecordAccess {
|
||||||
|
record_var: rec_var,
|
||||||
|
ext_var: env.new_ext_var(ExtensionKind::Record),
|
||||||
|
field_var: rec_dot_result,
|
||||||
|
loc_expr: Box::new(Loc::at_zero(Expr::Var(rec_symbol, rec_var))),
|
||||||
|
field: "result".into(),
|
||||||
|
})),
|
||||||
|
cond_var: rec_dot_result,
|
||||||
|
expr_var: when_expr_var,
|
||||||
|
region: Region::zero(),
|
||||||
|
branches,
|
||||||
|
branches_cond_var: rec_dot_result,
|
||||||
|
exhaustive: ExhaustiveMark::known_exhaustive(),
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// {
|
||||||
|
// rest: rec.rest,
|
||||||
|
// result: when rec.result is
|
||||||
|
// Ok val -> Ok {state & e0: Ok val},
|
||||||
|
// Err err -> Err err
|
||||||
|
// }
|
||||||
|
let mut fields_map = SendMap::default();
|
||||||
|
|
||||||
|
fields_map.insert(
|
||||||
|
"rest".into(),
|
||||||
|
Field {
|
||||||
|
var: Variable::LIST_U8,
|
||||||
|
region: Region::zero(),
|
||||||
|
loc_expr: Box::new(Loc::at_zero(Expr::RecordAccess {
|
||||||
|
record_var: rec_var,
|
||||||
|
ext_var: env.new_ext_var(ExtensionKind::Record),
|
||||||
|
field_var: Variable::LIST_U8,
|
||||||
|
loc_expr: Box::new(Loc::at_zero(Expr::Var(rec_symbol, rec_var))),
|
||||||
|
field: "rest".into(),
|
||||||
|
})),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
// result: when rec.result is
|
||||||
|
// Ok val -> Ok {state & e0: Ok val},
|
||||||
|
// Err err -> Err err
|
||||||
|
fields_map.insert(
|
||||||
|
"result".into(),
|
||||||
|
Field {
|
||||||
|
var: when_expr_var,
|
||||||
|
region: Region::zero(),
|
||||||
|
loc_expr: Box::new(Loc::at_zero(result_val)),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
Expr::Record {
|
||||||
|
record_var: custom_callback_ret_var,
|
||||||
|
fields: fields_map,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let branch = WhenBranch {
|
||||||
|
patterns: vec![WhenBranchPattern {
|
||||||
|
pattern: Loc::at_zero(Pattern::Identifier(rec_symbol)),
|
||||||
|
degenerate: false,
|
||||||
|
}],
|
||||||
|
value: Loc::at_zero(branch_body),
|
||||||
|
guard: None,
|
||||||
|
redundant: RedundantMark::known_non_redundant(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let condition_expr = Expr::Call(
|
||||||
|
Box::new((
|
||||||
|
this_decode_with_var,
|
||||||
|
Loc::at_zero(Expr::Var(Symbol::DECODE_DECODE_WITH, this_decode_with_var)),
|
||||||
|
lambda_set_var,
|
||||||
|
rec_var,
|
||||||
|
)),
|
||||||
|
vec![
|
||||||
|
(
|
||||||
|
Variable::LIST_U8,
|
||||||
|
Loc::at_zero(Expr::Var(bytes_arg_symbol, Variable::LIST_U8)),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
decoder_var,
|
||||||
|
Loc::at_zero(Expr::AbilityMember(
|
||||||
|
Symbol::DECODE_DECODER,
|
||||||
|
None,
|
||||||
|
decoder_var,
|
||||||
|
)),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
fmt_arg_var,
|
||||||
|
Loc::at_zero(Expr::Var(fmt_arg_symbol, fmt_arg_var)),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
CalledVia::Space,
|
||||||
|
);
|
||||||
|
|
||||||
|
// when Decode.decodeWith bytes Decode.decoder fmt is
|
||||||
|
Expr::When {
|
||||||
|
loc_cond: Box::new(Loc::at_zero(condition_expr)),
|
||||||
|
cond_var: rec_var,
|
||||||
|
expr_var: custom_callback_ret_var,
|
||||||
|
region: Region::zero(),
|
||||||
|
branches: vec![branch],
|
||||||
|
branches_cond_var: rec_var,
|
||||||
|
exhaustive: ExhaustiveMark::known_exhaustive(),
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let custom_closure_symbol = env.new_symbol("customCallback");
|
||||||
|
this_custom_callback_var = env.subs.fresh_unnamed_flex_var();
|
||||||
|
let custom_callback_lambda_set_var = {
|
||||||
|
let content = Content::LambdaSet(LambdaSet {
|
||||||
|
solved: UnionLambdas::insert_into_subs(
|
||||||
|
env.subs,
|
||||||
|
[(custom_closure_symbol, [state_record_var])],
|
||||||
|
),
|
||||||
|
recursion_var: OptVariable::NONE,
|
||||||
|
unspecialized: Default::default(),
|
||||||
|
ambient_function: this_custom_callback_var,
|
||||||
|
});
|
||||||
|
let custom_callback_lambda_set_var = synth_var(env.subs, content);
|
||||||
|
let subs_slice =
|
||||||
|
SubsSlice::insert_into_subs(env.subs, [bytes_arg_var, fmt_arg_var]);
|
||||||
|
|
||||||
|
env.subs.set_content(
|
||||||
|
this_custom_callback_var,
|
||||||
|
Content::Structure(FlatType::Func(
|
||||||
|
subs_slice,
|
||||||
|
custom_callback_lambda_set_var,
|
||||||
|
custom_callback_ret_var,
|
||||||
|
)),
|
||||||
|
);
|
||||||
|
|
||||||
|
custom_callback_lambda_set_var
|
||||||
|
};
|
||||||
|
|
||||||
|
// \bytes, fmt -> …
|
||||||
|
Expr::Closure(ClosureData {
|
||||||
|
function_type: this_custom_callback_var,
|
||||||
|
closure_type: custom_callback_lambda_set_var,
|
||||||
|
return_type: custom_callback_ret_var,
|
||||||
|
name: custom_closure_symbol,
|
||||||
|
captured_symbols: vec![(state_arg_symbol, state_record_var)],
|
||||||
|
recursive: Recursive::NotRecursive,
|
||||||
|
arguments: vec![
|
||||||
|
(
|
||||||
|
bytes_arg_var,
|
||||||
|
AnnotatedMark::known_exhaustive(),
|
||||||
|
Loc::at_zero(Pattern::Identifier(bytes_arg_symbol)),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
fmt_arg_var,
|
||||||
|
AnnotatedMark::known_exhaustive(),
|
||||||
|
Loc::at_zero(Pattern::Identifier(fmt_arg_symbol)),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
loc_body: Box::new(Loc::at_zero(custom_callback_body)),
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
let decode_custom_ret_var = env.subs.fresh_unnamed_flex_var();
|
||||||
|
let decode_custom = {
|
||||||
|
let decode_custom_var = env.import_builtin_symbol_var(Symbol::DECODE_CUSTOM);
|
||||||
|
let decode_custom_closure_var = env.subs.fresh_unnamed_flex_var();
|
||||||
|
let this_decode_custom_var = {
|
||||||
|
let subs_slice = SubsSlice::insert_into_subs(env.subs, [this_custom_callback_var]);
|
||||||
|
let flat_type =
|
||||||
|
FlatType::Func(subs_slice, decode_custom_closure_var, decode_custom_ret_var);
|
||||||
|
|
||||||
|
synth_var(env.subs, Content::Structure(flat_type))
|
||||||
|
};
|
||||||
|
|
||||||
|
env.unify(decode_custom_var, this_decode_custom_var);
|
||||||
|
|
||||||
|
// Decode.custom \bytes, fmt -> …
|
||||||
|
Expr::Call(
|
||||||
|
Box::new((
|
||||||
|
this_decode_custom_var,
|
||||||
|
Loc::at_zero(Expr::Var(Symbol::DECODE_CUSTOM, this_decode_custom_var)),
|
||||||
|
decode_custom_closure_var,
|
||||||
|
decode_custom_ret_var,
|
||||||
|
)),
|
||||||
|
vec![(this_custom_callback_var, Loc::at_zero(custom_callback))],
|
||||||
|
CalledVia::Space,
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
env.unify(keep_payload_var, decode_custom_ret_var);
|
||||||
|
|
||||||
|
let keep = {
|
||||||
|
// Next (Decode.custom \bytes, fmt ->
|
||||||
|
// when Decode.decodeWith bytes Decode.decoder fmt is
|
||||||
|
// rec ->
|
||||||
|
// {
|
||||||
|
// rest: rec.rest,
|
||||||
|
// result: when rec.result is
|
||||||
|
// Ok val -> Ok {state & e0: Ok val},
|
||||||
|
// Err err -> Err err
|
||||||
|
// }
|
||||||
|
// )
|
||||||
|
Expr::Tag {
|
||||||
|
tag_union_var: keep_or_skip_var,
|
||||||
|
ext_var: env.new_ext_var(ExtensionKind::TagUnion),
|
||||||
|
name: "Next".into(),
|
||||||
|
arguments: vec![(decode_custom_ret_var, Loc::at_zero(decode_custom))],
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let branch = {
|
||||||
|
// 0 ->
|
||||||
|
// Next (Decode.custom \bytes, fmt ->
|
||||||
|
// when Decode.decodeWith bytes Decode.decoder fmt is
|
||||||
|
// rec ->
|
||||||
|
// {
|
||||||
|
// rest: rec.rest,
|
||||||
|
// result: when rec.result is
|
||||||
|
// Ok val -> Ok {state & e0: Ok val},
|
||||||
|
// Err err -> Err err
|
||||||
|
// }
|
||||||
|
// )
|
||||||
|
WhenBranch {
|
||||||
|
patterns: vec![WhenBranchPattern {
|
||||||
|
pattern: Loc::at_zero(Pattern::IntLiteral(
|
||||||
|
Variable::NAT,
|
||||||
|
Variable::NATURAL,
|
||||||
|
index.to_string().into_boxed_str(),
|
||||||
|
IntValue::I128((index as i128).to_ne_bytes()),
|
||||||
|
IntBound::Exact(IntLitWidth::Nat),
|
||||||
|
)),
|
||||||
|
degenerate: false,
|
||||||
|
}],
|
||||||
|
value: Loc::at_zero(keep),
|
||||||
|
guard: None,
|
||||||
|
redundant: RedundantMark::known_non_redundant(),
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
branches.push(branch);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Example: `_ -> TooLong`
|
||||||
|
let default_branch = WhenBranch {
|
||||||
|
patterns: vec![WhenBranchPattern {
|
||||||
|
pattern: Loc::at_zero(Pattern::Underscore),
|
||||||
|
degenerate: false,
|
||||||
|
}],
|
||||||
|
value: Loc::at_zero(Expr::Tag {
|
||||||
|
tag_union_var: keep_or_skip_var,
|
||||||
|
ext_var: env.new_ext_var(ExtensionKind::TagUnion),
|
||||||
|
name: "TooLong".into(),
|
||||||
|
arguments: Vec::new(),
|
||||||
|
}),
|
||||||
|
guard: None,
|
||||||
|
redundant: RedundantMark::known_non_redundant(),
|
||||||
|
};
|
||||||
|
|
||||||
|
branches.push(default_branch);
|
||||||
|
|
||||||
|
// when index is
|
||||||
|
let body = Expr::When {
|
||||||
|
loc_cond: Box::new(Loc::at_zero(Expr::Var(index_arg_symbol, Variable::NAT))),
|
||||||
|
cond_var: Variable::NAT,
|
||||||
|
expr_var: keep_or_skip_var,
|
||||||
|
region: Region::zero(),
|
||||||
|
branches,
|
||||||
|
branches_cond_var: Variable::NAT,
|
||||||
|
exhaustive: ExhaustiveMark::known_exhaustive(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let step_elem_closure = env.new_symbol("stepElem");
|
||||||
|
let function_type = env.subs.fresh_unnamed_flex_var();
|
||||||
|
let closure_type = {
|
||||||
|
let lambda_set = LambdaSet {
|
||||||
|
solved: UnionLambdas::tag_without_arguments(env.subs, step_elem_closure),
|
||||||
|
recursion_var: OptVariable::NONE,
|
||||||
|
unspecialized: Default::default(),
|
||||||
|
ambient_function: function_type,
|
||||||
|
};
|
||||||
|
|
||||||
|
synth_var(env.subs, Content::LambdaSet(lambda_set))
|
||||||
|
};
|
||||||
|
|
||||||
|
{
|
||||||
|
let args_slice = SubsSlice::insert_into_subs(env.subs, [state_record_var, Variable::NAT]);
|
||||||
|
|
||||||
|
env.subs.set_content(
|
||||||
|
function_type,
|
||||||
|
Content::Structure(FlatType::Func(args_slice, closure_type, keep_or_skip_var)),
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
let expr = Expr::Closure(ClosureData {
|
||||||
|
function_type,
|
||||||
|
closure_type,
|
||||||
|
return_type: keep_or_skip_var,
|
||||||
|
name: step_elem_closure,
|
||||||
|
captured_symbols: Vec::new(),
|
||||||
|
recursive: Recursive::NotRecursive,
|
||||||
|
arguments: vec![
|
||||||
|
(
|
||||||
|
state_record_var,
|
||||||
|
AnnotatedMark::known_exhaustive(),
|
||||||
|
Loc::at_zero(Pattern::Identifier(state_arg_symbol)),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
Variable::NAT,
|
||||||
|
AnnotatedMark::known_exhaustive(),
|
||||||
|
Loc::at_zero(Pattern::Identifier(index_arg_symbol)),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
loc_body: Box::new(Loc::at_zero(body)),
|
||||||
|
});
|
||||||
|
|
||||||
|
(expr, function_type)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Example:
|
||||||
|
// finalizer = \rec ->
|
||||||
|
// when rec.e0 is
|
||||||
|
// Ok e0 ->
|
||||||
|
// when rec.e1 is
|
||||||
|
// Ok e1 -> Ok (e0, e1)
|
||||||
|
// Err NoElem -> Err TooShort
|
||||||
|
// Err NoElem -> Err TooShort
|
||||||
|
fn finalizer(
|
||||||
|
env: &mut Env,
|
||||||
|
index_vars: &[Variable],
|
||||||
|
state_record_var: Variable,
|
||||||
|
state_fields: &[Lowercase],
|
||||||
|
state_field_vars: &[Variable],
|
||||||
|
) -> (Expr, Variable, Variable) {
|
||||||
|
let state_arg_symbol = env.new_symbol("stateRecord");
|
||||||
|
let mut tuple_elems = Vec::with_capacity(index_vars.len());
|
||||||
|
let mut pattern_symbols = Vec::with_capacity(index_vars.len());
|
||||||
|
let decode_err_var = {
|
||||||
|
let flat_type = FlatType::TagUnion(
|
||||||
|
UnionTags::tag_without_arguments(env.subs, "TooShort".into()),
|
||||||
|
TagExt::Any(Variable::EMPTY_TAG_UNION),
|
||||||
|
);
|
||||||
|
|
||||||
|
synth_var(env.subs, Content::Structure(flat_type))
|
||||||
|
};
|
||||||
|
|
||||||
|
for (i, &index_var) in index_vars.iter().enumerate() {
|
||||||
|
let symbol = env.new_symbol(i);
|
||||||
|
|
||||||
|
pattern_symbols.push(symbol);
|
||||||
|
|
||||||
|
let index_expr = Expr::Var(symbol, index_var);
|
||||||
|
|
||||||
|
tuple_elems.push((index_var, Box::new(Loc::at_zero(index_expr))));
|
||||||
|
}
|
||||||
|
|
||||||
|
// The bottom of the happy path - return the decoded tuple (a, b) wrapped with
|
||||||
|
// "Ok".
|
||||||
|
let return_type_var;
|
||||||
|
let mut body = {
|
||||||
|
let subs = &mut env.subs;
|
||||||
|
let tuple_indices_iter = index_vars.iter().copied().enumerate();
|
||||||
|
let flat_type = FlatType::Tuple(
|
||||||
|
TupleElems::insert_into_subs(subs, tuple_indices_iter),
|
||||||
|
Variable::EMPTY_TUPLE,
|
||||||
|
);
|
||||||
|
let done_tuple_var = synth_var(subs, Content::Structure(flat_type));
|
||||||
|
let done_record = Expr::Tuple {
|
||||||
|
tuple_var: done_tuple_var,
|
||||||
|
elems: tuple_elems,
|
||||||
|
};
|
||||||
|
|
||||||
|
return_type_var = {
|
||||||
|
let flat_type = FlatType::TagUnion(
|
||||||
|
UnionTags::for_result(subs, done_tuple_var, decode_err_var),
|
||||||
|
TagExt::Any(Variable::EMPTY_TAG_UNION),
|
||||||
|
);
|
||||||
|
|
||||||
|
synth_var(subs, Content::Structure(flat_type))
|
||||||
|
};
|
||||||
|
|
||||||
|
Expr::Tag {
|
||||||
|
tag_union_var: return_type_var,
|
||||||
|
ext_var: env.new_ext_var(ExtensionKind::TagUnion),
|
||||||
|
name: "Ok".into(),
|
||||||
|
arguments: vec![(done_tuple_var, Loc::at_zero(done_record))],
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Unwrap each result in the decoded state
|
||||||
|
//
|
||||||
|
// when rec.e0 is
|
||||||
|
// Ok e0 -> ...happy path...
|
||||||
|
// Err NoElem -> Err TooShort
|
||||||
|
for (((symbol, field), &index_var), &result_index_var) in pattern_symbols
|
||||||
|
.iter()
|
||||||
|
.zip(state_fields)
|
||||||
|
.zip(index_vars)
|
||||||
|
.zip(state_field_vars)
|
||||||
|
.rev()
|
||||||
|
{
|
||||||
|
// when rec.e0 is
|
||||||
|
let cond_expr = Expr::RecordAccess {
|
||||||
|
record_var: state_record_var,
|
||||||
|
ext_var: env.new_ext_var(ExtensionKind::Record),
|
||||||
|
field_var: result_index_var,
|
||||||
|
loc_expr: Box::new(Loc::at_zero(Expr::Var(state_arg_symbol, state_record_var))),
|
||||||
|
field: field.clone(),
|
||||||
|
};
|
||||||
|
|
||||||
|
// Example: `Ok x -> expr`
|
||||||
|
let ok_branch = WhenBranch {
|
||||||
|
patterns: vec![WhenBranchPattern {
|
||||||
|
pattern: Loc::at_zero(Pattern::AppliedTag {
|
||||||
|
whole_var: result_index_var,
|
||||||
|
ext_var: Variable::EMPTY_TAG_UNION,
|
||||||
|
tag_name: "Ok".into(),
|
||||||
|
arguments: vec![(index_var, Loc::at_zero(Pattern::Identifier(*symbol)))],
|
||||||
|
}),
|
||||||
|
degenerate: false,
|
||||||
|
}],
|
||||||
|
value: Loc::at_zero(body),
|
||||||
|
guard: None,
|
||||||
|
redundant: RedundantMark::known_non_redundant(),
|
||||||
|
};
|
||||||
|
|
||||||
|
// Example: `_ -> Err TooShort`
|
||||||
|
let err_branch = WhenBranch {
|
||||||
|
patterns: vec![WhenBranchPattern {
|
||||||
|
pattern: Loc::at_zero(Pattern::Underscore),
|
||||||
|
degenerate: false,
|
||||||
|
}],
|
||||||
|
value: Loc::at_zero(Expr::Tag {
|
||||||
|
tag_union_var: return_type_var,
|
||||||
|
ext_var: env.new_ext_var(ExtensionKind::TagUnion),
|
||||||
|
name: "Err".into(),
|
||||||
|
arguments: vec![(
|
||||||
|
decode_err_var,
|
||||||
|
Loc::at_zero(Expr::Tag {
|
||||||
|
tag_union_var: decode_err_var,
|
||||||
|
ext_var: Variable::EMPTY_TAG_UNION,
|
||||||
|
name: "TooShort".into(),
|
||||||
|
arguments: Vec::new(),
|
||||||
|
}),
|
||||||
|
)],
|
||||||
|
}),
|
||||||
|
guard: None,
|
||||||
|
redundant: RedundantMark::known_non_redundant(),
|
||||||
|
};
|
||||||
|
|
||||||
|
body = Expr::When {
|
||||||
|
loc_cond: Box::new(Loc::at_zero(cond_expr)),
|
||||||
|
cond_var: result_index_var,
|
||||||
|
expr_var: return_type_var,
|
||||||
|
region: Region::zero(),
|
||||||
|
branches: vec![ok_branch, err_branch],
|
||||||
|
branches_cond_var: result_index_var,
|
||||||
|
exhaustive: ExhaustiveMark::known_exhaustive(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
let function_var = synth_var(env.subs, Content::Error); // We'll fix this up in subs later.
|
||||||
|
let function_symbol = env.new_symbol("finalizer");
|
||||||
|
let lambda_set = LambdaSet {
|
||||||
|
solved: UnionLambdas::tag_without_arguments(env.subs, function_symbol),
|
||||||
|
recursion_var: OptVariable::NONE,
|
||||||
|
unspecialized: Default::default(),
|
||||||
|
ambient_function: function_var,
|
||||||
|
};
|
||||||
|
let closure_type = synth_var(env.subs, Content::LambdaSet(lambda_set));
|
||||||
|
let flat_type = FlatType::Func(
|
||||||
|
SubsSlice::insert_into_subs(env.subs, [state_record_var]),
|
||||||
|
closure_type,
|
||||||
|
return_type_var,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Fix up function_var so it's not Content::Error anymore
|
||||||
|
env.subs
|
||||||
|
.set_content(function_var, Content::Structure(flat_type));
|
||||||
|
|
||||||
|
let finalizer = Expr::Closure(ClosureData {
|
||||||
|
function_type: function_var,
|
||||||
|
closure_type,
|
||||||
|
return_type: return_type_var,
|
||||||
|
name: function_symbol,
|
||||||
|
captured_symbols: Vec::new(),
|
||||||
|
recursive: Recursive::NotRecursive,
|
||||||
|
arguments: vec![(
|
||||||
|
state_record_var,
|
||||||
|
AnnotatedMark::known_exhaustive(),
|
||||||
|
Loc::at_zero(Pattern::Identifier(state_arg_symbol)),
|
||||||
|
)],
|
||||||
|
loc_body: Box::new(Loc::at_zero(body)),
|
||||||
|
});
|
||||||
|
|
||||||
|
(finalizer, function_var, decode_err_var)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Example:
|
||||||
|
// initialState : {e0: Result a [NoElem], e1: Result b [NoElem]}
|
||||||
|
// initialState = {e0: Err NoElem, e1: Err NoElem}
|
||||||
|
fn initial_state(
|
||||||
|
env: &mut Env<'_>,
|
||||||
|
arity: u32,
|
||||||
|
index_vars: &mut Vec<Variable>,
|
||||||
|
state_fields: &mut Vec<Lowercase>,
|
||||||
|
state_field_vars: &mut Vec<Variable>,
|
||||||
|
) -> (Variable, Expr) {
|
||||||
|
let mut initial_state_fields = SendMap::default();
|
||||||
|
|
||||||
|
for i in 0..arity {
|
||||||
|
let subs = &mut env.subs;
|
||||||
|
let index_var = subs.fresh_unnamed_flex_var();
|
||||||
|
|
||||||
|
index_vars.push(index_var);
|
||||||
|
|
||||||
|
let state_field = Lowercase::from(format!("e{i}"));
|
||||||
|
state_fields.push(state_field.clone());
|
||||||
|
|
||||||
|
let no_index_label = "NoElem";
|
||||||
|
let union_tags = UnionTags::tag_without_arguments(subs, no_index_label.into());
|
||||||
|
let no_index_var = synth_var(
|
||||||
|
subs,
|
||||||
|
Content::Structure(FlatType::TagUnion(
|
||||||
|
union_tags,
|
||||||
|
TagExt::Any(Variable::EMPTY_TAG_UNION),
|
||||||
|
)),
|
||||||
|
);
|
||||||
|
let no_index = Expr::Tag {
|
||||||
|
tag_union_var: no_index_var,
|
||||||
|
ext_var: Variable::EMPTY_TAG_UNION,
|
||||||
|
name: no_index_label.into(),
|
||||||
|
arguments: Vec::new(),
|
||||||
|
};
|
||||||
|
let err_label = "Err";
|
||||||
|
let union_tags = UnionTags::for_result(subs, index_var, no_index_var);
|
||||||
|
let result_var = synth_var(
|
||||||
|
subs,
|
||||||
|
Content::Structure(FlatType::TagUnion(
|
||||||
|
union_tags,
|
||||||
|
TagExt::Any(Variable::EMPTY_TAG_UNION),
|
||||||
|
)),
|
||||||
|
);
|
||||||
|
let index_expr = Expr::Tag {
|
||||||
|
tag_union_var: result_var,
|
||||||
|
ext_var: env.new_ext_var(ExtensionKind::TagUnion),
|
||||||
|
name: err_label.into(),
|
||||||
|
arguments: vec![(no_index_var, Loc::at_zero(no_index))],
|
||||||
|
};
|
||||||
|
state_field_vars.push(result_var);
|
||||||
|
let index = Field {
|
||||||
|
var: result_var,
|
||||||
|
region: Region::zero(),
|
||||||
|
loc_expr: Box::new(Loc::at_zero(index_expr)),
|
||||||
|
};
|
||||||
|
|
||||||
|
initial_state_fields.insert(state_field, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
let subs = &mut env.subs;
|
||||||
|
let record_index_iter = state_fields
|
||||||
|
.iter()
|
||||||
|
.zip(state_field_vars.iter())
|
||||||
|
.map(|(index_name, &var)| (index_name.clone(), RecordField::Required(var)));
|
||||||
|
let flat_type = FlatType::Record(
|
||||||
|
RecordFields::insert_into_subs(subs, record_index_iter),
|
||||||
|
Variable::EMPTY_RECORD,
|
||||||
|
);
|
||||||
|
|
||||||
|
let state_record_var = synth_var(subs, Content::Structure(flat_type));
|
||||||
|
|
||||||
|
(
|
||||||
|
state_record_var,
|
||||||
|
Expr::Record {
|
||||||
|
record_var: state_record_var,
|
||||||
|
fields: initial_state_fields,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
|
@ -14,7 +14,8 @@ use roc_module::symbol::Symbol;
|
||||||
use roc_region::all::{Loc, Region};
|
use roc_region::all::{Loc, Region};
|
||||||
use roc_types::subs::{
|
use roc_types::subs::{
|
||||||
Content, ExhaustiveMark, FlatType, GetSubsSlice, LambdaSet, OptVariable, RecordFields,
|
Content, ExhaustiveMark, FlatType, GetSubsSlice, LambdaSet, OptVariable, RecordFields,
|
||||||
RedundantMark, SubsSlice, TagExt, UnionLambdas, UnionTags, Variable, VariableSubsSlice,
|
RedundantMark, SubsSlice, TagExt, TupleElems, UnionLambdas, UnionTags, Variable,
|
||||||
|
VariableSubsSlice,
|
||||||
};
|
};
|
||||||
use roc_types::types::RecordField;
|
use roc_types::types::RecordField;
|
||||||
|
|
||||||
|
@ -50,6 +51,21 @@ pub(crate) fn derive_to_encoder(
|
||||||
|
|
||||||
to_encoder_record(env, record_var, fields, def_symbol)
|
to_encoder_record(env, record_var, fields, def_symbol)
|
||||||
}
|
}
|
||||||
|
FlatEncodableKey::Tuple(arity) => {
|
||||||
|
// Generalized tuple var so we can reuse this impl between many tuples:
|
||||||
|
// if arity = n, this is (t1, ..., tn) for fresh t1, ..., tn.
|
||||||
|
let flex_elems = (0..arity)
|
||||||
|
.into_iter()
|
||||||
|
.map(|idx| (idx as usize, env.subs.fresh_unnamed_flex_var()))
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
let elems = TupleElems::insert_into_subs(env.subs, flex_elems);
|
||||||
|
let tuple_var = synth_var(
|
||||||
|
env.subs,
|
||||||
|
Content::Structure(FlatType::Tuple(elems, Variable::EMPTY_TUPLE)),
|
||||||
|
);
|
||||||
|
|
||||||
|
to_encoder_tuple(env, tuple_var, elems, def_symbol)
|
||||||
|
}
|
||||||
FlatEncodableKey::TagUnion(tags) => {
|
FlatEncodableKey::TagUnion(tags) => {
|
||||||
// Generalized tag union var so we can reuse this impl between many unions:
|
// Generalized tag union var so we can reuse this impl between many unions:
|
||||||
// if tags = [ A arity=2, B arity=1 ], this is [ A t1 t2, B t3 ] for fresh t1, t2, t3
|
// if tags = [ A arity=2, B arity=1 ], this is [ A t1 t2, B t3 ] for fresh t1, t2, t3
|
||||||
|
@ -490,6 +506,189 @@ fn to_encoder_record(
|
||||||
(clos, fn_var)
|
(clos, fn_var)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn to_encoder_tuple(
|
||||||
|
env: &mut Env<'_>,
|
||||||
|
tuple_var: Variable,
|
||||||
|
elems: TupleElems,
|
||||||
|
fn_name: Symbol,
|
||||||
|
) -> (Expr, Variable) {
|
||||||
|
// Suppose tup = (t1, t2). Build
|
||||||
|
//
|
||||||
|
// \tup -> Encode.tuple [
|
||||||
|
// Encode.toEncoder tup.0,
|
||||||
|
// Encode.toEncoder tup.1,
|
||||||
|
// ]
|
||||||
|
|
||||||
|
let tup_sym = env.new_symbol("tup");
|
||||||
|
let whole_encoder_in_list_var = env.subs.fresh_unnamed_flex_var(); // type of the encoder in the list
|
||||||
|
|
||||||
|
use Expr::*;
|
||||||
|
|
||||||
|
let elem_encoders_list = elems
|
||||||
|
.iter_all()
|
||||||
|
.map(|(elem_index, elem_var_index)| {
|
||||||
|
let index = env.subs[elem_index];
|
||||||
|
let elem_var = env.subs[elem_var_index];
|
||||||
|
let elem_var_slice = VariableSubsSlice::new(elem_var_index.index, 1);
|
||||||
|
|
||||||
|
// tup.0
|
||||||
|
let tuple_access = TupleAccess {
|
||||||
|
tuple_var,
|
||||||
|
ext_var: env.subs.fresh_unnamed_flex_var(),
|
||||||
|
elem_var,
|
||||||
|
loc_expr: Box::new(Loc::at_zero(Var(
|
||||||
|
tup_sym,
|
||||||
|
env.subs.fresh_unnamed_flex_var(),
|
||||||
|
))),
|
||||||
|
index,
|
||||||
|
};
|
||||||
|
|
||||||
|
// build `toEncoder tup.0` type
|
||||||
|
// val -[uls]-> Encoder fmt | fmt has EncoderFormatting
|
||||||
|
let to_encoder_fn_var = env.import_builtin_symbol_var(Symbol::ENCODE_TO_ENCODER);
|
||||||
|
|
||||||
|
// (typeof tup.0) -[clos]-> t1
|
||||||
|
let to_encoder_clos_var = env.subs.fresh_unnamed_flex_var(); // clos
|
||||||
|
let encoder_var = env.subs.fresh_unnamed_flex_var(); // t1
|
||||||
|
let this_to_encoder_fn_var = synth_var(
|
||||||
|
env.subs,
|
||||||
|
Content::Structure(FlatType::Func(
|
||||||
|
elem_var_slice,
|
||||||
|
to_encoder_clos_var,
|
||||||
|
encoder_var,
|
||||||
|
)),
|
||||||
|
);
|
||||||
|
|
||||||
|
// val -[uls]-> Encoder fmt | fmt has EncoderFormatting
|
||||||
|
// ~ (typeof tup.0) -[clos]-> t1
|
||||||
|
env.unify(to_encoder_fn_var, this_to_encoder_fn_var);
|
||||||
|
|
||||||
|
// toEncoder : (typeof tup.0) -[clos]-> Encoder fmt | fmt has EncoderFormatting
|
||||||
|
let to_encoder_var = AbilityMember(Symbol::ENCODE_TO_ENCODER, None, to_encoder_fn_var);
|
||||||
|
let to_encoder_fn = Box::new((
|
||||||
|
to_encoder_fn_var,
|
||||||
|
Loc::at_zero(to_encoder_var),
|
||||||
|
to_encoder_clos_var,
|
||||||
|
encoder_var,
|
||||||
|
));
|
||||||
|
|
||||||
|
// toEncoder tup.0
|
||||||
|
let to_encoder_call = Call(
|
||||||
|
to_encoder_fn,
|
||||||
|
vec![(elem_var, Loc::at_zero(tuple_access))],
|
||||||
|
CalledVia::Space,
|
||||||
|
);
|
||||||
|
|
||||||
|
// NOTE: must be done to unify the lambda sets under `encoder_var`
|
||||||
|
env.unify(encoder_var, whole_encoder_in_list_var);
|
||||||
|
|
||||||
|
Loc::at_zero(to_encoder_call)
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
// typeof [ toEncoder tup.0, toEncoder tup.1 ]
|
||||||
|
let whole_encoder_in_list_var_slice =
|
||||||
|
VariableSubsSlice::insert_into_subs(env.subs, once(whole_encoder_in_list_var));
|
||||||
|
let elem_encoders_list_var = synth_var(
|
||||||
|
env.subs,
|
||||||
|
Content::Structure(FlatType::Apply(
|
||||||
|
Symbol::LIST_LIST,
|
||||||
|
whole_encoder_in_list_var_slice,
|
||||||
|
)),
|
||||||
|
);
|
||||||
|
|
||||||
|
// [ toEncoder tup.0, toEncoder tup.1 ]
|
||||||
|
let elem_encoders_list = List {
|
||||||
|
elem_var: whole_encoder_in_list_var,
|
||||||
|
loc_elems: elem_encoders_list,
|
||||||
|
};
|
||||||
|
|
||||||
|
// build `Encode.tuple [ toEncoder tup.0, toEncoder tup.1 ]` type
|
||||||
|
// List (Encoder fmt) -[uls]-> Encoder fmt | fmt has EncoderFormatting
|
||||||
|
let encode_tuple_fn_var = env.import_builtin_symbol_var(Symbol::ENCODE_TUPLE);
|
||||||
|
|
||||||
|
// elem_encoders_list_var -[clos]-> t1
|
||||||
|
let elem_encoders_list_var_slice =
|
||||||
|
VariableSubsSlice::insert_into_subs(env.subs, once(elem_encoders_list_var));
|
||||||
|
let encode_tuple_clos_var = env.subs.fresh_unnamed_flex_var(); // clos
|
||||||
|
let encoder_var = env.subs.fresh_unnamed_flex_var(); // t1
|
||||||
|
let this_encode_tuple_fn_var = synth_var(
|
||||||
|
env.subs,
|
||||||
|
Content::Structure(FlatType::Func(
|
||||||
|
elem_encoders_list_var_slice,
|
||||||
|
encode_tuple_clos_var,
|
||||||
|
encoder_var,
|
||||||
|
)),
|
||||||
|
);
|
||||||
|
|
||||||
|
// List (Encoder fmt) -[uls]-> Encoder fmt | fmt has EncoderFormatting
|
||||||
|
// ~ elem_encoders_list_var -[clos]-> t1
|
||||||
|
env.unify(encode_tuple_fn_var, this_encode_tuple_fn_var);
|
||||||
|
|
||||||
|
// Encode.tuple : elem_encoders_list_var -[clos]-> Encoder fmt | fmt has EncoderFormatting
|
||||||
|
let encode_tuple_var = AbilityMember(Symbol::ENCODE_TUPLE, None, encode_tuple_fn_var);
|
||||||
|
let encode_tuple_fn = Box::new((
|
||||||
|
encode_tuple_fn_var,
|
||||||
|
Loc::at_zero(encode_tuple_var),
|
||||||
|
encode_tuple_clos_var,
|
||||||
|
encoder_var,
|
||||||
|
));
|
||||||
|
|
||||||
|
// Encode.tuple [ { key: .., value: .. }, .. ]
|
||||||
|
let encode_tuple_call = Call(
|
||||||
|
encode_tuple_fn,
|
||||||
|
vec![(elem_encoders_list_var, Loc::at_zero(elem_encoders_list))],
|
||||||
|
CalledVia::Space,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Encode.custom \bytes, fmt -> Encode.appendWith bytes (Encode.tuple_var ..) fmt
|
||||||
|
let (body, this_encoder_var) =
|
||||||
|
wrap_in_encode_custom(env, encode_tuple_call, encoder_var, tup_sym, tuple_var);
|
||||||
|
|
||||||
|
// Create fn_var for ambient capture; we fix it up below.
|
||||||
|
let fn_var = synth_var(env.subs, Content::Error);
|
||||||
|
|
||||||
|
// -[fn_name]->
|
||||||
|
let fn_name_labels = UnionLambdas::insert_into_subs(env.subs, once((fn_name, vec![])));
|
||||||
|
let fn_clos_var = synth_var(
|
||||||
|
env.subs,
|
||||||
|
Content::LambdaSet(LambdaSet {
|
||||||
|
solved: fn_name_labels,
|
||||||
|
recursion_var: OptVariable::NONE,
|
||||||
|
unspecialized: SubsSlice::default(),
|
||||||
|
ambient_function: fn_var,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
// typeof tup -[fn_name]-> (typeof Encode.tuple [ .. ] = Encoder fmt)
|
||||||
|
let tuple_var_slice = SubsSlice::insert_into_subs(env.subs, once(tuple_var));
|
||||||
|
env.subs.set_content(
|
||||||
|
fn_var,
|
||||||
|
Content::Structure(FlatType::Func(
|
||||||
|
tuple_var_slice,
|
||||||
|
fn_clos_var,
|
||||||
|
this_encoder_var,
|
||||||
|
)),
|
||||||
|
);
|
||||||
|
|
||||||
|
// \tup -[fn_name]-> Encode.tuple [ { key: .., value: .. }, .. ]
|
||||||
|
let clos = Closure(ClosureData {
|
||||||
|
function_type: fn_var,
|
||||||
|
closure_type: fn_clos_var,
|
||||||
|
return_type: this_encoder_var,
|
||||||
|
name: fn_name,
|
||||||
|
captured_symbols: vec![],
|
||||||
|
recursive: Recursive::NotRecursive,
|
||||||
|
arguments: vec![(
|
||||||
|
tuple_var,
|
||||||
|
AnnotatedMark::known_exhaustive(),
|
||||||
|
Loc::at_zero(Pattern::Identifier(tup_sym)),
|
||||||
|
)],
|
||||||
|
loc_body: Box::new(Loc::at_zero(body)),
|
||||||
|
});
|
||||||
|
|
||||||
|
(clos, fn_var)
|
||||||
|
}
|
||||||
|
|
||||||
fn to_encoder_tag_union(
|
fn to_encoder_tag_union(
|
||||||
env: &mut Env<'_>,
|
env: &mut Env<'_>,
|
||||||
tag_union_var: Variable,
|
tag_union_var: Variable,
|
||||||
|
|
|
@ -19,8 +19,8 @@ use roc_types::{
|
||||||
num::int_lit_width_to_variable,
|
num::int_lit_width_to_variable,
|
||||||
subs::{
|
subs::{
|
||||||
Content, ExhaustiveMark, FlatType, GetSubsSlice, LambdaSet, OptVariable, RecordFields,
|
Content, ExhaustiveMark, FlatType, GetSubsSlice, LambdaSet, OptVariable, RecordFields,
|
||||||
RedundantMark, Subs, SubsIndex, SubsSlice, TagExt, UnionLambdas, UnionTags, Variable,
|
RedundantMark, Subs, SubsIndex, SubsSlice, TagExt, TupleElems, UnionLambdas, UnionTags,
|
||||||
VariableSubsSlice,
|
Variable, VariableSubsSlice,
|
||||||
},
|
},
|
||||||
types::RecordField,
|
types::RecordField,
|
||||||
};
|
};
|
||||||
|
@ -30,6 +30,7 @@ use crate::{synth_var, util::Env, DerivedBody};
|
||||||
pub(crate) fn derive_hash(env: &mut Env<'_>, key: FlatHashKey, def_symbol: Symbol) -> DerivedBody {
|
pub(crate) fn derive_hash(env: &mut Env<'_>, key: FlatHashKey, def_symbol: Symbol) -> DerivedBody {
|
||||||
let (body_type, body) = match key {
|
let (body_type, body) = match key {
|
||||||
FlatHashKey::Record(fields) => hash_record(env, def_symbol, fields),
|
FlatHashKey::Record(fields) => hash_record(env, def_symbol, fields),
|
||||||
|
FlatHashKey::Tuple(arity) => hash_tuple(env, def_symbol, arity),
|
||||||
FlatHashKey::TagUnion(tags) => {
|
FlatHashKey::TagUnion(tags) => {
|
||||||
if tags.len() == 1 {
|
if tags.len() == 1 {
|
||||||
hash_newtype_tag_union(env, def_symbol, tags.into_iter().next().unwrap())
|
hash_newtype_tag_union(env, def_symbol, tags.into_iter().next().unwrap())
|
||||||
|
@ -122,6 +123,76 @@ fn hash_record(env: &mut Env<'_>, fn_name: Symbol, fields: Vec<Lowercase>) -> (V
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn hash_tuple(env: &mut Env<'_>, fn_name: Symbol, arity: u32) -> (Variable, Expr) {
|
||||||
|
// Suppose tup = (v1, ..., vn).
|
||||||
|
// Build a generalized type t_tup = (t1, ..., tn), with fresh t1, ..., tn,
|
||||||
|
// so that we can re-use the derived impl for many tuples of the same arity.
|
||||||
|
let (tuple_var, tuple_elems) = {
|
||||||
|
// TODO: avoid an allocation here by pre-allocating the indices and variables `TupleElems`
|
||||||
|
// will be instantiated with.
|
||||||
|
let flex_elems: Vec<_> = (0..arity)
|
||||||
|
.into_iter()
|
||||||
|
.map(|i| (i as usize, env.subs.fresh_unnamed_flex_var()))
|
||||||
|
.collect();
|
||||||
|
let elems = TupleElems::insert_into_subs(env.subs, flex_elems);
|
||||||
|
let tuple_var = synth_var(
|
||||||
|
env.subs,
|
||||||
|
Content::Structure(FlatType::Tuple(elems, Variable::EMPTY_TUPLE)),
|
||||||
|
);
|
||||||
|
|
||||||
|
(tuple_var, elems)
|
||||||
|
};
|
||||||
|
|
||||||
|
// Now, a hasher for this tuple is
|
||||||
|
//
|
||||||
|
// hash_tup : hasher, (t1, ..., tn) -> hasher | hasher has Hasher
|
||||||
|
// hash_tup = \hasher, tup ->
|
||||||
|
// Hash.hash (
|
||||||
|
// Hash.hash
|
||||||
|
// ...
|
||||||
|
// (Hash.hash hasher tup.0)
|
||||||
|
// ...
|
||||||
|
// tup.n1)
|
||||||
|
// tup.n
|
||||||
|
//
|
||||||
|
// So, just a build a fold travelling up the elements.
|
||||||
|
let tup_sym = env.new_symbol("tup");
|
||||||
|
|
||||||
|
let hasher_sym = env.new_symbol("hasher");
|
||||||
|
let hasher_var = synth_var(env.subs, Content::FlexAbleVar(None, Subs::AB_HASHER));
|
||||||
|
|
||||||
|
let (body_var, body) = tuple_elems.iter_all().fold(
|
||||||
|
(hasher_var, Expr::Var(hasher_sym, hasher_var)),
|
||||||
|
|total_hasher, (elem_idx, elem_var)| {
|
||||||
|
let index = env.subs[elem_idx];
|
||||||
|
let elem_var = env.subs[elem_var];
|
||||||
|
|
||||||
|
let elem_access = Expr::TupleAccess {
|
||||||
|
tuple_var,
|
||||||
|
elem_var,
|
||||||
|
ext_var: env.subs.fresh_unnamed_flex_var(),
|
||||||
|
loc_expr: Box::new(Loc::at_zero(Expr::Var(
|
||||||
|
tup_sym,
|
||||||
|
env.subs.fresh_unnamed_flex_var(),
|
||||||
|
))),
|
||||||
|
index,
|
||||||
|
};
|
||||||
|
|
||||||
|
call_hash_hash(env, total_hasher, (elem_var, elem_access))
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
// Finally, build the closure
|
||||||
|
// \hasher, rcd -> body
|
||||||
|
build_outer_derived_closure(
|
||||||
|
env,
|
||||||
|
fn_name,
|
||||||
|
(hasher_var, hasher_sym),
|
||||||
|
(tuple_var, Pattern::Identifier(tup_sym)),
|
||||||
|
(body_var, body),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
/// Build a `hash` implementation for a non-singleton tag union.
|
/// Build a `hash` implementation for a non-singleton tag union.
|
||||||
fn hash_tag_union(
|
fn hash_tag_union(
|
||||||
env: &mut Env<'_>,
|
env: &mut Env<'_>,
|
||||||
|
|
|
@ -18,19 +18,20 @@ pub(crate) struct Env<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Env<'_> {
|
impl Env<'_> {
|
||||||
pub fn new_symbol(&mut self, name_hint: &str) -> Symbol {
|
pub fn new_symbol(&mut self, name_hint: impl std::string::ToString) -> Symbol {
|
||||||
if cfg!(any(
|
if cfg!(any(
|
||||||
debug_assertions,
|
debug_assertions,
|
||||||
test,
|
test,
|
||||||
feature = "debug-derived-symbols"
|
feature = "debug-derived-symbols"
|
||||||
)) {
|
)) {
|
||||||
let mut i = 0;
|
let mut i = 0;
|
||||||
|
let hint = name_hint.to_string();
|
||||||
let debug_name = loop {
|
let debug_name = loop {
|
||||||
i += 1;
|
i += 1;
|
||||||
let name = if i == 1 {
|
let name = if i == 1 {
|
||||||
name_hint.to_owned()
|
hint.clone()
|
||||||
} else {
|
} else {
|
||||||
format!("{}{}", name_hint, i)
|
format!("{}{}", hint, i)
|
||||||
};
|
};
|
||||||
if self.derived_ident_ids.get_id(&name).is_none() {
|
if self.derived_ident_ids.get_id(&name).is_none() {
|
||||||
break name;
|
break name;
|
||||||
|
|
|
@ -2,7 +2,7 @@ use roc_module::{ident::Lowercase, symbol::Symbol};
|
||||||
use roc_types::subs::{Content, FlatType, Subs, Variable};
|
use roc_types::subs::{Content, FlatType, Subs, Variable};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
util::{check_derivable_ext_var, debug_name_record},
|
util::{check_derivable_ext_var, debug_name_record, debug_name_tuple},
|
||||||
DeriveError,
|
DeriveError,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -18,6 +18,7 @@ pub enum FlatDecodableKey {
|
||||||
|
|
||||||
// Unfortunate that we must allocate here, c'est la vie
|
// Unfortunate that we must allocate here, c'est la vie
|
||||||
Record(Vec<Lowercase>),
|
Record(Vec<Lowercase>),
|
||||||
|
Tuple(u32),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FlatDecodableKey {
|
impl FlatDecodableKey {
|
||||||
|
@ -25,6 +26,7 @@ impl FlatDecodableKey {
|
||||||
match self {
|
match self {
|
||||||
FlatDecodableKey::List() => "list".to_string(),
|
FlatDecodableKey::List() => "list".to_string(),
|
||||||
FlatDecodableKey::Record(fields) => debug_name_record(fields),
|
FlatDecodableKey::Record(fields) => debug_name_record(fields),
|
||||||
|
FlatDecodableKey::Tuple(arity) => debug_name_tuple(*arity),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -61,8 +63,14 @@ impl FlatDecodable {
|
||||||
|
|
||||||
Ok(Key(FlatDecodableKey::Record(field_names)))
|
Ok(Key(FlatDecodableKey::Record(field_names)))
|
||||||
}
|
}
|
||||||
FlatType::Tuple(_elems, _ext) => {
|
FlatType::Tuple(elems, ext) => {
|
||||||
todo!()
|
let (elems_iter, ext) = elems.sorted_iterator_and_ext(subs, ext);
|
||||||
|
|
||||||
|
check_derivable_ext_var(subs, ext, |ext| {
|
||||||
|
matches!(ext, Content::Structure(FlatType::EmptyTuple))
|
||||||
|
})?;
|
||||||
|
|
||||||
|
Ok(Key(FlatDecodableKey::Tuple(elems_iter.count() as _)))
|
||||||
}
|
}
|
||||||
FlatType::TagUnion(_tags, _ext) | FlatType::RecursiveTagUnion(_, _tags, _ext) => {
|
FlatType::TagUnion(_tags, _ext) | FlatType::RecursiveTagUnion(_, _tags, _ext) => {
|
||||||
Err(Underivable) // yet
|
Err(Underivable) // yet
|
||||||
|
|
|
@ -5,7 +5,7 @@ use roc_module::{
|
||||||
use roc_types::subs::{Content, FlatType, GetSubsSlice, Subs, Variable};
|
use roc_types::subs::{Content, FlatType, GetSubsSlice, Subs, Variable};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
util::{check_derivable_ext_var, debug_name_record, debug_name_tag},
|
util::{check_derivable_ext_var, debug_name_record, debug_name_tag, debug_name_tuple},
|
||||||
DeriveError,
|
DeriveError,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -22,6 +22,7 @@ pub enum FlatEncodableKey {
|
||||||
Dict(/* takes two variables */),
|
Dict(/* takes two variables */),
|
||||||
// Unfortunate that we must allocate here, c'est la vie
|
// Unfortunate that we must allocate here, c'est la vie
|
||||||
Record(Vec<Lowercase>),
|
Record(Vec<Lowercase>),
|
||||||
|
Tuple(u32),
|
||||||
TagUnion(Vec<(TagName, u16)>),
|
TagUnion(Vec<(TagName, u16)>),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,6 +33,7 @@ impl FlatEncodableKey {
|
||||||
FlatEncodableKey::Set() => "set".to_string(),
|
FlatEncodableKey::Set() => "set".to_string(),
|
||||||
FlatEncodableKey::Dict() => "dict".to_string(),
|
FlatEncodableKey::Dict() => "dict".to_string(),
|
||||||
FlatEncodableKey::Record(fields) => debug_name_record(fields),
|
FlatEncodableKey::Record(fields) => debug_name_record(fields),
|
||||||
|
FlatEncodableKey::Tuple(arity) => debug_name_tuple(*arity),
|
||||||
FlatEncodableKey::TagUnion(tags) => debug_name_tag(tags),
|
FlatEncodableKey::TagUnion(tags) => debug_name_tag(tags),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -66,8 +68,14 @@ impl FlatEncodable {
|
||||||
|
|
||||||
Ok(Key(FlatEncodableKey::Record(field_names)))
|
Ok(Key(FlatEncodableKey::Record(field_names)))
|
||||||
}
|
}
|
||||||
FlatType::Tuple(_elems, _ext) => {
|
FlatType::Tuple(elems, ext) => {
|
||||||
todo!()
|
let (elems_iter, ext) = elems.sorted_iterator_and_ext(subs, ext);
|
||||||
|
|
||||||
|
check_derivable_ext_var(subs, ext, |ext| {
|
||||||
|
matches!(ext, Content::Structure(FlatType::EmptyTuple))
|
||||||
|
})?;
|
||||||
|
|
||||||
|
Ok(Key(FlatEncodableKey::Tuple(elems_iter.count() as _)))
|
||||||
}
|
}
|
||||||
FlatType::TagUnion(tags, ext) | FlatType::RecursiveTagUnion(_, tags, ext) => {
|
FlatType::TagUnion(tags, ext) | FlatType::RecursiveTagUnion(_, tags, ext) => {
|
||||||
// The recursion var doesn't matter, because the derived implementation will only
|
// The recursion var doesn't matter, because the derived implementation will only
|
||||||
|
|
|
@ -5,7 +5,7 @@ use roc_module::{
|
||||||
use roc_types::subs::{Content, FlatType, GetSubsSlice, Subs, Variable};
|
use roc_types::subs::{Content, FlatType, GetSubsSlice, Subs, Variable};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
util::{check_derivable_ext_var, debug_name_record, debug_name_tag},
|
util::{check_derivable_ext_var, debug_name_record, debug_name_tag, debug_name_tuple},
|
||||||
DeriveError,
|
DeriveError,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -21,6 +21,7 @@ pub enum FlatHash {
|
||||||
pub enum FlatHashKey {
|
pub enum FlatHashKey {
|
||||||
// Unfortunate that we must allocate here, c'est la vie
|
// Unfortunate that we must allocate here, c'est la vie
|
||||||
Record(Vec<Lowercase>),
|
Record(Vec<Lowercase>),
|
||||||
|
Tuple(u32),
|
||||||
TagUnion(Vec<(TagName, u16)>),
|
TagUnion(Vec<(TagName, u16)>),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,6 +29,7 @@ impl FlatHashKey {
|
||||||
pub(crate) fn debug_name(&self) -> String {
|
pub(crate) fn debug_name(&self) -> String {
|
||||||
match self {
|
match self {
|
||||||
FlatHashKey::Record(fields) => debug_name_record(fields),
|
FlatHashKey::Record(fields) => debug_name_record(fields),
|
||||||
|
FlatHashKey::Tuple(arity) => debug_name_tuple(*arity),
|
||||||
FlatHashKey::TagUnion(tags) => debug_name_tag(tags),
|
FlatHashKey::TagUnion(tags) => debug_name_tag(tags),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -65,8 +67,14 @@ impl FlatHash {
|
||||||
|
|
||||||
Ok(Key(FlatHashKey::Record(field_names)))
|
Ok(Key(FlatHashKey::Record(field_names)))
|
||||||
}
|
}
|
||||||
FlatType::Tuple(_elems, _ext) => {
|
FlatType::Tuple(elems, ext) => {
|
||||||
todo!();
|
let (elems_iter, ext) = elems.sorted_iterator_and_ext(subs, ext);
|
||||||
|
|
||||||
|
check_derivable_ext_var(subs, ext, |ext| {
|
||||||
|
matches!(ext, Content::Structure(FlatType::EmptyTuple))
|
||||||
|
})?;
|
||||||
|
|
||||||
|
Ok(Key(FlatHashKey::Tuple(elems_iter.count() as _)))
|
||||||
}
|
}
|
||||||
FlatType::TagUnion(tags, ext) | FlatType::RecursiveTagUnion(_, tags, ext) => {
|
FlatType::TagUnion(tags, ext) | FlatType::RecursiveTagUnion(_, tags, ext) => {
|
||||||
// The recursion var doesn't matter, because the derived implementation will only
|
// The recursion var doesn't matter, because the derived implementation will only
|
||||||
|
|
|
@ -43,6 +43,10 @@ pub(crate) fn debug_name_record(fields: &[Lowercase]) -> String {
|
||||||
str
|
str
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn debug_name_tuple(arity: u32) -> String {
|
||||||
|
format!("(arity:{arity})")
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn debug_name_tag(tags: &[(TagName, u16)]) -> String {
|
pub(crate) fn debug_name_tag(tags: &[(TagName, u16)]) -> String {
|
||||||
let mut str = String::from('[');
|
let mut str = String::from('[');
|
||||||
tags.iter().enumerate().for_each(|(i, (tag, arity))| {
|
tags.iter().enumerate().for_each(|(i, (tag, arity))| {
|
||||||
|
|
|
@ -1500,11 +1500,12 @@ define_builtins! {
|
||||||
18 ENCODE_STRING: "string"
|
18 ENCODE_STRING: "string"
|
||||||
19 ENCODE_LIST: "list"
|
19 ENCODE_LIST: "list"
|
||||||
20 ENCODE_RECORD: "record"
|
20 ENCODE_RECORD: "record"
|
||||||
21 ENCODE_TAG: "tag"
|
21 ENCODE_TUPLE: "tuple"
|
||||||
22 ENCODE_CUSTOM: "custom"
|
22 ENCODE_TAG: "tag"
|
||||||
23 ENCODE_APPEND_WITH: "appendWith"
|
23 ENCODE_CUSTOM: "custom"
|
||||||
24 ENCODE_APPEND: "append"
|
24 ENCODE_APPEND_WITH: "appendWith"
|
||||||
25 ENCODE_TO_BYTES: "toBytes"
|
25 ENCODE_APPEND: "append"
|
||||||
|
26 ENCODE_TO_BYTES: "toBytes"
|
||||||
}
|
}
|
||||||
12 DECODE: "Decode" => {
|
12 DECODE: "Decode" => {
|
||||||
0 DECODE_DECODE_ERROR: "DecodeError" exposed_type=true
|
0 DECODE_DECODE_ERROR: "DecodeError" exposed_type=true
|
||||||
|
@ -1530,11 +1531,12 @@ define_builtins! {
|
||||||
20 DECODE_STRING: "string"
|
20 DECODE_STRING: "string"
|
||||||
21 DECODE_LIST: "list"
|
21 DECODE_LIST: "list"
|
||||||
22 DECODE_RECORD: "record"
|
22 DECODE_RECORD: "record"
|
||||||
23 DECODE_CUSTOM: "custom"
|
23 DECODE_TUPLE: "tuple"
|
||||||
24 DECODE_DECODE_WITH: "decodeWith"
|
24 DECODE_CUSTOM: "custom"
|
||||||
25 DECODE_FROM_BYTES_PARTIAL: "fromBytesPartial"
|
25 DECODE_DECODE_WITH: "decodeWith"
|
||||||
26 DECODE_FROM_BYTES: "fromBytes"
|
26 DECODE_FROM_BYTES_PARTIAL: "fromBytesPartial"
|
||||||
27 DECODE_MAP_RESULT: "mapResult"
|
27 DECODE_FROM_BYTES: "fromBytes"
|
||||||
|
28 DECODE_MAP_RESULT: "mapResult"
|
||||||
}
|
}
|
||||||
13 HASH: "Hash" => {
|
13 HASH: "Hash" => {
|
||||||
0 HASH_HASH_ABILITY: "Hash" exposed_type=true
|
0 HASH_HASH_ABILITY: "Hash" exposed_type=true
|
||||||
|
|
|
@ -881,6 +881,15 @@ impl DerivableVisitor for DeriveEncoding {
|
||||||
Ok(Descend(true))
|
Ok(Descend(true))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
fn visit_tuple(
|
||||||
|
_subs: &Subs,
|
||||||
|
_var: Variable,
|
||||||
|
_elems: TupleElems,
|
||||||
|
) -> Result<Descend, NotDerivable> {
|
||||||
|
Ok(Descend(true))
|
||||||
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn visit_tag_union(_var: Variable) -> Result<Descend, NotDerivable> {
|
fn visit_tag_union(_var: Variable) -> Result<Descend, NotDerivable> {
|
||||||
Ok(Descend(true))
|
Ok(Descend(true))
|
||||||
|
@ -988,6 +997,15 @@ impl DerivableVisitor for DeriveDecoding {
|
||||||
Ok(Descend(true))
|
Ok(Descend(true))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
fn visit_tuple(
|
||||||
|
_subs: &Subs,
|
||||||
|
_var: Variable,
|
||||||
|
_elems: TupleElems,
|
||||||
|
) -> Result<Descend, NotDerivable> {
|
||||||
|
Ok(Descend(true))
|
||||||
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn visit_tag_union(_var: Variable) -> Result<Descend, NotDerivable> {
|
fn visit_tag_union(_var: Variable) -> Result<Descend, NotDerivable> {
|
||||||
Ok(Descend(true))
|
Ok(Descend(true))
|
||||||
|
@ -1094,6 +1112,15 @@ impl DerivableVisitor for DeriveHash {
|
||||||
Ok(Descend(true))
|
Ok(Descend(true))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
fn visit_tuple(
|
||||||
|
_subs: &Subs,
|
||||||
|
_var: Variable,
|
||||||
|
_elems: TupleElems,
|
||||||
|
) -> Result<Descend, NotDerivable> {
|
||||||
|
Ok(Descend(true))
|
||||||
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn visit_tag_union(_var: Variable) -> Result<Descend, NotDerivable> {
|
fn visit_tag_union(_var: Variable) -> Result<Descend, NotDerivable> {
|
||||||
Ok(Descend(true))
|
Ok(Descend(true))
|
||||||
|
@ -1200,6 +1227,15 @@ impl DerivableVisitor for DeriveEq {
|
||||||
Ok(Descend(true))
|
Ok(Descend(true))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
fn visit_tuple(
|
||||||
|
_subs: &Subs,
|
||||||
|
_var: Variable,
|
||||||
|
_elems: TupleElems,
|
||||||
|
) -> Result<Descend, NotDerivable> {
|
||||||
|
Ok(Descend(true))
|
||||||
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn visit_tag_union(_var: Variable) -> Result<Descend, NotDerivable> {
|
fn visit_tag_union(_var: Variable) -> Result<Descend, NotDerivable> {
|
||||||
Ok(Descend(true))
|
Ok(Descend(true))
|
||||||
|
|
|
@ -748,7 +748,7 @@ fn get_specialization_lambda_set_ambient_function<P: Phase>(
|
||||||
let specialized_lambda_set = *specialization
|
let specialized_lambda_set = *specialization
|
||||||
.specialization_lambda_sets
|
.specialization_lambda_sets
|
||||||
.get(&lset_region)
|
.get(&lset_region)
|
||||||
.expect("lambda set region not resolved");
|
.unwrap_or_else(|| panic!("lambda set region not resolved: {:?}", (spec_symbol, specialization)));
|
||||||
Ok(specialized_lambda_set)
|
Ok(specialized_lambda_set)
|
||||||
}
|
}
|
||||||
MemberImpl::Error => todo_abilities!(),
|
MemberImpl::Error => todo_abilities!(),
|
||||||
|
|
|
@ -28,6 +28,11 @@ test_key_eq! {
|
||||||
explicit_empty_record_and_implicit_empty_record:
|
explicit_empty_record_and_implicit_empty_record:
|
||||||
v!(EMPTY_RECORD), v!({})
|
v!(EMPTY_RECORD), v!({})
|
||||||
|
|
||||||
|
same_tuple:
|
||||||
|
v!((v!(U8), v!(U16),)), v!((v!(U8), v!(U16),))
|
||||||
|
same_tuple_fields_diff_types:
|
||||||
|
v!((v!(U8), v!(U16),)), v!((v!(U32), v!(U64),))
|
||||||
|
|
||||||
list_list_diff_types:
|
list_list_diff_types:
|
||||||
v!(Symbol::LIST_LIST v!(STR)), v!(Symbol::LIST_LIST v!(U8))
|
v!(Symbol::LIST_LIST v!(STR)), v!(Symbol::LIST_LIST v!(U8))
|
||||||
str_str:
|
str_str:
|
||||||
|
@ -41,6 +46,9 @@ test_key_neq! {
|
||||||
v!({ a: v!(U8), }), v!({ b: v!(U8), })
|
v!({ a: v!(U8), }), v!({ b: v!(U8), })
|
||||||
record_empty_vs_nonempty:
|
record_empty_vs_nonempty:
|
||||||
v!(EMPTY_RECORD), v!({ a: v!(U8), })
|
v!(EMPTY_RECORD), v!({ a: v!(U8), })
|
||||||
|
|
||||||
|
different_tuple_arities:
|
||||||
|
v!((v!(U8), v!(U16),)), v!((v!(U8), v!(U16), v!(U32),))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -167,3 +175,59 @@ fn record_2_fields() {
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn tuple_2_fields() {
|
||||||
|
derive_test(Decoder, v!((v!(STR), v!(U8),)), |golden| {
|
||||||
|
assert_snapshot!(golden, @r###"
|
||||||
|
# derived for ( Str, U8 )*
|
||||||
|
# Decoder ( val, val1 )* fmt | fmt has DecoderFormatting, val has Decoding, val1 has Decoding
|
||||||
|
# List U8, fmt -[[custom(22)]]-> { rest : List U8, result : [Err [TooShort], Ok ( val, val1 )a] } | fmt has DecoderFormatting, val has Decoding, val1 has Decoding
|
||||||
|
# Specialization lambda sets:
|
||||||
|
# @<1>: [[custom(22)]]
|
||||||
|
#Derived.decoder_(arity:2) =
|
||||||
|
custom
|
||||||
|
\#Derived.bytes3, #Derived.fmt3 ->
|
||||||
|
decodeWith
|
||||||
|
#Derived.bytes3
|
||||||
|
(tuple
|
||||||
|
{ e1: Err NoElem, e0: Err NoElem }
|
||||||
|
\#Derived.stateRecord2, #Derived.index ->
|
||||||
|
when #Derived.index is
|
||||||
|
0 ->
|
||||||
|
Next (custom
|
||||||
|
\#Derived.bytes, #Derived.fmt ->
|
||||||
|
when decodeWith #Derived.bytes decoder #Derived.fmt is
|
||||||
|
#Derived.rec ->
|
||||||
|
{
|
||||||
|
result: when #Derived.rec.result is
|
||||||
|
Ok #Derived.val ->
|
||||||
|
Ok { stateRecord2 & e0: Ok #Derived.val }
|
||||||
|
Err #Derived.err -> Err #Derived.err,
|
||||||
|
rest: #Derived.rec.rest
|
||||||
|
})
|
||||||
|
1 ->
|
||||||
|
Next (custom
|
||||||
|
\#Derived.bytes2, #Derived.fmt2 ->
|
||||||
|
when decodeWith #Derived.bytes2 decoder #Derived.fmt2 is
|
||||||
|
#Derived.rec2 ->
|
||||||
|
{
|
||||||
|
result: when #Derived.rec2.result is
|
||||||
|
Ok #Derived.val2 ->
|
||||||
|
Ok { stateRecord2 & e1: Ok #Derived.val2 }
|
||||||
|
Err #Derived.err2 -> Err #Derived.err2,
|
||||||
|
rest: #Derived.rec2.rest
|
||||||
|
})
|
||||||
|
_ -> TooLong
|
||||||
|
\#Derived.stateRecord ->
|
||||||
|
when #Derived.stateRecord.e0 is
|
||||||
|
Ok #Derived.0 ->
|
||||||
|
when #Derived.stateRecord.e1 is
|
||||||
|
Ok #Derived.1 -> Ok ( #Derived.0, #Derived.1 )
|
||||||
|
_ -> Err TooShort
|
||||||
|
_ -> Err TooShort)
|
||||||
|
#Derived.fmt3
|
||||||
|
"###
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
|
@ -33,6 +33,11 @@ test_key_eq! {
|
||||||
v!({ a: v!(U8), b: v!(U8), }),
|
v!({ a: v!(U8), b: v!(U8), }),
|
||||||
v!({ ?a: v!(U8), ?b: v!(U8), })
|
v!({ ?a: v!(U8), ?b: v!(U8), })
|
||||||
|
|
||||||
|
same_tuple:
|
||||||
|
v!((v!(U8), v!(U16),)), v!((v!(U8), v!(U16),))
|
||||||
|
same_tuple_fields_diff_types:
|
||||||
|
v!((v!(U8), v!(U16),)), v!((v!(U32), v!(U64),))
|
||||||
|
|
||||||
same_tag_union:
|
same_tag_union:
|
||||||
v!([ A v!(U8) v!(STR), B v!(STR) ]), v!([ A v!(U8) v!(STR), B v!(STR) ])
|
v!([ A v!(U8) v!(STR), B v!(STR) ]), v!([ A v!(U8) v!(STR), B v!(STR) ])
|
||||||
same_tag_union_tags_diff_types:
|
same_tag_union_tags_diff_types:
|
||||||
|
@ -78,6 +83,9 @@ test_key_neq! {
|
||||||
record_empty_vs_nonempty:
|
record_empty_vs_nonempty:
|
||||||
v!(EMPTY_RECORD), v!({ a: v!(U8), })
|
v!(EMPTY_RECORD), v!({ a: v!(U8), })
|
||||||
|
|
||||||
|
different_tuple_arities:
|
||||||
|
v!((v!(U8), v!(U16),)), v!((v!(U8), v!(U16), v!(U32),))
|
||||||
|
|
||||||
different_tag_union_tags:
|
different_tag_union_tags:
|
||||||
v!([ A v!(U8) ]), v!([ B v!(U8) ])
|
v!([ A v!(U8) ]), v!([ B v!(U8) ])
|
||||||
tag_union_empty_vs_nonempty:
|
tag_union_empty_vs_nonempty:
|
||||||
|
@ -265,6 +273,29 @@ fn two_field_record() {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn two_field_tuple() {
|
||||||
|
derive_test(ToEncoder, v!((v!(U8), v!(STR),)), |golden| {
|
||||||
|
assert_snapshot!(golden, @r###"
|
||||||
|
# derived for ( U8, Str )*
|
||||||
|
# ( val, val1 )* -[[toEncoder_(arity:2)(0)]]-> Encoder fmt | fmt has EncoderFormatting, val has Encoding, val1 has Encoding
|
||||||
|
# ( val, val1 )a -[[toEncoder_(arity:2)(0)]]-> (List U8, fmt -[[custom(2) ( val, val1 )a]]-> List U8) | fmt has EncoderFormatting, val has Encoding, val1 has Encoding
|
||||||
|
# Specialization lambda sets:
|
||||||
|
# @<1>: [[toEncoder_(arity:2)(0)]]
|
||||||
|
# @<2>: [[custom(2) ( val, val1 )*]] | val has Encoding, val1 has Encoding
|
||||||
|
#Derived.toEncoder_(arity:2) =
|
||||||
|
\#Derived.tup ->
|
||||||
|
custom
|
||||||
|
\#Derived.bytes, #Derived.fmt ->
|
||||||
|
appendWith
|
||||||
|
#Derived.bytes
|
||||||
|
(tuple [toEncoder #Derived.tup.0, toEncoder #Derived.tup.1])
|
||||||
|
#Derived.fmt
|
||||||
|
"###
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[ignore = "NOTE: this would never actually happen, because [] is uninhabited, and hence toEncoder can never be called with a value of []!
|
#[ignore = "NOTE: this would never actually happen, because [] is uninhabited, and hence toEncoder can never be called with a value of []!
|
||||||
Rightfully it induces broken assertions in other parts of the compiler, so we ignore it."]
|
Rightfully it induces broken assertions in other parts of the compiler, so we ignore it."]
|
||||||
|
|
|
@ -28,6 +28,11 @@ test_key_eq! {
|
||||||
explicit_empty_record_and_implicit_empty_record:
|
explicit_empty_record_and_implicit_empty_record:
|
||||||
v!(EMPTY_RECORD), v!({})
|
v!(EMPTY_RECORD), v!({})
|
||||||
|
|
||||||
|
same_tuple:
|
||||||
|
v!((v!(U8), v!(U16),)), v!((v!(U8), v!(U16),))
|
||||||
|
same_tuple_fields_diff_types:
|
||||||
|
v!((v!(U8), v!(U16),)), v!((v!(U32), v!(U64),))
|
||||||
|
|
||||||
same_tag_union:
|
same_tag_union:
|
||||||
v!([ A v!(U8) v!(STR), B v!(STR) ]), v!([ A v!(U8) v!(STR), B v!(STR) ])
|
v!([ A v!(U8) v!(STR), B v!(STR) ]), v!([ A v!(U8) v!(STR), B v!(STR) ])
|
||||||
same_tag_union_tags_diff_types:
|
same_tag_union_tags_diff_types:
|
||||||
|
@ -51,6 +56,9 @@ test_key_neq! {
|
||||||
record_empty_vs_nonempty:
|
record_empty_vs_nonempty:
|
||||||
v!(EMPTY_RECORD), v!({ a: v!(U8), })
|
v!(EMPTY_RECORD), v!({ a: v!(U8), })
|
||||||
|
|
||||||
|
different_tuple_arities:
|
||||||
|
v!((v!(U8), v!(U16),)), v!((v!(U8), v!(U16), v!(U32),))
|
||||||
|
|
||||||
different_tag_union_tags:
|
different_tag_union_tags:
|
||||||
v!([ A v!(U8) ]), v!([ B v!(U8) ])
|
v!([ A v!(U8) ]), v!([ B v!(U8) ])
|
||||||
tag_union_empty_vs_nonempty:
|
tag_union_empty_vs_nonempty:
|
||||||
|
@ -201,6 +209,23 @@ fn two_field_record() {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn two_element_tuple() {
|
||||||
|
derive_test(Hash, v!((v!(U8), v!(STR),)), |golden| {
|
||||||
|
assert_snapshot!(golden, @r###"
|
||||||
|
# derived for ( U8, Str )*
|
||||||
|
# hasher, ( a, a1 )* -[[hash_(arity:2)(0)]]-> hasher | a has Hash, a1 has Hash, hasher has Hasher
|
||||||
|
# hasher, ( a, a1 )* -[[hash_(arity:2)(0)]]-> hasher | a has Hash, a1 has Hash, hasher has Hasher
|
||||||
|
# Specialization lambda sets:
|
||||||
|
# @<1>: [[hash_(arity:2)(0)]]
|
||||||
|
#Derived.hash_(arity:2) =
|
||||||
|
\#Derived.hasher, #Derived.tup ->
|
||||||
|
hash (hash #Derived.hasher #Derived.tup.0) #Derived.tup.1
|
||||||
|
"###
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn tag_one_label_no_payloads() {
|
fn tag_one_label_no_payloads() {
|
||||||
derive_test(Hash, v!([A]), |golden| {
|
derive_test(Hash, v!([A]), |golden| {
|
||||||
|
|
|
@ -89,6 +89,22 @@ macro_rules! v {
|
||||||
roc_derive::synth_var(subs, Content::Structure(FlatType::Record(fields, ext)))
|
roc_derive::synth_var(subs, Content::Structure(FlatType::Record(fields, ext)))
|
||||||
}
|
}
|
||||||
}};
|
}};
|
||||||
|
(( $($make_v:expr,)* )$( $($ext:tt)+ )?) => {{
|
||||||
|
#[allow(unused)]
|
||||||
|
use roc_types::subs::{Subs, RecordFields, Content, FlatType, Variable, TupleElems};
|
||||||
|
|subs: &mut Subs| {
|
||||||
|
let elems = [
|
||||||
|
$($make_v(subs),)*
|
||||||
|
].into_iter().enumerate();
|
||||||
|
let elems = TupleElems::insert_into_subs(subs, elems);
|
||||||
|
|
||||||
|
#[allow(unused_mut, unused)]
|
||||||
|
let mut ext = Variable::EMPTY_TUPLE;
|
||||||
|
$( ext = $crate::v!($($ext)+)(subs); )?
|
||||||
|
|
||||||
|
roc_derive::synth_var(subs, Content::Structure(FlatType::Tuple(elems, ext)))
|
||||||
|
}
|
||||||
|
}};
|
||||||
([ $($tag:ident $($payload:expr)*),* ] as $rec_var:ident) => {{
|
([ $($tag:ident $($payload:expr)*),* ] as $rec_var:ident) => {{
|
||||||
use roc_types::subs::{Subs, SubsIndex, Variable, Content, FlatType, TagExt, UnionTags};
|
use roc_types::subs::{Subs, SubsIndex, Variable, Content, FlatType, TagExt, UnionTags};
|
||||||
use roc_module::ident::TagName;
|
use roc_module::ident::TagName;
|
||||||
|
|
|
@ -825,6 +825,52 @@ fn encode_derived_record_with_many_types() {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))]
|
||||||
|
fn encode_derived_tuple_two_fields() {
|
||||||
|
assert_evals_to!(
|
||||||
|
indoc!(
|
||||||
|
r#"
|
||||||
|
app "test"
|
||||||
|
imports [Encode, Json]
|
||||||
|
provides [main] to "./platform"
|
||||||
|
|
||||||
|
main =
|
||||||
|
tup = ("foo", 10u8)
|
||||||
|
result = Str.fromUtf8 (Encode.toBytes tup Json.toUtf8)
|
||||||
|
when result is
|
||||||
|
Ok s -> s
|
||||||
|
_ -> "<bad>"
|
||||||
|
"#
|
||||||
|
),
|
||||||
|
RocStr::from(r#"["foo",10]"#),
|
||||||
|
RocStr
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))]
|
||||||
|
fn encode_derived_tuple_of_tuples() {
|
||||||
|
assert_evals_to!(
|
||||||
|
indoc!(
|
||||||
|
r#"
|
||||||
|
app "test"
|
||||||
|
imports [Encode, Json]
|
||||||
|
provides [main] to "./platform"
|
||||||
|
|
||||||
|
main =
|
||||||
|
tup = ( ("foo", 10u8), (23u8, "bar", 15u8) )
|
||||||
|
result = Str.fromUtf8 (Encode.toBytes tup Json.toUtf8)
|
||||||
|
when result is
|
||||||
|
Ok s -> s
|
||||||
|
_ -> "<bad>"
|
||||||
|
"#
|
||||||
|
),
|
||||||
|
RocStr::from(r#"[["foo",10],[23,"bar",15]]"#),
|
||||||
|
RocStr
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg(all(any(feature = "gen-llvm", feature = "gen-wasm")))]
|
#[cfg(all(any(feature = "gen-llvm", feature = "gen-wasm")))]
|
||||||
fn encode_derived_generic_record_with_different_field_types() {
|
fn encode_derived_generic_record_with_different_field_types() {
|
||||||
|
@ -1312,6 +1358,50 @@ fn decode_record_of_record() {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[cfg(all(
|
||||||
|
any(feature = "gen-llvm", feature = "gen-wasm"),
|
||||||
|
not(debug_assertions) // https://github.com/roc-lang/roc/issues/3898
|
||||||
|
))]
|
||||||
|
fn decode_tuple_two_elements() {
|
||||||
|
assert_evals_to!(
|
||||||
|
indoc!(
|
||||||
|
r#"
|
||||||
|
app "test" imports [Json] provides [main] to "./platform"
|
||||||
|
|
||||||
|
main =
|
||||||
|
when Str.toUtf8 "[\"ab\",10]" |> Decode.fromBytes Json.fromUtf8 is
|
||||||
|
Ok ("ab", 10u8) -> "abcd"
|
||||||
|
_ -> "something went wrong"
|
||||||
|
"#
|
||||||
|
),
|
||||||
|
RocStr::from("abcd"),
|
||||||
|
RocStr
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[cfg(all(
|
||||||
|
any(feature = "gen-llvm", feature = "gen-wasm"),
|
||||||
|
not(debug_assertions) // https://github.com/roc-lang/roc/issues/3898
|
||||||
|
))]
|
||||||
|
fn decode_tuple_of_tuples() {
|
||||||
|
assert_evals_to!(
|
||||||
|
indoc!(
|
||||||
|
r#"
|
||||||
|
app "test" imports [Json] provides [main] to "./platform"
|
||||||
|
|
||||||
|
main =
|
||||||
|
when Str.toUtf8 "[[\"ab\",10],[\"cd\",25]]" |> Decode.fromBytes Json.fromUtf8 is
|
||||||
|
Ok ( ("ab", 10u8), ("cd", 25u8) ) -> "abcd"
|
||||||
|
_ -> "something went wrong"
|
||||||
|
"#
|
||||||
|
),
|
||||||
|
RocStr::from("abcd"),
|
||||||
|
RocStr
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(all(test, any(feature = "gen-llvm", feature = "gen-wasm")))]
|
#[cfg(all(test, any(feature = "gen-llvm", feature = "gen-wasm")))]
|
||||||
mod hash {
|
mod hash {
|
||||||
#[cfg(feature = "gen-llvm")]
|
#[cfg(feature = "gen-llvm")]
|
||||||
|
@ -1572,6 +1662,35 @@ mod hash {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn tuple_of_u8_and_str() {
|
||||||
|
assert_evals_to!(
|
||||||
|
&build_test(r#"(15u8, "bc")"#),
|
||||||
|
RocList::from_slice(&[15, 98, 99]),
|
||||||
|
RocList<u8>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn tuple_of_tuples() {
|
||||||
|
assert_evals_to!(
|
||||||
|
&build_test(r#"( (15u8, "bc"), (23u8, "ef") )"#),
|
||||||
|
RocList::from_slice(&[15, 98, 99, 23, 101, 102]),
|
||||||
|
RocList<u8>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn tuple_of_list_of_tuples() {
|
||||||
|
assert_evals_to!(
|
||||||
|
&build_test(
|
||||||
|
r#"( [ ( 15u8, 32u8 ), ( 23u8, 41u8 ) ], [ (45u8, 63u8), (58u8, 73u8) ] )"#
|
||||||
|
),
|
||||||
|
RocList::from_slice(&[15, 32, 23, 41, 45, 63, 58, 73]),
|
||||||
|
RocList<u8>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn hash_singleton_union() {
|
fn hash_singleton_union() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
|
@ -1840,6 +1959,22 @@ mod eq {
|
||||||
use indoc::indoc;
|
use indoc::indoc;
|
||||||
use roc_std::RocStr;
|
use roc_std::RocStr;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn eq_tuple() {
|
||||||
|
assert_evals_to!(
|
||||||
|
indoc!(
|
||||||
|
r#"
|
||||||
|
app "test" provides [main] to "./platform"
|
||||||
|
|
||||||
|
main =
|
||||||
|
("a", "b") == ("a", "b")
|
||||||
|
"#
|
||||||
|
),
|
||||||
|
true,
|
||||||
|
bool
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn custom_eq_impl() {
|
fn custom_eq_impl() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
procedure #Derived.0 (#Derived.1):
|
procedure #Derived.0 (#Derived.1):
|
||||||
let #Derived_gen.0 : Str = CallByName Encode.22 #Derived.1;
|
let #Derived_gen.0 : Str = CallByName Encode.23 #Derived.1;
|
||||||
ret #Derived_gen.0;
|
ret #Derived_gen.0;
|
||||||
|
|
||||||
procedure #Derived.2 (#Derived.3, #Derived.4, #Derived.1):
|
procedure #Derived.2 (#Derived.3, #Derived.4, #Derived.1):
|
||||||
|
@ -8,11 +8,11 @@ procedure #Derived.2 (#Derived.3, #Derived.4, #Derived.1):
|
||||||
let #Derived_gen.6 : {Str, Str} = Struct {#Derived_gen.7, #Derived_gen.8};
|
let #Derived_gen.6 : {Str, Str} = Struct {#Derived_gen.7, #Derived_gen.8};
|
||||||
let #Derived_gen.5 : List {Str, Str} = Array [#Derived_gen.6];
|
let #Derived_gen.5 : List {Str, Str} = Array [#Derived_gen.6];
|
||||||
let #Derived_gen.4 : List {Str, Str} = CallByName Json.20 #Derived_gen.5;
|
let #Derived_gen.4 : List {Str, Str} = CallByName Json.20 #Derived_gen.5;
|
||||||
let #Derived_gen.3 : List U8 = CallByName Encode.23 #Derived.3 #Derived_gen.4 #Derived.4;
|
let #Derived_gen.3 : List U8 = CallByName Encode.24 #Derived.3 #Derived_gen.4 #Derived.4;
|
||||||
ret #Derived_gen.3;
|
ret #Derived_gen.3;
|
||||||
|
|
||||||
procedure #Derived.5 (#Derived.6):
|
procedure #Derived.5 (#Derived.6):
|
||||||
let #Derived_gen.14 : Str = CallByName Encode.22 #Derived.6;
|
let #Derived_gen.14 : Str = CallByName Encode.23 #Derived.6;
|
||||||
ret #Derived_gen.14;
|
ret #Derived_gen.14;
|
||||||
|
|
||||||
procedure #Derived.7 (#Derived.8, #Derived.9, #Derived.6):
|
procedure #Derived.7 (#Derived.8, #Derived.9, #Derived.6):
|
||||||
|
@ -21,195 +21,195 @@ procedure #Derived.7 (#Derived.8, #Derived.9, #Derived.6):
|
||||||
let #Derived_gen.20 : {Str, Str} = Struct {#Derived_gen.21, #Derived_gen.22};
|
let #Derived_gen.20 : {Str, Str} = Struct {#Derived_gen.21, #Derived_gen.22};
|
||||||
let #Derived_gen.19 : List {Str, Str} = Array [#Derived_gen.20];
|
let #Derived_gen.19 : List {Str, Str} = Array [#Derived_gen.20];
|
||||||
let #Derived_gen.18 : List {Str, Str} = CallByName Json.20 #Derived_gen.19;
|
let #Derived_gen.18 : List {Str, Str} = CallByName Json.20 #Derived_gen.19;
|
||||||
let #Derived_gen.17 : List U8 = CallByName Encode.23 #Derived.8 #Derived_gen.18 #Derived.9;
|
let #Derived_gen.17 : List U8 = CallByName Encode.24 #Derived.8 #Derived_gen.18 #Derived.9;
|
||||||
ret #Derived_gen.17;
|
ret #Derived_gen.17;
|
||||||
|
|
||||||
procedure Encode.22 (Encode.93):
|
procedure Encode.23 (Encode.98):
|
||||||
ret Encode.93;
|
ret Encode.98;
|
||||||
|
|
||||||
procedure Encode.22 (Encode.93):
|
procedure Encode.23 (Encode.98):
|
||||||
ret Encode.93;
|
ret Encode.98;
|
||||||
|
|
||||||
procedure Encode.22 (Encode.93):
|
procedure Encode.23 (Encode.98):
|
||||||
ret Encode.93;
|
ret Encode.98;
|
||||||
|
|
||||||
procedure Encode.22 (Encode.93):
|
procedure Encode.23 (Encode.98):
|
||||||
ret Encode.93;
|
ret Encode.98;
|
||||||
|
|
||||||
procedure Encode.22 (Encode.93):
|
procedure Encode.23 (Encode.98):
|
||||||
ret Encode.93;
|
ret Encode.98;
|
||||||
|
|
||||||
procedure Encode.23 (Encode.94, Encode.102, Encode.96):
|
procedure Encode.24 (Encode.99, Encode.107, Encode.101):
|
||||||
let Encode.106 : List U8 = CallByName #Derived.2 Encode.94 Encode.96 Encode.102;
|
let Encode.111 : List U8 = CallByName #Derived.2 Encode.99 Encode.101 Encode.107;
|
||||||
ret Encode.106;
|
ret Encode.111;
|
||||||
|
|
||||||
procedure Encode.23 (Encode.94, Encode.102, Encode.96):
|
procedure Encode.24 (Encode.99, Encode.107, Encode.101):
|
||||||
let Encode.113 : List U8 = CallByName Json.114 Encode.94 Encode.96 Encode.102;
|
let Encode.118 : List U8 = CallByName Json.118 Encode.99 Encode.101 Encode.107;
|
||||||
ret Encode.113;
|
ret Encode.118;
|
||||||
|
|
||||||
procedure Encode.23 (Encode.94, Encode.102, Encode.96):
|
procedure Encode.24 (Encode.99, Encode.107, Encode.101):
|
||||||
let Encode.115 : List U8 = CallByName #Derived.7 Encode.94 Encode.96 Encode.102;
|
let Encode.120 : List U8 = CallByName #Derived.7 Encode.99 Encode.101 Encode.107;
|
||||||
ret Encode.115;
|
ret Encode.120;
|
||||||
|
|
||||||
procedure Encode.23 (Encode.94, Encode.102, Encode.96):
|
procedure Encode.24 (Encode.99, Encode.107, Encode.101):
|
||||||
let Encode.125 : List U8 = CallByName Json.114 Encode.94 Encode.96 Encode.102;
|
let Encode.130 : List U8 = CallByName Json.118 Encode.99 Encode.101 Encode.107;
|
||||||
ret Encode.125;
|
ret Encode.130;
|
||||||
|
|
||||||
procedure Encode.23 (Encode.94, Encode.102, Encode.96):
|
procedure Encode.24 (Encode.99, Encode.107, Encode.101):
|
||||||
let Encode.128 : List U8 = CallByName Json.98 Encode.94 Encode.96 Encode.102;
|
let Encode.133 : List U8 = CallByName Json.102 Encode.99 Encode.101 Encode.107;
|
||||||
ret Encode.128;
|
ret Encode.133;
|
||||||
|
|
||||||
procedure Encode.25 (Encode.100, Encode.101):
|
procedure Encode.26 (Encode.105, Encode.106):
|
||||||
let Encode.104 : List U8 = Array [];
|
let Encode.109 : List U8 = Array [];
|
||||||
let Encode.105 : Str = CallByName #Derived.0 Encode.100;
|
let Encode.110 : Str = CallByName #Derived.0 Encode.105;
|
||||||
let Encode.103 : List U8 = CallByName Encode.23 Encode.104 Encode.105 Encode.101;
|
let Encode.108 : List U8 = CallByName Encode.24 Encode.109 Encode.110 Encode.106;
|
||||||
ret Encode.103;
|
ret Encode.108;
|
||||||
|
|
||||||
procedure Json.1 ():
|
procedure Json.1 ():
|
||||||
let Json.425 : {} = Struct {};
|
let Json.483 : {} = Struct {};
|
||||||
ret Json.425;
|
ret Json.483;
|
||||||
|
|
||||||
procedure Json.114 (Json.115, Json.428, Json.113):
|
procedure Json.102 (Json.103, Json.562, Json.101):
|
||||||
let Json.461 : I64 = 123i64;
|
let Json.571 : I64 = 34i64;
|
||||||
let Json.460 : U8 = CallByName Num.127 Json.461;
|
let Json.570 : U8 = CallByName Num.127 Json.571;
|
||||||
let Json.117 : List U8 = CallByName List.4 Json.115 Json.460;
|
let Json.568 : List U8 = CallByName List.4 Json.103 Json.570;
|
||||||
let Json.459 : U64 = CallByName List.6 Json.113;
|
let Json.569 : List U8 = CallByName Str.12 Json.101;
|
||||||
let Json.436 : {List U8, U64} = Struct {Json.117, Json.459};
|
let Json.565 : List U8 = CallByName List.8 Json.568 Json.569;
|
||||||
let Json.437 : {} = Struct {};
|
let Json.567 : I64 = 34i64;
|
||||||
let Json.435 : {List U8, U64} = CallByName List.18 Json.113 Json.436 Json.437;
|
let Json.566 : U8 = CallByName Num.127 Json.567;
|
||||||
dec Json.113;
|
let Json.564 : List U8 = CallByName List.4 Json.565 Json.566;
|
||||||
let Json.119 : List U8 = StructAtIndex 0 Json.435;
|
ret Json.564;
|
||||||
inc Json.119;
|
|
||||||
dec Json.435;
|
|
||||||
let Json.434 : I64 = 125i64;
|
|
||||||
let Json.433 : U8 = CallByName Num.127 Json.434;
|
|
||||||
let Json.432 : List U8 = CallByName List.4 Json.119 Json.433;
|
|
||||||
ret Json.432;
|
|
||||||
|
|
||||||
procedure Json.114 (Json.115, Json.428, Json.113):
|
procedure Json.118 (Json.119, Json.486, Json.117):
|
||||||
let Json.501 : I64 = 123i64;
|
let Json.519 : I64 = 123i64;
|
||||||
let Json.500 : U8 = CallByName Num.127 Json.501;
|
let Json.518 : U8 = CallByName Num.127 Json.519;
|
||||||
let Json.117 : List U8 = CallByName List.4 Json.115 Json.500;
|
let Json.121 : List U8 = CallByName List.4 Json.119 Json.518;
|
||||||
let Json.499 : U64 = CallByName List.6 Json.113;
|
let Json.517 : U64 = CallByName List.6 Json.117;
|
||||||
let Json.476 : {List U8, U64} = Struct {Json.117, Json.499};
|
let Json.494 : {List U8, U64} = Struct {Json.121, Json.517};
|
||||||
let Json.477 : {} = Struct {};
|
let Json.495 : {} = Struct {};
|
||||||
let Json.475 : {List U8, U64} = CallByName List.18 Json.113 Json.476 Json.477;
|
let Json.493 : {List U8, U64} = CallByName List.18 Json.117 Json.494 Json.495;
|
||||||
dec Json.113;
|
dec Json.117;
|
||||||
let Json.119 : List U8 = StructAtIndex 0 Json.475;
|
let Json.123 : List U8 = StructAtIndex 0 Json.493;
|
||||||
inc Json.119;
|
|
||||||
dec Json.475;
|
|
||||||
let Json.474 : I64 = 125i64;
|
|
||||||
let Json.473 : U8 = CallByName Num.127 Json.474;
|
|
||||||
let Json.472 : List U8 = CallByName List.4 Json.119 Json.473;
|
|
||||||
ret Json.472;
|
|
||||||
|
|
||||||
procedure Json.116 (Json.430, Json.431):
|
|
||||||
let Json.122 : Str = StructAtIndex 0 Json.431;
|
|
||||||
inc Json.122;
|
|
||||||
let Json.123 : Str = StructAtIndex 1 Json.431;
|
|
||||||
inc Json.123;
|
inc Json.123;
|
||||||
dec Json.431;
|
dec Json.493;
|
||||||
let Json.120 : List U8 = StructAtIndex 0 Json.430;
|
let Json.492 : I64 = 125i64;
|
||||||
inc Json.120;
|
let Json.491 : U8 = CallByName Num.127 Json.492;
|
||||||
let Json.121 : U64 = StructAtIndex 1 Json.430;
|
let Json.490 : List U8 = CallByName List.4 Json.123 Json.491;
|
||||||
dec Json.430;
|
ret Json.490;
|
||||||
let Json.458 : I64 = 34i64;
|
|
||||||
let Json.457 : U8 = CallByName Num.127 Json.458;
|
|
||||||
let Json.455 : List U8 = CallByName List.4 Json.120 Json.457;
|
|
||||||
let Json.456 : List U8 = CallByName Str.12 Json.122;
|
|
||||||
let Json.452 : List U8 = CallByName List.8 Json.455 Json.456;
|
|
||||||
let Json.454 : I64 = 34i64;
|
|
||||||
let Json.453 : U8 = CallByName Num.127 Json.454;
|
|
||||||
let Json.449 : List U8 = CallByName List.4 Json.452 Json.453;
|
|
||||||
let Json.451 : I64 = 58i64;
|
|
||||||
let Json.450 : U8 = CallByName Num.127 Json.451;
|
|
||||||
let Json.447 : List U8 = CallByName List.4 Json.449 Json.450;
|
|
||||||
let Json.448 : {} = Struct {};
|
|
||||||
let Json.124 : List U8 = CallByName Encode.23 Json.447 Json.123 Json.448;
|
|
||||||
joinpoint Json.442 Json.125:
|
|
||||||
let Json.440 : U64 = 1i64;
|
|
||||||
let Json.439 : U64 = CallByName Num.20 Json.121 Json.440;
|
|
||||||
let Json.438 : {List U8, U64} = Struct {Json.125, Json.439};
|
|
||||||
ret Json.438;
|
|
||||||
in
|
|
||||||
let Json.446 : U64 = 1i64;
|
|
||||||
let Json.443 : Int1 = CallByName Num.24 Json.121 Json.446;
|
|
||||||
if Json.443 then
|
|
||||||
let Json.445 : I64 = 44i64;
|
|
||||||
let Json.444 : U8 = CallByName Num.127 Json.445;
|
|
||||||
let Json.441 : List U8 = CallByName List.4 Json.124 Json.444;
|
|
||||||
jump Json.442 Json.441;
|
|
||||||
else
|
|
||||||
jump Json.442 Json.124;
|
|
||||||
|
|
||||||
procedure Json.116 (Json.430, Json.431):
|
procedure Json.118 (Json.119, Json.486, Json.117):
|
||||||
let Json.122 : Str = StructAtIndex 0 Json.431;
|
let Json.559 : I64 = 123i64;
|
||||||
inc Json.122;
|
let Json.558 : U8 = CallByName Num.127 Json.559;
|
||||||
let Json.123 : Str = StructAtIndex 1 Json.431;
|
let Json.121 : List U8 = CallByName List.4 Json.119 Json.558;
|
||||||
|
let Json.557 : U64 = CallByName List.6 Json.117;
|
||||||
|
let Json.534 : {List U8, U64} = Struct {Json.121, Json.557};
|
||||||
|
let Json.535 : {} = Struct {};
|
||||||
|
let Json.533 : {List U8, U64} = CallByName List.18 Json.117 Json.534 Json.535;
|
||||||
|
dec Json.117;
|
||||||
|
let Json.123 : List U8 = StructAtIndex 0 Json.533;
|
||||||
inc Json.123;
|
inc Json.123;
|
||||||
dec Json.431;
|
dec Json.533;
|
||||||
let Json.120 : List U8 = StructAtIndex 0 Json.430;
|
let Json.532 : I64 = 125i64;
|
||||||
inc Json.120;
|
let Json.531 : U8 = CallByName Num.127 Json.532;
|
||||||
let Json.121 : U64 = StructAtIndex 1 Json.430;
|
let Json.530 : List U8 = CallByName List.4 Json.123 Json.531;
|
||||||
dec Json.430;
|
ret Json.530;
|
||||||
let Json.498 : I64 = 34i64;
|
|
||||||
let Json.497 : U8 = CallByName Num.127 Json.498;
|
|
||||||
let Json.495 : List U8 = CallByName List.4 Json.120 Json.497;
|
|
||||||
let Json.496 : List U8 = CallByName Str.12 Json.122;
|
|
||||||
let Json.492 : List U8 = CallByName List.8 Json.495 Json.496;
|
|
||||||
let Json.494 : I64 = 34i64;
|
|
||||||
let Json.493 : U8 = CallByName Num.127 Json.494;
|
|
||||||
let Json.489 : List U8 = CallByName List.4 Json.492 Json.493;
|
|
||||||
let Json.491 : I64 = 58i64;
|
|
||||||
let Json.490 : U8 = CallByName Num.127 Json.491;
|
|
||||||
let Json.487 : List U8 = CallByName List.4 Json.489 Json.490;
|
|
||||||
let Json.488 : {} = Struct {};
|
|
||||||
let Json.124 : List U8 = CallByName Encode.23 Json.487 Json.123 Json.488;
|
|
||||||
joinpoint Json.482 Json.125:
|
|
||||||
let Json.480 : U64 = 1i64;
|
|
||||||
let Json.479 : U64 = CallByName Num.20 Json.121 Json.480;
|
|
||||||
let Json.478 : {List U8, U64} = Struct {Json.125, Json.479};
|
|
||||||
ret Json.478;
|
|
||||||
in
|
|
||||||
let Json.486 : U64 = 1i64;
|
|
||||||
let Json.483 : Int1 = CallByName Num.24 Json.121 Json.486;
|
|
||||||
if Json.483 then
|
|
||||||
let Json.485 : I64 = 44i64;
|
|
||||||
let Json.484 : U8 = CallByName Num.127 Json.485;
|
|
||||||
let Json.481 : List U8 = CallByName List.4 Json.124 Json.484;
|
|
||||||
jump Json.482 Json.481;
|
|
||||||
else
|
|
||||||
jump Json.482 Json.124;
|
|
||||||
|
|
||||||
procedure Json.18 (Json.97):
|
procedure Json.120 (Json.488, Json.489):
|
||||||
let Json.502 : Str = CallByName Encode.22 Json.97;
|
let Json.126 : Str = StructAtIndex 0 Json.489;
|
||||||
ret Json.502;
|
inc Json.126;
|
||||||
|
let Json.127 : Str = StructAtIndex 1 Json.489;
|
||||||
procedure Json.20 (Json.113):
|
inc Json.127;
|
||||||
let Json.426 : List {Str, Str} = CallByName Encode.22 Json.113;
|
dec Json.489;
|
||||||
ret Json.426;
|
let Json.124 : List U8 = StructAtIndex 0 Json.488;
|
||||||
|
inc Json.124;
|
||||||
procedure Json.20 (Json.113):
|
let Json.125 : U64 = StructAtIndex 1 Json.488;
|
||||||
let Json.468 : List {Str, Str} = CallByName Encode.22 Json.113;
|
dec Json.488;
|
||||||
ret Json.468;
|
let Json.516 : I64 = 34i64;
|
||||||
|
let Json.515 : U8 = CallByName Num.127 Json.516;
|
||||||
procedure Json.98 (Json.99, Json.504, Json.97):
|
let Json.513 : List U8 = CallByName List.4 Json.124 Json.515;
|
||||||
let Json.513 : I64 = 34i64;
|
let Json.514 : List U8 = CallByName Str.12 Json.126;
|
||||||
let Json.512 : U8 = CallByName Num.127 Json.513;
|
let Json.510 : List U8 = CallByName List.8 Json.513 Json.514;
|
||||||
let Json.510 : List U8 = CallByName List.4 Json.99 Json.512;
|
let Json.512 : I64 = 34i64;
|
||||||
let Json.511 : List U8 = CallByName Str.12 Json.97;
|
let Json.511 : U8 = CallByName Num.127 Json.512;
|
||||||
let Json.507 : List U8 = CallByName List.8 Json.510 Json.511;
|
let Json.507 : List U8 = CallByName List.4 Json.510 Json.511;
|
||||||
let Json.509 : I64 = 34i64;
|
let Json.509 : I64 = 58i64;
|
||||||
let Json.508 : U8 = CallByName Num.127 Json.509;
|
let Json.508 : U8 = CallByName Num.127 Json.509;
|
||||||
let Json.506 : List U8 = CallByName List.4 Json.507 Json.508;
|
let Json.505 : List U8 = CallByName List.4 Json.507 Json.508;
|
||||||
ret Json.506;
|
let Json.506 : {} = Struct {};
|
||||||
|
let Json.128 : List U8 = CallByName Encode.24 Json.505 Json.127 Json.506;
|
||||||
|
joinpoint Json.500 Json.129:
|
||||||
|
let Json.498 : U64 = 1i64;
|
||||||
|
let Json.497 : U64 = CallByName Num.20 Json.125 Json.498;
|
||||||
|
let Json.496 : {List U8, U64} = Struct {Json.129, Json.497};
|
||||||
|
ret Json.496;
|
||||||
|
in
|
||||||
|
let Json.504 : U64 = 1i64;
|
||||||
|
let Json.501 : Int1 = CallByName Num.24 Json.125 Json.504;
|
||||||
|
if Json.501 then
|
||||||
|
let Json.503 : I64 = 44i64;
|
||||||
|
let Json.502 : U8 = CallByName Num.127 Json.503;
|
||||||
|
let Json.499 : List U8 = CallByName List.4 Json.128 Json.502;
|
||||||
|
jump Json.500 Json.499;
|
||||||
|
else
|
||||||
|
jump Json.500 Json.128;
|
||||||
|
|
||||||
|
procedure Json.120 (Json.488, Json.489):
|
||||||
|
let Json.126 : Str = StructAtIndex 0 Json.489;
|
||||||
|
inc Json.126;
|
||||||
|
let Json.127 : Str = StructAtIndex 1 Json.489;
|
||||||
|
inc Json.127;
|
||||||
|
dec Json.489;
|
||||||
|
let Json.124 : List U8 = StructAtIndex 0 Json.488;
|
||||||
|
inc Json.124;
|
||||||
|
let Json.125 : U64 = StructAtIndex 1 Json.488;
|
||||||
|
dec Json.488;
|
||||||
|
let Json.556 : I64 = 34i64;
|
||||||
|
let Json.555 : U8 = CallByName Num.127 Json.556;
|
||||||
|
let Json.553 : List U8 = CallByName List.4 Json.124 Json.555;
|
||||||
|
let Json.554 : List U8 = CallByName Str.12 Json.126;
|
||||||
|
let Json.550 : List U8 = CallByName List.8 Json.553 Json.554;
|
||||||
|
let Json.552 : I64 = 34i64;
|
||||||
|
let Json.551 : U8 = CallByName Num.127 Json.552;
|
||||||
|
let Json.547 : List U8 = CallByName List.4 Json.550 Json.551;
|
||||||
|
let Json.549 : I64 = 58i64;
|
||||||
|
let Json.548 : U8 = CallByName Num.127 Json.549;
|
||||||
|
let Json.545 : List U8 = CallByName List.4 Json.547 Json.548;
|
||||||
|
let Json.546 : {} = Struct {};
|
||||||
|
let Json.128 : List U8 = CallByName Encode.24 Json.545 Json.127 Json.546;
|
||||||
|
joinpoint Json.540 Json.129:
|
||||||
|
let Json.538 : U64 = 1i64;
|
||||||
|
let Json.537 : U64 = CallByName Num.20 Json.125 Json.538;
|
||||||
|
let Json.536 : {List U8, U64} = Struct {Json.129, Json.537};
|
||||||
|
ret Json.536;
|
||||||
|
in
|
||||||
|
let Json.544 : U64 = 1i64;
|
||||||
|
let Json.541 : Int1 = CallByName Num.24 Json.125 Json.544;
|
||||||
|
if Json.541 then
|
||||||
|
let Json.543 : I64 = 44i64;
|
||||||
|
let Json.542 : U8 = CallByName Num.127 Json.543;
|
||||||
|
let Json.539 : List U8 = CallByName List.4 Json.128 Json.542;
|
||||||
|
jump Json.540 Json.539;
|
||||||
|
else
|
||||||
|
jump Json.540 Json.128;
|
||||||
|
|
||||||
|
procedure Json.18 (Json.101):
|
||||||
|
let Json.560 : Str = CallByName Encode.23 Json.101;
|
||||||
|
ret Json.560;
|
||||||
|
|
||||||
|
procedure Json.20 (Json.117):
|
||||||
|
let Json.484 : List {Str, Str} = CallByName Encode.23 Json.117;
|
||||||
|
ret Json.484;
|
||||||
|
|
||||||
|
procedure Json.20 (Json.117):
|
||||||
|
let Json.526 : List {Str, Str} = CallByName Encode.23 Json.117;
|
||||||
|
ret Json.526;
|
||||||
|
|
||||||
procedure List.139 (List.140, List.141, List.138):
|
procedure List.139 (List.140, List.141, List.138):
|
||||||
let List.535 : {List U8, U64} = CallByName Json.116 List.140 List.141;
|
let List.535 : {List U8, U64} = CallByName Json.120 List.140 List.141;
|
||||||
ret List.535;
|
ret List.535;
|
||||||
|
|
||||||
procedure List.139 (List.140, List.141, List.138):
|
procedure List.139 (List.140, List.141, List.138):
|
||||||
let List.608 : {List U8, U64} = CallByName Json.116 List.140 List.141;
|
let List.608 : {List U8, U64} = CallByName Json.120 List.140 List.141;
|
||||||
ret List.608;
|
ret List.608;
|
||||||
|
|
||||||
procedure List.18 (List.136, List.137, List.138):
|
procedure List.18 (List.136, List.137, List.138):
|
||||||
|
@ -348,7 +348,7 @@ procedure Str.9 (Str.77):
|
||||||
procedure Test.0 ():
|
procedure Test.0 ():
|
||||||
let Test.12 : Str = "bar";
|
let Test.12 : Str = "bar";
|
||||||
let Test.10 : {} = CallByName Json.1;
|
let Test.10 : {} = CallByName Json.1;
|
||||||
let Test.8 : List U8 = CallByName Encode.25 Test.12 Test.10;
|
let Test.8 : List U8 = CallByName Encode.26 Test.12 Test.10;
|
||||||
let Test.1 : [C {U64, U8}, C Str] = CallByName Str.9 Test.8;
|
let Test.1 : [C {U64, U8}, C Str] = CallByName Str.9 Test.8;
|
||||||
let Test.5 : U8 = 1i64;
|
let Test.5 : U8 = 1i64;
|
||||||
let Test.6 : U8 = GetTagId Test.1;
|
let Test.6 : U8 = GetTagId Test.1;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
procedure #Derived.0 (#Derived.1):
|
procedure #Derived.0 (#Derived.1):
|
||||||
let #Derived_gen.0 : Str = CallByName Encode.22 #Derived.1;
|
let #Derived_gen.0 : Str = CallByName Encode.23 #Derived.1;
|
||||||
ret #Derived_gen.0;
|
ret #Derived_gen.0;
|
||||||
|
|
||||||
procedure #Derived.2 (#Derived.3, #Derived.4, #Derived.1):
|
procedure #Derived.2 (#Derived.3, #Derived.4, #Derived.1):
|
||||||
|
@ -8,117 +8,117 @@ procedure #Derived.2 (#Derived.3, #Derived.4, #Derived.1):
|
||||||
let #Derived_gen.6 : {Str, Str} = Struct {#Derived_gen.7, #Derived_gen.8};
|
let #Derived_gen.6 : {Str, Str} = Struct {#Derived_gen.7, #Derived_gen.8};
|
||||||
let #Derived_gen.5 : List {Str, Str} = Array [#Derived_gen.6];
|
let #Derived_gen.5 : List {Str, Str} = Array [#Derived_gen.6];
|
||||||
let #Derived_gen.4 : List {Str, Str} = CallByName Json.20 #Derived_gen.5;
|
let #Derived_gen.4 : List {Str, Str} = CallByName Json.20 #Derived_gen.5;
|
||||||
let #Derived_gen.3 : List U8 = CallByName Encode.23 #Derived.3 #Derived_gen.4 #Derived.4;
|
let #Derived_gen.3 : List U8 = CallByName Encode.24 #Derived.3 #Derived_gen.4 #Derived.4;
|
||||||
ret #Derived_gen.3;
|
ret #Derived_gen.3;
|
||||||
|
|
||||||
procedure Encode.22 (Encode.93):
|
procedure Encode.23 (Encode.98):
|
||||||
ret Encode.93;
|
ret Encode.98;
|
||||||
|
|
||||||
procedure Encode.22 (Encode.93):
|
procedure Encode.23 (Encode.98):
|
||||||
ret Encode.93;
|
ret Encode.98;
|
||||||
|
|
||||||
procedure Encode.22 (Encode.93):
|
procedure Encode.23 (Encode.98):
|
||||||
ret Encode.93;
|
ret Encode.98;
|
||||||
|
|
||||||
procedure Encode.23 (Encode.94, Encode.102, Encode.96):
|
procedure Encode.24 (Encode.99, Encode.107, Encode.101):
|
||||||
let Encode.106 : List U8 = CallByName #Derived.2 Encode.94 Encode.96 Encode.102;
|
let Encode.111 : List U8 = CallByName #Derived.2 Encode.99 Encode.101 Encode.107;
|
||||||
ret Encode.106;
|
ret Encode.111;
|
||||||
|
|
||||||
procedure Encode.23 (Encode.94, Encode.102, Encode.96):
|
procedure Encode.24 (Encode.99, Encode.107, Encode.101):
|
||||||
let Encode.113 : List U8 = CallByName Json.114 Encode.94 Encode.96 Encode.102;
|
let Encode.118 : List U8 = CallByName Json.118 Encode.99 Encode.101 Encode.107;
|
||||||
ret Encode.113;
|
ret Encode.118;
|
||||||
|
|
||||||
procedure Encode.23 (Encode.94, Encode.102, Encode.96):
|
procedure Encode.24 (Encode.99, Encode.107, Encode.101):
|
||||||
let Encode.116 : List U8 = CallByName Json.98 Encode.94 Encode.96 Encode.102;
|
let Encode.121 : List U8 = CallByName Json.102 Encode.99 Encode.101 Encode.107;
|
||||||
ret Encode.116;
|
ret Encode.121;
|
||||||
|
|
||||||
procedure Encode.25 (Encode.100, Encode.101):
|
procedure Encode.26 (Encode.105, Encode.106):
|
||||||
let Encode.104 : List U8 = Array [];
|
let Encode.109 : List U8 = Array [];
|
||||||
let Encode.105 : Str = CallByName #Derived.0 Encode.100;
|
let Encode.110 : Str = CallByName #Derived.0 Encode.105;
|
||||||
let Encode.103 : List U8 = CallByName Encode.23 Encode.104 Encode.105 Encode.101;
|
let Encode.108 : List U8 = CallByName Encode.24 Encode.109 Encode.110 Encode.106;
|
||||||
ret Encode.103;
|
ret Encode.108;
|
||||||
|
|
||||||
procedure Json.1 ():
|
procedure Json.1 ():
|
||||||
let Json.425 : {} = Struct {};
|
let Json.483 : {} = Struct {};
|
||||||
ret Json.425;
|
ret Json.483;
|
||||||
|
|
||||||
procedure Json.114 (Json.115, Json.428, Json.113):
|
procedure Json.102 (Json.103, Json.522, Json.101):
|
||||||
let Json.461 : I64 = 123i64;
|
let Json.531 : I64 = 34i64;
|
||||||
let Json.460 : U8 = CallByName Num.127 Json.461;
|
let Json.530 : U8 = CallByName Num.127 Json.531;
|
||||||
let Json.117 : List U8 = CallByName List.4 Json.115 Json.460;
|
let Json.528 : List U8 = CallByName List.4 Json.103 Json.530;
|
||||||
let Json.459 : U64 = CallByName List.6 Json.113;
|
let Json.529 : List U8 = CallByName Str.12 Json.101;
|
||||||
let Json.436 : {List U8, U64} = Struct {Json.117, Json.459};
|
let Json.525 : List U8 = CallByName List.8 Json.528 Json.529;
|
||||||
let Json.437 : {} = Struct {};
|
let Json.527 : I64 = 34i64;
|
||||||
let Json.435 : {List U8, U64} = CallByName List.18 Json.113 Json.436 Json.437;
|
let Json.526 : U8 = CallByName Num.127 Json.527;
|
||||||
dec Json.113;
|
let Json.524 : List U8 = CallByName List.4 Json.525 Json.526;
|
||||||
let Json.119 : List U8 = StructAtIndex 0 Json.435;
|
ret Json.524;
|
||||||
inc Json.119;
|
|
||||||
dec Json.435;
|
|
||||||
let Json.434 : I64 = 125i64;
|
|
||||||
let Json.433 : U8 = CallByName Num.127 Json.434;
|
|
||||||
let Json.432 : List U8 = CallByName List.4 Json.119 Json.433;
|
|
||||||
ret Json.432;
|
|
||||||
|
|
||||||
procedure Json.116 (Json.430, Json.431):
|
procedure Json.118 (Json.119, Json.486, Json.117):
|
||||||
let Json.122 : Str = StructAtIndex 0 Json.431;
|
let Json.519 : I64 = 123i64;
|
||||||
inc Json.122;
|
let Json.518 : U8 = CallByName Num.127 Json.519;
|
||||||
let Json.123 : Str = StructAtIndex 1 Json.431;
|
let Json.121 : List U8 = CallByName List.4 Json.119 Json.518;
|
||||||
|
let Json.517 : U64 = CallByName List.6 Json.117;
|
||||||
|
let Json.494 : {List U8, U64} = Struct {Json.121, Json.517};
|
||||||
|
let Json.495 : {} = Struct {};
|
||||||
|
let Json.493 : {List U8, U64} = CallByName List.18 Json.117 Json.494 Json.495;
|
||||||
|
dec Json.117;
|
||||||
|
let Json.123 : List U8 = StructAtIndex 0 Json.493;
|
||||||
inc Json.123;
|
inc Json.123;
|
||||||
dec Json.431;
|
dec Json.493;
|
||||||
let Json.120 : List U8 = StructAtIndex 0 Json.430;
|
let Json.492 : I64 = 125i64;
|
||||||
inc Json.120;
|
let Json.491 : U8 = CallByName Num.127 Json.492;
|
||||||
let Json.121 : U64 = StructAtIndex 1 Json.430;
|
let Json.490 : List U8 = CallByName List.4 Json.123 Json.491;
|
||||||
dec Json.430;
|
ret Json.490;
|
||||||
let Json.458 : I64 = 34i64;
|
|
||||||
let Json.457 : U8 = CallByName Num.127 Json.458;
|
procedure Json.120 (Json.488, Json.489):
|
||||||
let Json.455 : List U8 = CallByName List.4 Json.120 Json.457;
|
let Json.126 : Str = StructAtIndex 0 Json.489;
|
||||||
let Json.456 : List U8 = CallByName Str.12 Json.122;
|
inc Json.126;
|
||||||
let Json.452 : List U8 = CallByName List.8 Json.455 Json.456;
|
let Json.127 : Str = StructAtIndex 1 Json.489;
|
||||||
let Json.454 : I64 = 34i64;
|
inc Json.127;
|
||||||
let Json.453 : U8 = CallByName Num.127 Json.454;
|
dec Json.489;
|
||||||
let Json.449 : List U8 = CallByName List.4 Json.452 Json.453;
|
let Json.124 : List U8 = StructAtIndex 0 Json.488;
|
||||||
let Json.451 : I64 = 58i64;
|
inc Json.124;
|
||||||
let Json.450 : U8 = CallByName Num.127 Json.451;
|
let Json.125 : U64 = StructAtIndex 1 Json.488;
|
||||||
let Json.447 : List U8 = CallByName List.4 Json.449 Json.450;
|
dec Json.488;
|
||||||
let Json.448 : {} = Struct {};
|
let Json.516 : I64 = 34i64;
|
||||||
let Json.124 : List U8 = CallByName Encode.23 Json.447 Json.123 Json.448;
|
let Json.515 : U8 = CallByName Num.127 Json.516;
|
||||||
joinpoint Json.442 Json.125:
|
let Json.513 : List U8 = CallByName List.4 Json.124 Json.515;
|
||||||
let Json.440 : U64 = 1i64;
|
let Json.514 : List U8 = CallByName Str.12 Json.126;
|
||||||
let Json.439 : U64 = CallByName Num.20 Json.121 Json.440;
|
let Json.510 : List U8 = CallByName List.8 Json.513 Json.514;
|
||||||
let Json.438 : {List U8, U64} = Struct {Json.125, Json.439};
|
let Json.512 : I64 = 34i64;
|
||||||
ret Json.438;
|
let Json.511 : U8 = CallByName Num.127 Json.512;
|
||||||
|
let Json.507 : List U8 = CallByName List.4 Json.510 Json.511;
|
||||||
|
let Json.509 : I64 = 58i64;
|
||||||
|
let Json.508 : U8 = CallByName Num.127 Json.509;
|
||||||
|
let Json.505 : List U8 = CallByName List.4 Json.507 Json.508;
|
||||||
|
let Json.506 : {} = Struct {};
|
||||||
|
let Json.128 : List U8 = CallByName Encode.24 Json.505 Json.127 Json.506;
|
||||||
|
joinpoint Json.500 Json.129:
|
||||||
|
let Json.498 : U64 = 1i64;
|
||||||
|
let Json.497 : U64 = CallByName Num.20 Json.125 Json.498;
|
||||||
|
let Json.496 : {List U8, U64} = Struct {Json.129, Json.497};
|
||||||
|
ret Json.496;
|
||||||
in
|
in
|
||||||
let Json.446 : U64 = 1i64;
|
let Json.504 : U64 = 1i64;
|
||||||
let Json.443 : Int1 = CallByName Num.24 Json.121 Json.446;
|
let Json.501 : Int1 = CallByName Num.24 Json.125 Json.504;
|
||||||
if Json.443 then
|
if Json.501 then
|
||||||
let Json.445 : I64 = 44i64;
|
let Json.503 : I64 = 44i64;
|
||||||
let Json.444 : U8 = CallByName Num.127 Json.445;
|
let Json.502 : U8 = CallByName Num.127 Json.503;
|
||||||
let Json.441 : List U8 = CallByName List.4 Json.124 Json.444;
|
let Json.499 : List U8 = CallByName List.4 Json.128 Json.502;
|
||||||
jump Json.442 Json.441;
|
jump Json.500 Json.499;
|
||||||
else
|
else
|
||||||
jump Json.442 Json.124;
|
jump Json.500 Json.128;
|
||||||
|
|
||||||
procedure Json.18 (Json.97):
|
procedure Json.18 (Json.101):
|
||||||
let Json.462 : Str = CallByName Encode.22 Json.97;
|
let Json.520 : Str = CallByName Encode.23 Json.101;
|
||||||
ret Json.462;
|
ret Json.520;
|
||||||
|
|
||||||
procedure Json.20 (Json.113):
|
procedure Json.20 (Json.117):
|
||||||
let Json.426 : List {Str, Str} = CallByName Encode.22 Json.113;
|
let Json.484 : List {Str, Str} = CallByName Encode.23 Json.117;
|
||||||
ret Json.426;
|
ret Json.484;
|
||||||
|
|
||||||
procedure Json.98 (Json.99, Json.464, Json.97):
|
|
||||||
let Json.473 : I64 = 34i64;
|
|
||||||
let Json.472 : U8 = CallByName Num.127 Json.473;
|
|
||||||
let Json.470 : List U8 = CallByName List.4 Json.99 Json.472;
|
|
||||||
let Json.471 : List U8 = CallByName Str.12 Json.97;
|
|
||||||
let Json.467 : List U8 = CallByName List.8 Json.470 Json.471;
|
|
||||||
let Json.469 : I64 = 34i64;
|
|
||||||
let Json.468 : U8 = CallByName Num.127 Json.469;
|
|
||||||
let Json.466 : List U8 = CallByName List.4 Json.467 Json.468;
|
|
||||||
ret Json.466;
|
|
||||||
|
|
||||||
procedure List.139 (List.140, List.141, List.138):
|
procedure List.139 (List.140, List.141, List.138):
|
||||||
let List.541 : {List U8, U64} = CallByName Json.116 List.140 List.141;
|
let List.541 : {List U8, U64} = CallByName Json.120 List.140 List.141;
|
||||||
ret List.541;
|
ret List.541;
|
||||||
|
|
||||||
procedure List.18 (List.136, List.137, List.138):
|
procedure List.18 (List.136, List.137, List.138):
|
||||||
|
@ -225,7 +225,7 @@ procedure Str.9 (Str.77):
|
||||||
procedure Test.0 ():
|
procedure Test.0 ():
|
||||||
let Test.11 : Str = "foo";
|
let Test.11 : Str = "foo";
|
||||||
let Test.10 : {} = CallByName Json.1;
|
let Test.10 : {} = CallByName Json.1;
|
||||||
let Test.8 : List U8 = CallByName Encode.25 Test.11 Test.10;
|
let Test.8 : List U8 = CallByName Encode.26 Test.11 Test.10;
|
||||||
let Test.1 : [C {U64, U8}, C Str] = CallByName Str.9 Test.8;
|
let Test.1 : [C {U64, U8}, C Str] = CallByName Str.9 Test.8;
|
||||||
let Test.5 : U8 = 1i64;
|
let Test.5 : U8 = 1i64;
|
||||||
let Test.6 : U8 = GetTagId Test.1;
|
let Test.6 : U8 = GetTagId Test.1;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
procedure #Derived.0 (#Derived.1):
|
procedure #Derived.0 (#Derived.1):
|
||||||
let #Derived_gen.0 : {Str, Str} = CallByName Encode.22 #Derived.1;
|
let #Derived_gen.0 : {Str, Str} = CallByName Encode.23 #Derived.1;
|
||||||
ret #Derived_gen.0;
|
ret #Derived_gen.0;
|
||||||
|
|
||||||
procedure #Derived.2 (#Derived.3, #Derived.4, #Derived.1):
|
procedure #Derived.2 (#Derived.3, #Derived.4, #Derived.1):
|
||||||
|
@ -16,117 +16,117 @@ procedure #Derived.2 (#Derived.3, #Derived.4, #Derived.1):
|
||||||
let #Derived_gen.7 : {Str, Str} = Struct {#Derived_gen.8, #Derived_gen.9};
|
let #Derived_gen.7 : {Str, Str} = Struct {#Derived_gen.8, #Derived_gen.9};
|
||||||
let #Derived_gen.5 : List {Str, Str} = Array [#Derived_gen.6, #Derived_gen.7];
|
let #Derived_gen.5 : List {Str, Str} = Array [#Derived_gen.6, #Derived_gen.7];
|
||||||
let #Derived_gen.4 : List {Str, Str} = CallByName Json.20 #Derived_gen.5;
|
let #Derived_gen.4 : List {Str, Str} = CallByName Json.20 #Derived_gen.5;
|
||||||
let #Derived_gen.3 : List U8 = CallByName Encode.23 #Derived.3 #Derived_gen.4 #Derived.4;
|
let #Derived_gen.3 : List U8 = CallByName Encode.24 #Derived.3 #Derived_gen.4 #Derived.4;
|
||||||
ret #Derived_gen.3;
|
ret #Derived_gen.3;
|
||||||
|
|
||||||
procedure Encode.22 (Encode.93):
|
procedure Encode.23 (Encode.98):
|
||||||
ret Encode.93;
|
ret Encode.98;
|
||||||
|
|
||||||
procedure Encode.22 (Encode.93):
|
procedure Encode.23 (Encode.98):
|
||||||
ret Encode.93;
|
ret Encode.98;
|
||||||
|
|
||||||
procedure Encode.22 (Encode.93):
|
procedure Encode.23 (Encode.98):
|
||||||
ret Encode.93;
|
ret Encode.98;
|
||||||
|
|
||||||
procedure Encode.23 (Encode.94, Encode.102, Encode.96):
|
procedure Encode.24 (Encode.99, Encode.107, Encode.101):
|
||||||
let Encode.106 : List U8 = CallByName #Derived.2 Encode.94 Encode.96 Encode.102;
|
let Encode.111 : List U8 = CallByName #Derived.2 Encode.99 Encode.101 Encode.107;
|
||||||
ret Encode.106;
|
ret Encode.111;
|
||||||
|
|
||||||
procedure Encode.23 (Encode.94, Encode.102, Encode.96):
|
procedure Encode.24 (Encode.99, Encode.107, Encode.101):
|
||||||
let Encode.113 : List U8 = CallByName Json.114 Encode.94 Encode.96 Encode.102;
|
let Encode.118 : List U8 = CallByName Json.118 Encode.99 Encode.101 Encode.107;
|
||||||
ret Encode.113;
|
ret Encode.118;
|
||||||
|
|
||||||
procedure Encode.23 (Encode.94, Encode.102, Encode.96):
|
procedure Encode.24 (Encode.99, Encode.107, Encode.101):
|
||||||
let Encode.117 : List U8 = CallByName Json.98 Encode.94 Encode.96 Encode.102;
|
let Encode.122 : List U8 = CallByName Json.102 Encode.99 Encode.101 Encode.107;
|
||||||
ret Encode.117;
|
ret Encode.122;
|
||||||
|
|
||||||
procedure Encode.25 (Encode.100, Encode.101):
|
procedure Encode.26 (Encode.105, Encode.106):
|
||||||
let Encode.104 : List U8 = Array [];
|
let Encode.109 : List U8 = Array [];
|
||||||
let Encode.105 : {Str, Str} = CallByName #Derived.0 Encode.100;
|
let Encode.110 : {Str, Str} = CallByName #Derived.0 Encode.105;
|
||||||
let Encode.103 : List U8 = CallByName Encode.23 Encode.104 Encode.105 Encode.101;
|
let Encode.108 : List U8 = CallByName Encode.24 Encode.109 Encode.110 Encode.106;
|
||||||
ret Encode.103;
|
ret Encode.108;
|
||||||
|
|
||||||
procedure Json.1 ():
|
procedure Json.1 ():
|
||||||
let Json.425 : {} = Struct {};
|
let Json.483 : {} = Struct {};
|
||||||
ret Json.425;
|
ret Json.483;
|
||||||
|
|
||||||
procedure Json.114 (Json.115, Json.428, Json.113):
|
procedure Json.102 (Json.103, Json.522, Json.101):
|
||||||
let Json.461 : I64 = 123i64;
|
let Json.531 : I64 = 34i64;
|
||||||
let Json.460 : U8 = CallByName Num.127 Json.461;
|
let Json.530 : U8 = CallByName Num.127 Json.531;
|
||||||
let Json.117 : List U8 = CallByName List.4 Json.115 Json.460;
|
let Json.528 : List U8 = CallByName List.4 Json.103 Json.530;
|
||||||
let Json.459 : U64 = CallByName List.6 Json.113;
|
let Json.529 : List U8 = CallByName Str.12 Json.101;
|
||||||
let Json.436 : {List U8, U64} = Struct {Json.117, Json.459};
|
let Json.525 : List U8 = CallByName List.8 Json.528 Json.529;
|
||||||
let Json.437 : {} = Struct {};
|
let Json.527 : I64 = 34i64;
|
||||||
let Json.435 : {List U8, U64} = CallByName List.18 Json.113 Json.436 Json.437;
|
let Json.526 : U8 = CallByName Num.127 Json.527;
|
||||||
dec Json.113;
|
let Json.524 : List U8 = CallByName List.4 Json.525 Json.526;
|
||||||
let Json.119 : List U8 = StructAtIndex 0 Json.435;
|
ret Json.524;
|
||||||
inc Json.119;
|
|
||||||
dec Json.435;
|
|
||||||
let Json.434 : I64 = 125i64;
|
|
||||||
let Json.433 : U8 = CallByName Num.127 Json.434;
|
|
||||||
let Json.432 : List U8 = CallByName List.4 Json.119 Json.433;
|
|
||||||
ret Json.432;
|
|
||||||
|
|
||||||
procedure Json.116 (Json.430, Json.431):
|
procedure Json.118 (Json.119, Json.486, Json.117):
|
||||||
let Json.122 : Str = StructAtIndex 0 Json.431;
|
let Json.519 : I64 = 123i64;
|
||||||
inc Json.122;
|
let Json.518 : U8 = CallByName Num.127 Json.519;
|
||||||
let Json.123 : Str = StructAtIndex 1 Json.431;
|
let Json.121 : List U8 = CallByName List.4 Json.119 Json.518;
|
||||||
|
let Json.517 : U64 = CallByName List.6 Json.117;
|
||||||
|
let Json.494 : {List U8, U64} = Struct {Json.121, Json.517};
|
||||||
|
let Json.495 : {} = Struct {};
|
||||||
|
let Json.493 : {List U8, U64} = CallByName List.18 Json.117 Json.494 Json.495;
|
||||||
|
dec Json.117;
|
||||||
|
let Json.123 : List U8 = StructAtIndex 0 Json.493;
|
||||||
inc Json.123;
|
inc Json.123;
|
||||||
dec Json.431;
|
dec Json.493;
|
||||||
let Json.120 : List U8 = StructAtIndex 0 Json.430;
|
let Json.492 : I64 = 125i64;
|
||||||
inc Json.120;
|
let Json.491 : U8 = CallByName Num.127 Json.492;
|
||||||
let Json.121 : U64 = StructAtIndex 1 Json.430;
|
let Json.490 : List U8 = CallByName List.4 Json.123 Json.491;
|
||||||
dec Json.430;
|
ret Json.490;
|
||||||
let Json.458 : I64 = 34i64;
|
|
||||||
let Json.457 : U8 = CallByName Num.127 Json.458;
|
procedure Json.120 (Json.488, Json.489):
|
||||||
let Json.455 : List U8 = CallByName List.4 Json.120 Json.457;
|
let Json.126 : Str = StructAtIndex 0 Json.489;
|
||||||
let Json.456 : List U8 = CallByName Str.12 Json.122;
|
inc Json.126;
|
||||||
let Json.452 : List U8 = CallByName List.8 Json.455 Json.456;
|
let Json.127 : Str = StructAtIndex 1 Json.489;
|
||||||
let Json.454 : I64 = 34i64;
|
inc Json.127;
|
||||||
let Json.453 : U8 = CallByName Num.127 Json.454;
|
dec Json.489;
|
||||||
let Json.449 : List U8 = CallByName List.4 Json.452 Json.453;
|
let Json.124 : List U8 = StructAtIndex 0 Json.488;
|
||||||
let Json.451 : I64 = 58i64;
|
inc Json.124;
|
||||||
let Json.450 : U8 = CallByName Num.127 Json.451;
|
let Json.125 : U64 = StructAtIndex 1 Json.488;
|
||||||
let Json.447 : List U8 = CallByName List.4 Json.449 Json.450;
|
dec Json.488;
|
||||||
let Json.448 : {} = Struct {};
|
let Json.516 : I64 = 34i64;
|
||||||
let Json.124 : List U8 = CallByName Encode.23 Json.447 Json.123 Json.448;
|
let Json.515 : U8 = CallByName Num.127 Json.516;
|
||||||
joinpoint Json.442 Json.125:
|
let Json.513 : List U8 = CallByName List.4 Json.124 Json.515;
|
||||||
let Json.440 : U64 = 1i64;
|
let Json.514 : List U8 = CallByName Str.12 Json.126;
|
||||||
let Json.439 : U64 = CallByName Num.20 Json.121 Json.440;
|
let Json.510 : List U8 = CallByName List.8 Json.513 Json.514;
|
||||||
let Json.438 : {List U8, U64} = Struct {Json.125, Json.439};
|
let Json.512 : I64 = 34i64;
|
||||||
ret Json.438;
|
let Json.511 : U8 = CallByName Num.127 Json.512;
|
||||||
|
let Json.507 : List U8 = CallByName List.4 Json.510 Json.511;
|
||||||
|
let Json.509 : I64 = 58i64;
|
||||||
|
let Json.508 : U8 = CallByName Num.127 Json.509;
|
||||||
|
let Json.505 : List U8 = CallByName List.4 Json.507 Json.508;
|
||||||
|
let Json.506 : {} = Struct {};
|
||||||
|
let Json.128 : List U8 = CallByName Encode.24 Json.505 Json.127 Json.506;
|
||||||
|
joinpoint Json.500 Json.129:
|
||||||
|
let Json.498 : U64 = 1i64;
|
||||||
|
let Json.497 : U64 = CallByName Num.20 Json.125 Json.498;
|
||||||
|
let Json.496 : {List U8, U64} = Struct {Json.129, Json.497};
|
||||||
|
ret Json.496;
|
||||||
in
|
in
|
||||||
let Json.446 : U64 = 1i64;
|
let Json.504 : U64 = 1i64;
|
||||||
let Json.443 : Int1 = CallByName Num.24 Json.121 Json.446;
|
let Json.501 : Int1 = CallByName Num.24 Json.125 Json.504;
|
||||||
if Json.443 then
|
if Json.501 then
|
||||||
let Json.445 : I64 = 44i64;
|
let Json.503 : I64 = 44i64;
|
||||||
let Json.444 : U8 = CallByName Num.127 Json.445;
|
let Json.502 : U8 = CallByName Num.127 Json.503;
|
||||||
let Json.441 : List U8 = CallByName List.4 Json.124 Json.444;
|
let Json.499 : List U8 = CallByName List.4 Json.128 Json.502;
|
||||||
jump Json.442 Json.441;
|
jump Json.500 Json.499;
|
||||||
else
|
else
|
||||||
jump Json.442 Json.124;
|
jump Json.500 Json.128;
|
||||||
|
|
||||||
procedure Json.18 (Json.97):
|
procedure Json.18 (Json.101):
|
||||||
let Json.474 : Str = CallByName Encode.22 Json.97;
|
let Json.532 : Str = CallByName Encode.23 Json.101;
|
||||||
ret Json.474;
|
ret Json.532;
|
||||||
|
|
||||||
procedure Json.20 (Json.113):
|
procedure Json.20 (Json.117):
|
||||||
let Json.426 : List {Str, Str} = CallByName Encode.22 Json.113;
|
let Json.484 : List {Str, Str} = CallByName Encode.23 Json.117;
|
||||||
ret Json.426;
|
ret Json.484;
|
||||||
|
|
||||||
procedure Json.98 (Json.99, Json.464, Json.97):
|
|
||||||
let Json.473 : I64 = 34i64;
|
|
||||||
let Json.472 : U8 = CallByName Num.127 Json.473;
|
|
||||||
let Json.470 : List U8 = CallByName List.4 Json.99 Json.472;
|
|
||||||
let Json.471 : List U8 = CallByName Str.12 Json.97;
|
|
||||||
let Json.467 : List U8 = CallByName List.8 Json.470 Json.471;
|
|
||||||
let Json.469 : I64 = 34i64;
|
|
||||||
let Json.468 : U8 = CallByName Num.127 Json.469;
|
|
||||||
let Json.466 : List U8 = CallByName List.4 Json.467 Json.468;
|
|
||||||
ret Json.466;
|
|
||||||
|
|
||||||
procedure List.139 (List.140, List.141, List.138):
|
procedure List.139 (List.140, List.141, List.138):
|
||||||
let List.541 : {List U8, U64} = CallByName Json.116 List.140 List.141;
|
let List.541 : {List U8, U64} = CallByName Json.120 List.140 List.141;
|
||||||
ret List.541;
|
ret List.541;
|
||||||
|
|
||||||
procedure List.18 (List.136, List.137, List.138):
|
procedure List.18 (List.136, List.137, List.138):
|
||||||
|
@ -235,7 +235,7 @@ procedure Test.0 ():
|
||||||
let Test.12 : Str = "bar";
|
let Test.12 : Str = "bar";
|
||||||
let Test.9 : {Str, Str} = Struct {Test.11, Test.12};
|
let Test.9 : {Str, Str} = Struct {Test.11, Test.12};
|
||||||
let Test.10 : {} = CallByName Json.1;
|
let Test.10 : {} = CallByName Json.1;
|
||||||
let Test.8 : List U8 = CallByName Encode.25 Test.9 Test.10;
|
let Test.8 : List U8 = CallByName Encode.26 Test.9 Test.10;
|
||||||
let Test.1 : [C {U64, U8}, C Str] = CallByName Str.9 Test.8;
|
let Test.1 : [C {U64, U8}, C Str] = CallByName Str.9 Test.8;
|
||||||
let Test.5 : U8 = 1i64;
|
let Test.5 : U8 = 1i64;
|
||||||
let Test.6 : U8 = GetTagId Test.1;
|
let Test.6 : U8 = GetTagId Test.1;
|
||||||
|
|
|
@ -1,34 +1,34 @@
|
||||||
procedure Encode.22 (Encode.93):
|
procedure Encode.23 (Encode.98):
|
||||||
ret Encode.93;
|
ret Encode.98;
|
||||||
|
|
||||||
procedure Encode.23 (Encode.94, Encode.102, Encode.96):
|
procedure Encode.24 (Encode.99, Encode.107, Encode.101):
|
||||||
let Encode.106 : List U8 = CallByName Json.98 Encode.94 Encode.96 Encode.102;
|
let Encode.111 : List U8 = CallByName Json.102 Encode.99 Encode.101 Encode.107;
|
||||||
ret Encode.106;
|
ret Encode.111;
|
||||||
|
|
||||||
procedure Encode.25 (Encode.100, Encode.101):
|
procedure Encode.26 (Encode.105, Encode.106):
|
||||||
let Encode.104 : List U8 = Array [];
|
let Encode.109 : List U8 = Array [];
|
||||||
let Encode.105 : Str = CallByName Json.18 Encode.100;
|
let Encode.110 : Str = CallByName Json.18 Encode.105;
|
||||||
let Encode.103 : List U8 = CallByName Encode.23 Encode.104 Encode.105 Encode.101;
|
let Encode.108 : List U8 = CallByName Encode.24 Encode.109 Encode.110 Encode.106;
|
||||||
ret Encode.103;
|
ret Encode.108;
|
||||||
|
|
||||||
procedure Json.1 ():
|
procedure Json.1 ():
|
||||||
let Json.425 : {} = Struct {};
|
let Json.483 : {} = Struct {};
|
||||||
ret Json.425;
|
ret Json.483;
|
||||||
|
|
||||||
procedure Json.18 (Json.97):
|
procedure Json.102 (Json.103, Json.486, Json.101):
|
||||||
let Json.426 : Str = CallByName Encode.22 Json.97;
|
let Json.495 : I64 = 34i64;
|
||||||
ret Json.426;
|
let Json.494 : U8 = CallByName Num.127 Json.495;
|
||||||
|
let Json.492 : List U8 = CallByName List.4 Json.103 Json.494;
|
||||||
|
let Json.493 : List U8 = CallByName Str.12 Json.101;
|
||||||
|
let Json.489 : List U8 = CallByName List.8 Json.492 Json.493;
|
||||||
|
let Json.491 : I64 = 34i64;
|
||||||
|
let Json.490 : U8 = CallByName Num.127 Json.491;
|
||||||
|
let Json.488 : List U8 = CallByName List.4 Json.489 Json.490;
|
||||||
|
ret Json.488;
|
||||||
|
|
||||||
procedure Json.98 (Json.99, Json.428, Json.97):
|
procedure Json.18 (Json.101):
|
||||||
let Json.437 : I64 = 34i64;
|
let Json.484 : Str = CallByName Encode.23 Json.101;
|
||||||
let Json.436 : U8 = CallByName Num.127 Json.437;
|
ret Json.484;
|
||||||
let Json.434 : List U8 = CallByName List.4 Json.99 Json.436;
|
|
||||||
let Json.435 : List U8 = CallByName Str.12 Json.97;
|
|
||||||
let Json.431 : List U8 = CallByName List.8 Json.434 Json.435;
|
|
||||||
let Json.433 : I64 = 34i64;
|
|
||||||
let Json.432 : U8 = CallByName Num.127 Json.433;
|
|
||||||
let Json.430 : List U8 = CallByName List.4 Json.431 Json.432;
|
|
||||||
ret Json.430;
|
|
||||||
|
|
||||||
procedure List.4 (List.107, List.108):
|
procedure List.4 (List.107, List.108):
|
||||||
let List.503 : U64 = 1i64;
|
let List.503 : U64 = 1i64;
|
||||||
|
@ -86,7 +86,7 @@ procedure Str.9 (Str.77):
|
||||||
procedure Test.0 ():
|
procedure Test.0 ():
|
||||||
let Test.9 : Str = "abc";
|
let Test.9 : Str = "abc";
|
||||||
let Test.10 : {} = CallByName Json.1;
|
let Test.10 : {} = CallByName Json.1;
|
||||||
let Test.8 : List U8 = CallByName Encode.25 Test.9 Test.10;
|
let Test.8 : List U8 = CallByName Encode.26 Test.9 Test.10;
|
||||||
let Test.1 : [C {U64, U8}, C Str] = CallByName Str.9 Test.8;
|
let Test.1 : [C {U64, U8}, C Str] = CallByName Str.9 Test.8;
|
||||||
let Test.5 : U8 = 1i64;
|
let Test.5 : U8 = 1i64;
|
||||||
let Test.6 : U8 = GetTagId Test.1;
|
let Test.6 : U8 = GetTagId Test.1;
|
||||||
|
|
|
@ -1,133 +1,133 @@
|
||||||
procedure #Derived.0 (#Derived.1):
|
procedure #Derived.0 (#Derived.1):
|
||||||
let #Derived_gen.0 : Str = CallByName Encode.22 #Derived.1;
|
let #Derived_gen.0 : Str = CallByName Encode.23 #Derived.1;
|
||||||
ret #Derived_gen.0;
|
ret #Derived_gen.0;
|
||||||
|
|
||||||
procedure #Derived.3 (#Derived.4, #Derived.5, #Derived.1):
|
procedure #Derived.3 (#Derived.4, #Derived.5, #Derived.1):
|
||||||
joinpoint #Derived_gen.5 #Derived_gen.4:
|
joinpoint #Derived_gen.5 #Derived_gen.4:
|
||||||
let #Derived_gen.3 : List U8 = CallByName Encode.23 #Derived.4 #Derived_gen.4 #Derived.5;
|
let #Derived_gen.3 : List U8 = CallByName Encode.24 #Derived.4 #Derived_gen.4 #Derived.5;
|
||||||
ret #Derived_gen.3;
|
ret #Derived_gen.3;
|
||||||
in
|
in
|
||||||
let #Derived_gen.7 : Str = "A";
|
let #Derived_gen.7 : Str = "A";
|
||||||
let #Derived_gen.9 : Str = CallByName Json.18 #Derived.1;
|
let #Derived_gen.9 : Str = CallByName Json.18 #Derived.1;
|
||||||
let #Derived_gen.8 : List Str = Array [#Derived_gen.9];
|
let #Derived_gen.8 : List Str = Array [#Derived_gen.9];
|
||||||
let #Derived_gen.6 : {Str, List Str} = CallByName Json.21 #Derived_gen.7 #Derived_gen.8;
|
let #Derived_gen.6 : {Str, List Str} = CallByName Json.22 #Derived_gen.7 #Derived_gen.8;
|
||||||
jump #Derived_gen.5 #Derived_gen.6;
|
jump #Derived_gen.5 #Derived_gen.6;
|
||||||
|
|
||||||
procedure Encode.22 (Encode.93):
|
procedure Encode.23 (Encode.98):
|
||||||
ret Encode.93;
|
ret Encode.98;
|
||||||
|
|
||||||
procedure Encode.22 (Encode.93):
|
procedure Encode.23 (Encode.98):
|
||||||
ret Encode.93;
|
ret Encode.98;
|
||||||
|
|
||||||
procedure Encode.22 (Encode.93):
|
procedure Encode.23 (Encode.98):
|
||||||
ret Encode.93;
|
ret Encode.98;
|
||||||
|
|
||||||
procedure Encode.23 (Encode.94, Encode.102, Encode.96):
|
procedure Encode.24 (Encode.99, Encode.107, Encode.101):
|
||||||
let Encode.106 : List U8 = CallByName #Derived.3 Encode.94 Encode.96 Encode.102;
|
let Encode.111 : List U8 = CallByName #Derived.3 Encode.99 Encode.101 Encode.107;
|
||||||
ret Encode.106;
|
ret Encode.111;
|
||||||
|
|
||||||
procedure Encode.23 (Encode.94, Encode.102, Encode.96):
|
procedure Encode.24 (Encode.99, Encode.107, Encode.101):
|
||||||
let Encode.113 : List U8 = CallByName Json.128 Encode.94 Encode.96 Encode.102;
|
let Encode.118 : List U8 = CallByName Json.144 Encode.99 Encode.101 Encode.107;
|
||||||
ret Encode.113;
|
ret Encode.118;
|
||||||
|
|
||||||
procedure Encode.23 (Encode.94, Encode.102, Encode.96):
|
procedure Encode.24 (Encode.99, Encode.107, Encode.101):
|
||||||
let Encode.116 : List U8 = CallByName Json.98 Encode.94 Encode.96 Encode.102;
|
let Encode.121 : List U8 = CallByName Json.102 Encode.99 Encode.101 Encode.107;
|
||||||
ret Encode.116;
|
ret Encode.121;
|
||||||
|
|
||||||
procedure Encode.25 (Encode.100, Encode.101):
|
procedure Encode.26 (Encode.105, Encode.106):
|
||||||
let Encode.104 : List U8 = Array [];
|
let Encode.109 : List U8 = Array [];
|
||||||
let Encode.105 : Str = CallByName #Derived.0 Encode.100;
|
let Encode.110 : Str = CallByName #Derived.0 Encode.105;
|
||||||
let Encode.103 : List U8 = CallByName Encode.23 Encode.104 Encode.105 Encode.101;
|
let Encode.108 : List U8 = CallByName Encode.24 Encode.109 Encode.110 Encode.106;
|
||||||
ret Encode.103;
|
ret Encode.108;
|
||||||
|
|
||||||
procedure Json.1 ():
|
procedure Json.1 ():
|
||||||
let Json.425 : {} = Struct {};
|
let Json.483 : {} = Struct {};
|
||||||
ret Json.425;
|
ret Json.483;
|
||||||
|
|
||||||
procedure Json.128 (Json.129, Json.428, #Attr.12):
|
procedure Json.102 (Json.103, Json.527, Json.101):
|
||||||
let Json.127 : List Str = StructAtIndex 1 #Attr.12;
|
let Json.536 : I64 = 34i64;
|
||||||
inc Json.127;
|
let Json.535 : U8 = CallByName Num.127 Json.536;
|
||||||
let Json.126 : Str = StructAtIndex 0 #Attr.12;
|
let Json.533 : List U8 = CallByName List.4 Json.103 Json.535;
|
||||||
inc Json.126;
|
let Json.534 : List U8 = CallByName Str.12 Json.101;
|
||||||
|
let Json.530 : List U8 = CallByName List.8 Json.533 Json.534;
|
||||||
|
let Json.532 : I64 = 34i64;
|
||||||
|
let Json.531 : U8 = CallByName Num.127 Json.532;
|
||||||
|
let Json.529 : List U8 = CallByName List.4 Json.530 Json.531;
|
||||||
|
ret Json.529;
|
||||||
|
|
||||||
|
procedure Json.144 (Json.145, Json.486, #Attr.12):
|
||||||
|
let Json.143 : List Str = StructAtIndex 1 #Attr.12;
|
||||||
|
inc Json.143;
|
||||||
|
let Json.142 : Str = StructAtIndex 0 #Attr.12;
|
||||||
|
inc Json.142;
|
||||||
dec #Attr.12;
|
dec #Attr.12;
|
||||||
let Json.466 : I64 = 123i64;
|
let Json.524 : I64 = 123i64;
|
||||||
let Json.465 : U8 = CallByName Num.127 Json.466;
|
let Json.523 : U8 = CallByName Num.127 Json.524;
|
||||||
let Json.462 : List U8 = CallByName List.4 Json.129 Json.465;
|
let Json.520 : List U8 = CallByName List.4 Json.145 Json.523;
|
||||||
let Json.464 : I64 = 34i64;
|
let Json.522 : I64 = 34i64;
|
||||||
let Json.463 : U8 = CallByName Num.127 Json.464;
|
let Json.521 : U8 = CallByName Num.127 Json.522;
|
||||||
let Json.460 : List U8 = CallByName List.4 Json.462 Json.463;
|
let Json.518 : List U8 = CallByName List.4 Json.520 Json.521;
|
||||||
let Json.461 : List U8 = CallByName Str.12 Json.126;
|
let Json.519 : List U8 = CallByName Str.12 Json.142;
|
||||||
let Json.457 : List U8 = CallByName List.8 Json.460 Json.461;
|
let Json.515 : List U8 = CallByName List.8 Json.518 Json.519;
|
||||||
let Json.459 : I64 = 34i64;
|
let Json.517 : I64 = 34i64;
|
||||||
let Json.458 : U8 = CallByName Num.127 Json.459;
|
let Json.516 : U8 = CallByName Num.127 Json.517;
|
||||||
let Json.454 : List U8 = CallByName List.4 Json.457 Json.458;
|
let Json.512 : List U8 = CallByName List.4 Json.515 Json.516;
|
||||||
let Json.456 : I64 = 58i64;
|
let Json.514 : I64 = 58i64;
|
||||||
let Json.455 : U8 = CallByName Num.127 Json.456;
|
let Json.513 : U8 = CallByName Num.127 Json.514;
|
||||||
let Json.451 : List U8 = CallByName List.4 Json.454 Json.455;
|
let Json.509 : List U8 = CallByName List.4 Json.512 Json.513;
|
||||||
let Json.453 : I64 = 91i64;
|
let Json.511 : I64 = 91i64;
|
||||||
let Json.452 : U8 = CallByName Num.127 Json.453;
|
let Json.510 : U8 = CallByName Num.127 Json.511;
|
||||||
let Json.131 : List U8 = CallByName List.4 Json.451 Json.452;
|
let Json.147 : List U8 = CallByName List.4 Json.509 Json.510;
|
||||||
let Json.450 : U64 = CallByName List.6 Json.127;
|
let Json.508 : U64 = CallByName List.6 Json.143;
|
||||||
let Json.438 : {List U8, U64} = Struct {Json.131, Json.450};
|
let Json.496 : {List U8, U64} = Struct {Json.147, Json.508};
|
||||||
let Json.439 : {} = Struct {};
|
let Json.497 : {} = Struct {};
|
||||||
let Json.437 : {List U8, U64} = CallByName List.18 Json.127 Json.438 Json.439;
|
let Json.495 : {List U8, U64} = CallByName List.18 Json.143 Json.496 Json.497;
|
||||||
dec Json.127;
|
dec Json.143;
|
||||||
let Json.133 : List U8 = StructAtIndex 0 Json.437;
|
let Json.149 : List U8 = StructAtIndex 0 Json.495;
|
||||||
inc Json.133;
|
inc Json.149;
|
||||||
dec Json.437;
|
dec Json.495;
|
||||||
let Json.436 : I64 = 93i64;
|
let Json.494 : I64 = 93i64;
|
||||||
let Json.435 : U8 = CallByName Num.127 Json.436;
|
let Json.493 : U8 = CallByName Num.127 Json.494;
|
||||||
let Json.432 : List U8 = CallByName List.4 Json.133 Json.435;
|
let Json.490 : List U8 = CallByName List.4 Json.149 Json.493;
|
||||||
let Json.434 : I64 = 125i64;
|
let Json.492 : I64 = 125i64;
|
||||||
let Json.433 : U8 = CallByName Num.127 Json.434;
|
let Json.491 : U8 = CallByName Num.127 Json.492;
|
||||||
let Json.431 : List U8 = CallByName List.4 Json.432 Json.433;
|
let Json.489 : List U8 = CallByName List.4 Json.490 Json.491;
|
||||||
ret Json.431;
|
ret Json.489;
|
||||||
|
|
||||||
procedure Json.130 (Json.430, Json.136):
|
procedure Json.146 (Json.488, Json.152):
|
||||||
let Json.134 : List U8 = StructAtIndex 0 Json.430;
|
let Json.150 : List U8 = StructAtIndex 0 Json.488;
|
||||||
inc Json.134;
|
inc Json.150;
|
||||||
let Json.135 : U64 = StructAtIndex 1 Json.430;
|
let Json.151 : U64 = StructAtIndex 1 Json.488;
|
||||||
dec Json.430;
|
dec Json.488;
|
||||||
let Json.449 : {} = Struct {};
|
let Json.507 : {} = Struct {};
|
||||||
let Json.137 : List U8 = CallByName Encode.23 Json.134 Json.136 Json.449;
|
let Json.153 : List U8 = CallByName Encode.24 Json.150 Json.152 Json.507;
|
||||||
joinpoint Json.444 Json.138:
|
joinpoint Json.502 Json.154:
|
||||||
let Json.442 : U64 = 1i64;
|
let Json.500 : U64 = 1i64;
|
||||||
let Json.441 : U64 = CallByName Num.20 Json.135 Json.442;
|
let Json.499 : U64 = CallByName Num.20 Json.151 Json.500;
|
||||||
let Json.440 : {List U8, U64} = Struct {Json.138, Json.441};
|
let Json.498 : {List U8, U64} = Struct {Json.154, Json.499};
|
||||||
ret Json.440;
|
ret Json.498;
|
||||||
in
|
in
|
||||||
let Json.448 : U64 = 1i64;
|
let Json.506 : U64 = 1i64;
|
||||||
let Json.445 : Int1 = CallByName Num.24 Json.135 Json.448;
|
let Json.503 : Int1 = CallByName Num.24 Json.151 Json.506;
|
||||||
if Json.445 then
|
if Json.503 then
|
||||||
let Json.447 : I64 = 44i64;
|
let Json.505 : I64 = 44i64;
|
||||||
let Json.446 : U8 = CallByName Num.127 Json.447;
|
let Json.504 : U8 = CallByName Num.127 Json.505;
|
||||||
let Json.443 : List U8 = CallByName List.4 Json.137 Json.446;
|
let Json.501 : List U8 = CallByName List.4 Json.153 Json.504;
|
||||||
jump Json.444 Json.443;
|
jump Json.502 Json.501;
|
||||||
else
|
else
|
||||||
jump Json.444 Json.137;
|
jump Json.502 Json.153;
|
||||||
|
|
||||||
procedure Json.18 (Json.97):
|
procedure Json.18 (Json.101):
|
||||||
let Json.467 : Str = CallByName Encode.22 Json.97;
|
let Json.525 : Str = CallByName Encode.23 Json.101;
|
||||||
ret Json.467;
|
ret Json.525;
|
||||||
|
|
||||||
procedure Json.21 (Json.126, Json.127):
|
procedure Json.22 (Json.142, Json.143):
|
||||||
let Json.427 : {Str, List Str} = Struct {Json.126, Json.127};
|
let Json.485 : {Str, List Str} = Struct {Json.142, Json.143};
|
||||||
let Json.426 : {Str, List Str} = CallByName Encode.22 Json.427;
|
let Json.484 : {Str, List Str} = CallByName Encode.23 Json.485;
|
||||||
ret Json.426;
|
ret Json.484;
|
||||||
|
|
||||||
procedure Json.98 (Json.99, Json.469, Json.97):
|
|
||||||
let Json.478 : I64 = 34i64;
|
|
||||||
let Json.477 : U8 = CallByName Num.127 Json.478;
|
|
||||||
let Json.475 : List U8 = CallByName List.4 Json.99 Json.477;
|
|
||||||
let Json.476 : List U8 = CallByName Str.12 Json.97;
|
|
||||||
let Json.472 : List U8 = CallByName List.8 Json.475 Json.476;
|
|
||||||
let Json.474 : I64 = 34i64;
|
|
||||||
let Json.473 : U8 = CallByName Num.127 Json.474;
|
|
||||||
let Json.471 : List U8 = CallByName List.4 Json.472 Json.473;
|
|
||||||
ret Json.471;
|
|
||||||
|
|
||||||
procedure List.139 (List.140, List.141, List.138):
|
procedure List.139 (List.140, List.141, List.138):
|
||||||
let List.547 : {List U8, U64} = CallByName Json.130 List.140 List.141;
|
let List.547 : {List U8, U64} = CallByName Json.146 List.140 List.141;
|
||||||
ret List.547;
|
ret List.547;
|
||||||
|
|
||||||
procedure List.18 (List.136, List.137, List.138):
|
procedure List.18 (List.136, List.137, List.138):
|
||||||
|
@ -234,7 +234,7 @@ procedure Str.9 (Str.77):
|
||||||
procedure Test.0 ():
|
procedure Test.0 ():
|
||||||
let Test.12 : Str = "foo";
|
let Test.12 : Str = "foo";
|
||||||
let Test.11 : {} = CallByName Json.1;
|
let Test.11 : {} = CallByName Json.1;
|
||||||
let Test.10 : List U8 = CallByName Encode.25 Test.12 Test.11;
|
let Test.10 : List U8 = CallByName Encode.26 Test.12 Test.11;
|
||||||
let Test.2 : [C {U64, U8}, C Str] = CallByName Str.9 Test.10;
|
let Test.2 : [C {U64, U8}, C Str] = CallByName Str.9 Test.10;
|
||||||
let Test.7 : U8 = 1i64;
|
let Test.7 : U8 = 1i64;
|
||||||
let Test.8 : U8 = GetTagId Test.2;
|
let Test.8 : U8 = GetTagId Test.2;
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
procedure #Derived.0 (#Derived.1):
|
procedure #Derived.0 (#Derived.1):
|
||||||
let #Derived_gen.0 : {Str, Str} = CallByName Encode.22 #Derived.1;
|
let #Derived_gen.0 : {Str, Str} = CallByName Encode.23 #Derived.1;
|
||||||
ret #Derived_gen.0;
|
ret #Derived_gen.0;
|
||||||
|
|
||||||
procedure #Derived.4 (#Derived.5, #Derived.6, #Derived.1):
|
procedure #Derived.4 (#Derived.5, #Derived.6, #Derived.1):
|
||||||
joinpoint #Derived_gen.5 #Derived_gen.4:
|
joinpoint #Derived_gen.5 #Derived_gen.4:
|
||||||
let #Derived_gen.3 : List U8 = CallByName Encode.23 #Derived.5 #Derived_gen.4 #Derived.6;
|
let #Derived_gen.3 : List U8 = CallByName Encode.24 #Derived.5 #Derived_gen.4 #Derived.6;
|
||||||
ret #Derived_gen.3;
|
ret #Derived_gen.3;
|
||||||
in
|
in
|
||||||
let #Derived.2 : Str = StructAtIndex 0 #Derived.1;
|
let #Derived.2 : Str = StructAtIndex 0 #Derived.1;
|
||||||
|
@ -16,124 +16,124 @@ procedure #Derived.4 (#Derived.5, #Derived.6, #Derived.1):
|
||||||
let #Derived_gen.9 : Str = CallByName Json.18 #Derived.2;
|
let #Derived_gen.9 : Str = CallByName Json.18 #Derived.2;
|
||||||
let #Derived_gen.10 : Str = CallByName Json.18 #Derived.3;
|
let #Derived_gen.10 : Str = CallByName Json.18 #Derived.3;
|
||||||
let #Derived_gen.8 : List Str = Array [#Derived_gen.9, #Derived_gen.10];
|
let #Derived_gen.8 : List Str = Array [#Derived_gen.9, #Derived_gen.10];
|
||||||
let #Derived_gen.6 : {Str, List Str} = CallByName Json.21 #Derived_gen.7 #Derived_gen.8;
|
let #Derived_gen.6 : {Str, List Str} = CallByName Json.22 #Derived_gen.7 #Derived_gen.8;
|
||||||
jump #Derived_gen.5 #Derived_gen.6;
|
jump #Derived_gen.5 #Derived_gen.6;
|
||||||
|
|
||||||
procedure Encode.22 (Encode.93):
|
procedure Encode.23 (Encode.98):
|
||||||
ret Encode.93;
|
ret Encode.98;
|
||||||
|
|
||||||
procedure Encode.22 (Encode.93):
|
procedure Encode.23 (Encode.98):
|
||||||
ret Encode.93;
|
ret Encode.98;
|
||||||
|
|
||||||
procedure Encode.22 (Encode.93):
|
procedure Encode.23 (Encode.98):
|
||||||
ret Encode.93;
|
ret Encode.98;
|
||||||
|
|
||||||
procedure Encode.23 (Encode.94, Encode.102, Encode.96):
|
procedure Encode.24 (Encode.99, Encode.107, Encode.101):
|
||||||
let Encode.106 : List U8 = CallByName #Derived.4 Encode.94 Encode.96 Encode.102;
|
let Encode.111 : List U8 = CallByName #Derived.4 Encode.99 Encode.101 Encode.107;
|
||||||
ret Encode.106;
|
ret Encode.111;
|
||||||
|
|
||||||
procedure Encode.23 (Encode.94, Encode.102, Encode.96):
|
procedure Encode.24 (Encode.99, Encode.107, Encode.101):
|
||||||
let Encode.113 : List U8 = CallByName Json.128 Encode.94 Encode.96 Encode.102;
|
let Encode.118 : List U8 = CallByName Json.144 Encode.99 Encode.101 Encode.107;
|
||||||
ret Encode.113;
|
ret Encode.118;
|
||||||
|
|
||||||
procedure Encode.23 (Encode.94, Encode.102, Encode.96):
|
procedure Encode.24 (Encode.99, Encode.107, Encode.101):
|
||||||
let Encode.117 : List U8 = CallByName Json.98 Encode.94 Encode.96 Encode.102;
|
let Encode.122 : List U8 = CallByName Json.102 Encode.99 Encode.101 Encode.107;
|
||||||
ret Encode.117;
|
ret Encode.122;
|
||||||
|
|
||||||
procedure Encode.25 (Encode.100, Encode.101):
|
procedure Encode.26 (Encode.105, Encode.106):
|
||||||
let Encode.104 : List U8 = Array [];
|
let Encode.109 : List U8 = Array [];
|
||||||
let Encode.105 : {Str, Str} = CallByName #Derived.0 Encode.100;
|
let Encode.110 : {Str, Str} = CallByName #Derived.0 Encode.105;
|
||||||
let Encode.103 : List U8 = CallByName Encode.23 Encode.104 Encode.105 Encode.101;
|
let Encode.108 : List U8 = CallByName Encode.24 Encode.109 Encode.110 Encode.106;
|
||||||
ret Encode.103;
|
ret Encode.108;
|
||||||
|
|
||||||
procedure Json.1 ():
|
procedure Json.1 ():
|
||||||
let Json.425 : {} = Struct {};
|
let Json.483 : {} = Struct {};
|
||||||
ret Json.425;
|
ret Json.483;
|
||||||
|
|
||||||
procedure Json.128 (Json.129, Json.428, #Attr.12):
|
procedure Json.102 (Json.103, Json.527, Json.101):
|
||||||
let Json.127 : List Str = StructAtIndex 1 #Attr.12;
|
let Json.536 : I64 = 34i64;
|
||||||
inc Json.127;
|
let Json.535 : U8 = CallByName Num.127 Json.536;
|
||||||
let Json.126 : Str = StructAtIndex 0 #Attr.12;
|
let Json.533 : List U8 = CallByName List.4 Json.103 Json.535;
|
||||||
inc Json.126;
|
let Json.534 : List U8 = CallByName Str.12 Json.101;
|
||||||
|
let Json.530 : List U8 = CallByName List.8 Json.533 Json.534;
|
||||||
|
let Json.532 : I64 = 34i64;
|
||||||
|
let Json.531 : U8 = CallByName Num.127 Json.532;
|
||||||
|
let Json.529 : List U8 = CallByName List.4 Json.530 Json.531;
|
||||||
|
ret Json.529;
|
||||||
|
|
||||||
|
procedure Json.144 (Json.145, Json.486, #Attr.12):
|
||||||
|
let Json.143 : List Str = StructAtIndex 1 #Attr.12;
|
||||||
|
inc Json.143;
|
||||||
|
let Json.142 : Str = StructAtIndex 0 #Attr.12;
|
||||||
|
inc Json.142;
|
||||||
dec #Attr.12;
|
dec #Attr.12;
|
||||||
let Json.466 : I64 = 123i64;
|
let Json.524 : I64 = 123i64;
|
||||||
let Json.465 : U8 = CallByName Num.127 Json.466;
|
let Json.523 : U8 = CallByName Num.127 Json.524;
|
||||||
let Json.462 : List U8 = CallByName List.4 Json.129 Json.465;
|
let Json.520 : List U8 = CallByName List.4 Json.145 Json.523;
|
||||||
let Json.464 : I64 = 34i64;
|
let Json.522 : I64 = 34i64;
|
||||||
let Json.463 : U8 = CallByName Num.127 Json.464;
|
let Json.521 : U8 = CallByName Num.127 Json.522;
|
||||||
let Json.460 : List U8 = CallByName List.4 Json.462 Json.463;
|
let Json.518 : List U8 = CallByName List.4 Json.520 Json.521;
|
||||||
let Json.461 : List U8 = CallByName Str.12 Json.126;
|
let Json.519 : List U8 = CallByName Str.12 Json.142;
|
||||||
let Json.457 : List U8 = CallByName List.8 Json.460 Json.461;
|
let Json.515 : List U8 = CallByName List.8 Json.518 Json.519;
|
||||||
let Json.459 : I64 = 34i64;
|
let Json.517 : I64 = 34i64;
|
||||||
let Json.458 : U8 = CallByName Num.127 Json.459;
|
let Json.516 : U8 = CallByName Num.127 Json.517;
|
||||||
let Json.454 : List U8 = CallByName List.4 Json.457 Json.458;
|
let Json.512 : List U8 = CallByName List.4 Json.515 Json.516;
|
||||||
let Json.456 : I64 = 58i64;
|
let Json.514 : I64 = 58i64;
|
||||||
let Json.455 : U8 = CallByName Num.127 Json.456;
|
let Json.513 : U8 = CallByName Num.127 Json.514;
|
||||||
let Json.451 : List U8 = CallByName List.4 Json.454 Json.455;
|
let Json.509 : List U8 = CallByName List.4 Json.512 Json.513;
|
||||||
let Json.453 : I64 = 91i64;
|
let Json.511 : I64 = 91i64;
|
||||||
let Json.452 : U8 = CallByName Num.127 Json.453;
|
let Json.510 : U8 = CallByName Num.127 Json.511;
|
||||||
let Json.131 : List U8 = CallByName List.4 Json.451 Json.452;
|
let Json.147 : List U8 = CallByName List.4 Json.509 Json.510;
|
||||||
let Json.450 : U64 = CallByName List.6 Json.127;
|
let Json.508 : U64 = CallByName List.6 Json.143;
|
||||||
let Json.438 : {List U8, U64} = Struct {Json.131, Json.450};
|
let Json.496 : {List U8, U64} = Struct {Json.147, Json.508};
|
||||||
let Json.439 : {} = Struct {};
|
let Json.497 : {} = Struct {};
|
||||||
let Json.437 : {List U8, U64} = CallByName List.18 Json.127 Json.438 Json.439;
|
let Json.495 : {List U8, U64} = CallByName List.18 Json.143 Json.496 Json.497;
|
||||||
dec Json.127;
|
dec Json.143;
|
||||||
let Json.133 : List U8 = StructAtIndex 0 Json.437;
|
let Json.149 : List U8 = StructAtIndex 0 Json.495;
|
||||||
inc Json.133;
|
inc Json.149;
|
||||||
dec Json.437;
|
dec Json.495;
|
||||||
let Json.436 : I64 = 93i64;
|
let Json.494 : I64 = 93i64;
|
||||||
let Json.435 : U8 = CallByName Num.127 Json.436;
|
let Json.493 : U8 = CallByName Num.127 Json.494;
|
||||||
let Json.432 : List U8 = CallByName List.4 Json.133 Json.435;
|
let Json.490 : List U8 = CallByName List.4 Json.149 Json.493;
|
||||||
let Json.434 : I64 = 125i64;
|
let Json.492 : I64 = 125i64;
|
||||||
let Json.433 : U8 = CallByName Num.127 Json.434;
|
let Json.491 : U8 = CallByName Num.127 Json.492;
|
||||||
let Json.431 : List U8 = CallByName List.4 Json.432 Json.433;
|
let Json.489 : List U8 = CallByName List.4 Json.490 Json.491;
|
||||||
ret Json.431;
|
ret Json.489;
|
||||||
|
|
||||||
procedure Json.130 (Json.430, Json.136):
|
procedure Json.146 (Json.488, Json.152):
|
||||||
let Json.134 : List U8 = StructAtIndex 0 Json.430;
|
let Json.150 : List U8 = StructAtIndex 0 Json.488;
|
||||||
inc Json.134;
|
inc Json.150;
|
||||||
let Json.135 : U64 = StructAtIndex 1 Json.430;
|
let Json.151 : U64 = StructAtIndex 1 Json.488;
|
||||||
dec Json.430;
|
dec Json.488;
|
||||||
let Json.449 : {} = Struct {};
|
let Json.507 : {} = Struct {};
|
||||||
let Json.137 : List U8 = CallByName Encode.23 Json.134 Json.136 Json.449;
|
let Json.153 : List U8 = CallByName Encode.24 Json.150 Json.152 Json.507;
|
||||||
joinpoint Json.444 Json.138:
|
joinpoint Json.502 Json.154:
|
||||||
let Json.442 : U64 = 1i64;
|
let Json.500 : U64 = 1i64;
|
||||||
let Json.441 : U64 = CallByName Num.20 Json.135 Json.442;
|
let Json.499 : U64 = CallByName Num.20 Json.151 Json.500;
|
||||||
let Json.440 : {List U8, U64} = Struct {Json.138, Json.441};
|
let Json.498 : {List U8, U64} = Struct {Json.154, Json.499};
|
||||||
ret Json.440;
|
ret Json.498;
|
||||||
in
|
in
|
||||||
let Json.448 : U64 = 1i64;
|
let Json.506 : U64 = 1i64;
|
||||||
let Json.445 : Int1 = CallByName Num.24 Json.135 Json.448;
|
let Json.503 : Int1 = CallByName Num.24 Json.151 Json.506;
|
||||||
if Json.445 then
|
if Json.503 then
|
||||||
let Json.447 : I64 = 44i64;
|
let Json.505 : I64 = 44i64;
|
||||||
let Json.446 : U8 = CallByName Num.127 Json.447;
|
let Json.504 : U8 = CallByName Num.127 Json.505;
|
||||||
let Json.443 : List U8 = CallByName List.4 Json.137 Json.446;
|
let Json.501 : List U8 = CallByName List.4 Json.153 Json.504;
|
||||||
jump Json.444 Json.443;
|
jump Json.502 Json.501;
|
||||||
else
|
else
|
||||||
jump Json.444 Json.137;
|
jump Json.502 Json.153;
|
||||||
|
|
||||||
procedure Json.18 (Json.97):
|
procedure Json.18 (Json.101):
|
||||||
let Json.479 : Str = CallByName Encode.22 Json.97;
|
let Json.537 : Str = CallByName Encode.23 Json.101;
|
||||||
ret Json.479;
|
ret Json.537;
|
||||||
|
|
||||||
procedure Json.21 (Json.126, Json.127):
|
procedure Json.22 (Json.142, Json.143):
|
||||||
let Json.427 : {Str, List Str} = Struct {Json.126, Json.127};
|
let Json.485 : {Str, List Str} = Struct {Json.142, Json.143};
|
||||||
let Json.426 : {Str, List Str} = CallByName Encode.22 Json.427;
|
let Json.484 : {Str, List Str} = CallByName Encode.23 Json.485;
|
||||||
ret Json.426;
|
ret Json.484;
|
||||||
|
|
||||||
procedure Json.98 (Json.99, Json.469, Json.97):
|
|
||||||
let Json.478 : I64 = 34i64;
|
|
||||||
let Json.477 : U8 = CallByName Num.127 Json.478;
|
|
||||||
let Json.475 : List U8 = CallByName List.4 Json.99 Json.477;
|
|
||||||
let Json.476 : List U8 = CallByName Str.12 Json.97;
|
|
||||||
let Json.472 : List U8 = CallByName List.8 Json.475 Json.476;
|
|
||||||
let Json.474 : I64 = 34i64;
|
|
||||||
let Json.473 : U8 = CallByName Num.127 Json.474;
|
|
||||||
let Json.471 : List U8 = CallByName List.4 Json.472 Json.473;
|
|
||||||
ret Json.471;
|
|
||||||
|
|
||||||
procedure List.139 (List.140, List.141, List.138):
|
procedure List.139 (List.140, List.141, List.138):
|
||||||
let List.547 : {List U8, U64} = CallByName Json.130 List.140 List.141;
|
let List.547 : {List U8, U64} = CallByName Json.146 List.140 List.141;
|
||||||
ret List.547;
|
ret List.547;
|
||||||
|
|
||||||
procedure List.18 (List.136, List.137, List.138):
|
procedure List.18 (List.136, List.137, List.138):
|
||||||
|
@ -242,7 +242,7 @@ procedure Test.0 ():
|
||||||
let Test.12 : Str = "foo";
|
let Test.12 : Str = "foo";
|
||||||
let Test.1 : {Str, Str} = Struct {Test.12, Test.13};
|
let Test.1 : {Str, Str} = Struct {Test.12, Test.13};
|
||||||
let Test.11 : {} = CallByName Json.1;
|
let Test.11 : {} = CallByName Json.1;
|
||||||
let Test.10 : List U8 = CallByName Encode.25 Test.1 Test.11;
|
let Test.10 : List U8 = CallByName Encode.26 Test.1 Test.11;
|
||||||
let Test.2 : [C {U64, U8}, C Str] = CallByName Str.9 Test.10;
|
let Test.2 : [C {U64, U8}, C Str] = CallByName Str.9 Test.10;
|
||||||
let Test.7 : U8 = 1i64;
|
let Test.7 : U8 = 1i64;
|
||||||
let Test.8 : U8 = GetTagId Test.2;
|
let Test.8 : U8 = GetTagId Test.2;
|
||||||
|
|
|
@ -28,229 +28,229 @@ procedure Bool.7 (Bool.19, Bool.20):
|
||||||
let Bool.37 : Int1 = CallByName Bool.12 Bool.19 Bool.20;
|
let Bool.37 : Int1 = CallByName Bool.12 Bool.19 Bool.20;
|
||||||
ret Bool.37;
|
ret Bool.37;
|
||||||
|
|
||||||
procedure Decode.23 (Decode.94):
|
procedure Decode.24 (Decode.101):
|
||||||
ret Decode.94;
|
ret Decode.101;
|
||||||
|
|
||||||
procedure Decode.24 (Decode.95, Decode.114, Decode.97):
|
procedure Decode.25 (Decode.102, Decode.121, Decode.104):
|
||||||
let Decode.127 : {List U8, [C {}, C Str]} = CallByName Json.299 Decode.95 Decode.97;
|
let Decode.134 : {List U8, [C {}, C Str]} = CallByName Json.315 Decode.102 Decode.104;
|
||||||
ret Decode.127;
|
ret Decode.134;
|
||||||
|
|
||||||
procedure Decode.25 (Decode.98, Decode.99):
|
procedure Decode.26 (Decode.105, Decode.106):
|
||||||
let Decode.126 : {} = CallByName Json.42;
|
let Decode.133 : {} = CallByName Json.43;
|
||||||
let Decode.125 : {List U8, [C {}, C Str]} = CallByName Decode.24 Decode.98 Decode.126 Decode.99;
|
let Decode.132 : {List U8, [C {}, C Str]} = CallByName Decode.25 Decode.105 Decode.133 Decode.106;
|
||||||
ret Decode.125;
|
ret Decode.132;
|
||||||
|
|
||||||
procedure Decode.26 (Decode.100, Decode.101):
|
procedure Decode.27 (Decode.107, Decode.108):
|
||||||
let Decode.115 : {List U8, [C {}, C Str]} = CallByName Decode.25 Decode.100 Decode.101;
|
let Decode.122 : {List U8, [C {}, C Str]} = CallByName Decode.26 Decode.107 Decode.108;
|
||||||
let Decode.103 : List U8 = StructAtIndex 0 Decode.115;
|
let Decode.110 : List U8 = StructAtIndex 0 Decode.122;
|
||||||
inc Decode.103;
|
inc Decode.110;
|
||||||
let Decode.102 : [C {}, C Str] = StructAtIndex 1 Decode.115;
|
let Decode.109 : [C {}, C Str] = StructAtIndex 1 Decode.122;
|
||||||
inc Decode.102;
|
inc Decode.109;
|
||||||
dec Decode.115;
|
dec Decode.122;
|
||||||
let Decode.118 : Int1 = CallByName List.1 Decode.103;
|
let Decode.125 : Int1 = CallByName List.1 Decode.110;
|
||||||
if Decode.118 then
|
if Decode.125 then
|
||||||
dec Decode.103;
|
dec Decode.110;
|
||||||
let Decode.122 : U8 = 1i64;
|
let Decode.129 : U8 = 1i64;
|
||||||
let Decode.123 : U8 = GetTagId Decode.102;
|
let Decode.130 : U8 = GetTagId Decode.109;
|
||||||
let Decode.124 : Int1 = lowlevel Eq Decode.122 Decode.123;
|
let Decode.131 : Int1 = lowlevel Eq Decode.129 Decode.130;
|
||||||
if Decode.124 then
|
if Decode.131 then
|
||||||
let Decode.104 : Str = UnionAtIndex (Id 1) (Index 0) Decode.102;
|
let Decode.111 : Str = UnionAtIndex (Id 1) (Index 0) Decode.109;
|
||||||
inc Decode.104;
|
inc Decode.111;
|
||||||
dec Decode.102;
|
dec Decode.109;
|
||||||
let Decode.119 : [C [C List U8, C ], C Str] = TagId(1) Decode.104;
|
let Decode.126 : [C [C List U8, C ], C Str] = TagId(1) Decode.111;
|
||||||
ret Decode.119;
|
ret Decode.126;
|
||||||
else
|
else
|
||||||
dec Decode.102;
|
dec Decode.109;
|
||||||
let Decode.121 : [C List U8, C ] = TagId(1) ;
|
let Decode.128 : [C List U8, C ] = TagId(1) ;
|
||||||
let Decode.120 : [C [C List U8, C ], C Str] = TagId(0) Decode.121;
|
let Decode.127 : [C [C List U8, C ], C Str] = TagId(0) Decode.128;
|
||||||
ret Decode.120;
|
ret Decode.127;
|
||||||
else
|
else
|
||||||
dec Decode.102;
|
dec Decode.109;
|
||||||
let Decode.117 : [C List U8, C ] = TagId(0) Decode.103;
|
let Decode.124 : [C List U8, C ] = TagId(0) Decode.110;
|
||||||
let Decode.116 : [C [C List U8, C ], C Str] = TagId(0) Decode.117;
|
let Decode.123 : [C [C List U8, C ], C Str] = TagId(0) Decode.124;
|
||||||
ret Decode.116;
|
ret Decode.123;
|
||||||
|
|
||||||
procedure Json.144 (Json.512, Json.513):
|
procedure Json.160 (Json.570, Json.571):
|
||||||
joinpoint Json.450 Json.447 Json.143:
|
joinpoint Json.508 Json.505 Json.159:
|
||||||
let Json.146 : List U8 = StructAtIndex 0 Json.447;
|
let Json.162 : List U8 = StructAtIndex 0 Json.505;
|
||||||
inc Json.146;
|
inc Json.162;
|
||||||
let Json.145 : List U8 = StructAtIndex 1 Json.447;
|
let Json.161 : List U8 = StructAtIndex 1 Json.505;
|
||||||
inc Json.145;
|
inc Json.161;
|
||||||
dec Json.447;
|
dec Json.505;
|
||||||
joinpoint Json.490:
|
joinpoint Json.548:
|
||||||
let Json.487 : {List U8, List U8} = Struct {Json.146, Json.145};
|
let Json.545 : {List U8, List U8} = Struct {Json.162, Json.161};
|
||||||
ret Json.487;
|
ret Json.545;
|
||||||
in
|
in
|
||||||
let Json.496 : U64 = lowlevel ListLen Json.146;
|
let Json.554 : U64 = lowlevel ListLen Json.162;
|
||||||
let Json.497 : U64 = 2i64;
|
let Json.555 : U64 = 2i64;
|
||||||
let Json.498 : Int1 = lowlevel NumGte Json.496 Json.497;
|
let Json.556 : Int1 = lowlevel NumGte Json.554 Json.555;
|
||||||
if Json.498 then
|
if Json.556 then
|
||||||
let Json.489 : U64 = 0i64;
|
let Json.547 : U64 = 0i64;
|
||||||
let Json.147 : U8 = lowlevel ListGetUnsafe Json.146 Json.489;
|
let Json.163 : U8 = lowlevel ListGetUnsafe Json.162 Json.547;
|
||||||
let Json.488 : U64 = 1i64;
|
let Json.546 : U64 = 1i64;
|
||||||
let Json.148 : U8 = lowlevel ListGetUnsafe Json.146 Json.488;
|
let Json.164 : U8 = lowlevel ListGetUnsafe Json.162 Json.546;
|
||||||
let Json.458 : Int1 = CallByName Json.22 Json.147 Json.148;
|
let Json.516 : Int1 = CallByName Json.23 Json.163 Json.164;
|
||||||
if Json.458 then
|
if Json.516 then
|
||||||
let Json.465 : U64 = 2i64;
|
let Json.523 : U64 = 2i64;
|
||||||
let Json.462 : List U8 = CallByName List.29 Json.146 Json.465;
|
let Json.520 : List U8 = CallByName List.29 Json.162 Json.523;
|
||||||
let Json.464 : List U8 = CallByName List.4 Json.145 Json.147;
|
let Json.522 : List U8 = CallByName List.4 Json.161 Json.163;
|
||||||
let Json.463 : List U8 = CallByName List.4 Json.464 Json.148;
|
let Json.521 : List U8 = CallByName List.4 Json.522 Json.164;
|
||||||
let Json.460 : {List U8, List U8} = Struct {Json.462, Json.463};
|
let Json.518 : {List U8, List U8} = Struct {Json.520, Json.521};
|
||||||
jump Json.450 Json.460 Json.143;
|
jump Json.508 Json.518 Json.159;
|
||||||
else
|
else
|
||||||
let Json.452 : Int1 = CallByName Json.289 Json.147;
|
let Json.510 : Int1 = CallByName Json.305 Json.163;
|
||||||
if Json.452 then
|
if Json.510 then
|
||||||
let Json.456 : List U8 = CallByName List.38 Json.146;
|
let Json.514 : List U8 = CallByName List.38 Json.162;
|
||||||
let Json.457 : List U8 = CallByName List.4 Json.145 Json.147;
|
let Json.515 : List U8 = CallByName List.4 Json.161 Json.163;
|
||||||
let Json.454 : {List U8, List U8} = Struct {Json.456, Json.457};
|
let Json.512 : {List U8, List U8} = Struct {Json.514, Json.515};
|
||||||
jump Json.450 Json.454 Json.143;
|
jump Json.508 Json.512 Json.159;
|
||||||
else
|
else
|
||||||
let Json.451 : {List U8, List U8} = Struct {Json.146, Json.145};
|
let Json.509 : {List U8, List U8} = Struct {Json.162, Json.161};
|
||||||
ret Json.451;
|
ret Json.509;
|
||||||
else
|
else
|
||||||
let Json.493 : U64 = lowlevel ListLen Json.146;
|
let Json.551 : U64 = lowlevel ListLen Json.162;
|
||||||
let Json.494 : U64 = 1i64;
|
let Json.552 : U64 = 1i64;
|
||||||
let Json.495 : Int1 = lowlevel NumGte Json.493 Json.494;
|
let Json.553 : Int1 = lowlevel NumGte Json.551 Json.552;
|
||||||
if Json.495 then
|
if Json.553 then
|
||||||
let Json.492 : U64 = 0i64;
|
let Json.550 : U64 = 0i64;
|
||||||
let Json.149 : U8 = lowlevel ListGetUnsafe Json.146 Json.492;
|
let Json.165 : U8 = lowlevel ListGetUnsafe Json.162 Json.550;
|
||||||
joinpoint Json.485 Json.491:
|
joinpoint Json.543 Json.549:
|
||||||
if Json.491 then
|
if Json.549 then
|
||||||
let Json.483 : List U8 = CallByName List.38 Json.146;
|
let Json.541 : List U8 = CallByName List.38 Json.162;
|
||||||
let Json.484 : List U8 = CallByName List.4 Json.145 Json.149;
|
let Json.542 : List U8 = CallByName List.4 Json.161 Json.165;
|
||||||
let Json.481 : {List U8, List U8} = Struct {Json.483, Json.484};
|
let Json.539 : {List U8, List U8} = Struct {Json.541, Json.542};
|
||||||
jump Json.450 Json.481 Json.143;
|
jump Json.508 Json.539 Json.159;
|
||||||
else
|
else
|
||||||
jump Json.490;
|
jump Json.548;
|
||||||
in
|
in
|
||||||
let Json.486 : Int1 = CallByName Json.289 Json.149;
|
let Json.544 : Int1 = CallByName Json.305 Json.165;
|
||||||
jump Json.485 Json.486;
|
jump Json.543 Json.544;
|
||||||
else
|
else
|
||||||
jump Json.490;
|
jump Json.548;
|
||||||
in
|
in
|
||||||
jump Json.450 Json.512 Json.513;
|
jump Json.508 Json.570 Json.571;
|
||||||
|
|
||||||
procedure Json.2 ():
|
procedure Json.2 ():
|
||||||
let Json.425 : {} = Struct {};
|
let Json.483 : {} = Struct {};
|
||||||
ret Json.425;
|
ret Json.483;
|
||||||
|
|
||||||
procedure Json.22 (Json.139, Json.140):
|
procedure Json.23 (Json.155, Json.156):
|
||||||
let Json.466 : {U8, U8} = Struct {Json.139, Json.140};
|
let Json.524 : {U8, U8} = Struct {Json.155, Json.156};
|
||||||
joinpoint Json.475:
|
joinpoint Json.533:
|
||||||
let Json.474 : Int1 = CallByName Bool.1;
|
let Json.532 : Int1 = CallByName Bool.1;
|
||||||
ret Json.474;
|
ret Json.532;
|
||||||
in
|
in
|
||||||
let Json.477 : U8 = StructAtIndex 0 Json.466;
|
let Json.535 : U8 = StructAtIndex 0 Json.524;
|
||||||
let Json.478 : U8 = 92i64;
|
let Json.536 : U8 = 92i64;
|
||||||
let Json.479 : Int1 = lowlevel Eq Json.478 Json.477;
|
let Json.537 : Int1 = lowlevel Eq Json.536 Json.535;
|
||||||
if Json.479 then
|
if Json.537 then
|
||||||
let Json.476 : U8 = StructAtIndex 1 Json.466;
|
let Json.534 : U8 = StructAtIndex 1 Json.524;
|
||||||
switch Json.476:
|
switch Json.534:
|
||||||
case 98:
|
case 98:
|
||||||
let Json.467 : Int1 = CallByName Bool.2;
|
let Json.525 : Int1 = CallByName Bool.2;
|
||||||
ret Json.467;
|
ret Json.525;
|
||||||
|
|
||||||
case 102:
|
case 102:
|
||||||
let Json.468 : Int1 = CallByName Bool.2;
|
let Json.526 : Int1 = CallByName Bool.2;
|
||||||
ret Json.468;
|
ret Json.526;
|
||||||
|
|
||||||
case 110:
|
case 110:
|
||||||
let Json.469 : Int1 = CallByName Bool.2;
|
let Json.527 : Int1 = CallByName Bool.2;
|
||||||
ret Json.469;
|
ret Json.527;
|
||||||
|
|
||||||
case 114:
|
case 114:
|
||||||
let Json.470 : Int1 = CallByName Bool.2;
|
let Json.528 : Int1 = CallByName Bool.2;
|
||||||
ret Json.470;
|
ret Json.528;
|
||||||
|
|
||||||
case 116:
|
case 116:
|
||||||
let Json.471 : Int1 = CallByName Bool.2;
|
let Json.529 : Int1 = CallByName Bool.2;
|
||||||
ret Json.471;
|
ret Json.529;
|
||||||
|
|
||||||
case 34:
|
case 34:
|
||||||
let Json.472 : Int1 = CallByName Bool.2;
|
let Json.530 : Int1 = CallByName Bool.2;
|
||||||
ret Json.472;
|
ret Json.530;
|
||||||
|
|
||||||
case 92:
|
case 92:
|
||||||
let Json.473 : Int1 = CallByName Bool.2;
|
let Json.531 : Int1 = CallByName Bool.2;
|
||||||
ret Json.473;
|
ret Json.531;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
jump Json.475;
|
jump Json.533;
|
||||||
|
|
||||||
else
|
else
|
||||||
jump Json.475;
|
jump Json.533;
|
||||||
|
|
||||||
procedure Json.23 (Json.142, Json.143):
|
procedure Json.24 (Json.158, Json.159):
|
||||||
let Json.500 : List U8 = Array [];
|
let Json.558 : List U8 = Array [];
|
||||||
let Json.449 : {List U8, List U8} = Struct {Json.142, Json.500};
|
let Json.507 : {List U8, List U8} = Struct {Json.158, Json.558};
|
||||||
let Json.448 : {List U8, List U8} = CallByName Json.144 Json.449 Json.143;
|
let Json.506 : {List U8, List U8} = CallByName Json.160 Json.507 Json.159;
|
||||||
ret Json.448;
|
ret Json.506;
|
||||||
|
|
||||||
procedure Json.289 (Json.290):
|
procedure Json.305 (Json.306):
|
||||||
let Json.502 : U8 = 34i64;
|
let Json.560 : U8 = 34i64;
|
||||||
let Json.501 : Int1 = CallByName Bool.7 Json.290 Json.502;
|
let Json.559 : Int1 = CallByName Bool.7 Json.306 Json.560;
|
||||||
ret Json.501;
|
ret Json.559;
|
||||||
|
|
||||||
procedure Json.299 (Json.300, Json.428):
|
procedure Json.315 (Json.316, Json.486):
|
||||||
let Json.429 : {List U8, [C {}, C Str]} = CallByName Json.41 Json.300;
|
let Json.487 : {List U8, [C {}, C Str]} = CallByName Json.42 Json.316;
|
||||||
ret Json.429;
|
ret Json.487;
|
||||||
|
|
||||||
procedure Json.41 (Json.282):
|
procedure Json.42 (Json.298):
|
||||||
let Json.506 : U64 = 1i64;
|
let Json.564 : U64 = 1i64;
|
||||||
inc Json.282;
|
inc Json.298;
|
||||||
let Json.505 : {List U8, List U8} = CallByName List.52 Json.282 Json.506;
|
let Json.563 : {List U8, List U8} = CallByName List.52 Json.298 Json.564;
|
||||||
let Json.283 : List U8 = StructAtIndex 0 Json.505;
|
let Json.299 : List U8 = StructAtIndex 0 Json.563;
|
||||||
inc Json.283;
|
inc Json.299;
|
||||||
let Json.285 : List U8 = StructAtIndex 1 Json.505;
|
let Json.301 : List U8 = StructAtIndex 1 Json.563;
|
||||||
inc Json.285;
|
inc Json.301;
|
||||||
dec Json.505;
|
dec Json.563;
|
||||||
let Json.504 : U8 = 34i64;
|
let Json.562 : U8 = 34i64;
|
||||||
let Json.503 : List U8 = Array [Json.504];
|
let Json.561 : List U8 = Array [Json.562];
|
||||||
let Json.433 : Int1 = CallByName Bool.11 Json.283 Json.503;
|
let Json.491 : Int1 = CallByName Bool.11 Json.299 Json.561;
|
||||||
dec Json.503;
|
dec Json.561;
|
||||||
dec Json.283;
|
dec Json.299;
|
||||||
if Json.433 then
|
if Json.491 then
|
||||||
dec Json.282;
|
dec Json.298;
|
||||||
let Json.446 : {} = Struct {};
|
let Json.504 : {} = Struct {};
|
||||||
let Json.445 : {List U8, List U8} = CallByName Json.23 Json.285 Json.446;
|
let Json.503 : {List U8, List U8} = CallByName Json.24 Json.301 Json.504;
|
||||||
let Json.288 : List U8 = StructAtIndex 0 Json.445;
|
let Json.304 : List U8 = StructAtIndex 0 Json.503;
|
||||||
inc Json.288;
|
inc Json.304;
|
||||||
let Json.287 : List U8 = StructAtIndex 1 Json.445;
|
let Json.303 : List U8 = StructAtIndex 1 Json.503;
|
||||||
inc Json.287;
|
inc Json.303;
|
||||||
dec Json.445;
|
dec Json.503;
|
||||||
let Json.434 : [C {U64, U8}, C Str] = CallByName Str.9 Json.287;
|
let Json.492 : [C {U64, U8}, C Str] = CallByName Str.9 Json.303;
|
||||||
let Json.442 : U8 = 1i64;
|
let Json.500 : U8 = 1i64;
|
||||||
let Json.443 : U8 = GetTagId Json.434;
|
let Json.501 : U8 = GetTagId Json.492;
|
||||||
let Json.444 : Int1 = lowlevel Eq Json.442 Json.443;
|
let Json.502 : Int1 = lowlevel Eq Json.500 Json.501;
|
||||||
if Json.444 then
|
if Json.502 then
|
||||||
let Json.291 : Str = UnionAtIndex (Id 1) (Index 0) Json.434;
|
let Json.307 : Str = UnionAtIndex (Id 1) (Index 0) Json.492;
|
||||||
inc Json.291;
|
inc Json.307;
|
||||||
dec Json.434;
|
dec Json.492;
|
||||||
let Json.438 : U64 = 1i64;
|
let Json.496 : U64 = 1i64;
|
||||||
let Json.437 : {List U8, List U8} = CallByName List.52 Json.288 Json.438;
|
let Json.495 : {List U8, List U8} = CallByName List.52 Json.304 Json.496;
|
||||||
let Json.293 : List U8 = StructAtIndex 1 Json.437;
|
let Json.309 : List U8 = StructAtIndex 1 Json.495;
|
||||||
inc Json.293;
|
inc Json.309;
|
||||||
dec Json.437;
|
dec Json.495;
|
||||||
let Json.436 : [C {}, C Str] = TagId(1) Json.291;
|
let Json.494 : [C {}, C Str] = TagId(1) Json.307;
|
||||||
let Json.435 : {List U8, [C {}, C Str]} = Struct {Json.293, Json.436};
|
let Json.493 : {List U8, [C {}, C Str]} = Struct {Json.309, Json.494};
|
||||||
ret Json.435;
|
ret Json.493;
|
||||||
else
|
else
|
||||||
dec Json.434;
|
dec Json.492;
|
||||||
let Json.441 : {} = Struct {};
|
let Json.499 : {} = Struct {};
|
||||||
let Json.440 : [C {}, C Str] = TagId(0) Json.441;
|
let Json.498 : [C {}, C Str] = TagId(0) Json.499;
|
||||||
let Json.439 : {List U8, [C {}, C Str]} = Struct {Json.288, Json.440};
|
let Json.497 : {List U8, [C {}, C Str]} = Struct {Json.304, Json.498};
|
||||||
ret Json.439;
|
ret Json.497;
|
||||||
else
|
else
|
||||||
dec Json.285;
|
dec Json.301;
|
||||||
let Json.432 : {} = Struct {};
|
let Json.490 : {} = Struct {};
|
||||||
let Json.431 : [C {}, C Str] = TagId(0) Json.432;
|
let Json.489 : [C {}, C Str] = TagId(0) Json.490;
|
||||||
let Json.430 : {List U8, [C {}, C Str]} = Struct {Json.282, Json.431};
|
let Json.488 : {List U8, [C {}, C Str]} = Struct {Json.298, Json.489};
|
||||||
ret Json.430;
|
ret Json.488;
|
||||||
|
|
||||||
procedure Json.42 ():
|
procedure Json.43 ():
|
||||||
let Json.427 : {} = Struct {};
|
let Json.485 : {} = Struct {};
|
||||||
let Json.426 : {} = CallByName Decode.23 Json.427;
|
let Json.484 : {} = CallByName Decode.24 Json.485;
|
||||||
ret Json.426;
|
ret Json.484;
|
||||||
|
|
||||||
procedure List.1 (List.95):
|
procedure List.1 (List.95):
|
||||||
let List.495 : U64 = CallByName List.6 List.95;
|
let List.495 : U64 = CallByName List.6 List.95;
|
||||||
|
@ -374,7 +374,7 @@ procedure Test.3 ():
|
||||||
let Test.0 : List U8 = Array [82i64, 111i64, 99i64];
|
let Test.0 : List U8 = Array [82i64, 111i64, 99i64];
|
||||||
let Test.8 : {} = CallByName Json.2;
|
let Test.8 : {} = CallByName Json.2;
|
||||||
inc Test.0;
|
inc Test.0;
|
||||||
let Test.1 : [C [C List U8, C ], C Str] = CallByName Decode.26 Test.0 Test.8;
|
let Test.1 : [C [C List U8, C ], C Str] = CallByName Decode.27 Test.0 Test.8;
|
||||||
let Test.7 : Str = "Roc";
|
let Test.7 : Str = "Roc";
|
||||||
let Test.6 : [C [C List U8, C ], C Str] = TagId(1) Test.7;
|
let Test.6 : [C [C List U8, C ], C Str] = TagId(1) Test.7;
|
||||||
inc Test.1;
|
inc Test.1;
|
||||||
|
|
|
@ -32,199 +32,199 @@ procedure Bool.7 (Bool.19, Bool.20):
|
||||||
let Bool.37 : Int1 = CallByName Bool.12 Bool.19 Bool.20;
|
let Bool.37 : Int1 = CallByName Bool.12 Bool.19 Bool.20;
|
||||||
ret Bool.37;
|
ret Bool.37;
|
||||||
|
|
||||||
procedure Decode.23 (Decode.94):
|
procedure Decode.24 (Decode.101):
|
||||||
ret Decode.94;
|
ret Decode.101;
|
||||||
|
|
||||||
procedure Decode.24 (Decode.95, Decode.114, Decode.97):
|
procedure Decode.25 (Decode.102, Decode.121, Decode.104):
|
||||||
let Decode.117 : {List U8, [C {}, C Str]} = CallByName Json.299 Decode.95 Decode.97;
|
let Decode.124 : {List U8, [C {}, C Str]} = CallByName Json.315 Decode.102 Decode.104;
|
||||||
ret Decode.117;
|
ret Decode.124;
|
||||||
|
|
||||||
procedure Decode.25 (Decode.98, Decode.99):
|
procedure Decode.26 (Decode.105, Decode.106):
|
||||||
let Decode.116 : {} = CallByName Json.42;
|
let Decode.123 : {} = CallByName Json.43;
|
||||||
let Decode.115 : {List U8, [C {}, C Str]} = CallByName Decode.24 Decode.98 Decode.116 Decode.99;
|
let Decode.122 : {List U8, [C {}, C Str]} = CallByName Decode.25 Decode.105 Decode.123 Decode.106;
|
||||||
ret Decode.115;
|
ret Decode.122;
|
||||||
|
|
||||||
procedure Json.144 (Json.512, Json.513):
|
procedure Json.160 (Json.570, Json.571):
|
||||||
joinpoint Json.450 Json.447 Json.143:
|
joinpoint Json.508 Json.505 Json.159:
|
||||||
let Json.146 : List U8 = StructAtIndex 0 Json.447;
|
let Json.162 : List U8 = StructAtIndex 0 Json.505;
|
||||||
inc Json.146;
|
inc Json.162;
|
||||||
let Json.145 : List U8 = StructAtIndex 1 Json.447;
|
let Json.161 : List U8 = StructAtIndex 1 Json.505;
|
||||||
inc Json.145;
|
inc Json.161;
|
||||||
dec Json.447;
|
dec Json.505;
|
||||||
joinpoint Json.490:
|
joinpoint Json.548:
|
||||||
let Json.487 : {List U8, List U8} = Struct {Json.146, Json.145};
|
let Json.545 : {List U8, List U8} = Struct {Json.162, Json.161};
|
||||||
ret Json.487;
|
ret Json.545;
|
||||||
in
|
in
|
||||||
let Json.496 : U64 = lowlevel ListLen Json.146;
|
let Json.554 : U64 = lowlevel ListLen Json.162;
|
||||||
let Json.497 : U64 = 2i64;
|
let Json.555 : U64 = 2i64;
|
||||||
let Json.498 : Int1 = lowlevel NumGte Json.496 Json.497;
|
let Json.556 : Int1 = lowlevel NumGte Json.554 Json.555;
|
||||||
if Json.498 then
|
if Json.556 then
|
||||||
let Json.489 : U64 = 0i64;
|
let Json.547 : U64 = 0i64;
|
||||||
let Json.147 : U8 = lowlevel ListGetUnsafe Json.146 Json.489;
|
let Json.163 : U8 = lowlevel ListGetUnsafe Json.162 Json.547;
|
||||||
let Json.488 : U64 = 1i64;
|
let Json.546 : U64 = 1i64;
|
||||||
let Json.148 : U8 = lowlevel ListGetUnsafe Json.146 Json.488;
|
let Json.164 : U8 = lowlevel ListGetUnsafe Json.162 Json.546;
|
||||||
let Json.458 : Int1 = CallByName Json.22 Json.147 Json.148;
|
let Json.516 : Int1 = CallByName Json.23 Json.163 Json.164;
|
||||||
if Json.458 then
|
if Json.516 then
|
||||||
let Json.465 : U64 = 2i64;
|
let Json.523 : U64 = 2i64;
|
||||||
let Json.462 : List U8 = CallByName List.29 Json.146 Json.465;
|
let Json.520 : List U8 = CallByName List.29 Json.162 Json.523;
|
||||||
let Json.464 : List U8 = CallByName List.4 Json.145 Json.147;
|
let Json.522 : List U8 = CallByName List.4 Json.161 Json.163;
|
||||||
let Json.463 : List U8 = CallByName List.4 Json.464 Json.148;
|
let Json.521 : List U8 = CallByName List.4 Json.522 Json.164;
|
||||||
let Json.460 : {List U8, List U8} = Struct {Json.462, Json.463};
|
let Json.518 : {List U8, List U8} = Struct {Json.520, Json.521};
|
||||||
jump Json.450 Json.460 Json.143;
|
jump Json.508 Json.518 Json.159;
|
||||||
else
|
else
|
||||||
let Json.452 : Int1 = CallByName Json.289 Json.147;
|
let Json.510 : Int1 = CallByName Json.305 Json.163;
|
||||||
if Json.452 then
|
if Json.510 then
|
||||||
let Json.456 : List U8 = CallByName List.38 Json.146;
|
let Json.514 : List U8 = CallByName List.38 Json.162;
|
||||||
let Json.457 : List U8 = CallByName List.4 Json.145 Json.147;
|
let Json.515 : List U8 = CallByName List.4 Json.161 Json.163;
|
||||||
let Json.454 : {List U8, List U8} = Struct {Json.456, Json.457};
|
let Json.512 : {List U8, List U8} = Struct {Json.514, Json.515};
|
||||||
jump Json.450 Json.454 Json.143;
|
jump Json.508 Json.512 Json.159;
|
||||||
else
|
else
|
||||||
let Json.451 : {List U8, List U8} = Struct {Json.146, Json.145};
|
let Json.509 : {List U8, List U8} = Struct {Json.162, Json.161};
|
||||||
ret Json.451;
|
ret Json.509;
|
||||||
else
|
else
|
||||||
let Json.493 : U64 = lowlevel ListLen Json.146;
|
let Json.551 : U64 = lowlevel ListLen Json.162;
|
||||||
let Json.494 : U64 = 1i64;
|
let Json.552 : U64 = 1i64;
|
||||||
let Json.495 : Int1 = lowlevel NumGte Json.493 Json.494;
|
let Json.553 : Int1 = lowlevel NumGte Json.551 Json.552;
|
||||||
if Json.495 then
|
if Json.553 then
|
||||||
let Json.492 : U64 = 0i64;
|
let Json.550 : U64 = 0i64;
|
||||||
let Json.149 : U8 = lowlevel ListGetUnsafe Json.146 Json.492;
|
let Json.165 : U8 = lowlevel ListGetUnsafe Json.162 Json.550;
|
||||||
joinpoint Json.485 Json.491:
|
joinpoint Json.543 Json.549:
|
||||||
if Json.491 then
|
if Json.549 then
|
||||||
let Json.483 : List U8 = CallByName List.38 Json.146;
|
let Json.541 : List U8 = CallByName List.38 Json.162;
|
||||||
let Json.484 : List U8 = CallByName List.4 Json.145 Json.149;
|
let Json.542 : List U8 = CallByName List.4 Json.161 Json.165;
|
||||||
let Json.481 : {List U8, List U8} = Struct {Json.483, Json.484};
|
let Json.539 : {List U8, List U8} = Struct {Json.541, Json.542};
|
||||||
jump Json.450 Json.481 Json.143;
|
jump Json.508 Json.539 Json.159;
|
||||||
else
|
else
|
||||||
jump Json.490;
|
jump Json.548;
|
||||||
in
|
in
|
||||||
let Json.486 : Int1 = CallByName Json.289 Json.149;
|
let Json.544 : Int1 = CallByName Json.305 Json.165;
|
||||||
jump Json.485 Json.486;
|
jump Json.543 Json.544;
|
||||||
else
|
else
|
||||||
jump Json.490;
|
jump Json.548;
|
||||||
in
|
in
|
||||||
jump Json.450 Json.512 Json.513;
|
jump Json.508 Json.570 Json.571;
|
||||||
|
|
||||||
procedure Json.2 ():
|
procedure Json.2 ():
|
||||||
let Json.425 : {} = Struct {};
|
let Json.483 : {} = Struct {};
|
||||||
ret Json.425;
|
ret Json.483;
|
||||||
|
|
||||||
procedure Json.22 (Json.139, Json.140):
|
procedure Json.23 (Json.155, Json.156):
|
||||||
let Json.466 : {U8, U8} = Struct {Json.139, Json.140};
|
let Json.524 : {U8, U8} = Struct {Json.155, Json.156};
|
||||||
joinpoint Json.475:
|
joinpoint Json.533:
|
||||||
let Json.474 : Int1 = CallByName Bool.1;
|
let Json.532 : Int1 = CallByName Bool.1;
|
||||||
ret Json.474;
|
ret Json.532;
|
||||||
in
|
in
|
||||||
let Json.477 : U8 = StructAtIndex 0 Json.466;
|
let Json.535 : U8 = StructAtIndex 0 Json.524;
|
||||||
let Json.478 : U8 = 92i64;
|
let Json.536 : U8 = 92i64;
|
||||||
let Json.479 : Int1 = lowlevel Eq Json.478 Json.477;
|
let Json.537 : Int1 = lowlevel Eq Json.536 Json.535;
|
||||||
if Json.479 then
|
if Json.537 then
|
||||||
let Json.476 : U8 = StructAtIndex 1 Json.466;
|
let Json.534 : U8 = StructAtIndex 1 Json.524;
|
||||||
switch Json.476:
|
switch Json.534:
|
||||||
case 98:
|
case 98:
|
||||||
let Json.467 : Int1 = CallByName Bool.2;
|
let Json.525 : Int1 = CallByName Bool.2;
|
||||||
ret Json.467;
|
ret Json.525;
|
||||||
|
|
||||||
case 102:
|
case 102:
|
||||||
let Json.468 : Int1 = CallByName Bool.2;
|
let Json.526 : Int1 = CallByName Bool.2;
|
||||||
ret Json.468;
|
ret Json.526;
|
||||||
|
|
||||||
case 110:
|
case 110:
|
||||||
let Json.469 : Int1 = CallByName Bool.2;
|
let Json.527 : Int1 = CallByName Bool.2;
|
||||||
ret Json.469;
|
ret Json.527;
|
||||||
|
|
||||||
case 114:
|
case 114:
|
||||||
let Json.470 : Int1 = CallByName Bool.2;
|
let Json.528 : Int1 = CallByName Bool.2;
|
||||||
ret Json.470;
|
ret Json.528;
|
||||||
|
|
||||||
case 116:
|
case 116:
|
||||||
let Json.471 : Int1 = CallByName Bool.2;
|
let Json.529 : Int1 = CallByName Bool.2;
|
||||||
ret Json.471;
|
ret Json.529;
|
||||||
|
|
||||||
case 34:
|
case 34:
|
||||||
let Json.472 : Int1 = CallByName Bool.2;
|
let Json.530 : Int1 = CallByName Bool.2;
|
||||||
ret Json.472;
|
ret Json.530;
|
||||||
|
|
||||||
case 92:
|
case 92:
|
||||||
let Json.473 : Int1 = CallByName Bool.2;
|
let Json.531 : Int1 = CallByName Bool.2;
|
||||||
ret Json.473;
|
ret Json.531;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
jump Json.475;
|
jump Json.533;
|
||||||
|
|
||||||
else
|
else
|
||||||
jump Json.475;
|
jump Json.533;
|
||||||
|
|
||||||
procedure Json.23 (Json.142, Json.143):
|
procedure Json.24 (Json.158, Json.159):
|
||||||
let Json.500 : List U8 = Array [];
|
let Json.558 : List U8 = Array [];
|
||||||
let Json.449 : {List U8, List U8} = Struct {Json.142, Json.500};
|
let Json.507 : {List U8, List U8} = Struct {Json.158, Json.558};
|
||||||
let Json.448 : {List U8, List U8} = CallByName Json.144 Json.449 Json.143;
|
let Json.506 : {List U8, List U8} = CallByName Json.160 Json.507 Json.159;
|
||||||
ret Json.448;
|
ret Json.506;
|
||||||
|
|
||||||
procedure Json.289 (Json.290):
|
procedure Json.305 (Json.306):
|
||||||
let Json.502 : U8 = 34i64;
|
let Json.560 : U8 = 34i64;
|
||||||
let Json.501 : Int1 = CallByName Bool.7 Json.290 Json.502;
|
let Json.559 : Int1 = CallByName Bool.7 Json.306 Json.560;
|
||||||
ret Json.501;
|
ret Json.559;
|
||||||
|
|
||||||
procedure Json.299 (Json.300, Json.428):
|
procedure Json.315 (Json.316, Json.486):
|
||||||
let Json.429 : {List U8, [C {}, C Str]} = CallByName Json.41 Json.300;
|
let Json.487 : {List U8, [C {}, C Str]} = CallByName Json.42 Json.316;
|
||||||
ret Json.429;
|
ret Json.487;
|
||||||
|
|
||||||
procedure Json.41 (Json.282):
|
procedure Json.42 (Json.298):
|
||||||
let Json.506 : U64 = 1i64;
|
let Json.564 : U64 = 1i64;
|
||||||
inc Json.282;
|
inc Json.298;
|
||||||
let Json.505 : {List U8, List U8} = CallByName List.52 Json.282 Json.506;
|
let Json.563 : {List U8, List U8} = CallByName List.52 Json.298 Json.564;
|
||||||
let Json.283 : List U8 = StructAtIndex 0 Json.505;
|
let Json.299 : List U8 = StructAtIndex 0 Json.563;
|
||||||
inc Json.283;
|
inc Json.299;
|
||||||
let Json.285 : List U8 = StructAtIndex 1 Json.505;
|
let Json.301 : List U8 = StructAtIndex 1 Json.563;
|
||||||
inc Json.285;
|
inc Json.301;
|
||||||
dec Json.505;
|
dec Json.563;
|
||||||
let Json.504 : U8 = 34i64;
|
let Json.562 : U8 = 34i64;
|
||||||
let Json.503 : List U8 = Array [Json.504];
|
let Json.561 : List U8 = Array [Json.562];
|
||||||
let Json.433 : Int1 = CallByName Bool.11 Json.283 Json.503;
|
let Json.491 : Int1 = CallByName Bool.11 Json.299 Json.561;
|
||||||
dec Json.503;
|
dec Json.561;
|
||||||
dec Json.283;
|
dec Json.299;
|
||||||
if Json.433 then
|
if Json.491 then
|
||||||
dec Json.282;
|
dec Json.298;
|
||||||
let Json.446 : {} = Struct {};
|
let Json.504 : {} = Struct {};
|
||||||
let Json.445 : {List U8, List U8} = CallByName Json.23 Json.285 Json.446;
|
let Json.503 : {List U8, List U8} = CallByName Json.24 Json.301 Json.504;
|
||||||
let Json.288 : List U8 = StructAtIndex 0 Json.445;
|
let Json.304 : List U8 = StructAtIndex 0 Json.503;
|
||||||
inc Json.288;
|
inc Json.304;
|
||||||
let Json.287 : List U8 = StructAtIndex 1 Json.445;
|
let Json.303 : List U8 = StructAtIndex 1 Json.503;
|
||||||
inc Json.287;
|
inc Json.303;
|
||||||
dec Json.445;
|
dec Json.503;
|
||||||
let Json.434 : [C {U64, U8}, C Str] = CallByName Str.9 Json.287;
|
let Json.492 : [C {U64, U8}, C Str] = CallByName Str.9 Json.303;
|
||||||
let Json.442 : U8 = 1i64;
|
let Json.500 : U8 = 1i64;
|
||||||
let Json.443 : U8 = GetTagId Json.434;
|
let Json.501 : U8 = GetTagId Json.492;
|
||||||
let Json.444 : Int1 = lowlevel Eq Json.442 Json.443;
|
let Json.502 : Int1 = lowlevel Eq Json.500 Json.501;
|
||||||
if Json.444 then
|
if Json.502 then
|
||||||
let Json.291 : Str = UnionAtIndex (Id 1) (Index 0) Json.434;
|
let Json.307 : Str = UnionAtIndex (Id 1) (Index 0) Json.492;
|
||||||
inc Json.291;
|
inc Json.307;
|
||||||
dec Json.434;
|
dec Json.492;
|
||||||
let Json.438 : U64 = 1i64;
|
let Json.496 : U64 = 1i64;
|
||||||
let Json.437 : {List U8, List U8} = CallByName List.52 Json.288 Json.438;
|
let Json.495 : {List U8, List U8} = CallByName List.52 Json.304 Json.496;
|
||||||
let Json.293 : List U8 = StructAtIndex 1 Json.437;
|
let Json.309 : List U8 = StructAtIndex 1 Json.495;
|
||||||
inc Json.293;
|
inc Json.309;
|
||||||
dec Json.437;
|
dec Json.495;
|
||||||
let Json.436 : [C {}, C Str] = TagId(1) Json.291;
|
let Json.494 : [C {}, C Str] = TagId(1) Json.307;
|
||||||
let Json.435 : {List U8, [C {}, C Str]} = Struct {Json.293, Json.436};
|
let Json.493 : {List U8, [C {}, C Str]} = Struct {Json.309, Json.494};
|
||||||
ret Json.435;
|
ret Json.493;
|
||||||
else
|
else
|
||||||
dec Json.434;
|
dec Json.492;
|
||||||
let Json.441 : {} = Struct {};
|
let Json.499 : {} = Struct {};
|
||||||
let Json.440 : [C {}, C Str] = TagId(0) Json.441;
|
let Json.498 : [C {}, C Str] = TagId(0) Json.499;
|
||||||
let Json.439 : {List U8, [C {}, C Str]} = Struct {Json.288, Json.440};
|
let Json.497 : {List U8, [C {}, C Str]} = Struct {Json.304, Json.498};
|
||||||
ret Json.439;
|
ret Json.497;
|
||||||
else
|
else
|
||||||
dec Json.285;
|
dec Json.301;
|
||||||
let Json.432 : {} = Struct {};
|
let Json.490 : {} = Struct {};
|
||||||
let Json.431 : [C {}, C Str] = TagId(0) Json.432;
|
let Json.489 : [C {}, C Str] = TagId(0) Json.490;
|
||||||
let Json.430 : {List U8, [C {}, C Str]} = Struct {Json.282, Json.431};
|
let Json.488 : {List U8, [C {}, C Str]} = Struct {Json.298, Json.489};
|
||||||
ret Json.430;
|
ret Json.488;
|
||||||
|
|
||||||
procedure Json.42 ():
|
procedure Json.43 ():
|
||||||
let Json.427 : {} = Struct {};
|
let Json.485 : {} = Struct {};
|
||||||
let Json.426 : {} = CallByName Decode.23 Json.427;
|
let Json.484 : {} = CallByName Decode.24 Json.485;
|
||||||
ret Json.426;
|
ret Json.484;
|
||||||
|
|
||||||
procedure List.29 (List.298, List.299):
|
procedure List.29 (List.298, List.299):
|
||||||
let List.543 : U64 = CallByName List.6 List.298;
|
let List.543 : U64 = CallByName List.6 List.298;
|
||||||
|
@ -368,7 +368,7 @@ procedure Test.0 ():
|
||||||
let Test.37 : Str = "-1234";
|
let Test.37 : Str = "-1234";
|
||||||
let Test.35 : List U8 = CallByName Str.12 Test.37;
|
let Test.35 : List U8 = CallByName Str.12 Test.37;
|
||||||
let Test.36 : {} = CallByName Json.2;
|
let Test.36 : {} = CallByName Json.2;
|
||||||
let Test.34 : {List U8, [C {}, C Str]} = CallByName Decode.25 Test.35 Test.36;
|
let Test.34 : {List U8, [C {}, C Str]} = CallByName Decode.26 Test.35 Test.36;
|
||||||
let Test.2 : List U8 = StructAtIndex 0 Test.34;
|
let Test.2 : List U8 = StructAtIndex 0 Test.34;
|
||||||
inc Test.2;
|
inc Test.2;
|
||||||
let Test.1 : [C {}, C Str] = StructAtIndex 1 Test.34;
|
let Test.1 : [C {}, C Str] = StructAtIndex 1 Test.34;
|
||||||
|
|
|
@ -2,121 +2,121 @@ procedure Bool.2 ():
|
||||||
let Bool.23 : Int1 = true;
|
let Bool.23 : Int1 = true;
|
||||||
ret Bool.23;
|
ret Bool.23;
|
||||||
|
|
||||||
procedure Encode.22 (Encode.93):
|
procedure Encode.23 (Encode.98):
|
||||||
ret Encode.93;
|
ret Encode.98;
|
||||||
|
|
||||||
procedure Encode.22 (Encode.93):
|
procedure Encode.23 (Encode.98):
|
||||||
ret Encode.93;
|
ret Encode.98;
|
||||||
|
|
||||||
procedure Encode.22 (Encode.93):
|
procedure Encode.23 (Encode.98):
|
||||||
ret Encode.93;
|
ret Encode.98;
|
||||||
|
|
||||||
procedure Encode.23 (Encode.94, Encode.102, Encode.96):
|
procedure Encode.24 (Encode.99, Encode.107, Encode.101):
|
||||||
let Encode.106 : List U8 = CallByName Test.5 Encode.94 Encode.96 Encode.102;
|
let Encode.111 : List U8 = CallByName Test.5 Encode.99 Encode.101 Encode.107;
|
||||||
ret Encode.106;
|
ret Encode.111;
|
||||||
|
|
||||||
procedure Encode.23 (Encode.94, Encode.102, Encode.96):
|
procedure Encode.24 (Encode.99, Encode.107, Encode.101):
|
||||||
let Encode.113 : List U8 = CallByName Json.128 Encode.94 Encode.96 Encode.102;
|
let Encode.118 : List U8 = CallByName Json.144 Encode.99 Encode.101 Encode.107;
|
||||||
ret Encode.113;
|
|
||||||
|
|
||||||
procedure Encode.23 (Encode.94, Encode.102, Encode.96):
|
|
||||||
let Encode.118 : List U8 = CallByName Json.98 Encode.94 Encode.96 Encode.102;
|
|
||||||
ret Encode.118;
|
ret Encode.118;
|
||||||
|
|
||||||
procedure Encode.25 (Encode.100, Encode.101):
|
procedure Encode.24 (Encode.99, Encode.107, Encode.101):
|
||||||
let Encode.104 : List U8 = Array [];
|
let Encode.123 : List U8 = CallByName Json.102 Encode.99 Encode.101 Encode.107;
|
||||||
let Encode.105 : {Str, Str} = CallByName Test.2 Encode.100;
|
ret Encode.123;
|
||||||
let Encode.103 : List U8 = CallByName Encode.23 Encode.104 Encode.105 Encode.101;
|
|
||||||
ret Encode.103;
|
procedure Encode.26 (Encode.105, Encode.106):
|
||||||
|
let Encode.109 : List U8 = Array [];
|
||||||
|
let Encode.110 : {Str, Str} = CallByName Test.2 Encode.105;
|
||||||
|
let Encode.108 : List U8 = CallByName Encode.24 Encode.109 Encode.110 Encode.106;
|
||||||
|
ret Encode.108;
|
||||||
|
|
||||||
procedure Json.1 ():
|
procedure Json.1 ():
|
||||||
let Json.425 : {} = Struct {};
|
let Json.483 : {} = Struct {};
|
||||||
ret Json.425;
|
ret Json.483;
|
||||||
|
|
||||||
procedure Json.128 (Json.129, Json.428, #Attr.12):
|
procedure Json.102 (Json.103, Json.530, Json.101):
|
||||||
let Json.127 : List Str = StructAtIndex 1 #Attr.12;
|
let Json.539 : I64 = 34i64;
|
||||||
inc Json.127;
|
let Json.538 : U8 = CallByName Num.127 Json.539;
|
||||||
let Json.126 : Str = StructAtIndex 0 #Attr.12;
|
let Json.536 : List U8 = CallByName List.4 Json.103 Json.538;
|
||||||
inc Json.126;
|
let Json.537 : List U8 = CallByName Str.12 Json.101;
|
||||||
|
let Json.533 : List U8 = CallByName List.8 Json.536 Json.537;
|
||||||
|
let Json.535 : I64 = 34i64;
|
||||||
|
let Json.534 : U8 = CallByName Num.127 Json.535;
|
||||||
|
let Json.532 : List U8 = CallByName List.4 Json.533 Json.534;
|
||||||
|
ret Json.532;
|
||||||
|
|
||||||
|
procedure Json.144 (Json.145, Json.486, #Attr.12):
|
||||||
|
let Json.143 : List Str = StructAtIndex 1 #Attr.12;
|
||||||
|
inc Json.143;
|
||||||
|
let Json.142 : Str = StructAtIndex 0 #Attr.12;
|
||||||
|
inc Json.142;
|
||||||
dec #Attr.12;
|
dec #Attr.12;
|
||||||
let Json.466 : I64 = 123i64;
|
let Json.524 : I64 = 123i64;
|
||||||
let Json.465 : U8 = CallByName Num.127 Json.466;
|
let Json.523 : U8 = CallByName Num.127 Json.524;
|
||||||
let Json.462 : List U8 = CallByName List.4 Json.129 Json.465;
|
let Json.520 : List U8 = CallByName List.4 Json.145 Json.523;
|
||||||
let Json.464 : I64 = 34i64;
|
let Json.522 : I64 = 34i64;
|
||||||
let Json.463 : U8 = CallByName Num.127 Json.464;
|
let Json.521 : U8 = CallByName Num.127 Json.522;
|
||||||
let Json.460 : List U8 = CallByName List.4 Json.462 Json.463;
|
let Json.518 : List U8 = CallByName List.4 Json.520 Json.521;
|
||||||
let Json.461 : List U8 = CallByName Str.12 Json.126;
|
let Json.519 : List U8 = CallByName Str.12 Json.142;
|
||||||
let Json.457 : List U8 = CallByName List.8 Json.460 Json.461;
|
let Json.515 : List U8 = CallByName List.8 Json.518 Json.519;
|
||||||
let Json.459 : I64 = 34i64;
|
let Json.517 : I64 = 34i64;
|
||||||
let Json.458 : U8 = CallByName Num.127 Json.459;
|
let Json.516 : U8 = CallByName Num.127 Json.517;
|
||||||
let Json.454 : List U8 = CallByName List.4 Json.457 Json.458;
|
let Json.512 : List U8 = CallByName List.4 Json.515 Json.516;
|
||||||
let Json.456 : I64 = 58i64;
|
let Json.514 : I64 = 58i64;
|
||||||
let Json.455 : U8 = CallByName Num.127 Json.456;
|
let Json.513 : U8 = CallByName Num.127 Json.514;
|
||||||
let Json.451 : List U8 = CallByName List.4 Json.454 Json.455;
|
let Json.509 : List U8 = CallByName List.4 Json.512 Json.513;
|
||||||
let Json.453 : I64 = 91i64;
|
let Json.511 : I64 = 91i64;
|
||||||
let Json.452 : U8 = CallByName Num.127 Json.453;
|
let Json.510 : U8 = CallByName Num.127 Json.511;
|
||||||
let Json.131 : List U8 = CallByName List.4 Json.451 Json.452;
|
let Json.147 : List U8 = CallByName List.4 Json.509 Json.510;
|
||||||
let Json.450 : U64 = CallByName List.6 Json.127;
|
let Json.508 : U64 = CallByName List.6 Json.143;
|
||||||
let Json.438 : {List U8, U64} = Struct {Json.131, Json.450};
|
let Json.496 : {List U8, U64} = Struct {Json.147, Json.508};
|
||||||
let Json.439 : {} = Struct {};
|
let Json.497 : {} = Struct {};
|
||||||
let Json.437 : {List U8, U64} = CallByName List.18 Json.127 Json.438 Json.439;
|
let Json.495 : {List U8, U64} = CallByName List.18 Json.143 Json.496 Json.497;
|
||||||
dec Json.127;
|
dec Json.143;
|
||||||
let Json.133 : List U8 = StructAtIndex 0 Json.437;
|
let Json.149 : List U8 = StructAtIndex 0 Json.495;
|
||||||
inc Json.133;
|
inc Json.149;
|
||||||
dec Json.437;
|
dec Json.495;
|
||||||
let Json.436 : I64 = 93i64;
|
let Json.494 : I64 = 93i64;
|
||||||
let Json.435 : U8 = CallByName Num.127 Json.436;
|
let Json.493 : U8 = CallByName Num.127 Json.494;
|
||||||
let Json.432 : List U8 = CallByName List.4 Json.133 Json.435;
|
let Json.490 : List U8 = CallByName List.4 Json.149 Json.493;
|
||||||
let Json.434 : I64 = 125i64;
|
let Json.492 : I64 = 125i64;
|
||||||
let Json.433 : U8 = CallByName Num.127 Json.434;
|
let Json.491 : U8 = CallByName Num.127 Json.492;
|
||||||
let Json.431 : List U8 = CallByName List.4 Json.432 Json.433;
|
let Json.489 : List U8 = CallByName List.4 Json.490 Json.491;
|
||||||
ret Json.431;
|
ret Json.489;
|
||||||
|
|
||||||
procedure Json.130 (Json.430, Json.136):
|
procedure Json.146 (Json.488, Json.152):
|
||||||
let Json.134 : List U8 = StructAtIndex 0 Json.430;
|
let Json.150 : List U8 = StructAtIndex 0 Json.488;
|
||||||
inc Json.134;
|
inc Json.150;
|
||||||
let Json.135 : U64 = StructAtIndex 1 Json.430;
|
let Json.151 : U64 = StructAtIndex 1 Json.488;
|
||||||
dec Json.430;
|
dec Json.488;
|
||||||
let Json.449 : {} = Struct {};
|
let Json.507 : {} = Struct {};
|
||||||
let Json.137 : List U8 = CallByName Encode.23 Json.134 Json.136 Json.449;
|
let Json.153 : List U8 = CallByName Encode.24 Json.150 Json.152 Json.507;
|
||||||
joinpoint Json.444 Json.138:
|
joinpoint Json.502 Json.154:
|
||||||
let Json.442 : U64 = 1i64;
|
let Json.500 : U64 = 1i64;
|
||||||
let Json.441 : U64 = CallByName Num.20 Json.135 Json.442;
|
let Json.499 : U64 = CallByName Num.20 Json.151 Json.500;
|
||||||
let Json.440 : {List U8, U64} = Struct {Json.138, Json.441};
|
let Json.498 : {List U8, U64} = Struct {Json.154, Json.499};
|
||||||
ret Json.440;
|
ret Json.498;
|
||||||
in
|
in
|
||||||
let Json.448 : U64 = 1i64;
|
let Json.506 : U64 = 1i64;
|
||||||
let Json.445 : Int1 = CallByName Num.24 Json.135 Json.448;
|
let Json.503 : Int1 = CallByName Num.24 Json.151 Json.506;
|
||||||
if Json.445 then
|
if Json.503 then
|
||||||
let Json.447 : I64 = 44i64;
|
let Json.505 : I64 = 44i64;
|
||||||
let Json.446 : U8 = CallByName Num.127 Json.447;
|
let Json.504 : U8 = CallByName Num.127 Json.505;
|
||||||
let Json.443 : List U8 = CallByName List.4 Json.137 Json.446;
|
let Json.501 : List U8 = CallByName List.4 Json.153 Json.504;
|
||||||
jump Json.444 Json.443;
|
jump Json.502 Json.501;
|
||||||
else
|
else
|
||||||
jump Json.444 Json.137;
|
jump Json.502 Json.153;
|
||||||
|
|
||||||
procedure Json.18 (Json.97):
|
procedure Json.18 (Json.101):
|
||||||
let Json.482 : Str = CallByName Encode.22 Json.97;
|
let Json.540 : Str = CallByName Encode.23 Json.101;
|
||||||
ret Json.482;
|
ret Json.540;
|
||||||
|
|
||||||
procedure Json.21 (Json.126, Json.127):
|
procedure Json.22 (Json.142, Json.143):
|
||||||
let Json.468 : {Str, List Str} = Struct {Json.126, Json.127};
|
let Json.526 : {Str, List Str} = Struct {Json.142, Json.143};
|
||||||
let Json.467 : {Str, List Str} = CallByName Encode.22 Json.468;
|
let Json.525 : {Str, List Str} = CallByName Encode.23 Json.526;
|
||||||
ret Json.467;
|
ret Json.525;
|
||||||
|
|
||||||
procedure Json.98 (Json.99, Json.472, Json.97):
|
|
||||||
let Json.481 : I64 = 34i64;
|
|
||||||
let Json.480 : U8 = CallByName Num.127 Json.481;
|
|
||||||
let Json.478 : List U8 = CallByName List.4 Json.99 Json.480;
|
|
||||||
let Json.479 : List U8 = CallByName Str.12 Json.97;
|
|
||||||
let Json.475 : List U8 = CallByName List.8 Json.478 Json.479;
|
|
||||||
let Json.477 : I64 = 34i64;
|
|
||||||
let Json.476 : U8 = CallByName Num.127 Json.477;
|
|
||||||
let Json.474 : List U8 = CallByName List.4 Json.475 Json.476;
|
|
||||||
ret Json.474;
|
|
||||||
|
|
||||||
procedure List.139 (List.140, List.141, List.138):
|
procedure List.139 (List.140, List.141, List.138):
|
||||||
let List.545 : {List U8, U64} = CallByName Json.130 List.140 List.141;
|
let List.545 : {List U8, U64} = CallByName Json.146 List.140 List.141;
|
||||||
ret List.545;
|
ret List.545;
|
||||||
|
|
||||||
procedure List.18 (List.136, List.137, List.138):
|
procedure List.18 (List.136, List.137, List.138):
|
||||||
|
@ -194,7 +194,7 @@ procedure Str.12 (#Attr.2):
|
||||||
ret Str.267;
|
ret Str.267;
|
||||||
|
|
||||||
procedure Test.2 (Test.10):
|
procedure Test.2 (Test.10):
|
||||||
let Test.15 : {Str, Str} = CallByName Encode.22 Test.10;
|
let Test.15 : {Str, Str} = CallByName Encode.23 Test.10;
|
||||||
ret Test.15;
|
ret Test.15;
|
||||||
|
|
||||||
procedure Test.3 ():
|
procedure Test.3 ():
|
||||||
|
@ -205,7 +205,7 @@ procedure Test.3 ():
|
||||||
|
|
||||||
procedure Test.5 (Test.6, Test.7, Test.4):
|
procedure Test.5 (Test.6, Test.7, Test.4):
|
||||||
joinpoint Test.20 Test.8:
|
joinpoint Test.20 Test.8:
|
||||||
let Test.18 : List U8 = CallByName Encode.23 Test.6 Test.8 Test.7;
|
let Test.18 : List U8 = CallByName Encode.24 Test.6 Test.8 Test.7;
|
||||||
ret Test.18;
|
ret Test.18;
|
||||||
in
|
in
|
||||||
let Test.25 : Int1 = CallByName Bool.2;
|
let Test.25 : Int1 = CallByName Bool.2;
|
||||||
|
@ -216,7 +216,7 @@ procedure Test.5 (Test.6, Test.7, Test.4):
|
||||||
dec Test.4;
|
dec Test.4;
|
||||||
let Test.28 : Str = CallByName Json.18 Test.29;
|
let Test.28 : Str = CallByName Json.18 Test.29;
|
||||||
let Test.27 : List Str = Array [Test.28];
|
let Test.27 : List Str = Array [Test.28];
|
||||||
let Test.19 : {Str, List Str} = CallByName Json.21 Test.26 Test.27;
|
let Test.19 : {Str, List Str} = CallByName Json.22 Test.26 Test.27;
|
||||||
jump Test.20 Test.19;
|
jump Test.20 Test.19;
|
||||||
else
|
else
|
||||||
let Test.21 : Str = "B";
|
let Test.21 : Str = "B";
|
||||||
|
@ -225,11 +225,11 @@ procedure Test.5 (Test.6, Test.7, Test.4):
|
||||||
dec Test.4;
|
dec Test.4;
|
||||||
let Test.23 : Str = CallByName Json.18 Test.24;
|
let Test.23 : Str = CallByName Json.18 Test.24;
|
||||||
let Test.22 : List Str = Array [Test.23];
|
let Test.22 : List Str = Array [Test.23];
|
||||||
let Test.19 : {Str, List Str} = CallByName Json.21 Test.21 Test.22;
|
let Test.19 : {Str, List Str} = CallByName Json.22 Test.21 Test.22;
|
||||||
jump Test.20 Test.19;
|
jump Test.20 Test.19;
|
||||||
|
|
||||||
procedure Test.0 ():
|
procedure Test.0 ():
|
||||||
let Test.12 : {Str, Str} = CallByName Test.3;
|
let Test.12 : {Str, Str} = CallByName Test.3;
|
||||||
let Test.13 : {} = CallByName Json.1;
|
let Test.13 : {} = CallByName Json.1;
|
||||||
let Test.11 : List U8 = CallByName Encode.25 Test.12 Test.13;
|
let Test.11 : List U8 = CallByName Encode.26 Test.12 Test.13;
|
||||||
ret Test.11;
|
ret Test.11;
|
||||||
|
|
|
@ -1,230 +1,230 @@
|
||||||
procedure #Derived.0 (#Derived.1):
|
procedure #Derived.0 (#Derived.1):
|
||||||
let #Derived_gen.10 : [C {}, C {}] = TagId(0) #Derived.1;
|
let #Derived_gen.10 : [C {}, C {}] = TagId(0) #Derived.1;
|
||||||
let #Derived_gen.9 : [C {}, C {}] = CallByName Encode.22 #Derived_gen.10;
|
let #Derived_gen.9 : [C {}, C {}] = CallByName Encode.23 #Derived_gen.10;
|
||||||
ret #Derived_gen.9;
|
ret #Derived_gen.9;
|
||||||
|
|
||||||
procedure #Derived.2 (#Derived.3, #Derived.4, #Attr.12):
|
procedure #Derived.2 (#Derived.3, #Derived.4, #Attr.12):
|
||||||
let #Derived.1 : {} = UnionAtIndex (Id 0) (Index 0) #Attr.12;
|
let #Derived.1 : {} = UnionAtIndex (Id 0) (Index 0) #Attr.12;
|
||||||
joinpoint #Derived_gen.14 #Derived_gen.13:
|
joinpoint #Derived_gen.14 #Derived_gen.13:
|
||||||
let #Derived_gen.12 : List U8 = CallByName Encode.23 #Derived.3 #Derived_gen.13 #Derived.4;
|
let #Derived_gen.12 : List U8 = CallByName Encode.24 #Derived.3 #Derived_gen.13 #Derived.4;
|
||||||
ret #Derived_gen.12;
|
ret #Derived_gen.12;
|
||||||
in
|
in
|
||||||
let #Derived_gen.16 : Str = "A";
|
let #Derived_gen.16 : Str = "A";
|
||||||
let #Derived_gen.17 : List [] = Array [];
|
let #Derived_gen.17 : List [] = Array [];
|
||||||
let #Derived_gen.15 : {Str, List []} = CallByName Json.21 #Derived_gen.16 #Derived_gen.17;
|
let #Derived_gen.15 : {Str, List []} = CallByName Json.22 #Derived_gen.16 #Derived_gen.17;
|
||||||
jump #Derived_gen.14 #Derived_gen.15;
|
jump #Derived_gen.14 #Derived_gen.15;
|
||||||
|
|
||||||
procedure #Derived.5 (#Derived.6):
|
procedure #Derived.5 (#Derived.6):
|
||||||
let #Derived_gen.1 : [C {}, C {}] = TagId(1) #Derived.6;
|
let #Derived_gen.1 : [C {}, C {}] = TagId(1) #Derived.6;
|
||||||
let #Derived_gen.0 : [C {}, C {}] = CallByName Encode.22 #Derived_gen.1;
|
let #Derived_gen.0 : [C {}, C {}] = CallByName Encode.23 #Derived_gen.1;
|
||||||
ret #Derived_gen.0;
|
ret #Derived_gen.0;
|
||||||
|
|
||||||
procedure #Derived.7 (#Derived.8, #Derived.9, #Attr.12):
|
procedure #Derived.7 (#Derived.8, #Derived.9, #Attr.12):
|
||||||
let #Derived.6 : {} = UnionAtIndex (Id 1) (Index 0) #Attr.12;
|
let #Derived.6 : {} = UnionAtIndex (Id 1) (Index 0) #Attr.12;
|
||||||
joinpoint #Derived_gen.5 #Derived_gen.4:
|
joinpoint #Derived_gen.5 #Derived_gen.4:
|
||||||
let #Derived_gen.3 : List U8 = CallByName Encode.23 #Derived.8 #Derived_gen.4 #Derived.9;
|
let #Derived_gen.3 : List U8 = CallByName Encode.24 #Derived.8 #Derived_gen.4 #Derived.9;
|
||||||
ret #Derived_gen.3;
|
ret #Derived_gen.3;
|
||||||
in
|
in
|
||||||
let #Derived_gen.7 : Str = "B";
|
let #Derived_gen.7 : Str = "B";
|
||||||
let #Derived_gen.8 : List [] = Array [];
|
let #Derived_gen.8 : List [] = Array [];
|
||||||
let #Derived_gen.6 : {Str, List []} = CallByName Json.21 #Derived_gen.7 #Derived_gen.8;
|
let #Derived_gen.6 : {Str, List []} = CallByName Json.22 #Derived_gen.7 #Derived_gen.8;
|
||||||
jump #Derived_gen.5 #Derived_gen.6;
|
jump #Derived_gen.5 #Derived_gen.6;
|
||||||
|
|
||||||
procedure Bool.2 ():
|
procedure Bool.2 ():
|
||||||
let Bool.23 : Int1 = true;
|
let Bool.23 : Int1 = true;
|
||||||
ret Bool.23;
|
ret Bool.23;
|
||||||
|
|
||||||
procedure Encode.22 (Encode.93):
|
procedure Encode.23 (Encode.98):
|
||||||
ret Encode.93;
|
ret Encode.98;
|
||||||
|
|
||||||
procedure Encode.22 (Encode.93):
|
procedure Encode.23 (Encode.98):
|
||||||
ret Encode.93;
|
ret Encode.98;
|
||||||
|
|
||||||
procedure Encode.22 (Encode.93):
|
procedure Encode.23 (Encode.98):
|
||||||
ret Encode.93;
|
ret Encode.98;
|
||||||
|
|
||||||
procedure Encode.22 (Encode.93):
|
procedure Encode.23 (Encode.98):
|
||||||
ret Encode.93;
|
ret Encode.98;
|
||||||
|
|
||||||
procedure Encode.23 (Encode.94, Encode.102, Encode.96):
|
procedure Encode.24 (Encode.99, Encode.107, Encode.101):
|
||||||
let Encode.106 : List U8 = CallByName Test.5 Encode.94 Encode.96 Encode.102;
|
let Encode.111 : List U8 = CallByName Test.5 Encode.99 Encode.101 Encode.107;
|
||||||
ret Encode.106;
|
ret Encode.111;
|
||||||
|
|
||||||
procedure Encode.23 (Encode.94, Encode.102, Encode.96):
|
procedure Encode.24 (Encode.99, Encode.107, Encode.101):
|
||||||
let Encode.113 : List U8 = CallByName Json.128 Encode.94 Encode.96 Encode.102;
|
let Encode.118 : List U8 = CallByName Json.144 Encode.99 Encode.101 Encode.107;
|
||||||
ret Encode.113;
|
ret Encode.118;
|
||||||
|
|
||||||
procedure Encode.23 (Encode.94, Encode.102, Encode.96):
|
procedure Encode.24 (Encode.99, Encode.107, Encode.101):
|
||||||
let Encode.117 : U8 = GetTagId Encode.102;
|
let Encode.122 : U8 = GetTagId Encode.107;
|
||||||
switch Encode.117:
|
switch Encode.122:
|
||||||
case 0:
|
case 0:
|
||||||
let Encode.116 : List U8 = CallByName #Derived.2 Encode.94 Encode.96 Encode.102;
|
let Encode.121 : List U8 = CallByName #Derived.2 Encode.99 Encode.101 Encode.107;
|
||||||
ret Encode.116;
|
ret Encode.121;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
let Encode.116 : List U8 = CallByName #Derived.7 Encode.94 Encode.96 Encode.102;
|
let Encode.121 : List U8 = CallByName #Derived.7 Encode.99 Encode.101 Encode.107;
|
||||||
ret Encode.116;
|
ret Encode.121;
|
||||||
|
|
||||||
|
|
||||||
procedure Encode.23 (Encode.94, Encode.102, Encode.96):
|
procedure Encode.24 (Encode.99, Encode.107, Encode.101):
|
||||||
let Encode.129 : List U8 = CallByName Json.128 Encode.94 Encode.96 Encode.102;
|
let Encode.134 : List U8 = CallByName Json.144 Encode.99 Encode.101 Encode.107;
|
||||||
ret Encode.129;
|
ret Encode.134;
|
||||||
|
|
||||||
procedure Encode.23 (Encode.94, Encode.102, Encode.96):
|
procedure Encode.24 (Encode.99, Encode.107, Encode.101):
|
||||||
let Encode.133 : Str = "a Lambda Set is empty. Most likely there is a type error in your program.";
|
let Encode.138 : Str = "a Lambda Set is empty. Most likely there is a type error in your program.";
|
||||||
Crash Encode.133
|
Crash Encode.138
|
||||||
|
|
||||||
procedure Encode.25 (Encode.100, Encode.101):
|
procedure Encode.26 (Encode.105, Encode.106):
|
||||||
let Encode.104 : List U8 = Array [];
|
let Encode.109 : List U8 = Array [];
|
||||||
let Encode.105 : {{}, {}} = CallByName Test.2 Encode.100;
|
let Encode.110 : {{}, {}} = CallByName Test.2 Encode.105;
|
||||||
let Encode.103 : List U8 = CallByName Encode.23 Encode.104 Encode.105 Encode.101;
|
let Encode.108 : List U8 = CallByName Encode.24 Encode.109 Encode.110 Encode.106;
|
||||||
ret Encode.103;
|
ret Encode.108;
|
||||||
|
|
||||||
procedure Json.1 ():
|
procedure Json.1 ():
|
||||||
let Json.425 : {} = Struct {};
|
let Json.483 : {} = Struct {};
|
||||||
ret Json.425;
|
ret Json.483;
|
||||||
|
|
||||||
procedure Json.128 (Json.129, Json.428, #Attr.12):
|
procedure Json.144 (Json.145, Json.486, #Attr.12):
|
||||||
let Json.127 : List [C {}, C {}] = StructAtIndex 1 #Attr.12;
|
let Json.143 : List [C {}, C {}] = StructAtIndex 1 #Attr.12;
|
||||||
inc Json.127;
|
inc Json.143;
|
||||||
let Json.126 : Str = StructAtIndex 0 #Attr.12;
|
let Json.142 : Str = StructAtIndex 0 #Attr.12;
|
||||||
inc Json.126;
|
inc Json.142;
|
||||||
dec #Attr.12;
|
dec #Attr.12;
|
||||||
let Json.466 : I64 = 123i64;
|
let Json.524 : I64 = 123i64;
|
||||||
let Json.465 : U8 = CallByName Num.127 Json.466;
|
let Json.523 : U8 = CallByName Num.127 Json.524;
|
||||||
let Json.462 : List U8 = CallByName List.4 Json.129 Json.465;
|
let Json.520 : List U8 = CallByName List.4 Json.145 Json.523;
|
||||||
let Json.464 : I64 = 34i64;
|
let Json.522 : I64 = 34i64;
|
||||||
let Json.463 : U8 = CallByName Num.127 Json.464;
|
let Json.521 : U8 = CallByName Num.127 Json.522;
|
||||||
let Json.460 : List U8 = CallByName List.4 Json.462 Json.463;
|
let Json.518 : List U8 = CallByName List.4 Json.520 Json.521;
|
||||||
let Json.461 : List U8 = CallByName Str.12 Json.126;
|
let Json.519 : List U8 = CallByName Str.12 Json.142;
|
||||||
let Json.457 : List U8 = CallByName List.8 Json.460 Json.461;
|
let Json.515 : List U8 = CallByName List.8 Json.518 Json.519;
|
||||||
let Json.459 : I64 = 34i64;
|
let Json.517 : I64 = 34i64;
|
||||||
let Json.458 : U8 = CallByName Num.127 Json.459;
|
let Json.516 : U8 = CallByName Num.127 Json.517;
|
||||||
let Json.454 : List U8 = CallByName List.4 Json.457 Json.458;
|
let Json.512 : List U8 = CallByName List.4 Json.515 Json.516;
|
||||||
let Json.456 : I64 = 58i64;
|
let Json.514 : I64 = 58i64;
|
||||||
let Json.455 : U8 = CallByName Num.127 Json.456;
|
|
||||||
let Json.451 : List U8 = CallByName List.4 Json.454 Json.455;
|
|
||||||
let Json.453 : I64 = 91i64;
|
|
||||||
let Json.452 : U8 = CallByName Num.127 Json.453;
|
|
||||||
let Json.131 : List U8 = CallByName List.4 Json.451 Json.452;
|
|
||||||
let Json.450 : U64 = CallByName List.6 Json.127;
|
|
||||||
let Json.438 : {List U8, U64} = Struct {Json.131, Json.450};
|
|
||||||
let Json.439 : {} = Struct {};
|
|
||||||
let Json.437 : {List U8, U64} = CallByName List.18 Json.127 Json.438 Json.439;
|
|
||||||
dec Json.127;
|
|
||||||
let Json.133 : List U8 = StructAtIndex 0 Json.437;
|
|
||||||
inc Json.133;
|
|
||||||
dec Json.437;
|
|
||||||
let Json.436 : I64 = 93i64;
|
|
||||||
let Json.435 : U8 = CallByName Num.127 Json.436;
|
|
||||||
let Json.432 : List U8 = CallByName List.4 Json.133 Json.435;
|
|
||||||
let Json.434 : I64 = 125i64;
|
|
||||||
let Json.433 : U8 = CallByName Num.127 Json.434;
|
|
||||||
let Json.431 : List U8 = CallByName List.4 Json.432 Json.433;
|
|
||||||
ret Json.431;
|
|
||||||
|
|
||||||
procedure Json.128 (Json.129, Json.428, #Attr.12):
|
|
||||||
let Json.127 : List [] = StructAtIndex 1 #Attr.12;
|
|
||||||
inc Json.127;
|
|
||||||
let Json.126 : Str = StructAtIndex 0 #Attr.12;
|
|
||||||
inc Json.126;
|
|
||||||
dec #Attr.12;
|
|
||||||
let Json.516 : I64 = 123i64;
|
|
||||||
let Json.515 : U8 = CallByName Num.127 Json.516;
|
|
||||||
let Json.512 : List U8 = CallByName List.4 Json.129 Json.515;
|
|
||||||
let Json.514 : I64 = 34i64;
|
|
||||||
let Json.513 : U8 = CallByName Num.127 Json.514;
|
let Json.513 : U8 = CallByName Num.127 Json.514;
|
||||||
let Json.510 : List U8 = CallByName List.4 Json.512 Json.513;
|
let Json.509 : List U8 = CallByName List.4 Json.512 Json.513;
|
||||||
let Json.511 : List U8 = CallByName Str.12 Json.126;
|
let Json.511 : I64 = 91i64;
|
||||||
let Json.507 : List U8 = CallByName List.8 Json.510 Json.511;
|
let Json.510 : U8 = CallByName Num.127 Json.511;
|
||||||
let Json.509 : I64 = 34i64;
|
let Json.147 : List U8 = CallByName List.4 Json.509 Json.510;
|
||||||
let Json.508 : U8 = CallByName Num.127 Json.509;
|
let Json.508 : U64 = CallByName List.6 Json.143;
|
||||||
let Json.504 : List U8 = CallByName List.4 Json.507 Json.508;
|
let Json.496 : {List U8, U64} = Struct {Json.147, Json.508};
|
||||||
let Json.506 : I64 = 58i64;
|
let Json.497 : {} = Struct {};
|
||||||
let Json.505 : U8 = CallByName Num.127 Json.506;
|
let Json.495 : {List U8, U64} = CallByName List.18 Json.143 Json.496 Json.497;
|
||||||
let Json.501 : List U8 = CallByName List.4 Json.504 Json.505;
|
dec Json.143;
|
||||||
let Json.503 : I64 = 91i64;
|
let Json.149 : List U8 = StructAtIndex 0 Json.495;
|
||||||
let Json.502 : U8 = CallByName Num.127 Json.503;
|
inc Json.149;
|
||||||
let Json.131 : List U8 = CallByName List.4 Json.501 Json.502;
|
dec Json.495;
|
||||||
let Json.500 : U64 = CallByName List.6 Json.127;
|
let Json.494 : I64 = 93i64;
|
||||||
let Json.488 : {List U8, U64} = Struct {Json.131, Json.500};
|
let Json.493 : U8 = CallByName Num.127 Json.494;
|
||||||
let Json.489 : {} = Struct {};
|
let Json.490 : List U8 = CallByName List.4 Json.149 Json.493;
|
||||||
let Json.487 : {List U8, U64} = CallByName List.18 Json.127 Json.488 Json.489;
|
let Json.492 : I64 = 125i64;
|
||||||
dec Json.127;
|
let Json.491 : U8 = CallByName Num.127 Json.492;
|
||||||
let Json.133 : List U8 = StructAtIndex 0 Json.487;
|
let Json.489 : List U8 = CallByName List.4 Json.490 Json.491;
|
||||||
inc Json.133;
|
ret Json.489;
|
||||||
dec Json.487;
|
|
||||||
let Json.486 : I64 = 93i64;
|
|
||||||
let Json.485 : U8 = CallByName Num.127 Json.486;
|
|
||||||
let Json.482 : List U8 = CallByName List.4 Json.133 Json.485;
|
|
||||||
let Json.484 : I64 = 125i64;
|
|
||||||
let Json.483 : U8 = CallByName Num.127 Json.484;
|
|
||||||
let Json.481 : List U8 = CallByName List.4 Json.482 Json.483;
|
|
||||||
ret Json.481;
|
|
||||||
|
|
||||||
procedure Json.130 (Json.430, Json.136):
|
procedure Json.144 (Json.145, Json.486, #Attr.12):
|
||||||
let Json.134 : List U8 = StructAtIndex 0 Json.430;
|
let Json.143 : List [] = StructAtIndex 1 #Attr.12;
|
||||||
inc Json.134;
|
inc Json.143;
|
||||||
let Json.135 : U64 = StructAtIndex 1 Json.430;
|
let Json.142 : Str = StructAtIndex 0 #Attr.12;
|
||||||
dec Json.430;
|
inc Json.142;
|
||||||
let Json.449 : {} = Struct {};
|
dec #Attr.12;
|
||||||
let Json.137 : List U8 = CallByName Encode.23 Json.134 Json.136 Json.449;
|
let Json.574 : I64 = 123i64;
|
||||||
joinpoint Json.444 Json.138:
|
let Json.573 : U8 = CallByName Num.127 Json.574;
|
||||||
let Json.442 : U64 = 1i64;
|
let Json.570 : List U8 = CallByName List.4 Json.145 Json.573;
|
||||||
let Json.441 : U64 = CallByName Num.20 Json.135 Json.442;
|
let Json.572 : I64 = 34i64;
|
||||||
let Json.440 : {List U8, U64} = Struct {Json.138, Json.441};
|
let Json.571 : U8 = CallByName Num.127 Json.572;
|
||||||
ret Json.440;
|
let Json.568 : List U8 = CallByName List.4 Json.570 Json.571;
|
||||||
|
let Json.569 : List U8 = CallByName Str.12 Json.142;
|
||||||
|
let Json.565 : List U8 = CallByName List.8 Json.568 Json.569;
|
||||||
|
let Json.567 : I64 = 34i64;
|
||||||
|
let Json.566 : U8 = CallByName Num.127 Json.567;
|
||||||
|
let Json.562 : List U8 = CallByName List.4 Json.565 Json.566;
|
||||||
|
let Json.564 : I64 = 58i64;
|
||||||
|
let Json.563 : U8 = CallByName Num.127 Json.564;
|
||||||
|
let Json.559 : List U8 = CallByName List.4 Json.562 Json.563;
|
||||||
|
let Json.561 : I64 = 91i64;
|
||||||
|
let Json.560 : U8 = CallByName Num.127 Json.561;
|
||||||
|
let Json.147 : List U8 = CallByName List.4 Json.559 Json.560;
|
||||||
|
let Json.558 : U64 = CallByName List.6 Json.143;
|
||||||
|
let Json.546 : {List U8, U64} = Struct {Json.147, Json.558};
|
||||||
|
let Json.547 : {} = Struct {};
|
||||||
|
let Json.545 : {List U8, U64} = CallByName List.18 Json.143 Json.546 Json.547;
|
||||||
|
dec Json.143;
|
||||||
|
let Json.149 : List U8 = StructAtIndex 0 Json.545;
|
||||||
|
inc Json.149;
|
||||||
|
dec Json.545;
|
||||||
|
let Json.544 : I64 = 93i64;
|
||||||
|
let Json.543 : U8 = CallByName Num.127 Json.544;
|
||||||
|
let Json.540 : List U8 = CallByName List.4 Json.149 Json.543;
|
||||||
|
let Json.542 : I64 = 125i64;
|
||||||
|
let Json.541 : U8 = CallByName Num.127 Json.542;
|
||||||
|
let Json.539 : List U8 = CallByName List.4 Json.540 Json.541;
|
||||||
|
ret Json.539;
|
||||||
|
|
||||||
|
procedure Json.146 (Json.488, Json.152):
|
||||||
|
let Json.150 : List U8 = StructAtIndex 0 Json.488;
|
||||||
|
inc Json.150;
|
||||||
|
let Json.151 : U64 = StructAtIndex 1 Json.488;
|
||||||
|
dec Json.488;
|
||||||
|
let Json.507 : {} = Struct {};
|
||||||
|
let Json.153 : List U8 = CallByName Encode.24 Json.150 Json.152 Json.507;
|
||||||
|
joinpoint Json.502 Json.154:
|
||||||
|
let Json.500 : U64 = 1i64;
|
||||||
|
let Json.499 : U64 = CallByName Num.20 Json.151 Json.500;
|
||||||
|
let Json.498 : {List U8, U64} = Struct {Json.154, Json.499};
|
||||||
|
ret Json.498;
|
||||||
in
|
in
|
||||||
let Json.448 : U64 = 1i64;
|
let Json.506 : U64 = 1i64;
|
||||||
let Json.445 : Int1 = CallByName Num.24 Json.135 Json.448;
|
let Json.503 : Int1 = CallByName Num.24 Json.151 Json.506;
|
||||||
if Json.445 then
|
if Json.503 then
|
||||||
let Json.447 : I64 = 44i64;
|
let Json.505 : I64 = 44i64;
|
||||||
let Json.446 : U8 = CallByName Num.127 Json.447;
|
let Json.504 : U8 = CallByName Num.127 Json.505;
|
||||||
let Json.443 : List U8 = CallByName List.4 Json.137 Json.446;
|
let Json.501 : List U8 = CallByName List.4 Json.153 Json.504;
|
||||||
jump Json.444 Json.443;
|
jump Json.502 Json.501;
|
||||||
else
|
else
|
||||||
jump Json.444 Json.137;
|
jump Json.502 Json.153;
|
||||||
|
|
||||||
procedure Json.130 (Json.430, Json.136):
|
procedure Json.146 (Json.488, Json.152):
|
||||||
let Json.134 : List U8 = StructAtIndex 0 Json.430;
|
let Json.150 : List U8 = StructAtIndex 0 Json.488;
|
||||||
inc Json.134;
|
inc Json.150;
|
||||||
let Json.135 : U64 = StructAtIndex 1 Json.430;
|
let Json.151 : U64 = StructAtIndex 1 Json.488;
|
||||||
dec Json.430;
|
dec Json.488;
|
||||||
let Json.499 : {} = Struct {};
|
let Json.557 : {} = Struct {};
|
||||||
let Json.137 : List U8 = CallByName Encode.23 Json.134 Json.136 Json.499;
|
let Json.153 : List U8 = CallByName Encode.24 Json.150 Json.152 Json.557;
|
||||||
dec Json.134;
|
dec Json.150;
|
||||||
joinpoint Json.494 Json.138:
|
joinpoint Json.552 Json.154:
|
||||||
let Json.492 : U64 = 1i64;
|
let Json.550 : U64 = 1i64;
|
||||||
let Json.491 : U64 = CallByName Num.20 Json.135 Json.492;
|
let Json.549 : U64 = CallByName Num.20 Json.151 Json.550;
|
||||||
let Json.490 : {List U8, U64} = Struct {Json.138, Json.491};
|
let Json.548 : {List U8, U64} = Struct {Json.154, Json.549};
|
||||||
ret Json.490;
|
ret Json.548;
|
||||||
in
|
in
|
||||||
let Json.498 : U64 = 1i64;
|
let Json.556 : U64 = 1i64;
|
||||||
let Json.495 : Int1 = CallByName Num.24 Json.135 Json.498;
|
let Json.553 : Int1 = CallByName Num.24 Json.151 Json.556;
|
||||||
if Json.495 then
|
if Json.553 then
|
||||||
let Json.497 : I64 = 44i64;
|
let Json.555 : I64 = 44i64;
|
||||||
let Json.496 : U8 = CallByName Num.127 Json.497;
|
let Json.554 : U8 = CallByName Num.127 Json.555;
|
||||||
let Json.493 : List U8 = CallByName List.4 Json.137 Json.496;
|
let Json.551 : List U8 = CallByName List.4 Json.153 Json.554;
|
||||||
jump Json.494 Json.493;
|
jump Json.552 Json.551;
|
||||||
else
|
else
|
||||||
jump Json.494 Json.137;
|
jump Json.552 Json.153;
|
||||||
|
|
||||||
procedure Json.21 (Json.126, Json.127):
|
procedure Json.22 (Json.142, Json.143):
|
||||||
let Json.468 : {Str, List [C {}, C {}]} = Struct {Json.126, Json.127};
|
let Json.526 : {Str, List [C {}, C {}]} = Struct {Json.142, Json.143};
|
||||||
let Json.467 : {Str, List [C {}, C {}]} = CallByName Encode.22 Json.468;
|
let Json.525 : {Str, List [C {}, C {}]} = CallByName Encode.23 Json.526;
|
||||||
ret Json.467;
|
ret Json.525;
|
||||||
|
|
||||||
procedure Json.21 (Json.126, Json.127):
|
procedure Json.22 (Json.142, Json.143):
|
||||||
let Json.518 : {Str, List []} = Struct {Json.126, Json.127};
|
let Json.576 : {Str, List []} = Struct {Json.142, Json.143};
|
||||||
let Json.517 : {Str, List []} = CallByName Encode.22 Json.518;
|
let Json.575 : {Str, List []} = CallByName Encode.23 Json.576;
|
||||||
ret Json.517;
|
ret Json.575;
|
||||||
|
|
||||||
procedure List.139 (List.140, List.141, List.138):
|
procedure List.139 (List.140, List.141, List.138):
|
||||||
let List.539 : {List U8, U64} = CallByName Json.130 List.140 List.141;
|
let List.539 : {List U8, U64} = CallByName Json.146 List.140 List.141;
|
||||||
ret List.539;
|
ret List.539;
|
||||||
|
|
||||||
procedure List.139 (List.140, List.141, List.138):
|
procedure List.139 (List.140, List.141, List.138):
|
||||||
let List.612 : {List U8, U64} = CallByName Json.130 List.140 List.141;
|
let List.612 : {List U8, U64} = CallByName Json.146 List.140 List.141;
|
||||||
ret List.612;
|
ret List.612;
|
||||||
|
|
||||||
procedure List.18 (List.136, List.137, List.138):
|
procedure List.18 (List.136, List.137, List.138):
|
||||||
|
@ -334,7 +334,7 @@ procedure Str.12 (#Attr.2):
|
||||||
ret Str.268;
|
ret Str.268;
|
||||||
|
|
||||||
procedure Test.2 (Test.11):
|
procedure Test.2 (Test.11):
|
||||||
let Test.18 : {{}, {}} = CallByName Encode.22 Test.11;
|
let Test.18 : {{}, {}} = CallByName Encode.23 Test.11;
|
||||||
ret Test.18;
|
ret Test.18;
|
||||||
|
|
||||||
procedure Test.3 ():
|
procedure Test.3 ():
|
||||||
|
@ -345,7 +345,7 @@ procedure Test.3 ():
|
||||||
|
|
||||||
procedure Test.5 (Test.6, Test.7, Test.4):
|
procedure Test.5 (Test.6, Test.7, Test.4):
|
||||||
joinpoint Test.23 Test.8:
|
joinpoint Test.23 Test.8:
|
||||||
let Test.21 : List U8 = CallByName Encode.23 Test.6 Test.8 Test.7;
|
let Test.21 : List U8 = CallByName Encode.24 Test.6 Test.8 Test.7;
|
||||||
ret Test.21;
|
ret Test.21;
|
||||||
in
|
in
|
||||||
let Test.28 : Int1 = CallByName Bool.2;
|
let Test.28 : Int1 = CallByName Bool.2;
|
||||||
|
@ -354,18 +354,18 @@ procedure Test.5 (Test.6, Test.7, Test.4):
|
||||||
let Test.32 : {} = StructAtIndex 0 Test.4;
|
let Test.32 : {} = StructAtIndex 0 Test.4;
|
||||||
let Test.31 : [C {}, C {}] = CallByName #Derived.0 Test.32;
|
let Test.31 : [C {}, C {}] = CallByName #Derived.0 Test.32;
|
||||||
let Test.30 : List [C {}, C {}] = Array [Test.31];
|
let Test.30 : List [C {}, C {}] = Array [Test.31];
|
||||||
let Test.22 : {Str, List [C {}, C {}]} = CallByName Json.21 Test.29 Test.30;
|
let Test.22 : {Str, List [C {}, C {}]} = CallByName Json.22 Test.29 Test.30;
|
||||||
jump Test.23 Test.22;
|
jump Test.23 Test.22;
|
||||||
else
|
else
|
||||||
let Test.24 : Str = "B";
|
let Test.24 : Str = "B";
|
||||||
let Test.27 : {} = StructAtIndex 1 Test.4;
|
let Test.27 : {} = StructAtIndex 1 Test.4;
|
||||||
let Test.26 : [C {}, C {}] = CallByName #Derived.5 Test.27;
|
let Test.26 : [C {}, C {}] = CallByName #Derived.5 Test.27;
|
||||||
let Test.25 : List [C {}, C {}] = Array [Test.26];
|
let Test.25 : List [C {}, C {}] = Array [Test.26];
|
||||||
let Test.22 : {Str, List [C {}, C {}]} = CallByName Json.21 Test.24 Test.25;
|
let Test.22 : {Str, List [C {}, C {}]} = CallByName Json.22 Test.24 Test.25;
|
||||||
jump Test.23 Test.22;
|
jump Test.23 Test.22;
|
||||||
|
|
||||||
procedure Test.0 ():
|
procedure Test.0 ():
|
||||||
let Test.13 : {{}, {}} = CallByName Test.3;
|
let Test.13 : {{}, {}} = CallByName Test.3;
|
||||||
let Test.14 : {} = CallByName Json.1;
|
let Test.14 : {} = CallByName Json.1;
|
||||||
let Test.12 : List U8 = CallByName Encode.25 Test.13 Test.14;
|
let Test.12 : List U8 = CallByName Encode.26 Test.13 Test.14;
|
||||||
ret Test.12;
|
ret Test.12;
|
||||||
|
|
|
@ -4459,6 +4459,7 @@ pub struct StorageSubs {
|
||||||
struct StorageSubsOffsets {
|
struct StorageSubsOffsets {
|
||||||
utable: u32,
|
utable: u32,
|
||||||
variables: u32,
|
variables: u32,
|
||||||
|
tuple_elem_indices: u32,
|
||||||
tag_names: u32,
|
tag_names: u32,
|
||||||
symbol_names: u32,
|
symbol_names: u32,
|
||||||
field_names: u32,
|
field_names: u32,
|
||||||
|
@ -4542,6 +4543,7 @@ impl StorageSubs {
|
||||||
let self_offsets = StorageSubsOffsets {
|
let self_offsets = StorageSubsOffsets {
|
||||||
utable: self.subs.utable.len() as u32,
|
utable: self.subs.utable.len() as u32,
|
||||||
variables: self.subs.variables.len() as u32,
|
variables: self.subs.variables.len() as u32,
|
||||||
|
tuple_elem_indices: self.subs.tuple_elem_indices.len() as u32,
|
||||||
tag_names: self.subs.tag_names.len() as u32,
|
tag_names: self.subs.tag_names.len() as u32,
|
||||||
symbol_names: self.subs.symbol_names.len() as u32,
|
symbol_names: self.subs.symbol_names.len() as u32,
|
||||||
field_names: self.subs.field_names.len() as u32,
|
field_names: self.subs.field_names.len() as u32,
|
||||||
|
@ -4553,6 +4555,7 @@ impl StorageSubs {
|
||||||
let offsets = StorageSubsOffsets {
|
let offsets = StorageSubsOffsets {
|
||||||
utable: (target.utable.len() - Variable::NUM_RESERVED_VARS) as u32,
|
utable: (target.utable.len() - Variable::NUM_RESERVED_VARS) as u32,
|
||||||
variables: target.variables.len() as u32,
|
variables: target.variables.len() as u32,
|
||||||
|
tuple_elem_indices: target.tuple_elem_indices.len() as u32,
|
||||||
tag_names: target.tag_names.len() as u32,
|
tag_names: target.tag_names.len() as u32,
|
||||||
symbol_names: target.symbol_names.len() as u32,
|
symbol_names: target.symbol_names.len() as u32,
|
||||||
field_names: target.field_names.len() as u32,
|
field_names: target.field_names.len() as u32,
|
||||||
|
@ -4593,6 +4596,10 @@ impl StorageSubs {
|
||||||
.map(|v| Self::offset_variable(&offsets, *v)),
|
.map(|v| Self::offset_variable(&offsets, *v)),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
target
|
||||||
|
.tuple_elem_indices
|
||||||
|
.extend(self.subs.tuple_elem_indices);
|
||||||
|
|
||||||
target.variable_slices.extend(
|
target.variable_slices.extend(
|
||||||
self.subs
|
self.subs
|
||||||
.variable_slices
|
.variable_slices
|
||||||
|
@ -4613,6 +4620,11 @@ impl StorageSubs {
|
||||||
(self_offsets.utable + offsets.utable) as usize
|
(self_offsets.utable + offsets.utable) as usize
|
||||||
);
|
);
|
||||||
|
|
||||||
|
debug_assert_eq!(
|
||||||
|
target.tuple_elem_indices.len(),
|
||||||
|
(self_offsets.tuple_elem_indices + offsets.tuple_elem_indices) as usize
|
||||||
|
);
|
||||||
|
|
||||||
debug_assert_eq!(
|
debug_assert_eq!(
|
||||||
target.tag_names.len(),
|
target.tag_names.len(),
|
||||||
(self_offsets.tag_names + offsets.tag_names) as usize
|
(self_offsets.tag_names + offsets.tag_names) as usize
|
||||||
|
@ -4756,6 +4768,7 @@ impl StorageSubs {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn offset_tuple_elems(offsets: &StorageSubsOffsets, mut tuple_elems: TupleElems) -> TupleElems {
|
fn offset_tuple_elems(offsets: &StorageSubsOffsets, mut tuple_elems: TupleElems) -> TupleElems {
|
||||||
|
tuple_elems.elem_index_start += offsets.tuple_elem_indices;
|
||||||
tuple_elems.variables_start += offsets.variables;
|
tuple_elems.variables_start += offsets.variables;
|
||||||
|
|
||||||
tuple_elems
|
tuple_elems
|
||||||
|
|
|
@ -11177,6 +11177,55 @@ I recommend using camelCase. It's the standard style in Roc code!
|
||||||
"###
|
"###
|
||||||
);
|
);
|
||||||
|
|
||||||
|
test_no_problem!(
|
||||||
|
derive_hash_for_tuple,
|
||||||
|
indoc!(
|
||||||
|
r#"
|
||||||
|
app "test" provides [main] to "./platform"
|
||||||
|
|
||||||
|
foo : a -> {} | a has Hash
|
||||||
|
|
||||||
|
main = foo ("", 1)
|
||||||
|
"#
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
test_report!(
|
||||||
|
cannot_hash_tuple_with_non_hash_element,
|
||||||
|
indoc!(
|
||||||
|
r#"
|
||||||
|
app "test" provides [main] to "./platform"
|
||||||
|
|
||||||
|
foo : a -> {} | a has Hash
|
||||||
|
|
||||||
|
main = foo ("", \{} -> {})
|
||||||
|
"#
|
||||||
|
),
|
||||||
|
@r###"
|
||||||
|
── TYPE MISMATCH ───────────────────────────────────────── /code/proj/Main.roc ─
|
||||||
|
|
||||||
|
This expression has a type that does not implement the abilities it's expected to:
|
||||||
|
|
||||||
|
5│ main = foo ("", \{} -> {})
|
||||||
|
^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
I can't generate an implementation of the `Hash` ability for
|
||||||
|
|
||||||
|
(
|
||||||
|
Str,
|
||||||
|
{}a -> {},
|
||||||
|
)a
|
||||||
|
|
||||||
|
In particular, an implementation for
|
||||||
|
|
||||||
|
{}a -> {}
|
||||||
|
|
||||||
|
cannot be generated.
|
||||||
|
|
||||||
|
Note: `Hash` cannot be generated for functions.
|
||||||
|
"###
|
||||||
|
);
|
||||||
|
|
||||||
test_report!(
|
test_report!(
|
||||||
shift_by_negative,
|
shift_by_negative,
|
||||||
indoc!(
|
indoc!(
|
||||||
|
@ -11559,6 +11608,58 @@ I recommend using camelCase. It's the standard style in Roc code!
|
||||||
"###
|
"###
|
||||||
);
|
);
|
||||||
|
|
||||||
|
test_no_problem!(
|
||||||
|
derive_eq_for_tuple,
|
||||||
|
indoc!(
|
||||||
|
r#"
|
||||||
|
app "test" provides [main] to "./platform"
|
||||||
|
|
||||||
|
foo : a -> {} | a has Eq
|
||||||
|
|
||||||
|
main = foo ("", 1)
|
||||||
|
"#
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
test_report!(
|
||||||
|
cannot_eq_tuple_with_non_eq_element,
|
||||||
|
indoc!(
|
||||||
|
r#"
|
||||||
|
app "test" provides [main] to "./platform"
|
||||||
|
|
||||||
|
foo : a -> {} | a has Eq
|
||||||
|
|
||||||
|
main = foo ("", 1.0f64)
|
||||||
|
"#
|
||||||
|
),
|
||||||
|
@r###"
|
||||||
|
── TYPE MISMATCH ───────────────────────────────────────── /code/proj/Main.roc ─
|
||||||
|
|
||||||
|
This expression has a type that does not implement the abilities it's expected to:
|
||||||
|
|
||||||
|
5│ main = foo ("", 1.0f64)
|
||||||
|
^^^^^^^^^^^^
|
||||||
|
|
||||||
|
I can't generate an implementation of the `Eq` ability for
|
||||||
|
|
||||||
|
(
|
||||||
|
Str,
|
||||||
|
F64,
|
||||||
|
)a
|
||||||
|
|
||||||
|
In particular, an implementation for
|
||||||
|
|
||||||
|
F64
|
||||||
|
|
||||||
|
cannot be generated.
|
||||||
|
|
||||||
|
Note: I can't derive `Bool.isEq` for floating-point types. That's
|
||||||
|
because Roc's floating-point numbers cannot be compared for total
|
||||||
|
equality - in Roc, `NaN` is never comparable to `NaN`. If a type
|
||||||
|
doesn't support total equality, it cannot support the `Eq` ability!
|
||||||
|
"###
|
||||||
|
);
|
||||||
|
|
||||||
test_report!(
|
test_report!(
|
||||||
cannot_import_structural_eq_not_eq,
|
cannot_import_structural_eq_not_eq,
|
||||||
indoc!(
|
indoc!(
|
||||||
|
@ -13127,6 +13228,90 @@ I recommend using camelCase. It's the standard style in Roc code!
|
||||||
"###
|
"###
|
||||||
);
|
);
|
||||||
|
|
||||||
|
test_no_problem!(
|
||||||
|
derive_decoding_for_tuple,
|
||||||
|
indoc!(
|
||||||
|
r#"
|
||||||
|
app "test" imports [Decode.{decoder}] provides [main] to "./platform"
|
||||||
|
|
||||||
|
main =
|
||||||
|
myDecoder : Decoder (U32, Str) fmt | fmt has DecoderFormatting
|
||||||
|
myDecoder = decoder
|
||||||
|
|
||||||
|
myDecoder
|
||||||
|
"#
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
test_report!(
|
||||||
|
cannot_decode_tuple_with_non_decode_element,
|
||||||
|
indoc!(
|
||||||
|
r#"
|
||||||
|
app "test" imports [Decode.{decoder}] provides [main] to "./platform"
|
||||||
|
|
||||||
|
main =
|
||||||
|
myDecoder : Decoder (U32, {} -> {}) fmt | fmt has DecoderFormatting
|
||||||
|
myDecoder = decoder
|
||||||
|
|
||||||
|
myDecoder
|
||||||
|
"#
|
||||||
|
),
|
||||||
|
@r###"
|
||||||
|
── TYPE MISMATCH ───────────────────────────────────────── /code/proj/Main.roc ─
|
||||||
|
|
||||||
|
This expression has a type that does not implement the abilities it's expected to:
|
||||||
|
|
||||||
|
5│ myDecoder = decoder
|
||||||
|
^^^^^^^
|
||||||
|
|
||||||
|
I can't generate an implementation of the `Decoding` ability for
|
||||||
|
|
||||||
|
U32, {} -> {}
|
||||||
|
|
||||||
|
Note: `Decoding` cannot be generated for functions.
|
||||||
|
"###
|
||||||
|
);
|
||||||
|
|
||||||
|
test_no_problem!(
|
||||||
|
derive_encoding_for_tuple,
|
||||||
|
indoc!(
|
||||||
|
r#"
|
||||||
|
app "test" imports [] provides [main] to "./platform"
|
||||||
|
|
||||||
|
x : (U32, Str)
|
||||||
|
|
||||||
|
main = Encode.toEncoder x
|
||||||
|
"#
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
test_report!(
|
||||||
|
cannot_encode_tuple_with_non_encode_element,
|
||||||
|
indoc!(
|
||||||
|
r#"
|
||||||
|
app "test" imports [] provides [main] to "./platform"
|
||||||
|
|
||||||
|
x : (U32, {} -> {})
|
||||||
|
|
||||||
|
main = Encode.toEncoder x
|
||||||
|
"#
|
||||||
|
),
|
||||||
|
@r###"
|
||||||
|
── TYPE MISMATCH ───────────────────────────────────────── /code/proj/Main.roc ─
|
||||||
|
|
||||||
|
This expression has a type that does not implement the abilities it's expected to:
|
||||||
|
|
||||||
|
5│ main = Encode.toEncoder x
|
||||||
|
^
|
||||||
|
|
||||||
|
I can't generate an implementation of the `Encoding` ability for
|
||||||
|
|
||||||
|
U32, {} -> {}
|
||||||
|
|
||||||
|
Note: `Encoding` cannot be generated for functions.
|
||||||
|
"###
|
||||||
|
);
|
||||||
|
|
||||||
test_report!(
|
test_report!(
|
||||||
exhaustiveness_check_function_or_tag_union_issue_4994,
|
exhaustiveness_check_function_or_tag_union_issue_4994,
|
||||||
indoc!(
|
indoc!(
|
||||||
|
|
|
@ -19,6 +19,7 @@ EnvFormat := {} has [
|
||||||
string: envString,
|
string: envString,
|
||||||
list: envList,
|
list: envList,
|
||||||
record: envRecord,
|
record: envRecord,
|
||||||
|
tuple: envTuple,
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -93,3 +94,10 @@ envList = \decodeElem -> Decode.custom \bytes, @EnvFormat {} ->
|
||||||
envRecord : _, (_, _ -> [Keep (Decoder _ _), Skip]), (_ -> _) -> Decoder _ _
|
envRecord : _, (_, _ -> [Keep (Decoder _ _), Skip]), (_ -> _) -> Decoder _ _
|
||||||
envRecord = \_initialState, _stepField, _finalizer -> Decode.custom \bytes, @EnvFormat {} ->
|
envRecord = \_initialState, _stepField, _finalizer -> Decode.custom \bytes, @EnvFormat {} ->
|
||||||
{ result: Err TooShort, rest: bytes }
|
{ result: Err TooShort, rest: bytes }
|
||||||
|
|
||||||
|
# TODO: we must currently annotate the arrows here so that the lambda sets are
|
||||||
|
# exercised, and the solver can find an ambient lambda set for the
|
||||||
|
# specialization.
|
||||||
|
envTuple : _, (_, _ -> [Next (Decoder _ _), TooLong]), (_ -> _) -> Decoder _ _
|
||||||
|
envTuple = \_initialState, _stepElem, _finalizer -> Decode.custom \bytes, @EnvFormat {} ->
|
||||||
|
{ result: Err TooShort, rest: bytes }
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue