feat: changed air expressions clause guard
and list clause guard to air statements
This commit is contained in:
parent
023be88bf6
commit
5bcc425f0f
|
@ -1217,7 +1217,34 @@ impl<'a> CodeGenerator<'a> {
|
|||
defined_tails,
|
||||
} => {
|
||||
let Pattern::List { elements, .. } = &clause.pattern
|
||||
else { unreachable!() };
|
||||
else {
|
||||
let mut next_clause_props = ClauseProperties {
|
||||
clause_var_name: props.clause_var_name.clone(),
|
||||
complex_clause: false,
|
||||
needs_constr_var: false,
|
||||
original_subject_name: props.original_subject_name.clone(),
|
||||
final_clause: false,
|
||||
specific_clause: SpecificClause::ListClause {
|
||||
current_index: *current_index,
|
||||
defined_tails: defined_tails.clone(),
|
||||
},
|
||||
};
|
||||
|
||||
let (_, clause_assign) =
|
||||
self.clause_pattern(&clause.pattern, subject_tipo, props);
|
||||
|
||||
let clause_assign_hoisted = clause_assign.hoist_over(clause_then);
|
||||
|
||||
return AirTree::wrap_clause(
|
||||
clause_assign_hoisted,
|
||||
self.handle_each_clause(
|
||||
rest_clauses,
|
||||
final_clause,
|
||||
subject_tipo,
|
||||
&mut next_clause_props,
|
||||
),
|
||||
);
|
||||
};
|
||||
|
||||
let tail_name = if *current_index == 0 {
|
||||
props.original_subject_name.clone()
|
||||
|
@ -1255,7 +1282,7 @@ impl<'a> CodeGenerator<'a> {
|
|||
|
||||
let mut use_wrap_clause = false;
|
||||
|
||||
if elements.len() > *current_index as usize {
|
||||
if elements.len() >= *current_index as usize {
|
||||
*current_index += 1;
|
||||
defined_tails.push(tail_name.clone());
|
||||
} else if next_tail_name.is_none() {
|
||||
|
@ -1396,8 +1423,13 @@ impl<'a> CodeGenerator<'a> {
|
|||
elem_name.clone(),
|
||||
);
|
||||
|
||||
let statement =
|
||||
self.nested_clause_condition(elem, list_elem_type, &mut elem_props);
|
||||
let statement = self.nested_clause_condition(
|
||||
elem,
|
||||
AirTree::local_var(&elem_name, list_elem_type.clone()),
|
||||
list_elem_type,
|
||||
&mut elem_props,
|
||||
);
|
||||
|
||||
*complex_clause = *complex_clause || elem_props.complex_clause;
|
||||
|
||||
(tail, elem_name, statement)
|
||||
|
@ -1419,7 +1451,7 @@ impl<'a> CodeGenerator<'a> {
|
|||
tail.iter().for_each(|elem| {
|
||||
let tail = defined_tails
|
||||
.last()
|
||||
.unwrap_or_else(|| panic!("WHERE IS ME TAIL???"));
|
||||
.unwrap_or_else(|| panic!("WHERE IS THE TAIL???"));
|
||||
let elem_name = match elem.as_ref() {
|
||||
Pattern::Var { name, .. } => name.to_string(),
|
||||
Pattern::Assign { name, .. } => name.to_string(),
|
||||
|
@ -1440,8 +1472,12 @@ impl<'a> CodeGenerator<'a> {
|
|||
specific_clause: props.specific_clause.clone(),
|
||||
};
|
||||
|
||||
let statement =
|
||||
self.nested_clause_condition(elem, subject_tipo, &mut elem_props);
|
||||
let statement = self.nested_clause_condition(
|
||||
elem,
|
||||
AirTree::local_var(&elem_name, subject_tipo.clone()),
|
||||
subject_tipo,
|
||||
&mut elem_props,
|
||||
);
|
||||
*complex_clause = *complex_clause || elem_props.complex_clause;
|
||||
|
||||
air_elems.push(statement);
|
||||
|
@ -1542,6 +1578,7 @@ impl<'a> CodeGenerator<'a> {
|
|||
|
||||
let statement = self.nested_clause_condition(
|
||||
&arg.value,
|
||||
AirTree::local_var(&field_name, arg_type.clone()),
|
||||
arg_type,
|
||||
&mut field_props,
|
||||
);
|
||||
|
@ -1585,9 +1622,37 @@ impl<'a> CodeGenerator<'a> {
|
|||
fn nested_clause_condition(
|
||||
&mut self,
|
||||
pattern: &Pattern<PatternConstructor, Arc<Type>>,
|
||||
value: AirTree,
|
||||
subject_tipo: &Arc<Type>,
|
||||
props: &mut ClauseProperties,
|
||||
) -> AirTree {
|
||||
todo!()
|
||||
match pattern {
|
||||
Pattern::Int { value, .. } => {
|
||||
todo!();
|
||||
}
|
||||
Pattern::Var { location, name } => todo!(),
|
||||
Pattern::Assign {
|
||||
name,
|
||||
location,
|
||||
pattern,
|
||||
} => todo!(),
|
||||
Pattern::Discard { name, location } => todo!(),
|
||||
Pattern::List {
|
||||
location,
|
||||
elements,
|
||||
tail,
|
||||
} => todo!(),
|
||||
Pattern::Constructor {
|
||||
is_record,
|
||||
location,
|
||||
name,
|
||||
arguments,
|
||||
module,
|
||||
constructor,
|
||||
with_spread,
|
||||
tipo,
|
||||
} => todo!(),
|
||||
Pattern::Tuple { location, elems } => todo!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -45,6 +45,20 @@ pub enum AirStatement {
|
|||
is_true: bool,
|
||||
value: Box<AirTree>,
|
||||
},
|
||||
// Clause Guards
|
||||
ClauseGuard {
|
||||
subject_name: String,
|
||||
tipo: Arc<Type>,
|
||||
pattern: Box<AirTree>,
|
||||
then: Box<AirTree>,
|
||||
},
|
||||
ListClauseGuard {
|
||||
tipo: Arc<Type>,
|
||||
tail_name: String,
|
||||
next_tail_name: Option<String>,
|
||||
inverse: bool,
|
||||
then: Box<AirTree>,
|
||||
},
|
||||
// Field Access
|
||||
FieldsExpose {
|
||||
indices: Vec<(usize, String, Arc<Type>)>,
|
||||
|
@ -180,19 +194,7 @@ pub enum AirExpression {
|
|||
then: Box<AirTree>,
|
||||
otherwise: Box<AirTree>,
|
||||
},
|
||||
ClauseGuard {
|
||||
subject_name: String,
|
||||
tipo: Arc<Type>,
|
||||
pattern: Box<AirTree>,
|
||||
then: Box<AirTree>,
|
||||
},
|
||||
ListClauseGuard {
|
||||
tipo: Arc<Type>,
|
||||
tail_name: String,
|
||||
next_tail_name: Option<String>,
|
||||
inverse: bool,
|
||||
then: Box<AirTree>,
|
||||
},
|
||||
|
||||
Finally {
|
||||
pattern: Box<AirTree>,
|
||||
then: Box<AirTree>,
|
||||
|
@ -479,12 +481,15 @@ impl AirTree {
|
|||
tipo: Arc<Type>,
|
||||
then: AirTree,
|
||||
) -> AirTree {
|
||||
AirTree::Expression(AirExpression::ClauseGuard {
|
||||
AirTree::Statement {
|
||||
statement: AirStatement::ClauseGuard {
|
||||
subject_name: subject_name.to_string(),
|
||||
tipo,
|
||||
pattern: pattern.into(),
|
||||
then: then.into(),
|
||||
})
|
||||
},
|
||||
hoisted_over: None,
|
||||
}
|
||||
}
|
||||
pub fn list_clause_guard(
|
||||
tail_name: impl ToString,
|
||||
|
@ -493,13 +498,16 @@ impl AirTree {
|
|||
then: AirTree,
|
||||
next_tail_name: Option<String>,
|
||||
) -> AirTree {
|
||||
AirTree::Expression(AirExpression::ListClauseGuard {
|
||||
AirTree::Statement {
|
||||
statement: AirStatement::ListClauseGuard {
|
||||
tipo,
|
||||
tail_name: tail_name.to_string(),
|
||||
next_tail_name,
|
||||
inverse,
|
||||
then: then.into(),
|
||||
})
|
||||
},
|
||||
hoisted_over: None,
|
||||
}
|
||||
}
|
||||
pub fn finally(pattern: AirTree, then: AirTree) -> AirTree {
|
||||
AirTree::Expression(AirExpression::Finally {
|
||||
|
@ -768,6 +776,36 @@ impl AirTree {
|
|||
air_vec.push(Air::AssertBool { is_true: *is_true });
|
||||
value.create_air_vec(air_vec);
|
||||
}
|
||||
AirStatement::ClauseGuard {
|
||||
subject_name,
|
||||
tipo,
|
||||
pattern,
|
||||
then,
|
||||
} => {
|
||||
air_vec.push(Air::ClauseGuard {
|
||||
subject_name: subject_name.clone(),
|
||||
tipo: tipo.clone(),
|
||||
});
|
||||
|
||||
pattern.create_air_vec(air_vec);
|
||||
then.create_air_vec(air_vec);
|
||||
}
|
||||
AirStatement::ListClauseGuard {
|
||||
tipo,
|
||||
tail_name,
|
||||
next_tail_name,
|
||||
inverse,
|
||||
then,
|
||||
} => {
|
||||
air_vec.push(Air::ListClauseGuard {
|
||||
tipo: tipo.clone(),
|
||||
tail_name: tail_name.clone(),
|
||||
next_tail_name: next_tail_name.clone(),
|
||||
inverse: *inverse,
|
||||
});
|
||||
|
||||
then.create_air_vec(air_vec);
|
||||
}
|
||||
AirStatement::FieldsExpose {
|
||||
indices,
|
||||
check_last_item,
|
||||
|
@ -991,36 +1029,6 @@ impl AirTree {
|
|||
then.create_air_vec(air_vec);
|
||||
otherwise.create_air_vec(air_vec);
|
||||
}
|
||||
AirExpression::ClauseGuard {
|
||||
subject_name,
|
||||
tipo,
|
||||
pattern,
|
||||
then,
|
||||
} => {
|
||||
air_vec.push(Air::ClauseGuard {
|
||||
subject_name: subject_name.clone(),
|
||||
tipo: tipo.clone(),
|
||||
});
|
||||
|
||||
pattern.create_air_vec(air_vec);
|
||||
then.create_air_vec(air_vec);
|
||||
}
|
||||
AirExpression::ListClauseGuard {
|
||||
tipo,
|
||||
tail_name,
|
||||
next_tail_name,
|
||||
inverse,
|
||||
then,
|
||||
} => {
|
||||
air_vec.push(Air::ListClauseGuard {
|
||||
tipo: tipo.clone(),
|
||||
tail_name: tail_name.clone(),
|
||||
next_tail_name: next_tail_name.clone(),
|
||||
inverse: *inverse,
|
||||
});
|
||||
|
||||
then.create_air_vec(air_vec);
|
||||
}
|
||||
AirExpression::Finally { pattern, then } => {
|
||||
air_vec.push(Air::Finally);
|
||||
pattern.create_air_vec(air_vec);
|
||||
|
|
|
@ -419,6 +419,103 @@ fn acceptance_test_4_concat_no_anon_func() {
|
|||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn acceptance_test_5_direct_head() {
|
||||
let src = r#"
|
||||
use aiken/builtin.{head_list}
|
||||
|
||||
test head_1() {
|
||||
let head = fn(xs){
|
||||
when xs is {
|
||||
[] -> None
|
||||
_ -> Some(head_list(xs))
|
||||
}
|
||||
}
|
||||
|
||||
head([1, 2, 3]) == Some(1)
|
||||
}
|
||||
"#;
|
||||
|
||||
assert_uplc(
|
||||
src,
|
||||
Term::equals_data()
|
||||
.apply(
|
||||
Term::var("head")
|
||||
.lambda("head")
|
||||
.apply(
|
||||
Term::var("xs")
|
||||
.delayed_choose_list(
|
||||
Term::Constant(Constant::Data(Data::constr(1, vec![])).into()),
|
||||
Term::constr_data().apply(Term::integer(0.into())).apply(
|
||||
Term::mk_cons()
|
||||
.apply(Term::head_list().apply(Term::var("xs")))
|
||||
.apply(Term::empty_list()),
|
||||
),
|
||||
)
|
||||
.lambda("xs"),
|
||||
)
|
||||
.apply(Term::list_values(vec![
|
||||
Constant::Data(Data::integer(1.into())),
|
||||
Constant::Data(Data::integer(2.into())),
|
||||
Constant::Data(Data::integer(3.into())),
|
||||
])),
|
||||
)
|
||||
.apply(Term::Constant(
|
||||
Constant::Data(Data::constr(0, vec![Data::integer(1.into())])).into(),
|
||||
)),
|
||||
false,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn acceptance_test_5_direct_2_heads() {
|
||||
let src = r#"
|
||||
use aiken/builtin.{head_list}
|
||||
|
||||
test head_2() {
|
||||
let head = fn(xs: List<Int>){
|
||||
when xs is {
|
||||
[] -> None
|
||||
[a] -> Some(xs)
|
||||
[a, b, ..c] -> Some([a,b])
|
||||
}
|
||||
}
|
||||
|
||||
head([1, 2, 3]) == Some([1, 2])
|
||||
}
|
||||
"#;
|
||||
|
||||
assert_uplc(
|
||||
src,
|
||||
Term::equals_data()
|
||||
.apply(
|
||||
Term::var("head")
|
||||
.lambda("head")
|
||||
.apply(
|
||||
Term::var("xs")
|
||||
.delayed_choose_list(
|
||||
Term::Constant(Constant::Data(Data::constr(1, vec![])).into()),
|
||||
Term::constr_data().apply(Term::integer(0.into())).apply(
|
||||
Term::mk_cons()
|
||||
.apply(Term::head_list().apply(Term::var("xs")))
|
||||
.apply(Term::empty_list()),
|
||||
),
|
||||
)
|
||||
.lambda("xs"),
|
||||
)
|
||||
.apply(Term::list_values(vec![
|
||||
Constant::Data(Data::integer(1.into())),
|
||||
Constant::Data(Data::integer(2.into())),
|
||||
Constant::Data(Data::integer(3.into())),
|
||||
])),
|
||||
)
|
||||
.apply(Term::Constant(
|
||||
Constant::Data(Data::constr(0, vec![Data::integer(1.into())])).into(),
|
||||
)),
|
||||
false,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn acceptance_test_5_head_not_empty() {
|
||||
let src = r#"
|
||||
|
|
Loading…
Reference in New Issue