85 lines
1.9 KiB
Rust
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 }
|
|
}
|
|
}
|