From 72b6f0f847c998b575ca4c90fe3405e9959f6419 Mon Sep 17 00:00:00 2001 From: microproofs Date: Tue, 25 Jul 2023 15:46:53 -0400 Subject: [PATCH] all but six tests passing --- crates/aiken-lang/src/gen_uplc.rs | 101 ++++++++++++++++------- crates/aiken-lang/src/gen_uplc/tree.rs | 109 +++++++++++++------------ 2 files changed, 129 insertions(+), 81 deletions(-) diff --git a/crates/aiken-lang/src/gen_uplc.rs b/crates/aiken-lang/src/gen_uplc.rs index e7aba92c..20e97d6b 100644 --- a/crates/aiken-lang/src/gen_uplc.rs +++ b/crates/aiken-lang/src/gen_uplc.rs @@ -168,7 +168,6 @@ impl<'a> CodeGenerator<'a> { let mut air_tree = self.build(test_body); air_tree = AirTree::no_op().hoist_over(air_tree); - println!("{:#?}", air_tree.to_vec()); let full_tree = self.hoist_functions_to_validator(air_tree); @@ -810,7 +809,7 @@ impl<'a> CodeGenerator<'a> { let names = elems.iter().map(|(name, _)| name.to_string()).collect_vec(); let list_access = if elements.is_empty() { - AirTree::let_assignment("_", AirTree::list_empty(value)) + AirTree::list_empty(value) } else { AirTree::list_access(names, tipo.clone(), tail.is_some(), tail.is_none(), value) }; @@ -1366,7 +1365,7 @@ impl<'a> CodeGenerator<'a> { tipo.clone(), )); - assigns.insert(0, AirTree::let_assignment("_", empty)); + assigns.insert(0, empty); } else { let expose = AirTree::fields_expose( indices, @@ -3130,6 +3129,7 @@ impl<'a> CodeGenerator<'a> { } => { let value = arg_stack.pop().unwrap(); let mut term = arg_stack.pop().unwrap(); + let list_id = self.id_gen.next(); let mut id_list = vec![]; @@ -3146,20 +3146,34 @@ impl<'a> CodeGenerator<'a> { .take(names.len()) .collect_vec(); - term = builder::list_access_to_uplc( - &names, - &id_list, - tail, - 0, - term, - inner_types, - check_last_item, - true, - self.tracing, - ) - .apply(value); + if !names.is_empty() { + term = builder::list_access_to_uplc( + &names, + &id_list, + tail, + 0, + term, + inner_types, + check_last_item, + true, + self.tracing, + ) + .apply(value); - arg_stack.push(term); + arg_stack.push(term); + } else if check_last_item { + let trace_term = if self.tracing { + Term::Error.trace(Term::string("Expected no items for List")) + } else { + Term::Error + }; + + term = value.delayed_choose_list(term, trace_term); + + arg_stack.push(term); + } else { + arg_stack.push(term); + } } Air::ListExpose { tail_head_names, @@ -3170,13 +3184,13 @@ impl<'a> CodeGenerator<'a> { } => { let mut term = arg_stack.pop().unwrap(); - if let Some((tail_var, tail_name)) = tail { + if let Some((tail_var, tail_name)) = &tail { term = term .lambda(tail_name) .apply(Term::tail_list().apply(Term::var(tail_var))); } - for (tail_var, head_name) in tail_head_names.into_iter().rev() { + for (tail_var, head_name) in tail_head_names.iter().rev() { let head_list = if tipo.is_map() { Term::head_list().apply(Term::var(tail_var)) } else { @@ -3679,8 +3693,8 @@ impl<'a> CodeGenerator<'a> { } Air::WrapClause => { // no longer need to pop off discard - let mut term = arg_stack.pop().unwrap(); let arg = arg_stack.pop().unwrap(); + let mut term = arg_stack.pop().unwrap(); term = term.lambda("__other_clauses_delayed").apply(arg.delay()); @@ -3919,6 +3933,7 @@ impl<'a> CodeGenerator<'a> { } => { self.needs_field_access = true; let mut id_list = vec![]; + let value = arg_stack.pop().unwrap(); let mut term = arg_stack.pop().unwrap(); let list_id = self.id_gen.next(); @@ -3934,8 +3949,8 @@ impl<'a> CodeGenerator<'a> { let names = indices.iter().cloned().map(|item| item.1).collect_vec(); let inner_types = indices.iter().cloned().map(|item| item.2).collect_vec(); - term = if !indices.is_empty() { - builder::list_access_to_uplc( + if !indices.is_empty() { + term = builder::list_access_to_uplc( &names, &id_list, false, @@ -3945,14 +3960,26 @@ impl<'a> CodeGenerator<'a> { check_last_item, false, self.tracing, - ) + ); + + term = term.apply(Term::var(CONSTR_FIELDS_EXPOSER).apply(value)); + + arg_stack.push(term); + } else if check_last_item { + let trace_term = if self.tracing { + Term::Error.trace(Term::string("Expected no fields for Constr")) + } else { + Term::Error + }; + + term = Term::var(CONSTR_FIELDS_EXPOSER) + .apply(value) + .delayed_choose_list(term, trace_term); + + arg_stack.push(term); } else { - term + arg_stack.push(term); }; - - term = term.apply(Term::var(CONSTR_FIELDS_EXPOSER).apply(value)); - - arg_stack.push(term); } Air::FieldsEmpty => { self.needs_field_access = true; @@ -4209,7 +4236,9 @@ impl<'a> CodeGenerator<'a> { )) .lambda(format!("__tuple_{list_id}")) .apply(value); - } else { + + arg_stack.push(term); + } else if !names.is_empty() { let mut id_list = vec![]; id_list.push(list_id); @@ -4229,9 +4258,21 @@ impl<'a> CodeGenerator<'a> { self.tracing, ) .apply(value); - } - arg_stack.push(term); + arg_stack.push(term); + } else if check_last_item { + let trace_term = if self.tracing { + Term::Error.trace(Term::string("Expected no items for Tuple")) + } else { + Term::Error + }; + + term = value.delayed_choose_list(term, trace_term); + + arg_stack.push(term); + } else { + arg_stack.push(term); + } } Air::Trace { .. } => { let text = arg_stack.pop().unwrap(); diff --git a/crates/aiken-lang/src/gen_uplc/tree.rs b/crates/aiken-lang/src/gen_uplc/tree.rs index 2b72274e..fd074214 100644 --- a/crates/aiken-lang/src/gen_uplc/tree.rs +++ b/crates/aiken-lang/src/gen_uplc/tree.rs @@ -185,6 +185,12 @@ pub enum AirStatement { tuple: Box, }, // Misc. + FieldsEmpty { + constr: Box, + }, + ListEmpty { + list: Box, + }, NoOp, } @@ -339,12 +345,6 @@ pub enum AirExpression { msg: Box, then: Box, }, - FieldsEmpty { - constr: Box, - }, - ListEmpty { - list: Box, - }, } impl AirTree { @@ -769,12 +769,18 @@ impl AirTree { } } pub fn fields_empty(constr: AirTree) -> AirTree { - AirTree::Expression(AirExpression::FieldsEmpty { - constr: constr.into(), - }) + AirTree::Statement { + statement: AirStatement::FieldsEmpty { + constr: constr.into(), + }, + hoisted_over: None, + } } pub fn list_empty(list: AirTree) -> AirTree { - AirTree::Expression(AirExpression::ListEmpty { list: list.into() }) + AirTree::Statement { + statement: AirStatement::ListEmpty { list: list.into() }, + hoisted_over: None, + } } pub fn hoist_over(mut self, next_exp: AirTree) -> AirTree { match &mut self { @@ -969,6 +975,14 @@ impl AirTree { AirStatement::NoOp => { air_vec.push(Air::NoOp); } + AirStatement::FieldsEmpty { constr } => { + air_vec.push(Air::FieldsEmpty); + constr.create_air_vec(air_vec); + } + AirStatement::ListEmpty { list } => { + air_vec.push(Air::ListEmpty); + list.create_air_vec(air_vec); + } }; exp.create_air_vec(air_vec); } @@ -1212,14 +1226,6 @@ impl AirTree { msg.create_air_vec(air_vec); then.create_air_vec(air_vec); } - AirExpression::FieldsEmpty { constr } => { - air_vec.push(Air::FieldsEmpty); - constr.create_air_vec(air_vec); - } - AirExpression::ListEmpty { list } => { - air_vec.push(Air::ListEmpty); - list.create_air_vec(air_vec); - } }, AirTree::UnhoistedSequence(_) => { unreachable!("FIRST RESOLVE ALL UNHOISTED SEQUENCES") @@ -1266,9 +1272,6 @@ impl AirTree { | AirExpression::WrapClause { then, .. } | AirExpression::TupleClause { then, .. } | AirExpression::Finally { then, .. } => then.return_type(), - - AirExpression::FieldsEmpty { constr } => constr.return_type(), - AirExpression::ListEmpty { list } => list.return_type(), }, _ => unreachable!(), } @@ -1425,6 +1428,22 @@ impl AirTree { ); } AirStatement::NoOp => {} + AirStatement::FieldsEmpty { constr } => { + constr.do_traverse_tree_with( + tree_path, + current_depth + 1, + index_count.next_number(), + with, + ); + } + AirStatement::ListEmpty { list } => { + list.do_traverse_tree_with( + tree_path, + current_depth + 1, + index_count.next_number(), + with, + ); + } }; hoisted_over.do_traverse_tree_with( @@ -1721,22 +1740,6 @@ impl AirTree { with, ); } - AirExpression::FieldsEmpty { constr } => { - constr.do_traverse_tree_with( - tree_path, - current_depth + 1, - index_count.next_number(), - with, - ); - } - AirExpression::ListEmpty { list } => { - list.do_traverse_tree_with( - tree_path, - current_depth + 1, - index_count.next_number(), - with, - ); - } _ => {} }, a => unreachable!("GOT THIS {:#?}", a), @@ -1861,6 +1864,24 @@ impl AirTree { } } AirStatement::DefineFunc { .. } => unreachable!(), + AirStatement::FieldsEmpty { constr } => { + if *index == 0 { + constr.as_mut().do_find_air_tree_node(tree_path_iter) + } else if *index == 1 { + hoisted_over.as_mut().do_find_air_tree_node(tree_path_iter) + } else { + panic!("Tree Path index outside tree children nodes") + } + } + AirStatement::ListEmpty { list } => { + if *index == 0 { + list.as_mut().do_find_air_tree_node(tree_path_iter) + } else if *index == 1 { + hoisted_over.as_mut().do_find_air_tree_node(tree_path_iter) + } else { + panic!("Tree Path index outside tree children nodes") + } + } }, AirTree::Expression(e) => match e { AirExpression::List { items, .. } @@ -2037,20 +2058,6 @@ impl AirTree { panic!("Tree Path index outside tree children nodes") } } - AirExpression::FieldsEmpty { constr } => { - if *index == 0 { - constr.as_mut().do_find_air_tree_node(tree_path_iter) - } else { - panic!("Tree Path index outside tree children nodes") - } - } - AirExpression::ListEmpty { list } => { - if *index == 0 { - list.as_mut().do_find_air_tree_node(tree_path_iter) - } else { - panic!("Tree Path index outside tree children nodes") - } - } _ => unreachable!( "A tree node with no children was encountered with a longer tree path." ),