From 3f47a1f4b82ddd9f6966ea3880cc686f4f12fcc4 Mon Sep 17 00:00:00 2001 From: Kasey White Date: Mon, 5 Dec 2022 22:46:33 -0500 Subject: [PATCH] fix: constr issue - also fixed constant parsing - added new cbor flag to eval Co-authored-by: rvcas --- crates/cli/src/cmd/uplc/eval.rs | 23 ++- crates/cli/src/lib.rs | 3 +- crates/lang/src/parser.rs | 49 +++--- crates/lang/src/parser/lexer.rs | 2 +- crates/lang/src/tipo/error.rs | 2 +- crates/lang/src/uplc.rs | 111 +++++++++---- examples/sample/assets/swap/spend/mainnet.txt | 2 +- .../assets/swap/spend/payment_script.json | 2 +- examples/sample/assets/swap/spend/raw.uplc | 155 ++---------------- examples/sample/assets/swap/spend/script.txt | 2 +- examples/sample/assets/swap/spend/testnet.txt | 2 +- examples/sample/lib/sample.ak | 48 +----- examples/sample/lib/sample/context.ak | 8 - examples/sample/lib/sample/mint.ak | 8 - examples/sample/lib/sample/spend.ak | 8 - examples/sample/validators/swap.ak | 59 +------ 16 files changed, 155 insertions(+), 329 deletions(-) delete mode 100644 examples/sample/lib/sample/context.ak delete mode 100644 examples/sample/lib/sample/mint.ak delete mode 100644 examples/sample/lib/sample/spend.ak diff --git a/crates/cli/src/cmd/uplc/eval.rs b/crates/cli/src/cmd/uplc/eval.rs index 0f22cfee..8d251fb0 100644 --- a/crates/cli/src/cmd/uplc/eval.rs +++ b/crates/cli/src/cmd/uplc/eval.rs @@ -14,12 +14,31 @@ pub struct Args { #[clap(short, long)] flat: bool, + #[clap(short, long)] + cbor: bool, + /// Arguments to pass to the uplc program args: Vec, } -pub fn exec(Args { script, flat, args }: Args) -> miette::Result<()> { - let mut program = if flat { +pub fn exec( + Args { + script, + flat, + args, + cbor, + }: Args, +) -> miette::Result<()> { + let mut program = if cbor { + let cbor_hex = std::fs::read_to_string(&script).into_diagnostic()?; + + let raw_cbor = hex::decode(&cbor_hex).into_diagnostic()?; + + let prog = Program::::from_cbor(&raw_cbor, &mut Vec::new()) + .into_diagnostic()?; + + prog.into() + } else if flat { let bytes = std::fs::read(&script).into_diagnostic()?; let prog = Program::::from_flat(&bytes).into_diagnostic()?; diff --git a/crates/cli/src/lib.rs b/crates/cli/src/lib.rs index 9994ca2e..d5789d46 100644 --- a/crates/cli/src/lib.rs +++ b/crates/cli/src/lib.rs @@ -33,6 +33,7 @@ where miette::bail!("failed: {} error(s), {warning_count} warning(s)", err.len(),); }; - println!("finished with {warning_count} warning(s)"); + println!("\nfinished with {warning_count} warning(s)\n"); + Ok(()) } diff --git a/crates/lang/src/parser.rs b/crates/lang/src/parser.rs index 6bb7626e..d92e7e31 100644 --- a/crates/lang/src/parser.rs +++ b/crates/lang/src/parser.rs @@ -306,10 +306,12 @@ fn constant_value_parser() -> impl Parser impl Parser value}.validate(|value, span, emit| { - let byte: u8 = match value.parse() { - Ok(b) => b, - Err(_) => { - emit(ParseError::expected_input_found( - span, - None, - Some(error::Pattern::Byte), - )); + select! {Token::Int {value} => value} + .validate(|value, span, emit| { + let byte: u8 = match value.parse() { + Ok(b) => b, + Err(_) => { + emit(ParseError::expected_input_found( + span, + None, + Some(error::Pattern::Byte), + )); - 0 - } - }; + 0 + } + }; - byte - }), + byte + }) + .separated_by(just(Token::Comma)) + .allow_trailing() + .delimited_by(just(Token::LeftSquare), just(Token::RightSquare)), ) - .separated_by(just(Token::Comma)) - .allow_trailing() - .delimited_by(just(Token::LeftSquare), just(Token::RightSquare)) .map_with_span(|bytes, span| ast::UntypedConstant::ByteArray { location: span, bytes, @@ -453,8 +456,8 @@ fn constant_value_parser() -> impl Parser impl Parser .ignore_then( r.clone() .separated_by(just(Token::Comma)) + .allow_trailing() .delimited_by(just(Token::LeftParen), just(Token::RightParen)), ) .map_with_span(|elems, span| ast::Annotation::Tuple { @@ -1497,6 +1501,7 @@ pub fn pattern_parser() -> impl Parser impl Parser, Error = ParseError> { just("||").to(Token::VbarVbar), just('|').to(Token::Vbar), just("&&").to(Token::AmperAmper), - just("\n\n").to(Token::EmptyLine), just('#').to(Token::Hash), + just("\n\n").to(Token::EmptyLine), )); let grouping = choice(( diff --git a/crates/lang/src/tipo/error.rs b/crates/lang/src/tipo/error.rs index ae30413d..19352b0b 100644 --- a/crates/lang/src/tipo/error.rs +++ b/crates/lang/src/tipo/error.rs @@ -215,7 +215,7 @@ pub enum Error { types: Vec, }, - #[error("Unknown variable\n\n{name}\n")] + #[error("Unknown variable\n\n {name}\n")] UnknownVariable { #[label] location: Span, diff --git a/crates/lang/src/uplc.rs b/crates/lang/src/uplc.rs index 260ab378..c3364934 100644 --- a/crates/lang/src/uplc.rs +++ b/crates/lang/src/uplc.rs @@ -5,11 +5,10 @@ use itertools::Itertools; use uplc::{ ast::{ builder::{self, constr_index_exposer, CONSTR_FIELDS_EXPOSER, CONSTR_GET_FIELD}, - Constant as UplcConstant, Name, Program, Term, + Constant as UplcConstant, Name, Program, Term, Type as UplcType, }, builtins::DefaultFunction, parser::interner::Interner, - BigInt, PlutusData, }; use crate::{ @@ -166,11 +165,17 @@ impl<'a> CodeGenerator<'a> { TypedExpr::Var { constructor, name, .. } => { - ir_stack.push(Air::Var { - scope, - constructor: constructor.clone(), - name: name.clone(), - }); + if let ValueConstructorVariant::ModuleConstant { literal, .. } = + &constructor.variant + { + constants_ir(literal, ir_stack, scope); + } else { + ir_stack.push(Air::Var { + scope, + constructor: constructor.clone(), + name: name.clone(), + }); + } } TypedExpr::Fn { .. } => todo!(), TypedExpr::List { @@ -1371,7 +1376,9 @@ impl<'a> CodeGenerator<'a> { text: name, unique: 0.into(), })), - ValueConstructorVariant::ModuleConstant { .. } => todo!(), + ValueConstructorVariant::ModuleConstant { .. } => { + unreachable!() + } ValueConstructorVariant::ModuleFn { name: func_name, module, @@ -1420,25 +1427,78 @@ impl<'a> CodeGenerator<'a> { .unwrap(); let mut fields = - Term::Constant(UplcConstant::Data(PlutusData::Array(vec![]))); + Term::Constant(UplcConstant::ProtoList(UplcType::Data, vec![])); + + let tipo = constructor.tipo; + + let args_type = match tipo.as_ref() { + Type::Fn { args, .. } => args, + + _ => todo!(), + }; if let Some(field_map) = field_map.clone() { for field in field_map .fields .iter() .sorted_by(|item1, item2| item1.1.cmp(item2.1)) + .zip(args_type) .rev() { + let arg_to_data = if field.1.as_ref().is_bytearray() { + Term::Apply { + function: Term::Builtin(DefaultFunction::BData).into(), + argument: Term::Var(Name { + text: field.0 .0.clone(), + unique: 0.into(), + }) + .into(), + } + } else if field.1.as_ref().is_int() { + Term::Apply { + function: Term::Builtin(DefaultFunction::IData).into(), + argument: Term::Var(Name { + text: field.0 .0.clone(), + unique: 0.into(), + }) + .into(), + } + } else if field.1.as_ref().is_list() { + Term::Apply { + function: Term::Builtin(DefaultFunction::ListData).into(), + argument: Term::Var(Name { + text: field.0 .0.clone(), + unique: 0.into(), + }) + .into(), + } + } else if field.1.as_ref().is_string() { + Term::Apply { + function: Term::Builtin(DefaultFunction::BData).into(), + argument: Term::Apply { + function: Term::Builtin(DefaultFunction::DecodeUtf8) + .into(), + argument: Term::Var(Name { + text: field.0 .0.clone(), + unique: 0.into(), + }) + .into(), + } + .into(), + } + } else { + Term::Var(Name { + text: field.0 .0.clone(), + unique: 0.into(), + }) + }; + fields = Term::Apply { function: Term::Apply { function: Term::Builtin(DefaultFunction::MkCons) .force_wrap() .into(), - argument: Term::Var(Name { - text: field.0.clone(), - unique: 0.into(), - }) - .into(), + argument: arg_to_data.into(), } .into(), argument: fields.into(), @@ -1447,25 +1507,15 @@ impl<'a> CodeGenerator<'a> { } let mut term = Term::Apply { - function: Term::Builtin(DefaultFunction::ConstrData).into(), - argument: Term::Apply { - function: Term::Apply { - function: Term::Builtin(DefaultFunction::MkPairData).into(), - argument: Term::Constant(UplcConstant::Data( - PlutusData::BigInt(BigInt::Int( - (constr_index as i128).try_into().unwrap(), - )), - )) - .into(), - } - .into(), - argument: Term::Apply { - function: Term::Builtin(DefaultFunction::ListData).into(), - argument: fields.into(), - } + function: Term::Apply { + function: Term::Builtin(DefaultFunction::ConstrData).into(), + argument: Term::Constant(UplcConstant::Integer( + constr_index.try_into().unwrap(), + )) .into(), } .into(), + argument: fields.into(), }; if let Some(field_map) = field_map { @@ -2243,7 +2293,6 @@ impl<'a> CodeGenerator<'a> { arg_stack.push(term); } - Air::ListClause { tail_name, next_tail_name, diff --git a/examples/sample/assets/swap/spend/mainnet.txt b/examples/sample/assets/swap/spend/mainnet.txt index eeb5c39c..a0c4433e 100644 --- a/examples/sample/assets/swap/spend/mainnet.txt +++ b/examples/sample/assets/swap/spend/mainnet.txt @@ -1 +1 @@ -addr1wxdwvaptgf8kvxj3xuud67y6mnzgkvmkmz620nc77e9u65ghx46hl \ No newline at end of file +addr1wyqlmv9mg7cc5gcrhkxsnund3640hrfmj7ynxpcpc5kux2c6u6ewl \ No newline at end of file diff --git a/examples/sample/assets/swap/spend/payment_script.json b/examples/sample/assets/swap/spend/payment_script.json index b0399d52..400406f5 100644 --- a/examples/sample/assets/swap/spend/payment_script.json +++ b/examples/sample/assets/swap/spend/payment_script.json @@ -1,5 +1,5 @@ { "type": "PlutusScriptV2", "description": "Generated by Aiken", - "cborHex": "58b258b0010000222533357346464646464a666ae68cdc3800a40002646466e3c0052201030303ff00375c6ae84004c01400854ccd5cd19b87001480084c8c8cdc7800a441030303ff00375c6ae84004c0140085281aab9d375400200266446e94cdd82601010000374e66ae80008cd5d0000a61029fff004881030404ff00483403c88c8ccc00400520000032223333573466e1c0100095d0919980200219b8000348008d5d100080091aab9e37540022930b01" + "cborHex": "5854585201000022253335734646466e3cdd7198009801002a40006eb8cc004c008011200022323330010014800000c888cccd5cd19b870040025742466600800866e0000d20023574400200246aae78dd50008a4c2d" } \ No newline at end of file diff --git a/examples/sample/assets/swap/spend/raw.uplc b/examples/sample/assets/swap/spend/raw.uplc index 4e9863be..82bb0714 100644 --- a/examples/sample/assets/swap/spend/raw.uplc +++ b/examples/sample/assets/swap/spend/raw.uplc @@ -3,7 +3,7 @@ (lam datum (lam - _ + rdmr (lam _ (force @@ -18,156 +18,29 @@ (lam __constr_get_field [ - (lam - x - [ - (lam - __constr_name_8 - [ - (lam - __subject_name_7 - (force - [ - [ - [ - (force (builtin ifThenElse)) - [ - [ - (builtin equalsInteger) - __subject_name_7 - ] - (con integer 0) - ] - ] - (delay - [ - (lam - __constr_fields_18 - [ - (lam - signer - [ - [ - (builtin - equalsByteString - ) - signer - ] - (con bytestring #0303ff) - ] - ) - [ - (builtin unBData) - [ - (force (builtin headList)) - __constr_fields_18 - ] - ] - ] - ) - [ - __constr_fields_exposer - __constr_name_8 - ] - ] - ) - ] - (delay - (force - [ - [ - [ - (force (builtin ifThenElse)) - [ - [ - (builtin equalsInteger) - __subject_name_7 - ] - (con integer 1) - ] - ] - (delay - [ - (lam - __constr_fields_17 - [ - (lam - signer - [ - [ - (builtin - equalsByteString - ) - signer - ] - (con - bytestring - #0303ff - ) - ] - ) - [ - (builtin unBData) - [ - (force - (builtin headList) - ) - __constr_fields_17 - ] - ] - ] - ) - [ - __constr_fields_exposer - __constr_name_8 - ] - ] - ) - ] - (delay (con bool False)) - ] - ) - ) - ] - ) - ) - [ - (force (force (builtin fstPair))) - [ (builtin unConstrData) __constr_name_8 ] - ] - ] - ) - x - ] - ) [ [ - (lam - signer - (lam - amount + (force (builtin ifThenElse)) + [ + [ + (builtin equalsByteString) [ - (builtin constrData) + (builtin unBData) [ - [ (builtin mkPairData) (con data #00) ] [ - (builtin listData) - [ - [ (force (builtin mkCons)) signer ] - [ - [ (force (builtin mkCons)) amount ] - (con data #9fff) - ] - ] + __constr_get_field + [ __constr_fields_exposer datum ] ] + (con integer 0) ] ] - ) - ) - (con bytestring #0404ff) + ] + (con bytestring #0102) + ] ] - (con integer 1000) + (con bool False) ] + (con bool True) ] ) (lam diff --git a/examples/sample/assets/swap/spend/script.txt b/examples/sample/assets/swap/spend/script.txt index d8d62421..b9e334ea 100644 --- a/examples/sample/assets/swap/spend/script.txt +++ b/examples/sample/assets/swap/spend/script.txt @@ -1 +1 @@ -58b0010000222533357346464646464a666ae68cdc3800a40002646466e3c0052201030303ff00375c6ae84004c01400854ccd5cd19b87001480084c8c8cdc7800a441030303ff00375c6ae84004c0140085281aab9d375400200266446e94cdd82601010000374e66ae80008cd5d0000a61029fff004881030404ff00483403c88c8ccc00400520000032223333573466e1c0100095d0919980200219b8000348008d5d100080091aab9e37540022930b01 \ No newline at end of file +585201000022253335734646466e3cdd7198009801002a40006eb8cc004c008011200022323330010014800000c888cccd5cd19b870040025742466600800866e0000d20023574400200246aae78dd50008a4c2d \ No newline at end of file diff --git a/examples/sample/assets/swap/spend/testnet.txt b/examples/sample/assets/swap/spend/testnet.txt index 574c9a81..462b5d7b 100644 --- a/examples/sample/assets/swap/spend/testnet.txt +++ b/examples/sample/assets/swap/spend/testnet.txt @@ -1 +1 @@ -addr_test1wzdwvaptgf8kvxj3xuud67y6mnzgkvmkmz620nc77e9u65gvwpxc6 \ No newline at end of file +addr_test1wqqlmv9mg7cc5gcrhkxsnund3640hrfmj7ynxpcpc5kux2cp5w9p6 \ No newline at end of file diff --git a/examples/sample/lib/sample.ak b/examples/sample/lib/sample.ak index d9a51364..5f7c7ebc 100644 --- a/examples/sample/lib/sample.ak +++ b/examples/sample/lib/sample.ak @@ -1,49 +1,7 @@ -pub type Signer { - hash: ByteArray, -} - -pub type ScriptContext { - signer: Signer, -} - -pub type Redeem { - Buy { tipo: ByteArray, fin: Int } - Sell { twice: ByteArray, find: Int } - Hold(Int) +pub type Redeemer { + signer: ByteArray, } pub type Datum { - fin: Int, - sc: ScriptContext, - rdmr: Redeem, + random: ByteArray, } - -pub fn eqIntPlusOne(a: Int, b: Int) { - a + 1 == b -} - -pub fn eqString(a: ByteArray, b: ByteArray) { - a == b -} - -pub type Thing { - Some - None -} - -pub type Other { - Wow - Yes -} - -pub fn incrementor(counter: Int, target: Int) -> Int { - if counter == target { - counter - } else if counter > target { - counter - target - } else { - incrementor(counter + 1, target) - } -} - -pub const big_a = 5 diff --git a/examples/sample/lib/sample/context.ak b/examples/sample/lib/sample/context.ak deleted file mode 100644 index 2b891b45..00000000 --- a/examples/sample/lib/sample/context.ak +++ /dev/null @@ -1,8 +0,0 @@ -pub type ScriptContext(purpose) { - tx_info: TxInfo, - script_purpose: purpose, -} - -pub type TxInfo { - idk: Int, -} diff --git a/examples/sample/lib/sample/mint.ak b/examples/sample/lib/sample/mint.ak deleted file mode 100644 index fc5182b7..00000000 --- a/examples/sample/lib/sample/mint.ak +++ /dev/null @@ -1,8 +0,0 @@ -use sample/context - -pub type Mint { - currency_symbol: ByteArray, -} - -pub type ScriptContext = - context.ScriptContext(Mint) diff --git a/examples/sample/lib/sample/spend.ak b/examples/sample/lib/sample/spend.ak deleted file mode 100644 index 236cfd30..00000000 --- a/examples/sample/lib/sample/spend.ak +++ /dev/null @@ -1,8 +0,0 @@ -use sample/context - -pub type Spend { - idk: Int, -} - -pub type ScriptContext = - context.ScriptContext(Spend) diff --git a/examples/sample/validators/swap.ak b/examples/sample/validators/swap.ak index 2409c40c..63e81000 100644 --- a/examples/sample/validators/swap.ak +++ b/examples/sample/validators/swap.ak @@ -1,60 +1,5 @@ use sample -use sample/mint -use sample/spend -use aiken/builtin -const something = 5 - -pub type Redeemer { - signer: ByteArray, - amount: Int, - other_thing: Redeemer, -} - -pub type Reen { - Buy1 { signer: ByteArray, amount: Int } - Stuff(ByteArray, Int) - Sell1 -} - -pub fn twice(f: fn(Int) -> Int, initial: Int) -> Int { - f(f(initial)) -} - -pub fn add_one(value: Int) -> Int { - value + 1 -} - -pub fn add_two(x: Int) -> Int { - twice(add_one, x) -} - -pub fn final_check(z: Int) { - z < 4 -} - -pub fn incrementor(counter: Int, target: Int) -> Int { - if counter == target { - counter - } else if counter > target { - counter - target - } else { - incrementor(counter + 1, target) - } -} - -pub type Datum { - Offer { prices: List(Int), asset_class: ByteArray, other_thing: Datum } - Sell - Hold(Int) -} - -pub fn spend(datum: Datum, _rdmr: Nil, _ctx: Nil) -> Bool { - let amount = 1000 - let x = Buy1 { signer: #[4, 4, 255], amount } - when x is { - Buy1 { signer, .. } -> signer == #[3, 3, 255] - Stuff(signer, _) -> signer == #[3, 3, 255] - _ -> False - } +pub fn spend(datum: sample.Datum, rdmr: sample.Redeemer, _ctx: Nil) -> Bool { + datum.random == rdmr.signer }