use crate::parse::{PestPair, Rule as PestRule}; use std::str::FromStr; #[derive(Clone, Debug, Eq, Hash, PartialEq)] pub struct Span<'a> { pub slice: &'a str, pub line: usize, pub column: usize, } impl<'a> From> for Span<'a> { fn from(other: pest::Span<'a>) -> Self { let slice = other.as_str(); let (line, column) = other.start_pos().line_col(); Self { slice, line, column, } } } #[derive(Clone, Debug, Eq, Hash, PartialEq)] pub struct BranchBody<'a> { pub statements: Vec>, pub tail_expr: Option>>, } pub type ExprPair<'a> = Box<(Expr<'a>, Expr<'a>)>; #[derive(Clone, Debug, Eq, Hash, PartialEq)] pub enum Expr<'a> { BinaryOp(BinaryOp, ExprPair<'a>), Literal(Literal<'a>), Local(Span<'a>), } #[derive(Clone, Debug, Eq, Hash, PartialEq)] pub enum BinaryOp { Add, } impl FromStr for BinaryOp { type Err = (); fn from_str(s: &str) -> Result { use BinaryOp::*; match s { "+" => Ok(Add), _ => Err(()), } } } impl<'a> From> for BinaryOp { fn from(other: PestPair<'a>) -> Self { assert_eq!(other.as_rule(), PestRule::binary_op); let span = other.as_span().as_str(); Self::from_str(span).unwrap() } } #[derive(Clone, Debug, Eq, Hash, PartialEq)] pub enum Literal<'a> { DecimalInteger(Span<'a>), } #[derive(Clone, Debug, Eq, Hash, PartialEq)] pub enum Statement<'a> { Let { ident: Ident<'a>, expr: Expr<'a> }, } #[derive(Clone, Debug, Eq, Hash, PartialEq)] pub struct Ident<'a> { pub span: Span<'a>, } impl<'a> From> for Ident<'a> { fn from(other: PestPair<'a>) -> Self { assert_eq!(other.as_rule(), PestRule::identifier); let span = other.as_span().into(); Self { span } } }