From c32a9d7b6fac337f5f323c18801ab315c58f9319 Mon Sep 17 00:00:00 2001 From: Kasey White Date: Sun, 5 Feb 2023 15:35:32 -0500 Subject: [PATCH] commit working changes so far --- crates/aiken-lang/src/uplc.rs | 155 ++++++++++++++-------- crates/aiken-project/src/blueprint/mod.rs | 1 + crates/uplc/src/optimize/shrinker.rs | 30 +++-- 3 files changed, 121 insertions(+), 65 deletions(-) diff --git a/crates/aiken-lang/src/uplc.rs b/crates/aiken-lang/src/uplc.rs index 8b78d37b..7c1c6875 100644 --- a/crates/aiken-lang/src/uplc.rs +++ b/crates/aiken-lang/src/uplc.rs @@ -70,6 +70,14 @@ impl<'a> CodeGenerator<'a> { } } + pub fn reset(&mut self) { + self.needs_field_access = false; + self.used_data_assert_on_list = false; + self.zero_arg_functions = IndexMap::new(); + self.id_gen = IdGenerator::new(); + self.defined_functions = IndexMap::new(); + } + pub fn generate( &mut self, body: &TypedExpr, @@ -83,8 +91,12 @@ impl<'a> CodeGenerator<'a> { self.define_ir(&mut ir_stack); + println!("{ir_stack:#?}"); + self.convert_opaque_type_to_inner_ir(&mut ir_stack); + println!("{ir_stack:#?}"); + let mut term = self.uplc_code_gen(&mut ir_stack); if self.needs_field_access { @@ -113,6 +125,8 @@ impl<'a> CodeGenerator<'a> { term, }; + println!("{}", program.to_pretty()); + program = aiken_optimize_and_intern(program); program @@ -302,13 +316,16 @@ impl<'a> CodeGenerator<'a> { let mut value_scope = scope.clone(); value_scope.push(self.id_gen.next()); + let mut replaced_type = tipo.clone(); + replace_opaque_type(&mut replaced_type, self.data_types.clone()); + self.build_ir(value, &mut value_vec, value_scope); self.assignment_ir( pattern, &mut pattern_vec, &mut value_vec, - tipo, + &replaced_type, AssignmentProperties { value_type: value.tipo(), kind: *kind, @@ -326,6 +343,8 @@ impl<'a> CodeGenerator<'a> { // assuming one subject at the moment let subject = subjects[0].clone(); + let mut replaced_type = subject.tipo(); + replace_opaque_type(&mut replaced_type, self.data_types.clone()); if clauses.len() <= 1 { let mut value_vec: Vec = vec![]; let mut pattern_vec: Vec = vec![]; @@ -339,7 +358,7 @@ impl<'a> CodeGenerator<'a> { &clauses[0].pattern[0], &mut pattern_vec, &mut subject_vec, - &subject.tipo(), + &replaced_type, AssignmentProperties { value_type: clauses[0].then.tipo(), kind: AssignmentKind::Let, @@ -350,7 +369,8 @@ impl<'a> CodeGenerator<'a> { ir_stack.append(&mut pattern_vec); ir_stack.append(&mut value_vec); } else { - let clauses = if matches!(clauses[0].pattern[0], Pattern::List { .. }) { + // HERE TODO + let clauses = if replaced_type.is_list() { rearrange_clauses(clauses.clone()) } else { clauses.clone() @@ -360,7 +380,7 @@ impl<'a> CodeGenerator<'a> { let mut pattern_vec = vec![]; let mut clause_properties = ClauseProperties::init( - &subject.tipo(), + &replaced_type, constr_var.clone(), subject_name.clone(), ); @@ -369,7 +389,7 @@ impl<'a> CodeGenerator<'a> { &mut pattern_vec, &mut clause_properties, clauses, - &subject.tipo(), + &replaced_type, scope.clone(), ); @@ -395,7 +415,7 @@ impl<'a> CodeGenerator<'a> { last_pattern, &mut pattern_vec, &mut final_clause_vec, - &subject.tipo(), + &replaced_type, &mut clause_properties, final_scope, ); @@ -411,7 +431,7 @@ impl<'a> CodeGenerator<'a> { ir_stack.push(Air::When { scope: scope.clone(), subject_name, - tipo: subject.tipo(), + tipo: replaced_type.clone(), }); let mut scope = scope; @@ -420,7 +440,7 @@ impl<'a> CodeGenerator<'a> { ir_stack.push(Air::Var { scope, constructor: ValueConstructor::public( - subject.tipo(), + replaced_type, ValueConstructorVariant::LocalVariable { location: Span::empty(), }, @@ -432,7 +452,7 @@ impl<'a> CodeGenerator<'a> { ir_stack.push(Air::When { scope: scope.clone(), subject_name, - tipo: subject.tipo(), + tipo: replaced_type, }); let mut scope = scope; @@ -892,7 +912,6 @@ impl<'a> CodeGenerator<'a> { new_vec.append(values); - // pattern_vec.push(value) self.when_ir( pattern, pattern_vec, @@ -1724,8 +1743,7 @@ impl<'a> CodeGenerator<'a> { } } - if matches!(&assignment_properties.kind, AssignmentKind::Assert) { - } else { + if !names.is_empty() { pattern_vec.push(Air::ListAccessor { names, tail: tail.is_some(), @@ -1733,6 +1751,11 @@ impl<'a> CodeGenerator<'a> { tipo: tipo.clone().into(), check_last_item: false, }); + } else { + pattern_vec.push(Air::Let { + scope, + name: "_".to_string(), + }) } pattern_vec.append(values); @@ -1747,7 +1770,7 @@ impl<'a> CodeGenerator<'a> { let mut nested_pattern = vec![]; let field_map = match constructor { - PatternConstructor::Record { field_map, .. } => field_map.clone().unwrap(), + PatternConstructor::Record { field_map, .. } => field_map.clone(), }; let mut type_map: IndexMap> = IndexMap::new(); @@ -1759,14 +1782,19 @@ impl<'a> CodeGenerator<'a> { let arguments_index = arguments .iter() - .filter_map(|item| { + .enumerate() + .filter_map(|(index, item)| { let label = item.label.clone().unwrap_or_default(); - let field_index = field_map.fields.get(&label).map(|x| &x.0).unwrap_or(&0); + let field_index = if let Some(field_map) = &field_map { + *field_map.fields.get(&label).map(|x| &x.0).unwrap() + } else { + index + }; self.extract_arg_and_index( &item.value, - *field_index, + field_index, &mut nested_pattern, - type_map.get(field_index).unwrap(), + type_map.get(&field_index).unwrap(), &assignment_properties, &scope, ) @@ -1786,6 +1814,11 @@ impl<'a> CodeGenerator<'a> { scope, check_last_item: false, }); + } else { + pattern_vec.push(Air::Let { + scope, + name: "_".to_string(), + }); } pattern_vec.append(values); @@ -1826,10 +1859,14 @@ impl<'a> CodeGenerator<'a> { tipo: tipo.clone().into(), check_last_item: true, }); + } else { + pattern_vec.push(Air::Let { + scope, + name: "_".to_string(), + }); } pattern_vec.append(values); - pattern_vec.append(&mut nested_pattern); } } @@ -1904,6 +1941,8 @@ impl<'a> CodeGenerator<'a> { self.recursive_assert_tipo(tipo, &mut assert_list_vec, &name, scope.clone()); + names.push(name); + pattern_vec.push(Air::ListAccessor { scope, tipo: tipo.clone().into(), @@ -2105,6 +2144,9 @@ impl<'a> CodeGenerator<'a> { name: &str, scope: Vec, ) { + let mut tipo = tipo.clone().into(); + replace_opaque_type(&mut tipo, self.data_types.clone()); + if tipo.is_bool() || tipo.is_bytearray() || tipo.is_int() @@ -2123,25 +2165,25 @@ impl<'a> CodeGenerator<'a> { assert_vec.push(Air::Call { scope: scope.clone(), count: 2, - tipo: tipo.clone().into(), + tipo: tipo.clone(), }); assert_vec.push(Air::Builtin { scope: scope.clone(), func: DefaultFunction::ChooseUnit, - tipo: tipo.clone().into(), + tipo: tipo.clone(), }); assert_vec.push(Air::Call { scope: scope.clone(), count: 2, - tipo: tipo.clone().into(), + tipo: tipo.clone(), }); assert_vec.push(Air::Var { scope: scope.clone(), constructor: ValueConstructor::public( - tipo.clone().into(), + tipo.clone(), ValueConstructorVariant::LocalVariable { location: Span::empty(), }, @@ -2153,7 +2195,7 @@ impl<'a> CodeGenerator<'a> { assert_vec.push(Air::Var { scope: scope.clone(), constructor: ValueConstructor::public( - tipo.clone().into(), + tipo.clone(), ValueConstructorVariant::LocalVariable { location: Span::empty(), }, @@ -2180,7 +2222,7 @@ impl<'a> CodeGenerator<'a> { assert_vec.push(Air::Var { scope: scope.clone(), constructor: ValueConstructor::public( - tipo.clone().into(), + tipo.clone(), ValueConstructorVariant::LocalVariable { location: Span::empty(), }, @@ -2212,25 +2254,25 @@ impl<'a> CodeGenerator<'a> { assert_vec.push(Air::Call { scope: scope.clone(), count: 2, - tipo: tipo.clone().into(), + tipo: tipo.clone(), }); assert_vec.push(Air::Builtin { scope: scope.clone(), func: DefaultFunction::ChooseUnit, - tipo: tipo.clone().into(), + tipo: tipo.clone(), }); assert_vec.push(Air::Call { scope: scope.clone(), count: 2, - tipo: tipo.clone().into(), + tipo: tipo.clone(), }); assert_vec.push(Air::Var { scope: scope.clone(), constructor: ValueConstructor::public( - tipo.clone().into(), + tipo.clone(), ValueConstructorVariant::LocalVariable { location: Span::empty(), }, @@ -2242,7 +2284,7 @@ impl<'a> CodeGenerator<'a> { assert_vec.push(Air::Var { scope: scope.clone(), constructor: ValueConstructor::public( - tipo.clone().into(), + tipo.clone(), ValueConstructorVariant::LocalVariable { location: Span::empty(), }, @@ -2269,7 +2311,7 @@ impl<'a> CodeGenerator<'a> { assert_vec.push(Air::Var { scope: scope.clone(), constructor: ValueConstructor::public( - tipo.clone().into(), + tipo.clone(), ValueConstructorVariant::LocalVariable { location: Span::empty(), }, @@ -2327,31 +2369,31 @@ impl<'a> CodeGenerator<'a> { ); } } else { - let data_type = lookup_data_type_by_tipo(self.data_types.clone(), tipo).unwrap(); + let data_type = lookup_data_type_by_tipo(self.data_types.clone(), &tipo).unwrap(); let new_id = self.id_gen.next(); assert_vec.push(Air::Call { scope: scope.clone(), count: 2, - tipo: tipo.clone().into(), + tipo: tipo.clone(), }); assert_vec.push(Air::Builtin { scope: scope.clone(), func: DefaultFunction::ChooseUnit, - tipo: tipo.clone().into(), + tipo: tipo.clone(), }); assert_vec.push(Air::When { scope: scope.clone(), - tipo: tipo.clone().into(), + tipo: tipo.clone(), subject_name: format!("__subject_{new_id}"), }); assert_vec.push(Air::Var { scope: scope.clone(), constructor: ValueConstructor::public( - tipo.clone().into(), + tipo.clone(), ValueConstructorVariant::LocalVariable { location: Span::empty(), }, @@ -2376,7 +2418,7 @@ impl<'a> CodeGenerator<'a> { assert_vec.push(Air::Clause { scope: scope.clone(), - tipo: tipo.clone().into(), + tipo: tipo.clone(), subject_name: format!("__subject_{new_id}"), complex_clause: false, }); @@ -2386,23 +2428,25 @@ impl<'a> CodeGenerator<'a> { value: index.to_string(), }); - assert_vec.push(Air::FieldsExpose { - scope: scope.clone(), - indices: arg_indices.clone(), - check_last_item: true, - }); + if !arg_indices.is_empty() { + assert_vec.push(Air::FieldsExpose { + scope: scope.clone(), + indices: arg_indices.clone(), + check_last_item: true, + }); - assert_vec.push(Air::Var { - scope: scope.clone(), - constructor: ValueConstructor::public( - tipo.clone().into(), - ValueConstructorVariant::LocalVariable { - location: Span::empty(), - }, - ), - name: name.to_owned(), - variant_name: String::new(), - }); + assert_vec.push(Air::Var { + scope: scope.clone(), + constructor: ValueConstructor::public( + tipo.clone(), + ValueConstructorVariant::LocalVariable { + location: Span::empty(), + }, + ), + name: name.to_owned(), + variant_name: String::new(), + }); + } for (_, name, tipo) in arg_indices { self.recursive_assert_tipo(&tipo, assert_vec, &name, scope.clone()); @@ -3494,9 +3538,12 @@ impl<'a> CodeGenerator<'a> { let mut arg_stack: Vec> = vec![]; while let Some(ir_element) = ir_stack.pop() { + println!("IR ELEMENT IS {:#?}", ir_element); self.gen_uplc(ir_element, &mut arg_stack); - } + println!("Arg STACK LEN IS {:#?} ", arg_stack.len()); + } + println!("ARGSTACK FINALLY IS {:#?}", arg_stack); arg_stack[0].clone() } @@ -4595,7 +4642,7 @@ impl<'a> CodeGenerator<'a> { ), ) } else if tipo.is_list() || tipo.is_tuple() { - unreachable!() + unreachable!("{:#?}", tipo) } else { apply_wrap( DefaultFunction::EqualsInteger.into(), diff --git a/crates/aiken-project/src/blueprint/mod.rs b/crates/aiken-project/src/blueprint/mod.rs index 0f23a14d..882899b7 100644 --- a/crates/aiken-project/src/blueprint/mod.rs +++ b/crates/aiken-project/src/blueprint/mod.rs @@ -36,6 +36,7 @@ impl Blueprint { let validators: Result, Error> = modules .validators() .map(|(validator, def)| { + generator.reset(); Validator::from_checked_module(modules, generator, validator, def) }) .collect(); diff --git a/crates/uplc/src/optimize/shrinker.rs b/crates/uplc/src/optimize/shrinker.rs index d3513dc0..ef8eb28f 100644 --- a/crates/uplc/src/optimize/shrinker.rs +++ b/crates/uplc/src/optimize/shrinker.rs @@ -58,7 +58,7 @@ impl Program { pub fn inline_reduce(self) -> Program { let mut term = self.term.clone(); - inline_reduce(&mut term); + inline_basic_reduce(&mut term); Program { version: self.version, term, @@ -120,38 +120,46 @@ fn builtin_force_reduce(term: &mut Term, builtin_map: &mut IndexMap) { +fn inline_basic_reduce(term: &mut Term) { match term { Term::Delay(d) => { let d = Rc::make_mut(d); - inline_reduce(d); + inline_basic_reduce(d); } Term::Lambda { body, .. } => { let body = Rc::make_mut(body); - inline_reduce(body); + inline_basic_reduce(body); } Term::Apply { function, argument } => { let arg = Rc::make_mut(argument); - inline_reduce(arg); + inline_basic_reduce(arg); let func = Rc::make_mut(function); - inline_reduce(func); + inline_basic_reduce(func); if let Term::Lambda { parameter_name, body, } = func { - let mut occurrences = 0; - var_occurrences(body, parameter_name.clone(), &mut occurrences); - if occurrences <= 1 { - *term = substitute_term(body.as_ref(), parameter_name.clone(), argument); + if let replace_term @ (Term::Var(_) + | Term::Constant(_) + | Term::Error + | Term::Delay(_) + | Term::Lambda { .. }) = argument.as_ref() + { + let mut occurrences = 0; + var_occurrences(body, parameter_name.clone(), &mut occurrences); + if occurrences <= 1 { + *term = + substitute_term(body.as_ref(), parameter_name.clone(), replace_term); + } } } } Term::Force(f) => { let f = Rc::make_mut(f); - inline_reduce(f); + inline_basic_reduce(f); } _ => {} }