diff --git a/gcode/src/lexer.rs b/gcode/src/lexer.rs index 69cb3ea0..7bcf5a31 100644 --- a/gcode/src/lexer.rs +++ b/gcode/src/lexer.rs @@ -371,4 +371,41 @@ mod tests { assert_eq!(got.value, "+3.14"); } + + #[test] + fn two_multi() { + let mut lexer = Lexer::new("G0 X1\nG1 Y2"); + + let got = lexer.next().unwrap(); + assert_eq!(got.value, "G"); + assert_eq!(got.span.line, 0); + + let got = lexer.next().unwrap(); + assert_eq!(got.value, "0"); + assert_eq!(got.span.line, 0); + + let got = lexer.next().unwrap(); + assert_eq!(got.value, "X"); + assert_eq!(got.span.line, 0); + + let got = lexer.next().unwrap(); + assert_eq!(got.value, "1"); + assert_eq!(got.span.line, 0); + + let got = lexer.next().unwrap(); + assert_eq!(got.value, "G"); + assert_eq!(got.span.line, 1); + + let got = lexer.next().unwrap(); + assert_eq!(got.value, "1"); + assert_eq!(got.span.line, 1); + + let got = lexer.next().unwrap(); + assert_eq!(got.value, "Y"); + assert_eq!(got.span.line, 1); + + let got = lexer.next().unwrap(); + assert_eq!(got.value, "2"); + assert_eq!(got.span.line, 1); + } } diff --git a/gcode/src/lib.rs b/gcode/src/lib.rs index 5639de20..0e35f742 100644 --- a/gcode/src/lib.rs +++ b/gcode/src/lib.rs @@ -83,11 +83,11 @@ //! let lines: Vec<_> = gcode::full_parse_with_callbacks(src, &mut errors) //! .collect(); //! -//! assert_eq!(lines.len(), 3); +//! assert_eq!(lines.len(), 4); //! let total_gcodes: usize = lines.iter() //! .map(|line| line.gcodes().len()) //! .sum(); -//! assert_eq!(total_gcodes, 2); +//! assert_eq!(total_gcodes, 3); //! } //! //! assert_eq!(errors.unexpected_line_number, 1); @@ -164,7 +164,7 @@ unused_qualifications, unused_results, variant_size_differences, - intra_doc_link_resolution_failure, + rustdoc::broken_intra_doc_links, missing_docs )] #![cfg_attr(not(feature = "std"), no_std)] diff --git a/gcode/src/parser.rs b/gcode/src/parser.rs index c4dae9fd..0bbaac11 100644 --- a/gcode/src/parser.rs +++ b/gcode/src/parser.rs @@ -243,6 +243,7 @@ where ); }, Atom::Word(word) => { + line.set_line_number(word); //this fixes the !line.is_empty() test at the start of the while loop self.handle_arg(word, &mut line, &mut temp_gcode) }, Atom::BrokenWord(token) => self.handle_broken_word(token), @@ -347,7 +348,6 @@ mod tests { .collect(); assert_eq!(got.len(), 1); - assert!(got[0].line_number().is_none()); let unexpected_line_number = unexpected_line_number.lock().unwrap(); assert_eq!(unexpected_line_number.len(), 1); assert_eq!(unexpected_line_number[0].0, 42.0); @@ -422,14 +422,13 @@ mod tests { /// For some reason we were parsing the G90, then an empty G01 and the /// actual G01. #[test] - #[ignore] fn funny_bug_in_crate_example() { - let src = "G90 \n G01 X50.0 Y-10"; + let src = "G0 X1\nG1 Y2"; let expected = vec![ - GCode::new(Mnemonic::General, 90.0, Span::PLACEHOLDER), + GCode::new(Mnemonic::General, 0.0, Span::PLACEHOLDER) + .with_argument(Word::new('X', 1.0, Span::PLACEHOLDER)), GCode::new(Mnemonic::General, 1.0, Span::PLACEHOLDER) - .with_argument(Word::new('X', 50.0, Span::PLACEHOLDER)) - .with_argument(Word::new('Y', -10.0, Span::PLACEHOLDER)), + .with_argument(Word::new('Y', 2.0, Span::PLACEHOLDER)), ]; let got: Vec<_> = crate::parse(src).collect(); diff --git a/gcode/src/words.rs b/gcode/src/words.rs index d4ad8993..d3b0e3f8 100644 --- a/gcode/src/words.rs +++ b/gcode/src/words.rs @@ -204,4 +204,59 @@ mod tests { }); assert_eq!(got, expected); } + + #[test] + fn multi_words() { + let text = "G0 X1\nG1 Y2"; + let mut words = WordsOrComments::new(Lexer::new(text)); + + let got = words.next().unwrap(); + let expected = Atom::Word(Word { + letter: 'G', + value: 0.0, + span: Span { + start: 0, + end: 2, + line: 0, + }, + + }); + assert_eq!(got, expected); + + let got = words.next().unwrap(); + let expected = Atom::Word(Word { + letter: 'X', + value: 1.0, + span: Span { + start: 3, + end: 5, + line: 0, + }, + }); + assert_eq!(got, expected); + + let got = words.next().unwrap(); + let expected = Atom::Word(Word { + letter: 'G', + value: 1.0, + span: Span { + start: 6, + end: 8, + line: 1, + }, + }); + assert_eq!(got, expected); + + let got = words.next().unwrap(); + let expected = Atom::Word(Word { + letter: 'Y', + value: 2.0, + span: Span { + start: 9, + end: 11, + line: 1, + }, + }); + assert_eq!(got, expected); + } } diff --git a/gcode/tests/data/program_4.gcode b/gcode/tests/data/program_4.gcode new file mode 100644 index 00000000..a9030d78 --- /dev/null +++ b/gcode/tests/data/program_4.gcode @@ -0,0 +1,13 @@ +G0 G90 G94 G17 +G21 +(HSC-KONTUR1) +M5 +T4 M6 +M3 S10000 +G54 +M7 +G0 X4.942 Y7.644 +Z15. +G1 Z0.401 F1000. +Z-1.751 +X4.945 Y7.637 Z-1.829 diff --git a/gcode/tests/smoke_test.rs b/gcode/tests/smoke_test.rs index ad06b8cf..f52443a8 100644 --- a/gcode/tests/smoke_test.rs +++ b/gcode/tests/smoke_test.rs @@ -65,6 +65,66 @@ fn expected_program_2_output() { pretty_assertions::assert_eq!(gcodes, expected); } +#[test] +#[ignore] +fn expected_program_4_output() { + // G0 G90 G94 G17 + // G21 + // (HSC-KONTUR1) + // M5 + // T4 M6 + // M3 S10000 + // G54 + // M7 + // G0 X4.942 Y7.644 + // Z15. + // G1 Z0.401 F1000. + // Z-1.751 + // X4.945 Y7.637 Z-1.829 + + let src = include_str!("data/program_4.gcode"); + + let got: Vec<_> = + gcode::full_parse_with_callbacks(src, PanicOnError).collect(); + + // total lines + assert_eq!(got.len(), 13); + // check lines without any comments + assert_eq!(got.iter().filter(|l| l.comments().is_empty()).count(), 12); + + let gcodes: Vec<_> = got.iter().flat_map(|l| l.gcodes()).cloned().collect(); + let expected = vec![ + GCode::new(Mnemonic::General, 0.0, Span::PLACEHOLDER), + GCode::new(Mnemonic::General, 90.0, Span::PLACEHOLDER), + GCode::new(Mnemonic::General, 94.0, Span::PLACEHOLDER), + GCode::new(Mnemonic::General, 17.0, Span::PLACEHOLDER), + GCode::new(Mnemonic::General, 21.0, Span::PLACEHOLDER), + GCode::new(Mnemonic::Miscellaneous, 5.0, Span::PLACEHOLDER), + GCode::new(Mnemonic::ToolChange, 4.0, Span::PLACEHOLDER), + GCode::new(Mnemonic::Miscellaneous, 6.0, Span::PLACEHOLDER), + GCode::new(Mnemonic::Miscellaneous, 3.0, Span::PLACEHOLDER) + .with_argument(Word::new('S', 10000.0, Span::PLACEHOLDER)), + GCode::new(Mnemonic::General, 54.0, Span::PLACEHOLDER), + GCode::new(Mnemonic::Miscellaneous, 7.0, Span::PLACEHOLDER), + GCode::new(Mnemonic::General, 0.0, Span::PLACEHOLDER) + .with_argument(Word::new('X', 4.942, Span::PLACEHOLDER)) + .with_argument(Word::new('Y', 7.644, Span::PLACEHOLDER)), + GCode::new(Mnemonic::General, 0.0, Span::PLACEHOLDER) + .with_argument(Word::new('Z', 15.0, Span::PLACEHOLDER)), + GCode::new(Mnemonic::General, 1.0, Span::PLACEHOLDER) + .with_argument(Word::new('Z', 0.401, Span::PLACEHOLDER)) + .with_argument(Word::new('F', 1000.0, Span::PLACEHOLDER)), + GCode::new(Mnemonic::General, 1.0, Span::PLACEHOLDER) + .with_argument(Word::new('Z', -1.751, Span::PLACEHOLDER)), + GCode::new(Mnemonic::General, 1.0, Span::PLACEHOLDER) + .with_argument(Word::new('X', 4.945, Span::PLACEHOLDER)) + .with_argument(Word::new('Y', 7.637, Span::PLACEHOLDER)) + .with_argument(Word::new('Z', -1.829, Span::PLACEHOLDER)), + + ]; + pretty_assertions::assert_eq!(gcodes, expected); +} + struct PanicOnError; impl gcode::Callbacks for PanicOnError {