1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
//! The concrete syntax tree. //! //! Note that `Decl` and `Expr` both impl `FromStr`; hence they can be parsed //! with a simple `.parse()` call: //! //! ``` //! # use evaltrees::ast::{Literal, Op, Pattern}; //! # use evaltrees::cst::{Decl, Expr}; //! # fn main() { //! let expr: Expr = "(1 + 2) :: 3 :: []".parse().unwrap(); //! assert_eq!(expr, Expr::Op(Op::Cons, //! Box::new(Expr::Op(Op::Add, //! Box::new(Expr::Literal(Literal::Int(1))), //! Box::new(Expr::Literal(Literal::Int(2))), //! )), //! Box::new(Expr::Op(Op::Cons, //! Box::new(Expr::Literal(Literal::Int(3))), //! Box::new(Expr::Literal(Literal::Nil)), //! )), //! )); //! //! let decl: Decl = "id x = x".parse().unwrap(); //! assert_eq!(decl, Decl { //! name: "id".into(), //! args: vec![ //! Pattern::Binding("x".into(), ()), //! ], //! body: Expr::Variable("x".into()), //! }); //! # } //! ``` mod display; mod parser; use symbol::Symbol; use ast::{Literal, Op, Pattern}; pub use cst::parser::parse_decls; /// A function or value declaration. #[derive(Clone, Debug, PartialEq)] pub struct Decl { /// The name of the function or value. pub name: Symbol, /// The arguments to the function. If empty, the decl is for a value. pub args: Vec<Pattern<()>>, /// The body of the function, or the expression assigned to the value. pub body: Expr, } /// An expression. #[derive(Clone, Debug, PartialEq)] pub enum Expr { /// A conditional expression. If(Box<Expr>, Box<Expr>, Box<Expr>), /// A list. /// /// In theory, this can't be empty (since that'd be the nil literal). /// Either way, one should handle all cases. List(Vec<Expr>), /// A literal value. Literal(Literal), /// A binary operation. Op(Op, Box<Expr>, Box<Expr>), /// A variable. Variable(Symbol), }