From cffacc4dc4a46b525250772e87fd69a2f1c64dc2 Mon Sep 17 00:00:00 2001 From: Mike Buland Date: Thu, 11 Jun 2026 11:35:24 -0700 Subject: Split things out, made things easier to use. CrimError now has several constructors for different cases, so it's easier to use, using constructors is normalized now. Value has a load of From implementations now so it's much, much, much easier to use in practice. --- src/parser.rs | 60 ++++++++++++++++++++++++++++++----------------------------- 1 file changed, 31 insertions(+), 29 deletions(-) (limited to 'src/parser.rs') diff --git a/src/parser.rs b/src/parser.rs index 83144fb..be5492c 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -76,7 +76,7 @@ impl<'a> SymbolHelper for Option> { _ => false }) } else { - Err(CrimError::new( + Err(CrimError::parse( Position::none(), "Unexpeceted end of stream.".to_string() )) @@ -172,11 +172,11 @@ impl Parser { fn lex_error(&self, error: &Symbol) -> CrimResult { if let SymbolType::Error{what} = error.symbol() { - Err(CrimError::new( *error.start(), + Err(CrimError::parse( *error.start(), format!("What: {:?}", *what) )) } else { - Err(CrimError::new( Position::none(), "Not an error?".into())) + Err(CrimError::parse( Position::none(), "Not an error?".into())) } } @@ -214,7 +214,7 @@ impl Parser { fn parse_tag_view(&self, ctx: &mut Context) -> CrimResult { let tb = self.parse_open_tag( ctx )?; if !tb.is_name( &SymbolType::View ) { - return Err(CrimError::new(tb.start_pos(), + return Err(CrimError::parse(tb.start_pos(), "Unexpected tag type, only frament allowed at root".into() )); } @@ -260,7 +260,7 @@ impl Parser { }); } else { if !all_text { - return Err(CrimError::new( + return Err(CrimError::parse( *end.start(), "You cannot mix non-output and output tags in a view.".to_string() )); @@ -269,7 +269,7 @@ impl Parser { return tb.build_view(ctx,outputs); } else { // They don't match, complain. - return Err(CrimError::new( + return Err(CrimError::parse( *end.start(), "Mismatched open and closing tags.".to_string() )); @@ -279,7 +279,7 @@ impl Parser { return self.lex_error( &ctx.cur().unwrap() ); } _ => { - return Err(CrimError::new( + return Err(CrimError::parse( *ctx.cur().unwrap().start(), format!("Unexpected tag in view root: {:?}", ctx.cur().unwrap().symbol()) )); @@ -302,7 +302,7 @@ impl Parser { tb.set_name( name_sym ); } _ => { - return Err(CrimError::new( + return Err(CrimError::parse( *ctx.cur().unwrap().start(), "Unexpected symbol".to_string() )); @@ -318,13 +318,13 @@ impl Parser { if let Some(end_sym) = ctx.cur() { match end_sym.symbol() { SymbolType::EndPoint => { - tb.set_type( TagType::BinaryOpen ); + tb.set_type( TagType::MultinaryOpen ); } SymbolType::EndFlat => { tb.set_type( TagType::Unary ); } _ => { - return Err(CrimError::new( + return Err(CrimError::parse( *end_sym.start(), format!("Unexpected symbol {:?} looking for end of tag.", end_sym.symbol()) )); @@ -339,20 +339,20 @@ impl Parser { fn parse_end_tag<'a>(&self, ctx: &mut Context<'a> ) -> CrimResult> { if !ctx.cur().is("end tag",|s| *s == SymbolType::StartPoint )? { - return Err(CrimError::new( + return Err(CrimError::parse( *ctx.cur().unwrap().start(), "Invalid end tag?".to_string() )); } if !ctx.next().is_valid_tag_name()? { - return Err(CrimError::new( + return Err(CrimError::parse( *ctx.cur().unwrap().start(), "Invalid tag name".to_string() )); } let name = ctx.cur().unwrap(); if !ctx.next().is("end of end tag", |s| *s == SymbolType::EndFlat )? { - return Err(CrimError::new( + return Err(CrimError::parse( *ctx.cur().unwrap().start(), "Tag should be <| |] style end tag.".to_string(), )); @@ -386,7 +386,7 @@ impl Parser { return Ok(tb); } else { // They don't match, complain. - return Err(CrimError::new( + return Err(CrimError::parse( *end.start(), "Mismatched open and closing tags.".to_string() )); @@ -396,7 +396,7 @@ impl Parser { return self.lex_error( &ctx.cur().unwrap() ); } _ => { - return Err(CrimError::new( + return Err(CrimError::parse( *ctx.cur().unwrap().start(), format!("Unexpected token: {:?}", ctx.cur().unwrap().symbol()), )); @@ -438,7 +438,7 @@ impl Parser { id.push( IdentifierValue::Name(s.to_string()) ); } } else { - return Err(CrimError::new( 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 == SymbolType::Period )? { @@ -462,7 +462,7 @@ impl Parser { let SymbolType::Literal(lv) = sym.symbol() { tb.add_prop( s.to_string(), lv.to_string() ); } else { - return Err(CrimError::new(Position::none(),"Expected quoted literal string".to_string())); + return Err(CrimError::parse(Position::none(),"Expected quoted literal string".to_string())); } } else { break; @@ -480,7 +480,8 @@ impl Parser { enum TagType { Unknown, Unary, - BinaryOpen, + MultinaryOpen, + MultinaryMid, } struct TagBuilder<'a> { @@ -523,7 +524,8 @@ impl<'a> TagBuilder<'a> { } pub fn can_have_children(&self) -> bool { - if self.tag_type == TagType::BinaryOpen { + if self.tag_type == TagType::MultinaryOpen || + self.tag_type == TagType::MultinaryMid { true } else { false @@ -580,7 +582,7 @@ impl<'a> TagBuilder<'a> { let name = if let ParamValue::Literal(s) = self.params.swap_remove(0) { s.to_string() } else { - return Err(CrimError::new(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(View { name: name, @@ -590,10 +592,10 @@ impl<'a> TagBuilder<'a> { layout: self.props.get("layout").cloned(), }) } else { - Err(CrimError::new(self.start_pos, format!("Expected tag type view, found {:?}", sym.symbol()))) + Err(CrimError::parse(self.start_pos, format!("Expected tag type view, found {:?}", sym.symbol()))) } } else { - Err(CrimError::new(self.start_pos, "Broken Parser? No tag type found when building view.".to_string())) + Err(CrimError::parse(self.start_pos, "Broken Parser? No tag type found when building view.".to_string())) } } @@ -603,17 +605,17 @@ impl<'a> TagBuilder<'a> { let name = if let ParamValue::Literal(s) = self.params.swap_remove(0) { s.to_string() } else { - return Err(CrimError::new(Position::none(), "Expected string literal for output name.".into())); + return Err(CrimError::parse(Position::none(), "Expected string literal for output name.".into())); }; Ok(Output { name: name, code: self.children, }) } else { - Err(CrimError::new(self.start_pos, format!("Expected tag type view, found {:?}", sym.symbol()))) + Err(CrimError::parse(self.start_pos, format!("Expected tag type view, found {:?}", sym.symbol()))) } } else { - Err(CrimError::new(self.start_pos, "Broken Parser? No tag type found when building view.".into())) + Err(CrimError::parse(self.start_pos, "Broken Parser? No tag type found when building view.".into())) } } @@ -624,7 +626,7 @@ impl<'a> TagBuilder<'a> { let id = if let ParamValue::Identifier(id) = self.params.swap_remove(0) { id } else { - return Err(CrimError::new(Position::none(), "Identifier for loop variable name.".into())); + return Err(CrimError::parse(Position::none(), "Identifier for loop variable name.".into())); }; Ok(Token::Loop(id, self.children)) } @@ -632,16 +634,16 @@ impl<'a> TagBuilder<'a> { let id = if let ParamValue::Identifier(id) = self.params.swap_remove(0) { id } else { - return Err(CrimError::new(Position::none(), "Identifier for show variable name.".into())); + return Err(CrimError::parse(Position::none(), "Identifier for show variable name.".into())); }; Ok(Token::Show(id, self.props)) } _ => { - Err(CrimError::new( self.start_pos, "Bad tag type".into())) + Err(CrimError::parse( self.start_pos, "Bad tag type".into())) } } } else { - Err(CrimError::new(self.start_pos, "Bad tag type".into())) + Err(CrimError::parse(self.start_pos, "Bad tag type".into())) } } } -- cgit v1.2.3