diff options
| author | Mike Buland <mike@xagasoft.com> | 2026-06-11 10:43:24 -0700 |
|---|---|---|
| committer | Mike Buland <mike@xagasoft.com> | 2026-06-11 10:43:24 -0700 |
| commit | 92dbff3cda66a2a677f0c2306bb8508c64884445 (patch) | |
| tree | e0118f3a4f45b03558b878864c37d33384d736c8 /src/parser.rs | |
| parent | 887943e3f1908583d6888c8375f345b33b74fdb5 (diff) | |
| download | crimtag-92dbff3cda66a2a677f0c2306bb8508c64884445.tar.gz crimtag-92dbff3cda66a2a677f0c2306bb8508c64884445.tar.bz2 crimtag-92dbff3cda66a2a677f0c2306bb8508c64884445.tar.xz crimtag-92dbff3cda66a2a677f0c2306bb8508c64884445.zip | |
Broke out error and renamed it.
I like the new name, now it could be for all sorts.
Diffstat (limited to 'src/parser.rs')
| -rw-r--r-- | src/parser.rs | 221 |
1 files changed, 91 insertions, 130 deletions
diff --git a/src/parser.rs b/src/parser.rs index 07bbd93..83144fb 100644 --- a/src/parser.rs +++ b/src/parser.rs | |||
| @@ -1,41 +1,6 @@ | |||
| 1 | use crate::lexer::*; | 1 | use crate::lexer::*; |
| 2 | use crate::*; | 2 | use crate::*; |
| 3 | 3 | ||
| 4 | use core::error::Error; | ||
| 5 | use std::fmt; | ||
| 6 | |||
| 7 | #[derive(Debug)] | ||
| 8 | pub struct ParseError { | ||
| 9 | position: Position, | ||
| 10 | what: String, | ||
| 11 | } | ||
| 12 | |||
| 13 | impl ParseError { | ||
| 14 | pub fn new( position: Position, what: &str ) -> Self { | ||
| 15 | ParseError { | ||
| 16 | position, | ||
| 17 | what: what.to_string(), | ||
| 18 | } | ||
| 19 | } | ||
| 20 | |||
| 21 | pub fn eos( context: &str ) -> Self { | ||
| 22 | ParseError { | ||
| 23 | position: Position::none(), | ||
| 24 | what: format!("Premature end of stream while looking for {}", context), | ||
| 25 | } | ||
| 26 | } | ||
| 27 | } | ||
| 28 | |||
| 29 | impl fmt::Display for ParseError { | ||
| 30 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | ||
| 31 | write!(f, "Error parsing input: {}", "yeah") | ||
| 32 | } | ||
| 33 | } | ||
| 34 | |||
| 35 | impl Error for ParseError { } | ||
| 36 | |||
| 37 | pub type ParseResult<T> = Result<T, ParseError>; | ||
| 38 | |||
| 39 | struct Context<'a> { | 4 | struct Context<'a> { |
| 40 | cur: [Option<Symbol<'a>>;2], | 5 | cur: [Option<Symbol<'a>>;2], |
| 41 | icur: usize, | 6 | icur: usize, |
| @@ -70,9 +35,9 @@ impl<'a> Context<'a> { | |||
| 70 | self.cur[(self.icur+1)%2] | 35 | self.cur[(self.icur+1)%2] |
| 71 | } | 36 | } |
| 72 | 37 | ||
| 73 | pub fn check_unwrapped<T: Fn( &SymbolType, &SymbolType ) -> bool>(&self, context: &str, f: T) -> ParseResult<bool> { | 38 | pub fn check_unwrapped<T: Fn( &SymbolType, &SymbolType ) -> bool>(&self, context: &str, f: T) -> CrimResult<bool> { |
| 74 | if self.cur().is_none() || self.peek().is_none() { | 39 | if self.cur().is_none() || self.peek().is_none() { |
| 75 | Err(ParseError::eos( context )) | 40 | Err(CrimError::eos( context )) |
| 76 | } else { | 41 | } else { |
| 77 | Ok(f( self.cur().unwrap().symbol(), self.peek().unwrap().symbol())) | 42 | Ok(f( self.cur().unwrap().symbol(), self.peek().unwrap().symbol())) |
| 78 | } | 43 | } |
| @@ -84,34 +49,37 @@ impl<'a> Context<'a> { | |||
| 84 | } | 49 | } |
| 85 | 50 | ||
| 86 | trait SymbolHelper { | 51 | trait SymbolHelper { |
| 87 | fn is<T: Fn( &SymbolType ) -> bool>(&self, context: &str, f: T ) -> ParseResult<bool>; | 52 | fn is<T: Fn( &SymbolType ) -> bool>(&self, context: &str, f: T ) -> CrimResult<bool>; |
| 88 | fn is_valid_tag_name(&self) -> ParseResult<bool>; | 53 | fn is_valid_tag_name(&self) -> CrimResult<bool>; |
| 89 | } | 54 | } |
| 90 | 55 | ||
| 91 | impl<'a> SymbolHelper for Option<Symbol<'a>> { | 56 | impl<'a> SymbolHelper for Option<Symbol<'a>> { |
| 92 | fn is<T: Fn( &SymbolType ) -> bool>(&self, context: &str, f: T ) -> ParseResult<bool> { | 57 | fn is<T: Fn( &SymbolType ) -> bool>(&self, context: &str, f: T ) -> CrimResult<bool> { |
| 93 | if let Some(st) = self { | 58 | if let Some(st) = self { |
| 94 | Ok(f( &st.symbol() )) | 59 | Ok(f( &st.symbol() )) |
| 95 | } else { | 60 | } else { |
| 96 | Err(ParseError::eos( context )) | 61 | Err(CrimError::eos( context )) |
| 97 | } | 62 | } |
| 98 | } | 63 | } |
| 99 | 64 | ||
| 100 | fn is_valid_tag_name(&self) -> ParseResult<bool> { | 65 | fn is_valid_tag_name(&self) -> CrimResult<bool> { |
| 101 | if let Some(st) = self { | 66 | if let Some(st) = self { |
| 102 | Ok(match st.symbol() { | 67 | Ok(match st.symbol() { |
| 103 | SymbolType::Token(_) | | 68 | SymbolType::Token(_) | |
| 104 | SymbolType::View | | 69 | SymbolType::View | |
| 105 | SymbolType::Output | | 70 | SymbolType::Output | |
| 106 | SymbolType::Loop | | 71 | SymbolType::Loop | |
| 72 | SymbolType::If | | ||
| 73 | SymbolType::ElseIf | | ||
| 74 | SymbolType::Else | | ||
| 107 | SymbolType::Show => true, | 75 | SymbolType::Show => true, |
| 108 | _ => false | 76 | _ => false |
| 109 | }) | 77 | }) |
| 110 | } else { | 78 | } else { |
| 111 | Err(ParseError{ | 79 | Err(CrimError::new( |
| 112 | position: Position::new(0,0), | 80 | Position::none(), |
| 113 | what: "Unexpeceted end of stream.".to_string() | 81 | "Unexpeceted end of stream.".to_string() |
| 114 | }) | 82 | )) |
| 115 | } | 83 | } |
| 116 | } | 84 | } |
| 117 | } | 85 | } |
| @@ -202,21 +170,17 @@ impl Parser { | |||
| 202 | } | 170 | } |
| 203 | } | 171 | } |
| 204 | 172 | ||
| 205 | fn lex_error<T>(&self, error: &Symbol) -> ParseResult<T> { | 173 | fn lex_error<T>(&self, error: &Symbol) -> CrimResult<T> { |
| 206 | if let SymbolType::Error{what} = error.symbol() { | 174 | if let SymbolType::Error{what} = error.symbol() { |
| 207 | Err(ParseError { | 175 | Err(CrimError::new( *error.start(), |
| 208 | position: error.start().clone(), | 176 | format!("What: {:?}", *what) |
| 209 | what: format!("What: {:?}", *what) | 177 | )) |
| 210 | }) | ||
| 211 | } else { | 178 | } else { |
| 212 | Err(ParseError { | 179 | Err(CrimError::new( Position::none(), "Not an error?".into())) |
| 213 | position: Position::new(0,0), | ||
| 214 | what: "Not an error?".to_string(), | ||
| 215 | }) | ||
| 216 | } | 180 | } |
| 217 | } | 181 | } |
| 218 | 182 | ||
| 219 | pub fn parse(&self, src: &str, source: usize ) -> ParseResult<Vec<View>> { | 183 | pub fn parse(&self, src: &str, source: usize ) -> CrimResult<Vec<View>> { |
| 220 | let ll = Lexer::new( src ); | 184 | let ll = Lexer::new( src ); |
| 221 | let mut ctx = Context::new( ll, source ); | 185 | let mut ctx = Context::new( ll, source ); |
| 222 | 186 | ||
| @@ -224,7 +188,7 @@ impl Parser { | |||
| 224 | self.p_input( &mut ctx ) | 188 | self.p_input( &mut ctx ) |
| 225 | } | 189 | } |
| 226 | 190 | ||
| 227 | fn p_input(&self, ctx: &mut Context ) -> ParseResult<Vec<View>> { | 191 | fn p_input(&self, ctx: &mut Context ) -> CrimResult<Vec<View>> { |
| 228 | let mut children = Vec::new(); | 192 | let mut children = Vec::new(); |
| 229 | loop { | 193 | loop { |
| 230 | if ctx.cur().is_none() { | 194 | if ctx.cur().is_none() { |
| @@ -247,13 +211,12 @@ impl Parser { | |||
| 247 | Ok(children) | 211 | Ok(children) |
| 248 | } | 212 | } |
| 249 | 213 | ||
| 250 | fn parse_tag_view(&self, ctx: &mut Context) -> ParseResult<View> { | 214 | fn parse_tag_view(&self, ctx: &mut Context) -> CrimResult<View> { |
| 251 | let tb = self.parse_open_tag( ctx )?; | 215 | let tb = self.parse_open_tag( ctx )?; |
| 252 | if !tb.is_name( &SymbolType::View ) { | 216 | if !tb.is_name( &SymbolType::View ) { |
| 253 | return Err(ParseError{ | 217 | return Err(CrimError::new(tb.start_pos(), |
| 254 | position: tb.start_pos(), | 218 | "Unexpected tag type, only frament allowed at root".into() |
| 255 | what: "Unexpected tag type, only frament allowed at root".to_string(), | 219 | )); |
| 256 | }); | ||
| 257 | } | 220 | } |
| 258 | 221 | ||
| 259 | if tb.is_unary() { | 222 | if tb.is_unary() { |
| @@ -265,7 +228,7 @@ impl Parser { | |||
| 265 | //println!("--parse-tag-view-- tag parsed, next token: {:?}", ctx.cur() ); | 228 | //println!("--parse-tag-view-- tag parsed, next token: {:?}", ctx.cur() ); |
| 266 | loop { | 229 | loop { |
| 267 | if ctx.cur().is_none() { | 230 | if ctx.cur().is_none() { |
| 268 | return Err(ParseError::eos(format!("close tag for {:?}", tb.name()).as_str())) | 231 | return Err(CrimError::eos(format!("close tag for {:?}", tb.name()).as_str())) |
| 269 | } | 232 | } |
| 270 | match ctx.cur().unwrap().symbol() { | 233 | match ctx.cur().unwrap().symbol() { |
| 271 | SymbolType::Text(s) => { | 234 | SymbolType::Text(s) => { |
| @@ -297,52 +260,56 @@ impl Parser { | |||
| 297 | }); | 260 | }); |
| 298 | } else { | 261 | } else { |
| 299 | if !all_text { | 262 | if !all_text { |
| 300 | return Err(ParseError{ | 263 | return Err(CrimError::new( |
| 301 | position: *end.start(), | 264 | *end.start(), |
| 302 | what: "You cannot mix non-output and output tags in a view.".to_string() | 265 | "You cannot mix non-output and output tags in a view.".to_string() |
| 303 | }); | 266 | )); |
| 304 | } | 267 | } |
| 305 | } | 268 | } |
| 306 | return tb.build_view(ctx,outputs); | 269 | return tb.build_view(ctx,outputs); |
| 307 | } else { | 270 | } else { |
| 308 | // They don't match, complain. | 271 | // They don't match, complain. |
| 309 | return Err(ParseError{ | 272 | return Err(CrimError::new( |
| 310 | position: *end.start(), | 273 | *end.start(), |
| 311 | what: "Mismatched open and closing tags.".to_string() | 274 | "Mismatched open and closing tags.".to_string() |
| 312 | }); | 275 | )); |
| 313 | } | 276 | } |
| 314 | } | 277 | } |
| 315 | SymbolType::Error{..} => { | 278 | SymbolType::Error{..} => { |
| 316 | return self.lex_error( &ctx.cur().unwrap() ); | 279 | return self.lex_error( &ctx.cur().unwrap() ); |
| 317 | } | 280 | } |
| 318 | _ => { | 281 | _ => { |
| 319 | return Err(ParseError{ | 282 | return Err(CrimError::new( |
| 320 | position: *ctx.cur().unwrap().start(), | 283 | *ctx.cur().unwrap().start(), |
| 321 | what: format!("Unexpected tag in view root: {:?}", ctx.cur().unwrap().symbol()) | 284 | format!("Unexpected tag in view root: {:?}", ctx.cur().unwrap().symbol()) |
| 322 | }); | 285 | )); |
| 323 | } | 286 | } |
| 324 | } | 287 | } |
| 325 | } | 288 | } |
| 326 | } | 289 | } |
| 327 | 290 | ||
| 328 | fn parse_open_tag<'a>(&self, ctx: &mut Context<'a>) -> ParseResult<TagBuilder<'a>> { | 291 | fn parse_open_tag<'a>(&self, ctx: &mut Context<'a>) -> CrimResult<TagBuilder<'a>> { |
| 329 | let start_sym = ctx.cur().unwrap(); | 292 | let start_sym = ctx.cur().unwrap(); |
| 330 | let mut tb = TagBuilder::new(&start_sym); | 293 | let mut tb = TagBuilder::new(&start_sym); |
| 331 | 294 | ||
| 332 | if ctx.next().is_some() { | 295 | if ctx.next().is_some() { |
| 333 | match ctx.cur().unwrap().symbol() { | 296 | match ctx.cur().unwrap().symbol() { |
| 334 | SymbolType::View | SymbolType::Show | SymbolType::Loop | | 297 | SymbolType::View | SymbolType::Show | SymbolType::Loop | |
| 298 | SymbolType::If | SymbolType::ElseIf | SymbolType::Else | | ||
| 335 | SymbolType::Output => { | 299 | SymbolType::Output => { |
| 336 | let name_sym = ctx.cur().unwrap(); | 300 | let name_sym = ctx.cur().unwrap(); |
| 337 | ctx.next(); | 301 | ctx.next(); |
| 338 | tb.set_name( name_sym ); | 302 | tb.set_name( name_sym ); |
| 339 | } | 303 | } |
| 340 | _ => { | 304 | _ => { |
| 341 | return Err(ParseError{position: ctx.cur().unwrap().start().clone(), what: "Unexpected symbol".to_string()}); | 305 | return Err(CrimError::new( |
| 306 | *ctx.cur().unwrap().start(), | ||
| 307 | "Unexpected symbol".to_string() | ||
| 308 | )); | ||
| 342 | } | 309 | } |
| 343 | } | 310 | } |
| 344 | } else { | 311 | } else { |
| 345 | return Err(ParseError::eos("tag type")); | 312 | return Err(CrimError::eos("tag type")); |
| 346 | } | 313 | } |
| 347 | 314 | ||
| 348 | self.parse_tag_params( ctx, &mut tb )?; | 315 | self.parse_tag_params( ctx, &mut tb )?; |
| @@ -357,9 +324,9 @@ impl Parser { | |||
| 357 | tb.set_type( TagType::Unary ); | 324 | tb.set_type( TagType::Unary ); |
| 358 | } | 325 | } |
| 359 | _ => { | 326 | _ => { |
| 360 | return Err(ParseError::new( | 327 | return Err(CrimError::new( |
| 361 | end_sym.start().clone(), | 328 | *end_sym.start(), |
| 362 | format!("Unexpected symbol {:?} looking for end of tag.", end_sym.symbol()).as_str() | 329 | format!("Unexpected symbol {:?} looking for end of tag.", end_sym.symbol()) |
| 363 | )); | 330 | )); |
| 364 | } | 331 | } |
| 365 | } | 332 | } |
| @@ -370,31 +337,31 @@ impl Parser { | |||
| 370 | Ok(tb) | 337 | Ok(tb) |
| 371 | } | 338 | } |
| 372 | 339 | ||
| 373 | fn parse_end_tag<'a>(&self, ctx: &mut Context<'a> ) -> ParseResult<Symbol<'a>> { | 340 | fn parse_end_tag<'a>(&self, ctx: &mut Context<'a> ) -> CrimResult<Symbol<'a>> { |
| 374 | if !ctx.cur().is("end tag",|s| *s == SymbolType::StartPoint )? { | 341 | if !ctx.cur().is("end tag",|s| *s == SymbolType::StartPoint )? { |
| 375 | return Err(ParseError{ | 342 | return Err(CrimError::new( |
| 376 | position: *ctx.cur().unwrap().start(), | 343 | *ctx.cur().unwrap().start(), |
| 377 | what: "Invalid end tag?".to_string(), | 344 | "Invalid end tag?".to_string() |
| 378 | }); | 345 | )); |
| 379 | } | 346 | } |
| 380 | if !ctx.next().is_valid_tag_name()? { | 347 | if !ctx.next().is_valid_tag_name()? { |
| 381 | return Err(ParseError{ | 348 | return Err(CrimError::new( |
| 382 | position: *ctx.cur().unwrap().start(), | 349 | *ctx.cur().unwrap().start(), |
| 383 | what: "Invalid tag name".to_string(), | 350 | "Invalid tag name".to_string() |
| 384 | }); | 351 | )); |
| 385 | } | 352 | } |
| 386 | let name = ctx.cur().unwrap(); | 353 | let name = ctx.cur().unwrap(); |
| 387 | if !ctx.next().is("end of end tag", |s| *s == SymbolType::EndFlat )? { | 354 | if !ctx.next().is("end of end tag", |s| *s == SymbolType::EndFlat )? { |
| 388 | return Err(ParseError{ | 355 | return Err(CrimError::new( |
| 389 | position: *ctx.cur().unwrap().start(), | 356 | *ctx.cur().unwrap().start(), |
| 390 | what: "Tag should be <| |] style end tag.".to_string(), | 357 | "Tag should be <| |] style end tag.".to_string(), |
| 391 | }); | 358 | )); |
| 392 | } | 359 | } |
| 393 | ctx.next(); | 360 | ctx.next(); |
| 394 | Ok(name) | 361 | Ok(name) |
| 395 | } | 362 | } |
| 396 | 363 | ||
| 397 | fn parse_tag_body<'a>(&self, ctx: &mut Context<'a> ) -> ParseResult<TagBuilder<'a>> { | 364 | fn parse_tag_body<'a>(&self, ctx: &mut Context<'a> ) -> CrimResult<TagBuilder<'a>> { |
| 398 | let mut tb = self.parse_open_tag( ctx )?; | 365 | let mut tb = self.parse_open_tag( ctx )?; |
| 399 | if tb.is_unary() { | 366 | if tb.is_unary() { |
| 400 | return Ok(tb); | 367 | return Ok(tb); |
| @@ -402,7 +369,7 @@ impl Parser { | |||
| 402 | 369 | ||
| 403 | loop { | 370 | loop { |
| 404 | if ctx.cur().is_none() { | 371 | if ctx.cur().is_none() { |
| 405 | return Err(ParseError::eos(format!("close tag for {:?}", tb.name()).as_str())); | 372 | return Err(CrimError::eos(format!("close tag for {:?}", tb.name()).as_str())); |
| 406 | } | 373 | } |
| 407 | match ctx.cur().unwrap().symbol() { | 374 | match ctx.cur().unwrap().symbol() { |
| 408 | SymbolType::Text(s) => { | 375 | SymbolType::Text(s) => { |
| @@ -419,29 +386,29 @@ impl Parser { | |||
| 419 | return Ok(tb); | 386 | return Ok(tb); |
| 420 | } else { | 387 | } else { |
| 421 | // They don't match, complain. | 388 | // They don't match, complain. |
| 422 | return Err(ParseError{ | 389 | return Err(CrimError::new( |
| 423 | position: *end.start(), | 390 | *end.start(), |
| 424 | what: "Mismatched open and closing tags.".to_string() | 391 | "Mismatched open and closing tags.".to_string() |
| 425 | }); | 392 | )); |
| 426 | } | 393 | } |
| 427 | } | 394 | } |
| 428 | SymbolType::Error{..} => { | 395 | SymbolType::Error{..} => { |
| 429 | return self.lex_error( &ctx.cur().unwrap() ); | 396 | return self.lex_error( &ctx.cur().unwrap() ); |
| 430 | } | 397 | } |
| 431 | _ => { | 398 | _ => { |
| 432 | return Err(ParseError{ | 399 | return Err(CrimError::new( |
| 433 | position: ctx.cur().unwrap().start().clone(), | 400 | *ctx.cur().unwrap().start(), |
| 434 | what: format!("Unexpected token: {:?}", ctx.cur().unwrap().symbol()), | 401 | format!("Unexpected token: {:?}", ctx.cur().unwrap().symbol()), |
| 435 | }); | 402 | )); |
| 436 | } | 403 | } |
| 437 | } | 404 | } |
| 438 | } | 405 | } |
| 439 | } | 406 | } |
| 440 | 407 | ||
| 441 | fn parse_tag_params(&self, ctx: &mut Context, tb: &mut TagBuilder ) -> ParseResult<()> { | 408 | fn parse_tag_params(&self, ctx: &mut Context, tb: &mut TagBuilder ) -> CrimResult<()> { |
| 442 | loop { | 409 | loop { |
| 443 | if ctx.cur().is_none() { | 410 | if ctx.cur().is_none() { |
| 444 | return Err(ParseError::eos("tag parameters")); | 411 | return Err(CrimError::eos("tag parameters")); |
| 445 | } | 412 | } |
| 446 | match ctx.cur().unwrap().symbol() { | 413 | match ctx.cur().unwrap().symbol() { |
| 447 | SymbolType::Literal(s) => { | 414 | SymbolType::Literal(s) => { |
| @@ -462,7 +429,7 @@ impl Parser { | |||
| 462 | Ok(()) | 429 | Ok(()) |
| 463 | } | 430 | } |
| 464 | 431 | ||
| 465 | fn parse_identifier(&self, ctx: &mut Context ) -> ParseResult<ParamValue> { | 432 | fn parse_identifier(&self, ctx: &mut Context ) -> CrimResult<ParamValue> { |
| 466 | let mut id = Identifier::new(); | 433 | let mut id = Identifier::new(); |
| 467 | 434 | ||
| 468 | loop { | 435 | loop { |
| @@ -471,7 +438,7 @@ impl Parser { | |||
| 471 | id.push( IdentifierValue::Name(s.to_string()) ); | 438 | id.push( IdentifierValue::Name(s.to_string()) ); |
| 472 | } | 439 | } |
| 473 | } else { | 440 | } else { |
| 474 | return Err(ParseError::new( ctx.cur().unwrap().start().clone(), &format!("Expeceted identifier, found {:?}", ctx.cur().unwrap().symbol() ) ) ); | 441 | return Err(CrimError::new( ctx.cur().unwrap().start().clone(), format!("Expeceted identifier, found {:?}", ctx.cur().unwrap().symbol() ) ) ); |
| 475 | } | 442 | } |
| 476 | 443 | ||
| 477 | if !ctx.next().is("identifier seperator",|s| *s == SymbolType::Period )? { | 444 | if !ctx.next().is("identifier seperator",|s| *s == SymbolType::Period )? { |
| @@ -483,10 +450,10 @@ impl Parser { | |||
| 483 | Ok(ParamValue::Identifier(id)) | 450 | Ok(ParamValue::Identifier(id)) |
| 484 | } | 451 | } |
| 485 | 452 | ||
| 486 | fn parse_tag_props(&self, ctx: &mut Context, tb: &mut TagBuilder ) -> ParseResult<()> { | 453 | fn parse_tag_props(&self, ctx: &mut Context, tb: &mut TagBuilder ) -> CrimResult<()> { |
| 487 | loop { | 454 | loop { |
| 488 | if ctx.cur().is_none() { | 455 | if ctx.cur().is_none() { |
| 489 | return Err(ParseError::eos("tag properties")); | 456 | return Err(CrimError::eos("tag properties")); |
| 490 | } | 457 | } |
| 491 | if let SymbolType::Token(s) = ctx.cur().unwrap().symbol() { | 458 | if let SymbolType::Token(s) = ctx.cur().unwrap().symbol() { |
| 492 | if ctx.peek().is_some_and(|s|s.check_type(|t| matches!(t,SymbolType::Equals))) { | 459 | if ctx.peek().is_some_and(|s|s.check_type(|t| matches!(t,SymbolType::Equals))) { |
| @@ -495,7 +462,7 @@ impl Parser { | |||
| 495 | let SymbolType::Literal(lv) = sym.symbol() { | 462 | let SymbolType::Literal(lv) = sym.symbol() { |
| 496 | tb.add_prop( s.to_string(), lv.to_string() ); | 463 | tb.add_prop( s.to_string(), lv.to_string() ); |
| 497 | } else { | 464 | } else { |
| 498 | return Err(ParseError{position: Position::new(0,0), what: "Expected quoted literal string".to_string()}); | 465 | return Err(CrimError::new(Position::none(),"Expected quoted literal string".to_string())); |
| 499 | } | 466 | } |
| 500 | } else { | 467 | } else { |
| 501 | break; | 468 | break; |
| @@ -607,13 +574,13 @@ impl<'a> TagBuilder<'a> { | |||
| 607 | self.tag_type | 574 | self.tag_type |
| 608 | } | 575 | } |
| 609 | 576 | ||
| 610 | pub fn build_view(mut self, ctx: &Context, outputs: Vec<Output>) -> ParseResult<View> { | 577 | pub fn build_view(mut self, ctx: &Context, outputs: Vec<Output>) -> CrimResult<View> { |
| 611 | if let Some(sym) = self.name { | 578 | if let Some(sym) = self.name { |
| 612 | if *sym.symbol() == SymbolType::View { | 579 | if *sym.symbol() == SymbolType::View { |
| 613 | let name = if let ParamValue::Literal(s) = self.params.swap_remove(0) { | 580 | let name = if let ParamValue::Literal(s) = self.params.swap_remove(0) { |
| 614 | s.to_string() | 581 | s.to_string() |
| 615 | } else { | 582 | } else { |
| 616 | return Err(ParseError::new(Position::none(), "Expected string literal for view name.")); | 583 | return Err(CrimError::new(Position::none(), "Expected string literal for view name.".to_string())); |
| 617 | }; | 584 | }; |
| 618 | Ok(View { | 585 | Ok(View { |
| 619 | name: name, | 586 | name: name, |
| @@ -623,41 +590,41 @@ impl<'a> TagBuilder<'a> { | |||
| 623 | layout: self.props.get("layout").cloned(), | 590 | layout: self.props.get("layout").cloned(), |
| 624 | }) | 591 | }) |
| 625 | } else { | 592 | } else { |
| 626 | Err(ParseError::new(self.start_pos, &format!("Expected tag type view, found {:?}", sym.symbol()))) | 593 | Err(CrimError::new(self.start_pos, format!("Expected tag type view, found {:?}", sym.symbol()))) |
| 627 | } | 594 | } |
| 628 | } else { | 595 | } else { |
| 629 | Err(ParseError::new(self.start_pos, "Broken Parser? No tag type found when building view.")) | 596 | Err(CrimError::new(self.start_pos, "Broken Parser? No tag type found when building view.".to_string())) |
| 630 | } | 597 | } |
| 631 | } | 598 | } |
| 632 | 599 | ||
| 633 | pub fn build_output(mut self) -> ParseResult<Output> { | 600 | pub fn build_output(mut self) -> CrimResult<Output> { |
| 634 | if let Some(sym) = self.name { | 601 | if let Some(sym) = self.name { |
| 635 | if *sym.symbol() == SymbolType::Output { | 602 | if *sym.symbol() == SymbolType::Output { |
| 636 | let name = if let ParamValue::Literal(s) = self.params.swap_remove(0) { | 603 | let name = if let ParamValue::Literal(s) = self.params.swap_remove(0) { |
| 637 | s.to_string() | 604 | s.to_string() |
| 638 | } else { | 605 | } else { |
| 639 | return Err(ParseError::new(Position::none(), "Expected string literal for output name.")); | 606 | return Err(CrimError::new(Position::none(), "Expected string literal for output name.".into())); |
| 640 | }; | 607 | }; |
| 641 | Ok(Output { | 608 | Ok(Output { |
| 642 | name: name, | 609 | name: name, |
| 643 | code: self.children, | 610 | code: self.children, |
| 644 | }) | 611 | }) |
| 645 | } else { | 612 | } else { |
| 646 | Err(ParseError::new(self.start_pos, &format!("Expected tag type view, found {:?}", sym.symbol()))) | 613 | Err(CrimError::new(self.start_pos, format!("Expected tag type view, found {:?}", sym.symbol()))) |
| 647 | } | 614 | } |
| 648 | } else { | 615 | } else { |
| 649 | Err(ParseError::new(self.start_pos, "Broken Parser? No tag type found when building view.")) | 616 | Err(CrimError::new(self.start_pos, "Broken Parser? No tag type found when building view.".into())) |
| 650 | } | 617 | } |
| 651 | } | 618 | } |
| 652 | 619 | ||
| 653 | pub fn build(mut self) -> ParseResult<Token> { | 620 | pub fn build(mut self) -> CrimResult<Token> { |
| 654 | if let Some(sym) = self.name { | 621 | if let Some(sym) = self.name { |
| 655 | match sym.symbol() { | 622 | match sym.symbol() { |
| 656 | SymbolType::Loop => { | 623 | SymbolType::Loop => { |
| 657 | let id = if let ParamValue::Identifier(id) = self.params.swap_remove(0) { | 624 | let id = if let ParamValue::Identifier(id) = self.params.swap_remove(0) { |
| 658 | id | 625 | id |
| 659 | } else { | 626 | } else { |
| 660 | return Err(ParseError::new(Position::none(), "Identifier for loop variable name.")); | 627 | return Err(CrimError::new(Position::none(), "Identifier for loop variable name.".into())); |
| 661 | }; | 628 | }; |
| 662 | Ok(Token::Loop(id, self.children)) | 629 | Ok(Token::Loop(id, self.children)) |
| 663 | } | 630 | } |
| @@ -665,22 +632,16 @@ impl<'a> TagBuilder<'a> { | |||
| 665 | let id = if let ParamValue::Identifier(id) = self.params.swap_remove(0) { | 632 | let id = if let ParamValue::Identifier(id) = self.params.swap_remove(0) { |
| 666 | id | 633 | id |
| 667 | } else { | 634 | } else { |
| 668 | return Err(ParseError::new(Position::none(), "Identifier for show variable name.")); | 635 | return Err(CrimError::new(Position::none(), "Identifier for show variable name.".into())); |
| 669 | }; | 636 | }; |
| 670 | Ok(Token::Show(id, self.props)) | 637 | Ok(Token::Show(id, self.props)) |
| 671 | } | 638 | } |
| 672 | _ => { | 639 | _ => { |
| 673 | Err(ParseError { | 640 | Err(CrimError::new( self.start_pos, "Bad tag type".into())) |
| 674 | position: self.start_pos, | ||
| 675 | what: "Bad tag type".to_string(), | ||
| 676 | }) | ||
| 677 | } | 641 | } |
| 678 | } | 642 | } |
| 679 | } else { | 643 | } else { |
| 680 | Err(ParseError { | 644 | Err(CrimError::new(self.start_pos, "Bad tag type".into())) |
| 681 | position: self.start_pos, | ||
| 682 | what: "Bad tag type".to_string(), | ||
| 683 | }) | ||
| 684 | } | 645 | } |
| 685 | } | 646 | } |
| 686 | } | 647 | } |
