From be637846b15bc019f888ec9e56a5d6680d272843 Mon Sep 17 00:00:00 2001 From: Schrottkatze Date: Fri, 12 Apr 2024 21:31:55 +0200 Subject: [PATCH] lang: kinda fun parsing things that can now parse attribute sets with one attribute --- crates/lang/src/parser/ast/lossless/parser.rs | 66 ++++++++++++++----- testfiles/test.owo | 8 ++- 2 files changed, 55 insertions(+), 19 deletions(-) diff --git a/crates/lang/src/parser/ast/lossless/parser.rs b/crates/lang/src/parser/ast/lossless/parser.rs index adcb08e..dc7868d 100644 --- a/crates/lang/src/parser/ast/lossless/parser.rs +++ b/crates/lang/src/parser/ast/lossless/parser.rs @@ -40,7 +40,7 @@ pub mod parser_to_events { } pub fn to_events(tokens: &[(SyntaxKind, &str)]) -> Vec { - let mut only_toks: Vec = tokens.iter().map(|(t, _)| *t).collect(); + let only_toks: Vec = tokens.iter().map(|(t, _)| *t).collect(); let res = parser().parse(&only_toks); res.unwrap() } @@ -60,27 +60,28 @@ pub mod parser_to_events { }) }}; } + macro_rules! parenthesized { + ($parser:expr) => { + just(L_PAREN) + .to(vec![Event::EatToken]) + .then($parser) + .then(just(R_PAREN).to(vec![Event::EatToken])) + .map(|((mut before, mut c), mut after)| { + before.insert(0, Event::StartNode(PARENTHESIZED_EXPR)); + before.append(&mut c); + before.append(&mut after); + before.push(Event::FinishNode); + before + }) + }; + } pub fn parser<'toks>() -> impl Parser<'toks, &'toks [SyntaxKind], Vec> { let ws = one_of([WHITESPACE, NEWLINE]) .to(Event::EatToken) .repeated() .collect::>(); - // let ws_without_newlines = just(WHITESPACE) - // .to(Event::EatToken) - // .repeated() - // .collect::>(); - let parenthesized = |c| { - just(L_PAREN) - .to(vec![Event::EatToken]) - .then(c) - .then(just(R_PAREN).to(vec![Event::EatToken])) - .map(|((mut before, mut c), mut after)| { - before.append(&mut c); - before.append(&mut after); - before - }) - }; + let ident = just(IDENT).to(vec![Event::EatToken]); let expr = recursive(|expr| { let lit = one_of([INT_NUM, FLOAT_NUM, STRING]).to(vec![ @@ -88,10 +89,39 @@ pub mod parser_to_events { Event::EatToken, Event::FinishNode, ]); + let attrset = just(L_CURLY) + .then( + padded!(just(IDENT).to(vec![ + Event::StartNode(ATTR), + Event::StartNode(ATTR_NAME), + Event::EatToken, + Event::FinishNode + ])) + .then(just(COLON)) + .then(padded!(expr.clone().map(|mut exp: Vec| { + exp.insert(0, Event::StartNode(ATTR_VALUE)); + exp.push(Event::FinishNode); + exp.push(Event::FinishNode); + exp + }))) + .map(|((mut name, _), mut value)| { + // colon + name.push(Event::EatToken); + name.append(&mut value); + name + }), + ) + .then(just(R_CURLY)) + .map(|((_, mut attrs), _)| { + attrs.insert(0, Event::StartNode(ATTR_SET)); + attrs.insert(0, Event::EatToken); + attrs.push(Event::EatToken); + attrs.push(Event::FinishNode); + attrs + }); - let atom = lit.clone().or(parenthesized(expr)); + let atom = lit.clone().or(attrset).or(parenthesized!(expr)); - let ident = just(IDENT).to(vec![Event::EatToken]); let instr_name = ident .clone() .map(|mut v| { diff --git a/testfiles/test.owo b/testfiles/test.owo index 78cbbda..dc95a8d 100644 --- a/testfiles/test.owo +++ b/testfiles/test.owo @@ -1 +1,7 @@ -hello world test 42 3.14 "uwu" +hello world test + 42 + (another command 3.14 "meow") + "uwu" + { + some: attrs 42 (meow gay 1) + }