fix: constrs that contain fields now work when passed as an arg to a function.
Convert acceptance test 22 Create test for passing constr as a function
This commit is contained in:
parent
26a607eb00
commit
a65821d5ab
|
@ -3809,34 +3809,59 @@ impl<'a> CodeGenerator<'a> {
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let (constr_index, _) = data_type
|
let (constr_index, constr_type) = data_type
|
||||||
.constructors
|
.constructors
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.find(|(_, x)| x.name == *constr_name)
|
.find(|(_, x)| x.name == *constr_name)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let fields = Term::empty_list();
|
let mut term = Term::empty_list();
|
||||||
|
|
||||||
let mut term = Term::constr_data()
|
if constr_type.arguments.is_empty() {
|
||||||
.apply(Term::integer(constr_index.try_into().unwrap()))
|
term = Term::constr_data()
|
||||||
.apply(fields);
|
.apply(Term::integer(constr_index.try_into().unwrap()))
|
||||||
|
.apply(term);
|
||||||
|
|
||||||
let mut program: Program<Name> = Program {
|
let mut program: Program<Name> = Program {
|
||||||
version: (1, 0, 0),
|
version: (1, 0, 0),
|
||||||
term,
|
term,
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut interner = Interner::new();
|
let mut interner = Interner::new();
|
||||||
|
|
||||||
interner.program(&mut program);
|
interner.program(&mut program);
|
||||||
|
|
||||||
let eval_program: Program<NamedDeBruijn> = program.try_into().unwrap();
|
let eval_program: Program<NamedDeBruijn> =
|
||||||
|
program.try_into().unwrap();
|
||||||
|
|
||||||
let evaluated_term: Term<NamedDeBruijn> =
|
let evaluated_term: Term<NamedDeBruijn> =
|
||||||
eval_program.eval(ExBudget::default()).result().unwrap();
|
eval_program.eval(ExBudget::default()).result().unwrap();
|
||||||
term = evaluated_term.try_into().unwrap();
|
term = evaluated_term.try_into().unwrap();
|
||||||
|
} else {
|
||||||
|
for (index, arg) in constr_type.arguments.iter().enumerate().rev() {
|
||||||
|
term = Term::mk_cons()
|
||||||
|
.apply(builder::convert_type_to_data(
|
||||||
|
Term::var(
|
||||||
|
arg.label
|
||||||
|
.clone()
|
||||||
|
.unwrap_or_else(|| format!("arg_{index}")),
|
||||||
|
),
|
||||||
|
&arg.tipo,
|
||||||
|
))
|
||||||
|
.apply(term);
|
||||||
|
}
|
||||||
|
|
||||||
|
term = Term::constr_data()
|
||||||
|
.apply(Term::integer(constr_index.into()))
|
||||||
|
.apply(term);
|
||||||
|
|
||||||
|
for (index, arg) in constr_type.arguments.iter().enumerate().rev() {
|
||||||
|
term = term.lambda(
|
||||||
|
arg.label.clone().unwrap_or_else(|| format!("arg_{index}")),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
arg_stack.push(term);
|
arg_stack.push(term);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4569,9 +4594,11 @@ impl<'a> CodeGenerator<'a> {
|
||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
let mut arg_vec = vec![];
|
let mut arg_vec = vec![];
|
||||||
|
|
||||||
for _ in 0..count {
|
for _ in 0..count {
|
||||||
arg_vec.push(arg_stack.pop().unwrap());
|
arg_vec.push(arg_stack.pop().unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut term = Term::empty_list();
|
let mut term = Term::empty_list();
|
||||||
|
|
||||||
for (index, arg) in arg_vec.iter().enumerate().rev() {
|
for (index, arg) in arg_vec.iter().enumerate().rev() {
|
||||||
|
|
|
@ -2374,3 +2374,183 @@ fn acceptance_test_20_map_some() {
|
||||||
false,
|
false,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn acceptance_test_22_filter_map() {
|
||||||
|
let src = r#"
|
||||||
|
pub fn foldr(xs: List<a>, f: fn(a, b) -> b, zero: b) -> b {
|
||||||
|
when xs is {
|
||||||
|
[] ->
|
||||||
|
zero
|
||||||
|
[x, ..rest] ->
|
||||||
|
f(x, foldr(rest, f, zero))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn filter_map(xs: List<a>, f: fn(a) -> Option<b>) -> List<b> {
|
||||||
|
foldr(
|
||||||
|
xs,
|
||||||
|
fn(x, ys) {
|
||||||
|
when f(x) is {
|
||||||
|
None ->
|
||||||
|
ys
|
||||||
|
Some(y) ->
|
||||||
|
[y, ..ys]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[],
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
test filter_map_1() {
|
||||||
|
filter_map([], fn(_) { Some(43) }) == []
|
||||||
|
}
|
||||||
|
"#;
|
||||||
|
|
||||||
|
assert_uplc(
|
||||||
|
src,
|
||||||
|
Term::equals_data()
|
||||||
|
.apply(
|
||||||
|
Term::list_data().apply(
|
||||||
|
Term::var("filter_map")
|
||||||
|
.lambda("filter_map")
|
||||||
|
.apply(
|
||||||
|
Term::var("foldr")
|
||||||
|
.apply(Term::var("xs"))
|
||||||
|
.apply(
|
||||||
|
Term::equals_integer()
|
||||||
|
.apply(Term::integer(1.into()))
|
||||||
|
.apply(Term::var("subject_index"))
|
||||||
|
.delayed_if_else(
|
||||||
|
Term::var("ys"),
|
||||||
|
Term::mk_cons()
|
||||||
|
.apply(Term::i_data().apply(Term::var("y")))
|
||||||
|
.apply(Term::var("ys"))
|
||||||
|
.lambda("y")
|
||||||
|
.apply(
|
||||||
|
Term::un_i_data().apply(
|
||||||
|
Term::head_list()
|
||||||
|
.apply(Term::var("subject_fields")),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.lambda("subject_fields")
|
||||||
|
.apply(
|
||||||
|
Term::var(CONSTR_FIELDS_EXPOSER)
|
||||||
|
.apply(Term::var("subject")),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.lambda("subject_index")
|
||||||
|
.apply(
|
||||||
|
Term::var(CONSTR_INDEX_EXPOSER)
|
||||||
|
.apply(Term::var("subject")),
|
||||||
|
)
|
||||||
|
.lambda("subject")
|
||||||
|
.apply(Term::var("f").apply(Term::var("x")))
|
||||||
|
.lambda("ys")
|
||||||
|
.lambda("x"),
|
||||||
|
)
|
||||||
|
.apply(Term::empty_list())
|
||||||
|
.lambda("f")
|
||||||
|
.lambda("xs"),
|
||||||
|
)
|
||||||
|
.lambda("foldr")
|
||||||
|
.apply(Term::var("foldr").apply(Term::var("foldr")))
|
||||||
|
.lambda("foldr")
|
||||||
|
.apply(
|
||||||
|
Term::var("xs")
|
||||||
|
.delayed_choose_list(
|
||||||
|
Term::var("zero"),
|
||||||
|
Term::var("f")
|
||||||
|
.apply(Term::var("x"))
|
||||||
|
.apply(
|
||||||
|
Term::var("foldr")
|
||||||
|
.apply(Term::var("foldr"))
|
||||||
|
.apply(Term::var("rest"))
|
||||||
|
.apply(Term::var("f"))
|
||||||
|
.apply(Term::var("zero")),
|
||||||
|
)
|
||||||
|
.lambda("rest")
|
||||||
|
.apply(Term::tail_list().apply(Term::var("xs")))
|
||||||
|
.lambda("x")
|
||||||
|
.apply(Term::head_list().apply(Term::var("xs"))),
|
||||||
|
)
|
||||||
|
.lambda("zero")
|
||||||
|
.lambda("f")
|
||||||
|
.lambda("xs")
|
||||||
|
.lambda("foldr"),
|
||||||
|
)
|
||||||
|
.apply(Term::empty_list())
|
||||||
|
.apply(
|
||||||
|
Term::data(Data::constr(0, vec![Data::integer(42.into())])).lambda("_"),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.apply(Term::list_data().apply(Term::empty_list()))
|
||||||
|
.constr_get_field()
|
||||||
|
.constr_fields_exposer()
|
||||||
|
.constr_index_exposer(),
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn pass_constr_as_function() {
|
||||||
|
let src = r#"
|
||||||
|
type Make {
|
||||||
|
a: Int,
|
||||||
|
b: SubMake
|
||||||
|
}
|
||||||
|
|
||||||
|
type SubMake {
|
||||||
|
c: Int
|
||||||
|
}
|
||||||
|
|
||||||
|
fn hi(sm: SubMake, to_make: fn (Int, SubMake) -> Make) -> Make {
|
||||||
|
to_make(3, sm)
|
||||||
|
}
|
||||||
|
|
||||||
|
test cry() {
|
||||||
|
Make(3, SubMake(1)) == hi(SubMake(1), Make)
|
||||||
|
}
|
||||||
|
"#;
|
||||||
|
|
||||||
|
assert_uplc(
|
||||||
|
src,
|
||||||
|
Term::equals_data()
|
||||||
|
.apply(Term::data(Data::constr(
|
||||||
|
0,
|
||||||
|
vec![
|
||||||
|
Data::integer(3.into()),
|
||||||
|
Data::constr(0, vec![Data::integer(1.into())]),
|
||||||
|
],
|
||||||
|
)))
|
||||||
|
.apply(
|
||||||
|
Term::var("hi")
|
||||||
|
.lambda("hi")
|
||||||
|
.apply(
|
||||||
|
Term::var("to_make")
|
||||||
|
.apply(Term::integer(3.into()))
|
||||||
|
.apply(Term::var("sm"))
|
||||||
|
.lambda("to_make")
|
||||||
|
.lambda("sm"),
|
||||||
|
)
|
||||||
|
.apply(Term::data(Data::constr(0, vec![Data::integer(1.into())])))
|
||||||
|
.apply(
|
||||||
|
Term::constr_data()
|
||||||
|
.apply(Term::integer(0.into()))
|
||||||
|
.apply(
|
||||||
|
Term::mk_cons()
|
||||||
|
.apply(Term::i_data().apply(Term::var("a")))
|
||||||
|
.apply(
|
||||||
|
Term::mk_cons()
|
||||||
|
.apply(Term::var("b"))
|
||||||
|
.apply(Term::empty_list()),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.lambda("b")
|
||||||
|
.lambda("a"),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue