Skip to content

Commit bf27557

Browse files
authored
[Cairo 1] Improve arg handling (#1782)
* Improve arg handling * Fix * Clippy * Remove unwraps * Add changelog entry * Update comments
1 parent 7159ed9 commit bf27557

File tree

2 files changed

+48
-39
lines changed

2 files changed

+48
-39
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@
22

33
#### Upcoming Changes
44

5+
* refactor + bugfix: Improve arg handling for cairo1-run [#1782](https://github.com/lambdaclass/cairo-vm/pull/1782)
6+
* Now uses ascii whitespace as separator, preventing errors when using newlines in args file
7+
* No longer gets stuck on improperly-formatted arrays
8+
* Returns an informative clap error upon invalid felt strings instead of unwrapping
9+
510
* fix: Ignore memory order when comparing instances of `CairoPieMemory` [#1780](https://github.com/lambdaclass/cairo-vm/pull/1780)
611

712
* feat: Add `EXCESS_BALANCE` hint [#1777](https://github.com/lambdaclass/cairo-vm/pull/1777)

cairo1-run/src/main.rs

Lines changed: 43 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -63,48 +63,52 @@ struct Args {
6363
#[derive(Debug, Clone, Default)]
6464
struct FuncArgs(Vec<FuncArg>);
6565

66-
fn process_args(value: &str) -> Result<FuncArgs, String> {
67-
if value.is_empty() {
68-
return Ok(FuncArgs::default());
66+
/// Processes an iterator of format [s1, s2,.., sn, "]", ...], stopping at the first "]" string
67+
/// and returning the array [f1, f2,.., fn] where fi = Felt::from_dec_str(si)
68+
fn process_array<'a>(iter: &mut impl Iterator<Item = &'a str>) -> Result<FuncArg, String> {
69+
let mut array = vec![];
70+
for value in iter {
71+
match value {
72+
"]" => break,
73+
_ => array.push(
74+
Felt252::from_dec_str(value)
75+
.map_err(|_| format!("\"{}\" is not a valid felt", value))?,
76+
),
77+
}
6978
}
79+
Ok(FuncArg::Array(array))
80+
}
81+
82+
/// Parses a string of ascii whitespace separated values, containing either numbers or series of numbers wrapped in brackets
83+
/// Returns an array of felts and felt arrays
84+
fn process_args(value: &str) -> Result<FuncArgs, String> {
7085
let mut args = Vec::new();
71-
let mut input = value.split(' ');
72-
while let Some(value) = input.next() {
73-
// First argument in an array
74-
if value.starts_with('[') {
75-
if value.ends_with(']') {
76-
if value.len() == 2 {
77-
args.push(FuncArg::Array(Vec::new()));
78-
} else {
79-
args.push(FuncArg::Array(vec![Felt252::from_dec_str(
80-
value.strip_prefix('[').unwrap().strip_suffix(']').unwrap(),
81-
)
82-
.unwrap()]));
83-
}
84-
} else {
85-
let mut array_arg =
86-
vec![Felt252::from_dec_str(value.strip_prefix('[').unwrap()).unwrap()];
87-
// Process following args in array
88-
let mut array_end = false;
89-
while !array_end {
90-
if let Some(value) = input.next() {
91-
// Last arg in array
92-
if value.ends_with(']') {
93-
array_arg.push(
94-
Felt252::from_dec_str(value.strip_suffix(']').unwrap()).unwrap(),
95-
);
96-
array_end = true;
97-
} else {
98-
array_arg.push(Felt252::from_dec_str(value).unwrap())
99-
}
100-
}
101-
}
102-
// Finalize array
103-
args.push(FuncArg::Array(array_arg))
86+
// Split input string into numbers and array delimiters
87+
let mut input = value.split_ascii_whitespace().flat_map(|mut x| {
88+
// We don't have a way to split and keep the separate delimiters so we do it manually
89+
let mut res = vec![];
90+
if let Some(val) = x.strip_prefix('[') {
91+
res.push("[");
92+
x = val;
93+
}
94+
if let Some(val) = x.strip_suffix(']') {
95+
if !val.is_empty() {
96+
res.push(val)
10497
}
105-
} else {
106-
// Single argument
107-
args.push(FuncArg::Single(Felt252::from_dec_str(value).unwrap()))
98+
res.push("]")
99+
} else if !x.is_empty() {
100+
res.push(x)
101+
}
102+
res
103+
});
104+
// Process iterator of numbers & array delimiters
105+
while let Some(value) = input.next() {
106+
match value {
107+
"[" => args.push(process_array(&mut input)?),
108+
_ => args.push(FuncArg::Single(
109+
Felt252::from_dec_str(value)
110+
.map_err(|_| format!("\"{}\" is not a valid felt", value))?,
111+
)),
108112
}
109113
}
110114
Ok(FuncArgs(args))

0 commit comments

Comments
 (0)