diff options
Diffstat (limited to 'src/parser.rs')
| -rw-r--r-- | src/parser.rs | 65 |
1 files changed, 56 insertions, 9 deletions
diff --git a/src/parser.rs b/src/parser.rs index 297230c..5f53557 100644 --- a/src/parser.rs +++ b/src/parser.rs | |||
| @@ -274,7 +274,7 @@ impl Parser { | |||
| 274 | SymbolType::StartFlat => { | 274 | SymbolType::StartFlat => { |
| 275 | let subtb = self.parse_tag_body( ctx )?; | 275 | let subtb = self.parse_tag_body( ctx )?; |
| 276 | if subtb.is_name(&SymbolType::Output) { | 276 | if subtb.is_name(&SymbolType::Output) { |
| 277 | outputs.push(subtb.build_output(ctx)?); | 277 | outputs.push(subtb.build_output()?); |
| 278 | } else { | 278 | } else { |
| 279 | children.push(subtb.build()?); | 279 | children.push(subtb.build()?); |
| 280 | } | 280 | } |
| @@ -437,16 +437,43 @@ impl Parser { | |||
| 437 | } | 437 | } |
| 438 | match ctx.cur().unwrap().symbol() { | 438 | match ctx.cur().unwrap().symbol() { |
| 439 | SymbolType::Literal(s) => { | 439 | SymbolType::Literal(s) => { |
| 440 | tb.add_param( s.to_string() ); | 440 | tb.add_param( ParamValue::Literal(s.to_string()) ); |
| 441 | ctx.next(); | ||
| 442 | } | ||
| 443 | SymbolType::Token(_) => { | ||
| 444 | if ctx.peek().is("tag data", |s| *s == SymbolType::Equals)? { | ||
| 445 | break; | ||
| 446 | } | ||
| 447 | tb.add_param( self.parse_identifier( ctx )? ); | ||
| 441 | } | 448 | } |
| 442 | _ => { | 449 | _ => { |
| 443 | break; | 450 | break; |
| 444 | } | 451 | } |
| 445 | } | 452 | } |
| 446 | ctx.next(); | ||
| 447 | } | 453 | } |
| 448 | Ok(()) | 454 | Ok(()) |
| 449 | } | 455 | } |
| 456 | |||
| 457 | fn parse_identifier(&self, ctx: &mut Context ) -> ParseResult<ParamValue> { | ||
| 458 | let mut id = Identifier::new(); | ||
| 459 | |||
| 460 | loop { | ||
| 461 | if ctx.cur().is("identifier",|s| matches!( s, SymbolType::Token(_) ))? { | ||
| 462 | if let SymbolType::Token(s) = ctx.cur().unwrap().symbol() { | ||
| 463 | id.push( IdentifierValue::Name(s.to_string()) ); | ||
| 464 | } | ||
| 465 | } else { | ||
| 466 | return Err(ParseError::new( ctx.cur().unwrap().start().clone(), &format!("Expeceted identifier, found {:?}", ctx.cur().unwrap().symbol() ) ) ); | ||
| 467 | } | ||
| 468 | |||
| 469 | if !ctx.next().is("identifier seperator",|s| *s == SymbolType::Period )? { | ||
| 470 | break; | ||
| 471 | } | ||
| 472 | ctx.next(); | ||
| 473 | } | ||
| 474 | |||
| 475 | Ok(ParamValue::Identifier(id)) | ||
| 476 | } | ||
| 450 | 477 | ||
| 451 | fn parse_tag_props(&self, ctx: &mut Context, tb: &mut TagBuilder ) -> ParseResult<()> { | 478 | fn parse_tag_props(&self, ctx: &mut Context, tb: &mut TagBuilder ) -> ParseResult<()> { |
| 452 | loop { | 479 | loop { |
| @@ -483,13 +510,18 @@ enum TagType { | |||
| 483 | 510 | ||
| 484 | struct TagBuilder<'a> { | 511 | struct TagBuilder<'a> { |
| 485 | name: Option<Symbol<'a>>, | 512 | name: Option<Symbol<'a>>, |
| 486 | params: Vec<String>, | 513 | params: Vec<ParamValue>, |
| 487 | props: Properties, | 514 | props: Properties, |
| 488 | children: Vec<Token>, | 515 | children: Vec<Token>, |
| 489 | tag_type: TagType, | 516 | tag_type: TagType, |
| 490 | start_pos: Position, | 517 | start_pos: Position, |
| 491 | } | 518 | } |
| 492 | 519 | ||
| 520 | enum ParamValue { | ||
| 521 | Literal(String), | ||
| 522 | Identifier(Identifier), | ||
| 523 | } | ||
| 524 | |||
| 493 | impl<'a> TagBuilder<'a> { | 525 | impl<'a> TagBuilder<'a> { |
| 494 | pub fn new(start: &Symbol) -> TagBuilder<'a> { | 526 | pub fn new(start: &Symbol) -> TagBuilder<'a> { |
| 495 | TagBuilder { | 527 | TagBuilder { |
| @@ -538,7 +570,7 @@ impl<'a> TagBuilder<'a> { | |||
| 538 | self.name = Some(name); | 570 | self.name = Some(name); |
| 539 | } | 571 | } |
| 540 | 572 | ||
| 541 | pub fn add_param(&mut self, param: String) { | 573 | pub fn add_param(&mut self, param: ParamValue) { |
| 542 | self.params.push( param ); | 574 | self.params.push( param ); |
| 543 | } | 575 | } |
| 544 | 576 | ||
| @@ -565,8 +597,13 @@ impl<'a> TagBuilder<'a> { | |||
| 565 | pub fn build_view(mut self, ctx: &Context, outputs: Vec<Output>) -> ParseResult<View> { | 597 | pub fn build_view(mut self, ctx: &Context, outputs: Vec<Output>) -> ParseResult<View> { |
| 566 | if let Some(sym) = self.name { | 598 | if let Some(sym) = self.name { |
| 567 | if *sym.symbol() == SymbolType::View { | 599 | if *sym.symbol() == SymbolType::View { |
| 600 | let name = if let ParamValue::Literal(s) = self.params.swap_remove(0) { | ||
| 601 | s.to_string() | ||
| 602 | } else { | ||
| 603 | return Err(ParseError::new(Position::none(), "Expected string literal for view name.")); | ||
| 604 | }; | ||
| 568 | Ok(View { | 605 | Ok(View { |
| 569 | name: self.params.swap_remove(0), | 606 | name: name, |
| 570 | source: ctx.source(), | 607 | source: ctx.source(), |
| 571 | outputs: outputs, | 608 | outputs: outputs, |
| 572 | //theme: Option<String> | 609 | //theme: Option<String> |
| @@ -580,11 +617,16 @@ impl<'a> TagBuilder<'a> { | |||
| 580 | } | 617 | } |
| 581 | } | 618 | } |
| 582 | 619 | ||
| 583 | pub fn build_output(mut self, ctx: &Context) -> ParseResult<Output> { | 620 | pub fn build_output(mut self) -> ParseResult<Output> { |
| 584 | if let Some(sym) = self.name { | 621 | if let Some(sym) = self.name { |
| 585 | if *sym.symbol() == SymbolType::Output { | 622 | if *sym.symbol() == SymbolType::Output { |
| 623 | let name = if let ParamValue::Literal(s) = self.params.swap_remove(0) { | ||
| 624 | s.to_string() | ||
| 625 | } else { | ||
| 626 | return Err(ParseError::new(Position::none(), "Expected string literal for output name.")); | ||
| 627 | }; | ||
| 586 | Ok(Output { | 628 | Ok(Output { |
| 587 | name: self.params.swap_remove(0), | 629 | name: name, |
| 588 | code: self.children, | 630 | code: self.children, |
| 589 | }) | 631 | }) |
| 590 | } else { | 632 | } else { |
| @@ -599,7 +641,12 @@ impl<'a> TagBuilder<'a> { | |||
| 599 | if let Some(sym) = self.name { | 641 | if let Some(sym) = self.name { |
| 600 | match sym.symbol() { | 642 | match sym.symbol() { |
| 601 | SymbolType::Show => { | 643 | SymbolType::Show => { |
| 602 | Ok(Token::Show(self.params.swap_remove(0), self.props)) | 644 | let id = if let ParamValue::Identifier(id) = self.params.swap_remove(0) { |
| 645 | id | ||
| 646 | } else { | ||
| 647 | return Err(ParseError::new(Position::none(), "Identifier for show variable name.")); | ||
| 648 | }; | ||
| 649 | Ok(Token::Show(id, self.props)) | ||
| 603 | } | 650 | } |
| 604 | _ => { | 651 | _ => { |
| 605 | Err(ParseError { | 652 | Err(ParseError { |
