From 61b54e8f6b177f33a1428ab6a3622503a63cc1d6 Mon Sep 17 00:00:00 2001 From: Mike Buland Date: Tue, 9 Jun 2026 14:02:53 -0700 Subject: Identifiers work! --- src/parser.rs | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 56 insertions(+), 9 deletions(-) (limited to 'src/parser.rs') 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 { SymbolType::StartFlat => { let subtb = self.parse_tag_body( ctx )?; if subtb.is_name(&SymbolType::Output) { - outputs.push(subtb.build_output(ctx)?); + outputs.push(subtb.build_output()?); } else { children.push(subtb.build()?); } @@ -437,16 +437,43 @@ impl Parser { } match ctx.cur().unwrap().symbol() { SymbolType::Literal(s) => { - tb.add_param( s.to_string() ); + tb.add_param( ParamValue::Literal(s.to_string()) ); + ctx.next(); + } + SymbolType::Token(_) => { + if ctx.peek().is("tag data", |s| *s == SymbolType::Equals)? { + break; + } + tb.add_param( self.parse_identifier( ctx )? ); } _ => { break; } } - ctx.next(); } Ok(()) } + + fn parse_identifier(&self, ctx: &mut Context ) -> ParseResult { + let mut id = Identifier::new(); + + loop { + 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(ParseError::new( ctx.cur().unwrap().start().clone(), &format!("Expeceted identifier, found {:?}", ctx.cur().unwrap().symbol() ) ) ); + } + + if !ctx.next().is("identifier seperator",|s| *s == SymbolType::Period )? { + break; + } + ctx.next(); + } + + Ok(ParamValue::Identifier(id)) + } fn parse_tag_props(&self, ctx: &mut Context, tb: &mut TagBuilder ) -> ParseResult<()> { loop { @@ -483,13 +510,18 @@ enum TagType { struct TagBuilder<'a> { name: Option>, - params: Vec, + params: Vec, props: Properties, children: Vec, tag_type: TagType, start_pos: Position, } +enum ParamValue { + Literal(String), + Identifier(Identifier), +} + impl<'a> TagBuilder<'a> { pub fn new(start: &Symbol) -> TagBuilder<'a> { TagBuilder { @@ -538,7 +570,7 @@ impl<'a> TagBuilder<'a> { self.name = Some(name); } - pub fn add_param(&mut self, param: String) { + pub fn add_param(&mut self, param: ParamValue) { self.params.push( param ); } @@ -565,8 +597,13 @@ impl<'a> TagBuilder<'a> { pub fn build_view(mut self, ctx: &Context, outputs: Vec) -> ParseResult { if let Some(sym) = self.name { if *sym.symbol() == SymbolType::View { + let name = if let ParamValue::Literal(s) = self.params.swap_remove(0) { + s.to_string() + } else { + return Err(ParseError::new(Position::none(), "Expected string literal for view name.")); + }; Ok(View { - name: self.params.swap_remove(0), + name: name, source: ctx.source(), outputs: outputs, //theme: Option @@ -580,11 +617,16 @@ impl<'a> TagBuilder<'a> { } } - pub fn build_output(mut self, ctx: &Context) -> ParseResult { + pub fn build_output(mut self) -> ParseResult { if let Some(sym) = self.name { if *sym.symbol() == SymbolType::Output { + let name = if let ParamValue::Literal(s) = self.params.swap_remove(0) { + s.to_string() + } else { + return Err(ParseError::new(Position::none(), "Expected string literal for output name.")); + }; Ok(Output { - name: self.params.swap_remove(0), + name: name, code: self.children, }) } else { @@ -599,7 +641,12 @@ impl<'a> TagBuilder<'a> { if let Some(sym) = self.name { match sym.symbol() { SymbolType::Show => { - Ok(Token::Show(self.params.swap_remove(0), self.props)) + let id = if let ParamValue::Identifier(id) = self.params.swap_remove(0) { + id + } else { + return Err(ParseError::new(Position::none(), "Identifier for show variable name.")); + }; + Ok(Token::Show(id, self.props)) } _ => { Err(ParseError { -- cgit v1.2.3