mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-28 14:24:45 +00:00
Factor out decoders into separate files
This commit is contained in:
parent
5e0a6e5926
commit
e96be7c746
4 changed files with 1104 additions and 1073 deletions
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 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),
|
||||
)
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue