From c9889f7c6622def3b6badde2738c3e912b48144f Mon Sep 17 00:00:00 2001 From: Mike Buland Date: Thu, 11 Jun 2026 13:42:31 -0700 Subject: Basic if statements work. I need to tweak the parser to get mid-tags working, then we can have else, and maybe elif. After that is expressions. --- src/context.rs | 7 +++++++ src/lexer.rs | 4 ++-- src/lib.rs | 23 +++++++++++++++++++++-- src/parser.rs | 28 +++++++++++++++++++++++----- 4 files changed, 53 insertions(+), 9 deletions(-) diff --git a/src/context.rs b/src/context.rs index 78a7940..e4cd5c2 100644 --- a/src/context.rs +++ b/src/context.rs @@ -44,6 +44,7 @@ pub enum Value { String(String), Int(i64), Float(f64), + Bool(bool), Identifier(Identifier), } @@ -71,6 +72,12 @@ impl From for Value { } } +impl From for Value { + fn from(val: bool) -> Value { + Value::Bool(val) + } +} + impl From> for Value { fn from(val: Vec) -> Value { Value::List(val) diff --git a/src/lexer.rs b/src/lexer.rs index 2fa29ce..2bf7e9e 100644 --- a/src/lexer.rs +++ b/src/lexer.rs @@ -23,7 +23,7 @@ pub enum SymbolType<'a> { Equals, Period, If, - ElseIf, + ElIf, Else, Token(&'a str), Literal(&'a str), @@ -250,7 +250,7 @@ impl<'a> Lexer<'a> { "output" => SymbolType::Output, "loop" => SymbolType::Loop, "if" => SymbolType::If, - "elseif" => SymbolType::ElseIf, + "elif" => SymbolType::ElIf, "else" => SymbolType::Else, _ => SymbolType::Token(s) }, start_pos, end_pos )) diff --git a/src/lib.rs b/src/lib.rs index b0bc688..8c91686 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -65,7 +65,7 @@ enum Token { Loop(Identifier, Vec), Show(Identifier,Properties), If(Identifier, Vec), - ElseIf(Identifier, Vec), + ElIf(Identifier, Vec), Else(Vec), Text(String), } @@ -205,6 +205,14 @@ fn exec(input: &impl MappedStructure, tokens: &Vec, buf: &mut String) -> } } } + Token::If(ident,code) => { + if let Some(value) = input.get_value( &ident ) && + let Value::Bool(b) = value && + b { + + exec(input, code, buf)? + } + } Token::Show(ident,p) => { let format = if let Some(s) = p.get("format") { s @@ -219,6 +227,13 @@ fn exec(input: &impl MappedStructure, tokens: &Vec, buf: &mut String) -> Value::List(_) => { buf.push_str(""); } + Value::Bool(b) => { + if b { + buf.push_str("true"); + } else { + buf.push_str("false"); + } + } Value::String(s) => { buf.push_str(s.as_str()); } @@ -313,7 +328,7 @@ Now with explicit outputs: let mut ct = Crimtag::new(); if let Err(e) = ct.load_static(r#"Looping code: [|view "index"|>We will enumerate people here:[|loop people|> - - [|show last_name|], [|show first_name|]: [|show title|] [|loop tags|> [|show tag|]<|loop|] <|loop|] + - [|show last_name|], [|show first_name|][|if show_title |>: [|show title|] <|if|] [|loop tags|> [|show tag|]<|loop|] <|loop|] <|view|] "#) { println!("Error: {:?}", e ); @@ -325,21 +340,25 @@ Now with explicit outputs: [ ("first_name".into(), "Joe".into()), ("last_name".into(), "Smith".into()), + ("show_title".into(), true.into()), ("title".into(), "CEO".into()), ].into(), [ ("first_name".into(), "Chris".into()), ("last_name".into(), "Perkens".into()), + ("show_title".into(), false.into()), ("title".into(), "Baconeer".into()), ].into(), [ ("first_name".into(), "Will".into()), ("last_name".into(), "Power".into()), + ("show_title".into(), false.into()), ("title".into(), "CFO".into()), ].into(), [ ("first_name".into(), "Justin".into()), ("last_name".into(), "Time".into()), + ("show_title".into(), true.into()), ("title".into(), "CIO".into()), ].into(), ].into()), diff --git a/src/parser.rs b/src/parser.rs index be5492c..6ba6cfe 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -70,7 +70,7 @@ impl<'a> SymbolHelper for Option> { SymbolType::Output | SymbolType::Loop | SymbolType::If | - SymbolType::ElseIf | + SymbolType::ElIf | SymbolType::Else | SymbolType::Show => true, _ => false @@ -88,13 +88,23 @@ pub struct Parser { } /** - * input: input tag - * | input tag_pair + * input: input complete_tag * | input text * | * ; * - * tag: '[|' tag_guts '|]' + * tag: unary_tag + * | multinary_open_tag + * | multinary_mid_tag + * | multinary_close_tag + * ; + * + * unary_tag: '[|' tag_guts '|]' + * ; + * + * | '[|' tag_guts '|>' + * | '<|' tag_guts '|>' + * | '<|' tag_guts '|]' * ; * * tag_pair: open_tag tag_body close_tag @@ -295,7 +305,7 @@ impl Parser { if ctx.next().is_some() { match ctx.cur().unwrap().symbol() { SymbolType::View | SymbolType::Show | SymbolType::Loop | - SymbolType::If | SymbolType::ElseIf | SymbolType::Else | + SymbolType::If | SymbolType::ElIf | SymbolType::Else | SymbolType::Output => { let name_sym = ctx.cur().unwrap(); ctx.next(); @@ -638,6 +648,14 @@ impl<'a> TagBuilder<'a> { }; Ok(Token::Show(id, self.props)) } + SymbolType::If => { + let id = if let ParamValue::Identifier(id) = self.params.swap_remove(0) { + id + } else { + return Err(CrimError::parse(Position::none(), "Identifier for show variable name.".into())); + }; + Ok(Token::If(id, self.children)) + } _ => { Err(CrimError::parse( self.start_pos, "Bad tag type".into())) } -- cgit v1.2.3