diff --git a/crates/ltk_ritobin/src/parse.rs b/crates/ltk_ritobin/src/parse.rs index 8d269f1f..be631653 100644 --- a/crates/ltk_ritobin/src/parse.rs +++ b/crates/ltk_ritobin/src/parse.rs @@ -56,11 +56,12 @@ mod test { assert_success( r#" #PROP_text -type: string = "my_str" +type: string = "my_str" # inline comment # version: u32 = 3 linked: list[string] = { } entries: map[hash, embed] = { "foo" = Bar { + a = 5 # 23 # asdasd } } @@ -68,6 +69,11 @@ entries: map[hash, embed] = { ); } + #[test] + fn inline_comment_into_eof() { + assert_success(r#"mVelMultiplier: f32 = 0 # asd"#); + } + #[ignore = "Nice to have"] #[test] fn naked_class() { diff --git a/crates/ltk_ritobin/src/parse/impls.rs b/crates/ltk_ritobin/src/parse/impls.rs index 1c6c2543..7c04a74f 100644 --- a/crates/ltk_ritobin/src/parse/impls.rs +++ b/crates/ltk_ritobin/src/parse/impls.rs @@ -10,9 +10,6 @@ use TokenKind::*; pub fn file(p: &mut Parser) { let m = p.open(); while !p.eof() { - if p.at(Comment) { - p.scope(TreeKind::Comment, |p| p.advance()); - } stmt_or_list_item(p); } p.close(m, TreeKind::File); @@ -22,7 +19,10 @@ pub fn stmt_or_list_item(p: &mut Parser) -> (MarkClosed, TreeKind) { let res; match (p.nth(0), p.nth(1), p.nth(2)) { (Comment, _, _) => { - let (_, m) = p.scope(TreeKind::Comment, |p| while p.eat(TokenKind::Comment) {}); + let (_, m) = p.scope(TreeKind::Comment, |p| { + p.eat(TokenKind::Comment); + while p.eat(TokenKind::Newline) {} + }); res = (m, TreeKind::Comment); } (Name | HexLit, LCurly, _) => { @@ -43,6 +43,7 @@ pub fn stmt_or_list_item(p: &mut Parser) -> (MarkClosed, TreeKind) { (Name | HexLit | String | Number | True | False, _, _) => { let m = p.open(); p.scope(TreeKind::Literal, |p| p.advance()); + p.eat(Comment); res = (p.close(m, TreeKind::ListItem), TreeKind::ListItem); p.eat(Comma); } @@ -79,9 +80,12 @@ pub fn stmt(p: &mut Parser) -> MarkClosed { p.scope(TreeKind::EntryTerminator, |p| { let mut one = false; + + p.eat(TokenKind::Comment); if p.eof() { return; } + while p .eat_any(&[TokenKind::SemiColon, TokenKind::Newline]) .is_some() diff --git a/crates/ltk_ritobin/src/parse/tokenizer.rs b/crates/ltk_ritobin/src/parse/tokenizer.rs index 8fd8afdc..58c1d9ae 100644 --- a/crates/ltk_ritobin/src/parse/tokenizer.rs +++ b/crates/ltk_ritobin/src/parse/tokenizer.rs @@ -128,6 +128,7 @@ pub fn lex(mut text: &str) -> Vec { | TokenKind::RCurly | TokenKind::String | TokenKind::Eq + | TokenKind::Comment ) && eaten.find(['\n', '\r']).is_some() { let start = source.len() - text.len(); diff --git a/crates/ltk_ritobin/src/print.rs b/crates/ltk_ritobin/src/print.rs index d8179256..542194e0 100644 --- a/crates/ltk_ritobin/src/print.rs +++ b/crates/ltk_ritobin/src/print.rs @@ -85,6 +85,43 @@ mod test { assert_pretty(input, input, config); } + #[test] + fn stmt_inline_comment() { + assert_pretty( + r#" b : list [ i8, ] = { 3, 6 1 }# inline + #not inline"#, + r#"b: list[i8] = { 3, 6, 1 } # inline +#not inline"#, + PrintConfig::default(), + ); + } + + #[test] + fn list_comments() { + assert_pretty_rt( + r#"linked: list[string] = { + "aasdjaskhdkajshdkjahskdjh aksjhd akjshd kajhs dkjh kajshdakjshd " + "basjd askjdh aksjhd akjsh dkjahsd jkahsd kajsh dkajsh d" # ad + # asd +}"#, + PrintConfig::default(), + ); + } + + #[test] + fn dont_inline_lists_with_comments() { + assert_pretty( + r#"linked: list[string] = { "a", "b" # asd +}"#, + r#"linked: list[string] = { + "a" + "b" # asd +} +"#, + PrintConfig::default(), + ); + } + #[test] fn simple_list() { assert_pretty( diff --git a/crates/ltk_ritobin/src/print/visitor.rs b/crates/ltk_ritobin/src/print/visitor.rs index 4f115c7f..0e08e4fb 100644 --- a/crates/ltk_ritobin/src/print/visitor.rs +++ b/crates/ltk_ritobin/src/print/visitor.rs @@ -238,17 +238,17 @@ impl<'a, W: Write> CstVisitor<'a, W> { true } - pub fn force_group(&mut self, group: GroupId, mode: Mode) { + pub fn force_group(&mut self, group: GroupId, mode: Mode) -> Option { if group.0 < self.printed_commands { // eprintln!("[!!] trying to mutate already printed group! {group:?}"); - return; + return None; // panic!("trying to mutate already printed group!"); } let cmd = self.queue.get_mut(group.0 - self.printed_commands).unwrap(); let Cmd::Begin(grp_mode) = cmd else { unreachable!("grp pointing at non begin cmd {cmd:?}"); }; - grp_mode.replace(mode); + grp_mode.replace(mode) } fn last_mode(&self) -> &Mode { @@ -543,7 +543,7 @@ impl<'a, W: Write> CstVisitor<'a, W> { fn visit_token_inner( &mut self, token: &crate::parse::Token, - _context: &Cst, + ctx: &Cst, ) -> Result<(), PrintError> { let txt = self.src[token.span].trim(); let print_value = token.kind.print_value(); @@ -555,7 +555,21 @@ impl<'a, W: Write> CstVisitor<'a, W> { // eprintln!("->{:?}", token.kind); match token.kind { TokenKind::Comment => { - self.line()?; + match ctx.kind { + Kind::EntryTerminator => self.space()?, + Kind::ListItem => { + if let Some(list) = self.list_stack.last() { + self.force_group(list.grp, Mode::Break); + } + self.space()?; + } + _ => { + if let Some(list) = self.list_stack.last() { + self.force_group(list.grp, Mode::Break); + } + self.line()? + } + } self.text(txt)?; } TokenKind::LCurly => { diff --git a/crates/ltk_ritobin/tests/snapshots/parse_sample__parse_sample.snap b/crates/ltk_ritobin/tests/snapshots/parse_sample__parse_sample.snap index cc4e896d..e4a53d5f 100644 --- a/crates/ltk_ritobin/tests/snapshots/parse_sample__parse_sample.snap +++ b/crates/ltk_ritobin/tests/snapshots/parse_sample__parse_sample.snap @@ -3,9 +3,10 @@ source: crates/ltk_ritobin/tests/parse_sample.rs expression: tree(SAMPLE_RITOBIN) --- File - (0..1310): "#PROP_text\ntype: string = \"PROP\"\nversion: u32 = 3\nlinked: list[string] = {\n \"DATA/Characters/Test/Animations/Skin0.bin\"\n \"DATA/Characters/Test/Test.bin\"\n}\nentries: map[hash,embed] = {\n \"Characters/Test/Skins/Skin0\" = SkinCharacterDataProperties {\n skinClassification: u32 = 1\n championSkinName: string = \"TestBase\"\n metaDataTags: string = \"gender:male\"\n loadscreen: embed = CensoredImage {\n image: string = \"ASSETS/Characters/Test/Skins/Base/TestLoadScreen.tex\"\n }\n skinAudioProperties: embed = skinAudioProperties {\n tagEventList: list[string] = {\n \"Test\"\n }\n bankUnits: list2[embed] = {\n BankUnit {\n name: string = \"Test_Base_SFX\"\n bankPath: list[string] = {\n \"ASSETS/Sounds/Test/audio.bnk\"\n \"ASSETS/Sounds/Test/events.bnk\"\n }\n events: list[string] = {\n \"Play_sfx_Test_Attack\"\n \"Play_sfx_Test_Death\"\n }\n }\n }\n }\n iconCircle: option[string] = {\n \"ASSETS/Characters/Test/Icons/Circle.tex\"\n }\n iconSquare: option[string] = {}\n }\n}\n" - Comment - (0..10): "#PROP_text" + Comment - (0..11): "#PROP_text\n" "#PROP_text" (Comment) - Entry - (10..33): "\ntype: string = \"PROP\"\n" + "\n" (Newline) + Entry - (11..33): "type: string = \"PROP\"\n" EntryKey - (11..15): "type" "type" (Name) ":" (Colon)