use std::str::FromStr; use ast::{self, WithLocation}; grammar; pub Program: ast::Program = { Expression => ast::Program(<>), }; VarDec: Box> = "var" "=" => Box::new(WithLocation::new(ast::VarDec::new(name, None, exp), l, r)); DeclarationsList: Vec> = { => { let mut h = h; h.push(*t); h }, => vec![*<>], }; Expression: Box> = { "&&" => Box::new(e1.join_map(*e2, |v1, v2| { ast::Expression::BinOp(ast::BinOp::And, Box::new(v1), Box::new(v2)) })), "||" => Box::new(e1.join_map(*e2, |v1, v2| { ast::Expression::BinOp(ast::BinOp::Or, Box::new(v1), Box::new(v2)) })), "!" => Box::new(WithLocation::new( ast::Expression::UnaryOp(ast::UnaryOp::Not, e), l, r )), => <>, }; ExpressionEq: Box> = { "=" => Box::new(e1.join_map(*e2, |v1, v2| { ast::Expression::BinOp(ast::BinOp::Eq, Box::new(v1), Box::new(v2)) })), "!=" => Box::new(e1.join_map(*e2, |v1, v2| { ast::Expression::BinOp(ast::BinOp::Neq, Box::new(v1), Box::new(v2)) })), => <>, }; ExpressionCmp: Box> = { ">" => Box::new(e1.join_map(*e2, |v1, v2| { ast::Expression::BinOp(ast::BinOp::Gt, Box::new(v1), Box::new(v2)) })), "<" => Box::new(e1.join_map(*e2, |v1, v2| { ast::Expression::BinOp(ast::BinOp::Lt, Box::new(v1), Box::new(v2)) })), ">=" => Box::new(e1.join_map(*e2, |v1, v2| { ast::Expression::BinOp(ast::BinOp::Ge, Box::new(v1), Box::new(v2)) })), "<=" => Box::new(e1.join_map(*e2, |v1, v2| { ast::Expression::BinOp(ast::BinOp::Le, Box::new(v1), Box::new(v2)) })), => <>, }; ExpressionAdd: Box> = { "+" => Box::new(e1.join_map(*e2, |v1, v2| { ast::Expression::BinOp(ast::BinOp::Add, Box::new(v1), Box::new(v2)) })), "-" => Box::new(e1.join_map(*e2, |v1, v2| { ast::Expression::BinOp(ast::BinOp::Sub, Box::new(v1), Box::new(v2)) })), => <>, }; ExpressionMul: Box> = { "*" => Box::new(e1.join_map(*e2, |v1, v2| { ast::Expression::BinOp(ast::BinOp::Mul, Box::new(v1), Box::new(v2)) })), "/" => Box::new(e1.join_map(*e2, |v1, v2| { ast::Expression::BinOp(ast::BinOp::Div, Box::new(v1), Box::new(v2)) })), "//" => Box::new(e1.join_map(*e2, |v1, v2| { ast::Expression::BinOp(ast::BinOp::FloorDiv, Box::new(v1), Box::new(v2)) })), => <>, }; ExpressionSign: Box> = { "+" => Box::new(WithLocation::new( ast::Expression::UnaryOp(ast::UnaryOp::Pos, e), l, r )), "-" => Box::new(WithLocation::new( ast::Expression::UnaryOp(ast::UnaryOp::Neg, e), l, r )), => <>, }; ExpressionBase: Box> = { Num => Box::new(<>.map(|v| ast::Expression::Number(v))), String => Box::new(<>.map(|v| ast::Expression::String(v))), Name => Box::new(<>.map(|v| ast::Expression::Name(v))), Spanned => Box::new(<>.map(|v| ast::Expression::Nil)), "let" "in" "end" => Box::new(WithLocation::new(ast::Expression::Let(d, e), l, r)), "(" ")" => <>, }; Name: WithLocation = > => e.map(|v| v.to_owned()); Num: WithLocation = > => e.map(|v| u64::from_str(v).unwrap()); String: WithLocation = => { WithLocation::new(v[1..v.len() - 1].to_owned(), l, r) }; Spanned: WithLocation = { => WithLocation::new(v, l, r) }; match { "nil", "var", "let", "in", "end", } else { r"[[:alpha:]_][[:alpha:]_0-9]*", } else { _, }