diff --git a/matugen-parser/example/template.txt b/matugen-parser/example/template.txt index ea7278b..370b1e3 100644 --- a/matugen-parser/example/template.txt +++ b/matugen-parser/example/template.txt @@ -2,10 +2,17 @@ 15 +hello + +world + {{ colors.colors | a }} -{{ colors.colors | b: c }} -{{ colors.colors | b: c, d, e, f, g }} +{{ colors1.colors2 | b: . }} +{{ colors3.colors4 | b: a b }} +{{ colors5.colors6 | b: 1, 2.0 }} +{{ colors7.colors8 | b: . }} +{{ colors9.colors10 | b: c, d, e, f, g }} {{ colors.source_color.default.hex }} diff --git a/matugen-parser/src/errors/mod.rs b/matugen-parser/src/errors/mod.rs index 65d4b4b..5f5c930 100644 --- a/matugen-parser/src/errors/mod.rs +++ b/matugen-parser/src/errors/mod.rs @@ -2,10 +2,13 @@ use parse::ParseError; pub mod parse; -pub fn handle_error(f: Result>) { - if let Err(ref e) = f { +pub fn handle_error(f: Result>) -> Option { + if let Err(e) = f { std::eprintln!("{}", e); - }; + Some(e) + } else { + None + } } pub fn handle_error_panic(f: Result>) { diff --git a/matugen-parser/src/errors/parse.rs b/matugen-parser/src/errors/parse.rs index 20a67d8..bb3f4e8 100644 --- a/matugen-parser/src/errors/parse.rs +++ b/matugen-parser/src/errors/parse.rs @@ -1,6 +1,6 @@ use std::fmt; -use crate::parser::Parser; +use crate::{lexer::Token, parser::Parser}; #[derive(Debug)] pub struct ParseError<'a> { @@ -10,6 +10,7 @@ pub struct ParseError<'a> { pub source: &'a str, pub filename: &'a str, pub line_number: u64, + pub cur_token: Token, } impl ParseError<'_> { @@ -20,6 +21,7 @@ impl ParseError<'_> { source: &'a str, filename: &'a str, line_number: u64, + cur_token: Token, ) -> ParseError<'a> { ParseError { err_type, @@ -28,16 +30,18 @@ impl ParseError<'_> { source, filename, line_number, + cur_token, } } pub fn new_from_parser<'a>(err_type: ParseErrorTypes, parser: &Parser<'a>) -> ParseError<'a> { ParseError { err_type, - start: parser.last_bracket_start, + start: parser.parser_state.last_bracket_start, end: parser.lexer_state.prev_token_end, source: parser.source, filename: &parser.filename, line_number: parser.lexer_state.lexer.cur_line, + cur_token: parser.lexer_state.cur_token.clone(), } } } @@ -51,6 +55,11 @@ impl<'a> fmt::Display for ParseError<'a> { ParseErrorTypes::UnclosedBracket => "Unclosed bracket", ParseErrorTypes::DoubleDot => "Double dot", ParseErrorTypes::DoubleString => "Double string", + ParseErrorTypes::DoubleComma => "Double comma", + ParseErrorTypes::FilterArgumentNotSeparated => { + "Filter argument not separated by a comma" + } + ParseErrorTypes::NoFilterArgument => "No filter argument", }; let mut str = "".to_string(); @@ -62,8 +71,8 @@ impl<'a> fmt::Display for ParseError<'a> { write!( f, - "\n\u{1b}[2;30;41m ERROR \u{1b}[0m\u{1b}[2;30;47m {} \u{1b}[0m\n\x1b[94m-->\x1b[0m {}:{}:{}\n{}\n", - err_msg, self.filename, self.start, self.end, str, + "\n\u{1b}[2;30;41m ERROR \u{1b}[0m\u{1b}[2;30;47m {} \u{1b}[0m\n\x1b[94m-->\x1b[0m {}:{}:{}\n{}\n{:?}\n", + err_msg, self.filename, self.start, self.end, str, self.cur_token ) // write!( @@ -79,5 +88,8 @@ pub enum ParseErrorTypes { UnclosedBracket, DoubleDot, DoubleString, + DoubleComma, + FilterArgumentNotSeparated, UnexpectedFilterArgumentToken, + NoFilterArgument, } diff --git a/matugen-parser/src/lexer.rs b/matugen-parser/src/lexer.rs index 76f313b..04fb2af 100644 --- a/matugen-parser/src/lexer.rs +++ b/matugen-parser/src/lexer.rs @@ -1,3 +1,4 @@ +use colored::Colorize; use std::str::Chars; use string_cache::DefaultAtom as Atom; @@ -51,6 +52,7 @@ pub struct Lexer<'a> { source: &'a str, chars: Chars<'a>, pub cur_line: u64, + pub opened: bool, } impl<'a> Lexer<'a> { @@ -58,7 +60,8 @@ impl<'a> Lexer<'a> { Lexer { source: &input, chars: input.chars(), - cur_line: 0, + cur_line: 1, + opened: false, } } @@ -141,6 +144,15 @@ impl<'a> Lexer<'a> { ',' => (Kind::Comma, TokenValue::None), ' ' => (Kind::Space, TokenValue::None), '0'..='9' => { + if !self.opened { + println!( + "{}", + format!("SKIPPED BECAUSE NOT OPEN: {:?}", next_char) + .red() + .bold() + ); + self.read_next_kind(); + } let mut str = String::from(next_char.unwrap()); let mut is_float = false; @@ -155,7 +167,6 @@ impl<'a> Lexer<'a> { str.push(next_char); self.chars.next(); } else { - println!("{}", str); break; } } @@ -215,6 +226,16 @@ impl<'a> Lexer<'a> { TokenValue::String(String::from(next_char.unwrap()).into()), ) } else { + if !self.opened { + println!( + "{}", + format!("SKIPPED BECAUSE NOT OPEN: {:?}", next_char) + .red() + .bold() + ); + self.read_next_kind(); + } + let start = self.offset() - 1; let mut string = String::from(next_char.unwrap()); while let Some(next_char) = self.peek() { diff --git a/matugen-parser/src/parser/keywords.rs b/matugen-parser/src/parser/keywords.rs index 0109503..326ce49 100644 --- a/matugen-parser/src/parser/keywords.rs +++ b/matugen-parser/src/parser/keywords.rs @@ -17,10 +17,10 @@ impl Parser<'_> { self.lexer_state.bump_any(); - while !self.opened { + while !self.lexer_state.lexer.opened { if self.lexer_state.eat(&self.syntax.keyword_opening[0]) { - self.opened = true; - self.closed = false; + self.lexer_state.lexer.opened = true; + self.parser_state.closed = false; } else if self.lexer_state.eat(&Kind::Eof) { return None; } @@ -35,8 +35,8 @@ impl Parser<'_> { println!("STARTING TO CLOSE"); self.lexer_state.bump_any(); if self.lexer_state.eat(&self.syntax.keyword_closing[0]) { - self.closed = true; - self.opened = false; + self.parser_state.closed = true; + self.lexer_state.lexer.opened = false; Ok(()) } else { Err(ParseError::new_from_parser( @@ -65,13 +65,13 @@ impl Parser<'_> { return vec; } - self.last_bracket_start = opening.unwrap() - 1; + self.parser_state.last_bracket_start = opening.unwrap() - 1; let start = self.start_node(); let mut strings: Vec = vec![]; let mut filters: Vec = vec![]; - handle_error_panic(self.collect_strings(&mut strings, &mut filters)); + handle_error(self.collect_strings(&mut strings, &mut filters)); vec.push(Statement::KeywordDefinition(Box::new(KeywordDefinition { node: self.finish_node(start), @@ -123,6 +123,8 @@ impl Parser<'_> { // THIS SHOULD BE THE FILTER NAME self.lexer_state.eat(&Kind::String); + let mut first_arg = true; + if !self.lexer_state.eat_ignore_spaces(&Kind::Colon) { println!( "{}", @@ -133,37 +135,77 @@ impl Parser<'_> { self.lexer_state .bump_while_not(&self.syntax.keyword_closing[0]) } else { - // while !self.lexer_state.at(Kind::RBracket) { - // match self.lexer_state.cur_kind() { - // Kind::String => arguments.push(&self.lexer_state.cur_token.value), - // Kind::Number => todo!(), - // _ => {} - // } - // } loop { match self.lexer_state.cur_kind() { Kind::Space => { self.lexer_state.bump_until_not_at(&Kind::Space); } Kind::String => { - arguments.push(self.lexer_state.cur_token.value.clone()); - self.lexer_state.bump(&Kind::String) + if self.parser_state.seen_comma || first_arg { + arguments.push(self.lexer_state.cur_token.clone().value); + self.lexer_state.bump(&Kind::String); + self.parser_state.seen_comma = false; + first_arg = false; + } else { + self.lexer_state + .bump_while_not(&self.syntax.keyword_closing[0]); + return Err(ParseError::new_from_parser( + ParseErrorTypes::FilterArgumentNotSeparated, + &self, + )); + } } Kind::Number => { - arguments.push(self.lexer_state.cur_token.value.clone()); - self.lexer_state.bump(&Kind::Number) + if self.parser_state.seen_comma || first_arg { + arguments.push(self.lexer_state.cur_token.clone().value); + self.lexer_state.bump(&Kind::Number); + self.parser_state.seen_comma = false; + first_arg = false; + } else { + self.lexer_state + .bump_while_not(&self.syntax.keyword_closing[0]); + return Err(ParseError::new_from_parser( + ParseErrorTypes::FilterArgumentNotSeparated, + &self, + )); + } + } + Kind::Float => { + if self.parser_state.seen_comma || first_arg { + arguments.push(self.lexer_state.cur_token.clone().value); + self.lexer_state.bump(&Kind::Float); + self.parser_state.seen_comma = false; + first_arg = false; + } else { + self.lexer_state + .bump_while_not(&self.syntax.keyword_closing[0]); + return Err(ParseError::new_from_parser( + ParseErrorTypes::FilterArgumentNotSeparated, + &self, + )); + } } kind if *kind == self.syntax.keyword_closing[1] => { break; } Kind::Comma => { - self.lexer_state.bump_until_not_at(&Kind::Comma); + if self.parser_state.seen_comma && self.lexer_state.eat(&Kind::Comma) { + self.parser_state.seen_comma = false; + return Err(ParseError::new_from_parser( + ParseErrorTypes::DoubleComma, + &self, + )); + } else { + self.parser_state.seen_comma = true; + self.lexer_state.bump(&Kind::Comma); + } } _ => { + self.lexer_state.bump_any(); return Err(ParseError::new_from_parser( ParseErrorTypes::UnexpectedFilterArgumentToken, &self, - )) + )); } } } @@ -190,25 +232,25 @@ impl Parser<'_> { self.lexer_state.bump_any(); - while !&self.closed && !self.lexer_state.at(&Kind::Eof) { + while !&self.parser_state.closed && !self.lexer_state.at(&Kind::Eof) { match &self.lexer_state.cur_kind() { Kind::Dot => { - if self.seen_dot && self.lexer_state.eat(&Kind::Dot) { - self.seen_dot = false; + if self.parser_state.seen_dot && self.lexer_state.eat(&Kind::Dot) { + self.parser_state.seen_dot = false; return Err(ParseError::new_from_parser( ParseErrorTypes::DoubleDot, &self, )); } else { - self.seen_dot = true; + self.parser_state.seen_dot = true; self.lexer_state.bump(&Kind::Dot); } } Kind::String => { - if self.seen_dot { + if self.parser_state.seen_dot { strings.push(self.lexer_state.cur_token.clone().value); self.lexer_state.bump(&Kind::String); - self.seen_dot = false; + self.parser_state.seen_dot = false; } else { self.lexer_state .bump_while_not(&self.syntax.keyword_closing[0]); @@ -232,8 +274,8 @@ impl Parser<'_> { kind if **kind == self.syntax.keyword_closing[0] => { return self.get_closing(); // if self.lexer_state.eat(Kind::RBracket) { - // self.closed = true; - // self.opened = false; + // self.parser_state.closed = true; + // self.lexer.opened = false; // println!("closed without filter") // } else { // println!("fucked the closing"); diff --git a/matugen-parser/src/parser/mod.rs b/matugen-parser/src/parser/mod.rs index 2789792..0b25f98 100644 --- a/matugen-parser/src/parser/mod.rs +++ b/matugen-parser/src/parser/mod.rs @@ -12,13 +12,16 @@ pub struct Parser<'a> { pub source: &'a str, pub filename: &'a str, pub lexer_state: LexerState<'a>, + pub parser_state: ParserState, + pub syntax: &'a SyntaxSettings, +} - pub opened: bool, +#[derive(Debug)] +pub struct ParserState { pub closed: bool, pub seen_dot: bool, - + pub seen_comma: bool, pub last_bracket_start: usize, - pub syntax: &'a SyntaxSettings, } #[derive(Debug)] @@ -39,10 +42,12 @@ impl<'a> Parser<'a> { prev_token_end: 0, lexer, }, - opened: false, - closed: false, - seen_dot: false, - last_bracket_start: 0, + parser_state: ParserState { + closed: false, + seen_dot: false, + seen_comma: false, + last_bracket_start: 0, + }, syntax: &syntax, } }