diff --git a/crates/aiken-lang/src/builder.rs b/crates/aiken-lang/src/builder.rs index c6dfb7c3..eabe6439 100644 --- a/crates/aiken-lang/src/builder.rs +++ b/crates/aiken-lang/src/builder.rs @@ -552,28 +552,125 @@ pub fn list_access_to_uplc( }; if names.len() == 1 && tail { - Term::Lambda { - parameter_name: Name { - text: format!("tail_index_{}_{}", current_index, id_list[current_index]), - unique: 0.into(), + if first == "_" && names[0] == "_" { + Term::Lambda { + parameter_name: Name { + text: "_".to_string(), + unique: 0.into(), + } + .into(), + body: term.into(), } - .into(), - body: apply_wrap( - Term::Lambda { - parameter_name: Name { - text: first.clone(), - unique: 0.into(), - } - .into(), - body: apply_wrap( - Term::Lambda { - parameter_name: Name { - text: names[0].clone(), + } else if first == "_" { + Term::Lambda { + parameter_name: Name { + text: format!("tail_index_{}_{}", current_index, id_list[current_index]), + unique: 0.into(), + } + .into(), + body: apply_wrap( + Term::Lambda { + parameter_name: Name { + text: names[0].clone(), + unique: 0.into(), + } + .into(), + body: term.into(), + }, + apply_wrap( + Term::Builtin(DefaultFunction::TailList).force_wrap(), + Term::Var( + Name { + text: format!( + "tail_index_{}_{}", + current_index, id_list[current_index] + ), unique: 0.into(), } .into(), - body: term.into(), - }, + ), + ), + ) + .into(), + } + } else if names[0] == "_" { + Term::Lambda { + parameter_name: Name { + text: format!("tail_index_{}_{}", current_index, id_list[current_index]), + unique: 0.into(), + } + .into(), + body: apply_wrap( + Term::Lambda { + parameter_name: Name { + text: first.clone(), + unique: 0.into(), + } + .into(), + body: term.into(), + }, + head_list, + ) + .into(), + } + } else { + Term::Lambda { + parameter_name: Name { + text: format!("tail_index_{}_{}", current_index, id_list[current_index]), + unique: 0.into(), + } + .into(), + body: apply_wrap( + Term::Lambda { + parameter_name: Name { + text: first.clone(), + unique: 0.into(), + } + .into(), + body: apply_wrap( + Term::Lambda { + parameter_name: Name { + text: names[0].clone(), + unique: 0.into(), + } + .into(), + body: term.into(), + }, + apply_wrap( + Term::Builtin(DefaultFunction::TailList).force_wrap(), + Term::Var( + Name { + text: format!( + "tail_index_{}_{}", + current_index, id_list[current_index] + ), + unique: 0.into(), + } + .into(), + ), + ), + ) + .into(), + }, + head_list, + ) + .into(), + } + } + } else if names.is_empty() { + if first == "_" { + Term::Lambda { + parameter_name: Name { + text: if check_last_item { + format!("tail_index_{}_{}", current_index, id_list[current_index]) + } else { + "_".to_string() + }, + unique: 0.into(), + } + .into(), + body: if check_last_item { + delayed_choose_list( apply_wrap( Term::Builtin(DefaultFunction::TailList).force_wrap(), Term::Var( @@ -587,15 +684,29 @@ pub fn list_access_to_uplc( .into(), ), ), + term, + apply_wrap( + apply_wrap( + Term::Builtin(DefaultFunction::Trace).force_wrap(), + Term::Constant( + UplcConstant::String( + "List/Tuple/Constr contains more items than expected" + .to_string(), + ) + .into(), + ), + ), + Term::Delay(Term::Error.into()), + ) + .force_wrap(), ) - .into(), + .into() + } else { + term.into() }, - head_list, - ) - .into(), - } - } else if names.is_empty() { - Term::Lambda { + } + } else { + Term::Lambda { parameter_name: Name { text: format!("tail_index_{}_{}", current_index, id_list[current_index]), unique: 0.into(), @@ -629,7 +740,7 @@ pub fn list_access_to_uplc( Term::Builtin(DefaultFunction::Trace).force_wrap(), Term::Constant( UplcConstant::String( - "List/Tuple/Constr contains more items than it should" + "List/Tuple/Constr contains more items than it expected" .to_string(), ) .into(), @@ -648,51 +759,172 @@ pub fn list_access_to_uplc( ) .into(), } - } else { - Term::Lambda { - parameter_name: Name { - text: format!("tail_index_{}_{}", current_index, id_list[current_index]), - unique: 0.into(), - } - .into(), - body: apply_wrap( - Term::Lambda { - parameter_name: Name { - text: first.clone(), - unique: 0.into(), + } + } else if first == "_" { + let mut list_access_inner = list_access_to_uplc( + names, + id_list, + tail, + current_index + 1, + term, + tipos.to_owned(), + check_last_item, + is_list_accessor, + ); + + list_access_inner = match &list_access_inner { + Term::Lambda { + parameter_name, + body, + } => { + if ¶meter_name.text == "_" { + body.as_ref().clone() + } else { + Term::Lambda { + parameter_name: Name { + text: format!( + "tail_index_{}_{}", + current_index, id_list[current_index] + ), + unique: 0.into(), + } + .into(), + body: apply_wrap( + list_access_inner, + apply_wrap( + Term::Builtin(DefaultFunction::TailList).force_wrap(), + Term::Var( + Name { + text: format!( + "tail_index_{}_{}", + current_index, id_list[current_index] + ), + unique: 0.into(), + } + .into(), + ), + ), + ) + .into(), } - .into(), - body: apply_wrap( - list_access_to_uplc( - names, - id_list, - tail, - current_index + 1, - term, - tipos.to_owned(), - check_last_item, - is_list_accessor, - ), - apply_wrap( - Term::Builtin(DefaultFunction::TailList).force_wrap(), - Term::Var( - Name { - text: format!( - "tail_index_{}_{}", - current_index, id_list[current_index] - ), + } + } + _ => list_access_inner, + }; + + match &list_access_inner { + Term::Lambda { .. } => list_access_inner, + _ => Term::Lambda { + parameter_name: Name { + text: "_".to_string(), + unique: 0.into(), + } + .into(), + body: list_access_inner.into(), + }, + } + } else { + let mut list_access_inner = list_access_to_uplc( + names, + id_list, + tail, + current_index + 1, + term, + tipos.to_owned(), + check_last_item, + is_list_accessor, + ); + + list_access_inner = match &list_access_inner { + Term::Lambda { + parameter_name, + body, + } => { + if ¶meter_name.text == "_" { + Term::Lambda { + parameter_name: Name { + text: format!( + "tail_index_{}_{}", + current_index, id_list[current_index] + ), + unique: 0.into(), + } + .into(), + body: apply_wrap( + Term::Lambda { + parameter_name: Name { + text: first.clone(), unique: 0.into(), } .into(), + body: body.as_ref().clone().into(), + }, + head_list, + ) + .into(), + } + } else { + Term::Lambda { + parameter_name: Name { + text: format!( + "tail_index_{}_{}", + current_index, id_list[current_index] ), - ), - ) - .into(), - }, - head_list, - ) - .into(), - } + unique: 0.into(), + } + .into(), + body: apply_wrap( + Term::Lambda { + parameter_name: Name { + text: first.clone(), + unique: 0.into(), + } + .into(), + body: apply_wrap( + list_access_inner, + apply_wrap( + Term::Builtin(DefaultFunction::TailList).force_wrap(), + Term::Var( + Name { + text: format!( + "tail_index_{}_{}", + current_index, id_list[current_index] + ), + unique: 0.into(), + } + .into(), + ), + ), + ) + .into(), + }, + head_list, + ) + .into(), + } + } + } + _ => Term::Lambda { + parameter_name: Name { + text: format!("tail_index_{}_{}", current_index, id_list[current_index]), + unique: 0.into(), + } + .into(), + body: apply_wrap( + Term::Lambda { + parameter_name: Name { + text: first.clone(), + unique: 0.into(), + } + .into(), + body: list_access_inner.into(), + }, + head_list, + ) + .into(), + }, + }; + list_access_inner } } else { term diff --git a/crates/uplc/src/machine/runtime.rs b/crates/uplc/src/machine/runtime.rs index db2f0053..2fb3523e 100644 --- a/crates/uplc/src/machine/runtime.rs +++ b/crates/uplc/src/machine/runtime.rs @@ -1042,7 +1042,7 @@ impl DefaultFunction { ) .into()), v => Err(Error::DeserialisationError( - "UnMapData".to_string(), + "UnListData".to_string(), Value::Con(v.clone().into()), )), }, @@ -1057,7 +1057,7 @@ impl DefaultFunction { Ok(Value::Con(Constant::Integer(from_pallas_bigint(b)).into()).into()) } v => Err(Error::DeserialisationError( - "UnMapData".to_string(), + "UnIData".to_string(), Value::Con(v.clone().into()), )), }, @@ -1072,7 +1072,7 @@ impl DefaultFunction { Ok(Value::Con(Constant::ByteString(b.to_vec()).into()).into()) } v => Err(Error::DeserialisationError( - "UnMapData".to_string(), + "UnBData".to_string(), Value::Con(v.clone().into()), )), }, diff --git a/examples/acceptance_tests/036/plutus.json b/examples/acceptance_tests/036/plutus.json index e5c14d92..f2024bc8 100644 --- a/examples/acceptance_tests/036/plutus.json +++ b/examples/acceptance_tests/036/plutus.json @@ -15,8 +15,8 @@ "title": "Data", "description": "Any Plutus data." }, - "compiledCode": "59013d010000323232323232322225333004323232323233001003232323322323232323330120014a0944004c94ccc0500045288a5000133223233223253330153370e00290010801099190009bab301b00130110033015375400400297adef6c6033223300800200100200100100237566601260140049001001a441050000000000003001001222533301000213374a900125eb804c8c8c8c94ccc044cdc7802800899ba548000cc054dd300125eb804ccc01c01c00c014dd718088019bab3011002301400330120023001001222533300d00214a026464a666018600600429444ccc01401400400cc04400cc03c008dd6198009801198009801001a400090021119199800800a4000006444666601466e1c01000803c8ccc010010cdc0001a400460220020024600e6ea8004526165734aae7555cf2ab9f5740ae855d101", - "hash": "cd1b163efdcf1680c020a03752dca86a4cc9c4fd37148bc7c9be87ec" + "compiledCode": "59015f010000323232323232323232322225333006323232323233001003232323322323232323330140014a0944004c94ccc05c0045288a5000133223233223253330173370e00290010801099190009bab301e00130110033018375400400297adef6c6033223300800200100200100100237566601260140049001001a441050000000000003001001222533301300213374a900125eb804c8c8c8c94ccc04ccdc7802800899ba548000cc060dd300125eb804ccc01c01c00c014dd7180a0019bab3014002301700330150023001001222533301000214a026464a66601c600600429444ccc01401400400cc05000cc048008dd6198009801198009801001a400090021119199800800a4000006444666601866e1c0100080488ccc010010cdc0001a40046028002002460146ea8004526163001001222533300800214984cc014c004c028008ccc00c00cc02c0080055cd2b9b5573aaae7955cfaba05742ae89", + "hash": "3f46b921ead33594e1da4afa1f1ba31807c0d8deca029f96fe9fe394" } ] } \ No newline at end of file diff --git a/examples/acceptance_tests/047/plutus.json b/examples/acceptance_tests/047/plutus.json index 5b3d43ac..6fe46442 100644 --- a/examples/acceptance_tests/047/plutus.json +++ b/examples/acceptance_tests/047/plutus.json @@ -29,8 +29,8 @@ } ] }, - "compiledCode": "500100003222253330044a22930b2b9a01", - "hash": "90592520b329fe08f0e93946ecd405e49b7480795e27cb618f002d88" + "compiledCode": "583b0100003232323232323222253330064a22930b180080091129998030010a4c26600a6002600e0046660060066010004002ae695cdaab9f5742ae89", + "hash": "e37db487fbd58c45d059bcbf5cd6b1604d3bec16cf888f1395a4ebc4" } ] } \ No newline at end of file diff --git a/examples/acceptance_tests/048/plutus.json b/examples/acceptance_tests/048/plutus.json index 4d2d013b..00eaa5f2 100644 --- a/examples/acceptance_tests/048/plutus.json +++ b/examples/acceptance_tests/048/plutus.json @@ -15,8 +15,8 @@ "title": "Data", "description": "Any Plutus data." }, - "compiledCode": "582b010000323222253330043370e64640026eb4c0180052f7b630010104000101010048020526165734aae741", - "hash": "5d97657f60a5566b7bf85d235541761df0468a5be3c30946f9ed304e" + "compiledCode": "586001000032323232323232323222253330063370e6464640046eb4c02c008dd69804800a5ef6c6010104000101010048020526163001001222533300800214984cc014c004c024008ccc00c00cc0280080055cd2b9b5573aaae7955cfaba157441", + "hash": "7ecbfc3ae91c4d5ba3799b4d283e385d457c860cd22034d825379ae2" } ] } \ No newline at end of file