dust-bunny/src/ast.rs

85 lines
1.9 KiB
Rust

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<pest::Span<'a>> 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<Statement<'a>>,
pub tail_expr: Option<Box<Expr<'a>>>,
}
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<Self, Self::Err> {
use BinaryOp::*;
match s {
"+" => Ok(Add),
_ => Err(()),
}
}
}
impl<'a> From<PestPair<'a>> 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<PestPair<'a>> for Ident<'a> {
fn from(other: PestPair<'a>) -> Self {
assert_eq!(other.as_rule(), PestRule::identifier);
let span = other.as_span().into();
Self { span }
}
}