From 12c7b851d866401ac4a32c746ed237b051aa3dd3 Mon Sep 17 00:00:00 2001 From: Mike Buland Date: Thu, 20 Aug 2026 08:16:58 -0700 Subject: Making progress cleaning up. --- deepcrow/src/parser.rs | 217 ++++++++++++++++++++++++------------------------- 1 file changed, 108 insertions(+), 109 deletions(-) (limited to 'deepcrow/src/parser.rs') diff --git a/deepcrow/src/parser.rs b/deepcrow/src/parser.rs index 529c58e..5c6680e 100644 --- a/deepcrow/src/parser.rs +++ b/deepcrow/src/parser.rs @@ -36,9 +36,9 @@ impl<'a> Context<'a> { } /* - pub fn check_unwrapped bool>(&self, context: &str, f: T) -> Result { + pub fn check_unwrapped bool>(&self, context: &str, f: T) -> CrimResult { if self.cur().is_none() || self.peek().is_none() { - Err(DeepCrowError::eos( context )) + Err(CrimError::eos( context )) } else { Ok(f( self.cur().unwrap().symbol(), self.peek().unwrap().symbol())) } @@ -51,35 +51,34 @@ impl<'a> Context<'a> { } trait SymbolHelper { - fn is bool>(&self, context: &str, f: T ) -> Result; + fn is bool>(&self, context: &str, f: T ) -> CrimResult; #[allow(dead_code)] - fn is_valid_tag_name(&self) -> Result; + fn is_valid_tag_name(&self) -> CrimResult; } impl<'a> SymbolHelper for Option> { - fn is bool>(&self, context: &str, f: T ) -> Result { + fn is bool>(&self, context: &str, f: T ) -> CrimResult { if let Some(st) = self { Ok(f( &st.symbol() )) } else { - Err(DeepCrowError::eos( context )) + Err(CrimError::eos( context )) } } - fn is_valid_tag_name(&self) -> Result { + fn is_valid_tag_name(&self) -> CrimResult { if let Some(st) = self { Ok(match st.symbol() { - TokenType::Identifier(_) | - TokenType::View | - TokenType::Output | - TokenType::Loop | - TokenType::If | - TokenType::ElIf | - TokenType::Else | - TokenType::Show => true, + TokenType::Identifier("view") | + TokenType::Identifier("output") | + TokenType::Identifier("loop") | + TokenType::Identifier("if") | + TokenType::Identifier("elif") | + TokenType::Identifier("else") | + TokenType::Identifier("show") => true, _ => false }) } else { - Err(DeepCrowError::parse( + Err(CrimError::parse( Position::none(), "Unexpeceted end of stream.".to_string() )) @@ -183,17 +182,17 @@ impl Parser { } } - fn lex_error(&self, error: &Symbol) -> Result { - if let TokenType::Error{what} = error.symbol() { - Err(DeepCrowError::parse( *error.start(), + fn lex_error(&self, error: &Symbol) -> CrimResult { + if let SymbolType::Error{what} = error.symbol() { + Err(CrimError::parse( *error.start(), format!("What: {:?}", *what) )) } else { - Err(DeepCrowError::parse( Position::none(), "Not an error?".into())) + Err(CrimError::parse( Position::none(), "Not an error?".into())) } } - pub fn parse(&self, src: &str, source: usize ) -> Result> { + pub fn parse(&self, src: &str, source: usize ) -> CrimResult> { let ll = Lexer::new( src ); let mut ctx = Context::new( ll, source ); @@ -201,24 +200,24 @@ impl Parser { self.p_input( &mut ctx ) } - fn p_input(&self, ctx: &mut Context ) -> Result> { + fn p_input(&self, ctx: &mut Context ) -> CrimResult> { let mut tags = Vec::new(); loop { if ctx.cur().is_none() { break; } match ctx.cur().unwrap().symbol() { - TokenType::Text(_) => { /* Skip top level text */ } - TokenType::StartFlat => { + SymbolType::Text(_) => { /* Skip top level text */ } + SymbolType::StartFlat => { let tb = self.parse_tag( ctx )?; let tb = self.parse_tag_set( ctx, tb )?; tags.push( tb ); } - TokenType::Error{..} => { + SymbolType::Error{..} => { self.lex_error( &ctx.cur().unwrap() )?; } _ => { - return Err(DeepCrowError::parse( + return Err(CrimError::parse( *ctx.cur().unwrap().start(), format!("Unexpected symbol {:?} found looking for tags.", ctx.cur().unwrap().symbol() ) )); @@ -231,11 +230,11 @@ impl Parser { for tag in tags { let start_pos = tag.start_pos(); let name = tag.name().clone(); - if tag.is_name(&TokenType::View) && + if tag.is_name(&SymbolType::View) && let BuildResult::View(view) = tag.build( ctx )? { views.push( view ); } else { - return Err(DeepCrowError::parse( + return Err(CrimError::parse( start_pos, format!("Expected view at root, found {:?}", name ) )); @@ -244,28 +243,28 @@ impl Parser { Ok(views) } - fn parse_tag<'a>(&self, ctx: &mut Context<'a>) -> Result> { + fn parse_tag<'a>(&self, ctx: &mut Context<'a>) -> CrimResult> { let start_sym = ctx.cur().unwrap(); let mut tb = TagBuilder::new(&start_sym); if ctx.next().is_some() { match ctx.cur().unwrap().symbol() { - TokenType::View | TokenType::Show | TokenType::Loop | - TokenType::If | TokenType::ElIf | TokenType::Else | - TokenType::Output => { + SymbolType::View | SymbolType::Show | SymbolType::Loop | + SymbolType::If | SymbolType::ElIf | SymbolType::Else | + SymbolType::Output => { let name_sym = ctx.cur().unwrap(); ctx.next(); tb.set_name( name_sym ); } _ => { - return Err(DeepCrowError::parse( + return Err(CrimError::parse( *ctx.cur().unwrap().start(), "Unexpected symbol".to_string() )); } } } else { - return Err(DeepCrowError::eos("tag type")); + return Err(CrimError::eos("tag type")); } if tb.can_have_params() || tb.can_have_expr() { @@ -277,11 +276,11 @@ impl Parser { if let Some(end_sym) = ctx.cur() { match end_sym.symbol() { - TokenType::EndPoint | TokenType::EndFlat => { + SymbolType::EndPoint | SymbolType::EndFlat => { tb.set_end( &end_sym )?; } _ => { - return Err(DeepCrowError::parse( + return Err(CrimError::parse( *end_sym.start(), format!("Unexpected symbol {:?} looking for end of tag.", end_sym.symbol()) )); @@ -294,21 +293,21 @@ impl Parser { Ok(tb) } - fn parse_tag_set<'a>(&self, ctx: &mut Context<'a>, mut base: TagBuilder<'a>) -> Result> { + fn parse_tag_set<'a>(&self, ctx: &mut Context<'a>, mut base: TagBuilder<'a>) -> CrimResult> { if base.is_unary() { return Ok(base); } loop { if ctx.cur().is_none() { - return Err(DeepCrowError::eos(format!("close tag for {:?}", base.name()).as_str())); + return Err(CrimError::eos(format!("close tag for {:?}", base.name()).as_str())); } match ctx.cur().unwrap().symbol() { - TokenType::Text(s) => { + SymbolType::Text(s) => { base.add_child(Entry::Token(Token::Text(s.to_string()))); ctx.next(); } - TokenType::StartFlat | TokenType::StartPoint => { + SymbolType::StartFlat | SymbolType::StartPoint => { let tb = self.parse_tag( ctx )?; match tb.tag_type() { @@ -320,13 +319,13 @@ impl Parser { return Ok(base); } TagType::MultinaryClose => { - if (tb.is_name(&TokenType::If) && - (base.is_name(&TokenType::ElIf) || - base.is_name(&TokenType::Else))) || + if (tb.is_name(&SymbolType::If) && + (base.is_name(&SymbolType::ElIf) || + base.is_name(&SymbolType::Else))) || tb.is_name(base.name().unwrap().symbol()) { return Ok(base); } else { - return Err(DeepCrowError::parse( + return Err(CrimError::parse( *tb.name().unwrap().start(), format!("Found {:?} looking for close of {:?}", tb.name().unwrap().symbol(), base.name().unwrap().symbol()) )); @@ -336,15 +335,15 @@ impl Parser { base.add_child(Entry::TagBuilder(tb)); } TagType::Unknown => { - return Err(DeepCrowError::broken(base.start_pos(), "Found unknown tag when looking for something else.")); + return Err(CrimError::broken(base.start_pos(), "Found unknown tag when looking for something else.")); } } } - TokenType::Error{..} => { + SymbolType::Error{..} => { return self.lex_error( &ctx.cur().unwrap() ); } _ => { - return Err(DeepCrowError::parse( + return Err(CrimError::parse( *ctx.cur().unwrap().start(), format!("Unexpected token: {:?}", ctx.cur().unwrap().symbol()), )); @@ -353,18 +352,18 @@ impl Parser { } } - fn parse_tag_params(&self, ctx: &mut Context, tb: &mut TagBuilder ) -> Result<()> { + fn parse_tag_params(&self, ctx: &mut Context, tb: &mut TagBuilder ) -> CrimResult<()> { loop { if ctx.cur().is_none() { - return Err(DeepCrowError::eos("tag parameters")); + return Err(CrimError::eos("tag parameters")); } match ctx.cur().unwrap().symbol() { - TokenType::Literal(s) => { - tb.add_param( ParamValue::Literal(s.to_string()) ); + SymbolType::LiteralStr(s) => { + tb.add_param( ParamValue::LiteralStr(s.to_string()) ); ctx.next(); } - TokenType::Identifier(_) | TokenType::Sharp => { - if ctx.peek().is("tag data", |s| *s == TokenType::Equals)? { + SymbolType::Token(_) | SymbolType::Sharp => { + if ctx.peek().is("tag data", |s| *s == SymbolType::Equals)? { break; } tb.add_param( self.parse_identifier( ctx )? ); @@ -377,23 +376,23 @@ impl Parser { Ok(()) } - fn parse_identifier(&self, ctx: &mut Context ) -> Result { + fn parse_identifier(&self, ctx: &mut Context ) -> CrimResult { let mut id = Identifier::new(); - if ctx.cur().is("identifier",|s| matches!( s, TokenType::Sharp))? { + if ctx.cur().is("identifier",|s| matches!( s, SymbolType::Sharp))? { id.push( IdentifierValue::Root ); ctx.next(); } loop { - if ctx.cur().is("identifier",|s| matches!( s, TokenType::Identifier(_) ))? { - if let TokenType::Identifier(s) = ctx.cur().unwrap().symbol() { + if ctx.cur().is("identifier",|s| matches!( s, SymbolType::Token(_) ))? { + if let SymbolType::Token(s) = ctx.cur().unwrap().symbol() { id.push( IdentifierValue::Name(s.to_string()) ); } } else { - return Err(DeepCrowError::parse( ctx.cur().unwrap().start().clone(), format!("Expeceted identifier, found {:?}", ctx.cur().unwrap().symbol() ) ) ); + return Err(CrimError::parse( ctx.cur().unwrap().start().clone(), format!("Expeceted identifier, found {:?}", ctx.cur().unwrap().symbol() ) ) ); } - if !ctx.next().is("identifier seperator",|s| *s == TokenType::Period )? { + if !ctx.next().is("identifier seperator",|s| *s == SymbolType::Period )? { break; } ctx.next(); @@ -402,19 +401,19 @@ impl Parser { Ok(ParamValue::Identifier(id)) } - fn parse_tag_props(&self, ctx: &mut Context, tb: &mut TagBuilder ) -> Result<()> { + fn parse_tag_props(&self, ctx: &mut Context, tb: &mut TagBuilder ) -> CrimResult<()> { loop { if ctx.cur().is_none() { - return Err(DeepCrowError::eos("tag properties")); + return Err(CrimError::eos("tag properties")); } - if let TokenType::Identifier(s) = ctx.cur().unwrap().symbol() { - if ctx.peek().is_some_and(|s|s.check_type(|t| matches!(t,TokenType::Equals))) { + if let SymbolType::Token(s) = ctx.cur().unwrap().symbol() { + if ctx.peek().is_some_and(|s|s.check_type(|t| matches!(t,SymbolType::Equals))) { ctx.next(); if let Some(sym) = ctx.next() && - let TokenType::Literal(lv) = sym.symbol() { + let SymbolType::LiteralStr(lv) = sym.symbol() { tb.add_prop( s.to_string(), lv.to_string() ); } else { - return Err(DeepCrowError::parse(Position::none(),"Expected quoted literal string".to_string())); + return Err(CrimError::parse(Position::none(),"Expected quoted literal string".to_string())); } } else { break; @@ -447,15 +446,15 @@ type EntryList<'a> = Vec>; trait EntryListConverter { fn has_outputs(&self) -> bool; - fn to_outputs(&mut self, ctx: &mut Context ) -> Result>; - fn to_tokens(&mut self, ctx: &mut Context) -> Result>; + fn to_outputs(&mut self, ctx: &mut Context ) -> CrimResult>; + fn to_tokens(&mut self, ctx: &mut Context) -> CrimResult>; } impl<'a> EntryListConverter for EntryList<'a> { fn has_outputs(&self) -> bool { self.iter().any(|e| if let Entry::TagBuilder(tb) = e - && tb.is_name(&TokenType::Output) { + && tb.is_name(&SymbolType::Output) { true } else { false @@ -463,7 +462,7 @@ impl<'a> EntryListConverter for EntryList<'a> { ) } - fn to_outputs(&mut self, ctx: &mut Context) -> Result> { + fn to_outputs(&mut self, ctx: &mut Context) -> CrimResult> { let mut outputs = Vec::new(); if self.has_outputs() { @@ -489,7 +488,7 @@ impl<'a> EntryListConverter for EntryList<'a> { Ok(outputs) } - fn to_tokens(&mut self, ctx: &mut Context) -> Result> { + fn to_tokens(&mut self, ctx: &mut Context) -> CrimResult> { let mut tokens : Vec = Vec::new(); for e in self.drain(..) { match e { @@ -500,7 +499,7 @@ impl<'a> EntryListConverter for EntryList<'a> { if let BuildResult::Token(token) = tb.build(ctx)? { tokens.push( token ); } else { - return Err(DeepCrowError::broken( Position::none(), "Non-token result built.")); + return Err(CrimError::broken( Position::none(), "Non-token result built.")); } } } @@ -522,7 +521,7 @@ struct TagBuilder<'a> { #[derive(Debug)] enum ParamValue { - Literal(String), + LiteralStr(String), Identifier(Identifier), } @@ -545,25 +544,25 @@ impl<'a> TagBuilder<'a> { } } - pub fn set_end(&mut self, end: &Symbol) -> Result<()> { - if *self.start.symbol() == TokenType::StartFlat { - if *end.symbol() == TokenType::EndFlat { + pub fn set_end(&mut self, end: &Symbol) -> CrimResult<()> { + if *self.start.symbol() == SymbolType::StartFlat { + if *end.symbol() == SymbolType::EndFlat { self.tag_type = TagType::Unary; - } else if *end.symbol() == TokenType::EndPoint { + } else if *end.symbol() == SymbolType::EndPoint { self.tag_type = TagType::MultinaryOpen; } else { - return Err(DeepCrowError::broken( *end.start(), "Invalid bracket token type.")); + return Err(CrimError::broken( *end.start(), "Invalid bracket token type.")); } - } else if *self.start.symbol() == TokenType::StartPoint { - if *end.symbol() == TokenType::EndFlat { + } else if *self.start.symbol() == SymbolType::StartPoint { + if *end.symbol() == SymbolType::EndFlat { self.tag_type = TagType::MultinaryClose; - } else if *end.symbol() == TokenType::EndPoint { + } else if *end.symbol() == SymbolType::EndPoint { self.tag_type = TagType::MultinaryMid; } else { - return Err(DeepCrowError::broken( *end.start(), "Invalid bracket token type.")); + return Err(CrimError::broken( *end.start(), "Invalid bracket token type.")); } } else { - return Err(DeepCrowError::broken( *self.start.start(), "Invalid bracket token type.")); + return Err(CrimError::broken( *self.start.start(), "Invalid bracket token type.")); } Ok(()) } @@ -582,18 +581,18 @@ impl<'a> TagBuilder<'a> { */ pub fn can_have_params(&self) -> bool { match self.name.unwrap().symbol() { - TokenType::View | TokenType::Output | TokenType::Loop => true, - TokenType::Show | TokenType::If | TokenType::ElIf | - TokenType::Else => false, + SymbolType::View | SymbolType::Output | SymbolType::Loop => true, + SymbolType::Show | SymbolType::If | SymbolType::ElIf | + SymbolType::Else => false, _ => false, } } pub fn can_have_expr(&self) -> bool { match self.name.unwrap().symbol() { - TokenType::View | TokenType::Output | TokenType::Loop => false, - TokenType::Show | TokenType::If | TokenType::ElIf | - TokenType::Else => true, + SymbolType::View | SymbolType::Output | SymbolType::Loop => false, + SymbolType::Show | SymbolType::If | SymbolType::ElIf | + SymbolType::Else => true, _ => false, } } @@ -611,7 +610,7 @@ impl<'a> TagBuilder<'a> { } } */ - pub fn is_name(&self, name: &TokenType<'a>) -> bool { + pub fn is_name(&self, name: &SymbolType<'a>) -> bool { if let Some(a) = self.name { a.symbol() == name } else { @@ -659,14 +658,14 @@ impl<'a> TagBuilder<'a> { self.tag_type } - pub fn build(mut self, ctx: &mut Context ) -> Result { + pub fn build(mut self, ctx: &mut Context ) -> CrimResult { if let Some(sym) = self.name { match sym.symbol() { - TokenType::View => { - let name = if let ParamValue::Literal(s) = self.params.swap_remove(0) { + SymbolType::View => { + let name = if let ParamValue::LiteralStr(s) = self.params.swap_remove(0) { s.to_string() } else { - return Err(DeepCrowError::parse(Position::none(), "Expected string literal for view name.".to_string())); + return Err(CrimError::parse(Position::none(), "Expected string literal for view name.".to_string())); }; Ok(BuildResult::View(View { name: name, @@ -676,23 +675,23 @@ impl<'a> TagBuilder<'a> { layout: self.props.get("layout").cloned(), })) } - TokenType::Output => { - let name = if let ParamValue::Literal(s) = self.params.swap_remove(0) { + SymbolType::Output => { + let name = if let ParamValue::LiteralStr(s) = self.params.swap_remove(0) { s.to_string() } else { - return Err(DeepCrowError::parse(Position::none(), "Expected string literal for output name.".into())); + return Err(CrimError::parse(Position::none(), "Expected string literal for output name.".into())); }; Ok(BuildResult::Output(Output { name: name, code: self.children.to_tokens(ctx)?, })) } - TokenType::Loop => { + SymbolType::Loop => { let id = if let ParamValue::Identifier(id) = self.params.swap_remove(0) { id } else { - return Err(DeepCrowError::parse( + return Err(CrimError::parse( Position::none(), "Identifier for loop variable name.".into()) ); @@ -701,24 +700,24 @@ impl<'a> TagBuilder<'a> { Token::Loop(id, self.children.to_tokens(ctx)?) )) } - TokenType::Show => { + SymbolType::Show => { let id = if let ParamValue::Identifier(id) = self.params.swap_remove(0) { id } else { - return Err(DeepCrowError::parse( + return Err(CrimError::parse( Position::none(), "Identifier for show variable name.".into()) ); }; Ok(BuildResult::Token(Token::Show(id, self.props))) } - TokenType::If => { + SymbolType::If => { let id = if let ParamValue::Identifier(id) = self.params.swap_remove(0) { id } else { - return Err(DeepCrowError::parse( + return Err(CrimError::parse( Position::none(), "Identifier for if variable name.".into()) ); @@ -726,7 +725,7 @@ impl<'a> TagBuilder<'a> { let is_else = if self.chain.len() == 1 && let Entry::TagBuilder(tb) = &self.chain[0] && - tb.is_name(&TokenType::Else) && + tb.is_name(&SymbolType::Else) && tb.params.len() == 0 { true } else { @@ -740,11 +739,11 @@ impl<'a> TagBuilder<'a> { } Ok(BuildResult::Token(Token::If(id, self.children.to_tokens(ctx)?, self.chain.to_tokens(ctx)?))) } - TokenType::ElIf => { + SymbolType::ElIf => { let id = if let ParamValue::Identifier(id) = self.params.swap_remove(0) { id } else { - return Err(DeepCrowError::parse( + return Err(CrimError::parse( Position::none(), "Identifier for elif variable name.".into()) ); @@ -755,7 +754,7 @@ impl<'a> TagBuilder<'a> { // ...but I can't do that right now. let is_else = if self.chain.len() == 1 && let Entry::TagBuilder(tb) = &self.chain[0] && - tb.is_name(&TokenType::Else) && + tb.is_name(&SymbolType::Else) && tb.params.len() == 0 { true } else { @@ -771,15 +770,15 @@ impl<'a> TagBuilder<'a> { Ok(BuildResult::Token(Token::If(id, self.children.to_tokens(ctx)?, self.chain.to_tokens(ctx)?))) } - TokenType::Else => { + SymbolType::Else => { Ok(BuildResult::Token(Token::If(Identifier::new(), self.children.to_tokens(ctx)?, self.chain.to_tokens(ctx)?))) } _ => { - Err(DeepCrowError::parse( self.start_pos(), "Bad tag type".into())) + Err(CrimError::parse( self.start_pos(), "Bad tag type".into())) } } } else { - Err(DeepCrowError::parse(self.start_pos(), "Bad tag type".into())) + Err(CrimError::parse(self.start_pos(), "Bad tag type".into())) } } } -- cgit v1.2.3