From 421eefb494c5451d3b21a4ddd9066affc772d870 Mon Sep 17 00:00:00 2001 From: Dennis Ranke Date: Sun, 31 Oct 2021 20:49:46 +0100 Subject: [PATCH] parse trainride as well --- src/parser2.rs | 71 +++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 68 insertions(+), 3 deletions(-) diff --git a/src/parser2.rs b/src/parser2.rs index d3ff216..485169d 100644 --- a/src/parser2.rs +++ b/src/parser2.rs @@ -17,6 +17,7 @@ enum Token { BranchIf, Defer, As, + Select, Ident(String), Str(String), Int(i32), @@ -39,6 +40,7 @@ impl fmt::Display for Token { Token::BranchIf => write!(f, "branch_if"), Token::Defer => write!(f, "defer"), Token::As => write!(f, "as"), + Token::Select => write!(f, "select"), Token::Ident(s) => write!(f, "{}", s), Token::Str(s) => write!(f, "{:?}", s), Token::Int(v) => write!(f, "{}", v), @@ -189,6 +191,7 @@ fn lexer() -> impl Parser, Error = Simple> { "branch_if" => Token::BranchIf, "defer" => Token::Defer, "as" => Token::As, + "select" => Token::Select, _ => Token::Ident(ident), }); @@ -326,6 +329,10 @@ mod ast { condition: Box, label: String, }, + UnaryOp { + op: UnaryOp, + value: Box, + }, BinOp { op: BinOp, left: Box, @@ -361,6 +368,11 @@ mod ast { } } + #[derive(Debug, Clone, Copy)] + pub enum UnaryOp { + Negate, + } + #[derive(Debug, Clone, Copy)] pub enum BinOp { Add, @@ -481,13 +493,41 @@ fn block_parser() -> impl Parser> + Clo value: Box::new(value), }); + let select = just(Token::Select) + .ignore_then( + expression + .clone() + .then_ignore(just(Token::Ctrl(','))) + .then(expression.clone()) + .then_ignore(just(Token::Ctrl(','))) + .then(expression.clone()) + .delimited_by(Token::Ctrl('('), Token::Ctrl(')')), + ) + .map(|((condition, if_true), if_false)| ast::Expr::Select { + condition: Box::new(condition), + if_true: Box::new(if_true), + if_false: Box::new(if_false), + }); + + let function_call = ident + .clone() + .then( + expression + .clone() + .separated_by(just(Token::Ctrl(','))) + .delimited_by(Token::Ctrl('('), Token::Ctrl(')')), + ) + .map(|(name, params)| ast::Expr::FuncCall { name, params }); + let atom = val .or(tee) + .or(function_call) .or(variable) .or(local_tee) .or(loop_expr) .or(branch_if) .or(let_) + .or(select) .map_with_span(|expr, span| expr.with_span(span)) .or(expression .clone() @@ -499,7 +539,23 @@ fn block_parser() -> impl Parser> + Clo |span| ast::Expr::Error.with_span(span), )); - let op_cast = atom + let unary_op = just(Token::Op("-".to_string())) + .to(ast::UnaryOp::Negate) + .map_with_span(|op, span| (op, span)) + .repeated() + .then(atom) + .map(|(ops, value)| { + ops.into_iter().rev().fold(value, |acc, (op, span)| { + let span = span.start..acc.span.end; + ast::Expr::UnaryOp { + op, + value: Box::new(acc), + } + .with_span(span) + }) + }); + + let op_cast = unary_op .clone() .then( just(Token::As) @@ -709,7 +765,7 @@ fn top_level_item_parser() -> impl Parser impl Parser impl Parser> + Clone {