From 4333a436120414f117091dcca33caa9f0f22c858 Mon Sep 17 00:00:00 2001 From: Rachel Powers <508861+Ryex@users.noreply.github.com> Date: Mon, 22 Apr 2024 15:47:22 -0700 Subject: [PATCH] don't just unwrap number prase during grammer, fixes #28 Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com> --- ic10emu/build.rs | 4 +-- ic10emu/src/grammar.rs | 63 ++++++++++++++++++++++++++++++------------ 2 files changed, 48 insertions(+), 19 deletions(-) diff --git a/ic10emu/build.rs b/ic10emu/build.rs index ad9659f..87da430 100644 --- a/ic10emu/build.rs +++ b/ic10emu/build.rs @@ -174,7 +174,7 @@ fn write_enums() { let output_file = File::create(dest_path).unwrap(); let mut writer = BufWriter::new(&output_file); - let mut enums_map: Vec<(String, EnumVariant)> = Vec::new(); + let mut enums_map: Vec<(String, EnumVariant)> = Vec::new(); let e_infile = Path::new("data/enums.txt"); let e_contents = fs::read_to_string(e_infile).unwrap(); @@ -182,7 +182,7 @@ fn write_enums() { let mut it = line.splitn(3, ' '); let name = it.next().unwrap(); let val_str = it.next().unwrap(); - let val: Option = val_str.parse().ok(); + let val: Option = val_str.parse().ok(); let docs = it.next(); let deprecated = docs .map(|docs| docs.trim().to_uppercase() == "DEPRECATED") diff --git a/ic10emu/src/grammar.rs b/ic10emu/src/grammar.rs index 1902822..744956e 100644 --- a/ic10emu/src/grammar.rs +++ b/ic10emu/src/grammar.rs @@ -743,11 +743,11 @@ impl FromStr for Operand { if rest_iter.next().is_none() { Ok(Some(connection)) } else { - let start = 1 + target_str.len() + 1 + connection_str.len(); + let end = 1 + target_str.len() + 1 + connection_str.len(); Err(ParseError { line: 0, - start, - end: start, + start: end - connection_str.len(), + end, msg: "Invalid device connection specifier".to_owned(), }) } @@ -762,10 +762,11 @@ impl FromStr for Operand { connection, })) } else { + let end = 1 + target_str.len(); Err(ParseError { line: 0, - start: 0, - end: 0, + start: 1, + end, msg: "Invalid device specifier".to_owned(), }) } @@ -780,8 +781,8 @@ impl FromStr for Operand { } else { Err(ParseError { line: 0, - start: 0, - end: 0, + start: 6, + end: hash_str.len(), msg: "Invalid hash string: Can not contain '\"'".to_owned(), }) } @@ -837,26 +838,40 @@ impl FromStr for Operand { .collect::(); if !decimal_str.is_empty() { let float_str = float_str + "." + &decimal_str; - let num = f64::from_str(&float_str).unwrap(); - Ok(Operand::Number(Number::Float(num))) + if let Ok(num) = f64::from_str(&float_str) { + Ok(Operand::Number(Number::Float(num))) + } else { + Err(ParseError { + line: 0, + start: 0, + end: 0, + msg: "Invalid Number".to_owned(), + }) + } } else { - let start = float_str.len() + 1; Err(ParseError { line: 0, - start, - end: start, + start: 0, + end: float_str.len(), msg: "Invalid Decimal Number".to_owned(), }) } } else if rest_iter.next().is_none() { - let num = f64::from_str(&float_str).unwrap(); - Ok(Operand::Number(Number::Float(num))) + if let Ok(num) = f64::from_str(&float_str) { + Ok(Operand::Number(Number::Float(num))) + } else { + Err(ParseError { + line: 0, + start: 0, + end: float_str.len(), + msg: "Invalid Number".to_owned(), + }) + } } else { - let start = float_str.len(); Err(ParseError { line: 0, - start, - end: start, + start: 0, + end: float_str.len(), msg: "Invalid Integer Number".to_owned(), }) } @@ -1484,5 +1499,19 @@ mod tests { assert!(value.is_some()); assert!(value.unwrap().parse::().is_ok()); } + for le in LogicEnums::iter() { + println!("testing Enum.{le}"); + let value = le.get_str("value"); + assert!(value.is_some()); + assert!(value.unwrap().parse::().is_ok()); + } + } + + #[test] + fn bad_parse_does_not_panic() { + let code = "move foo -"; + let parsed = parse(code); + assert!(parsed.is_err()); + println!("{}", parsed.unwrap_err()); } }