From 5f9d88eae64038d2cdd5330472eaf7a9e14f1dbb Mon Sep 17 00:00:00 2001 From: Pranav Gaddamadugu <23022326+d0cd@users.noreply.github.com> Date: Mon, 20 Nov 2023 09:43:15 -0800 Subject: [PATCH 1/2] Support parsing a program ID as a literal --- vm/cli/commands/run.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/vm/cli/commands/run.rs b/vm/cli/commands/run.rs index db13d5e741..285b46034b 100644 --- a/vm/cli/commands/run.rs +++ b/vm/cli/commands/run.rs @@ -106,12 +106,16 @@ mod tests { #[test] fn clap_snarkvm_run() { - let arg_vec = vec!["snarkvm", "run", "hello", "1u32", "2u32"]; + let arg_vec = vec!["snarkvm", "run", "hello", "1u32", "2u32", "foo.aleo"]; let cli = CLI::parse_from(&arg_vec); if let Command::Run(run) = cli.command { assert_eq!(run.function, Identifier::try_from(arg_vec[2]).unwrap()); - assert_eq!(run.inputs, vec![Value::try_from(arg_vec[3]).unwrap(), Value::try_from(arg_vec[4]).unwrap()]); + assert_eq!(run.inputs, vec![ + Value::try_from(arg_vec[3]).unwrap(), + Value::try_from(arg_vec[4]).unwrap(), + Value::try_from(arg_vec[5]).unwrap() + ]); } else { panic!("Unexpected result of clap parsing!"); } From 084260262d0d9c0019d2e1c458fbb72c0d2ffe95 Mon Sep 17 00:00:00 2001 From: Pranav Gaddamadugu <23022326+d0cd@users.noreply.github.com> Date: Mon, 20 Nov 2023 09:53:43 -0800 Subject: [PATCH 2/2] Reorder operand parsers --- console/program/src/data/literal/mod.rs | 2 +- console/program/src/data/literal/parse.rs | 26 +++++++++++++++++++ .../src/logic/instruction/operand/parse.rs | 4 ++- 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/console/program/src/data/literal/mod.rs b/console/program/src/data/literal/mod.rs index 23f085e504..5b904165ca 100644 --- a/console/program/src/data/literal/mod.rs +++ b/console/program/src/data/literal/mod.rs @@ -28,7 +28,7 @@ mod to_bits; mod to_type; mod variant; -use crate::LiteralType; +use crate::{LiteralType, ProgramID}; use snarkvm_console_account::{ComputeKey, PrivateKey, Signature}; use snarkvm_console_network::Network; use snarkvm_console_types::{prelude::*, Boolean}; diff --git a/console/program/src/data/literal/parse.rs b/console/program/src/data/literal/parse.rs index 330914363d..0a02b7200d 100644 --- a/console/program/src/data/literal/parse.rs +++ b/console/program/src/data/literal/parse.rs @@ -36,6 +36,8 @@ impl Parser for Literal { map(Scalar::::parse, |literal| Self::Scalar(literal)), map(Signature::::parse, |literal| Self::Signature(Box::new(literal))), map(StringType::::parse, |literal| Self::String(literal)), + // This allows users to implicitly declare program IDs as literals. + map_res(ProgramID::::parse, |program_id| Ok::(Self::Address(program_id.to_address()?))), ))(string) } } @@ -87,3 +89,27 @@ impl Display for Literal { } } } + +#[cfg(test)] +mod tests { + use super::*; + use snarkvm_console_network::Testnet3; + + type CurrentNetwork = Testnet3; + + #[test] + fn test_parse_program_id() -> Result<()> { + let (remainder, candidate) = Literal::::parse("credits.aleo")?; + assert!(matches!(candidate, Literal::Address(_))); + assert_eq!(candidate.to_string(), "aleo1lqmly7ez2k48ajf5hs92ulphaqr05qm4n8qwzj8v0yprmasgpqgsez59gg"); + assert_eq!("", remainder); + + let result = Literal::::parse("credits.ale"); + assert!(result.is_err()); + + let result = Literal::::parse("credits.aleo1"); + assert!(result.is_err()); + + Ok(()) + } +} diff --git a/synthesizer/program/src/logic/instruction/operand/parse.rs b/synthesizer/program/src/logic/instruction/operand/parse.rs index 8a277ea91d..ccc699ee60 100644 --- a/synthesizer/program/src/logic/instruction/operand/parse.rs +++ b/synthesizer/program/src/logic/instruction/operand/parse.rs @@ -26,9 +26,11 @@ impl Parser for Operand { map(tag("self.signer"), |_| Self::Signer), map(tag("self.caller"), |_| Self::Caller), map(tag("block.height"), |_| Self::BlockHeight), + // Note that `Operand::ProgramID`s must be parsed before `Operand::Literal`s, since a program ID can be implicitly parsed as a literal address. + // This ensures that the string representation of a program uses the `Operand::ProgramID` variant. + map(ProgramID::parse, |program_id| Self::ProgramID(program_id)), map(Literal::parse, |literal| Self::Literal(literal)), map(Register::parse, |register| Self::Register(register)), - map(ProgramID::parse, |program_id| Self::ProgramID(program_id)), ))(string) } }