add Expr type for union of BoolExpr or NumExpr
This commit is contained in:
parent
7c81b30a8f
commit
6632e897ba
6 changed files with 32 additions and 22 deletions
|
|
@ -17,7 +17,7 @@ use crate::{ArgusResult, Error};
|
||||||
|
|
||||||
/// All expressions that are numeric
|
/// All expressions that are numeric
|
||||||
#[derive(Clone, Debug, PartialEq, argus_derive::NumExpr)]
|
#[derive(Clone, Debug, PartialEq, argus_derive::NumExpr)]
|
||||||
#[enum_dispatch(Expr)]
|
#[enum_dispatch(AnyExpr)]
|
||||||
pub enum NumExpr {
|
pub enum NumExpr {
|
||||||
/// A signed integer literal
|
/// A signed integer literal
|
||||||
IntLit(IntLit),
|
IntLit(IntLit),
|
||||||
|
|
@ -54,7 +54,7 @@ impl NumExpr {
|
||||||
|
|
||||||
/// All expressions that are evaluated to be of type `bool`
|
/// All expressions that are evaluated to be of type `bool`
|
||||||
#[derive(Clone, Debug, PartialEq, argus_derive::BoolExpr)]
|
#[derive(Clone, Debug, PartialEq, argus_derive::BoolExpr)]
|
||||||
#[enum_dispatch(Expr)]
|
#[enum_dispatch(AnyExpr)]
|
||||||
pub enum BoolExpr {
|
pub enum BoolExpr {
|
||||||
/// A `bool` literal
|
/// A `bool` literal
|
||||||
BoolLit(BoolLit),
|
BoolLit(BoolLit),
|
||||||
|
|
@ -118,6 +118,15 @@ pub enum ExprRef<'a> {
|
||||||
Num(&'a NumExpr),
|
Num(&'a NumExpr),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// An expression (either [`BoolExpr`] or [`NumExpr`])
|
||||||
|
#[derive(Clone, Debug, derive_more::From)]
|
||||||
|
pub enum Expr {
|
||||||
|
/// A reference to a [`BoolExpr`]
|
||||||
|
Bool(BoolExpr),
|
||||||
|
/// A reference to a [`NumExpr`]
|
||||||
|
Num(NumExpr),
|
||||||
|
}
|
||||||
|
|
||||||
/// Expression builder
|
/// Expression builder
|
||||||
///
|
///
|
||||||
/// The `ExprBuilder` is a factory structure that deals with the creation of
|
/// The `ExprBuilder` is a factory structure that deals with the creation of
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
use std::ops::{Bound, RangeBounds};
|
use std::ops::{Bound, RangeBounds};
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
use super::{BoolExpr, Expr, NumExpr};
|
use super::{AnyExpr, BoolExpr, NumExpr};
|
||||||
|
|
||||||
/// Types of comparison operations
|
/// Types of comparison operations
|
||||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||||
|
|
@ -142,7 +142,7 @@ where
|
||||||
// TODO(anand): Can I implement this within argus_derive?
|
// TODO(anand): Can I implement this within argus_derive?
|
||||||
macro_rules! impl_bool_expr {
|
macro_rules! impl_bool_expr {
|
||||||
($ty:ty$(, $($arg:ident),* )? ) => {
|
($ty:ty$(, $($arg:ident),* )? ) => {
|
||||||
impl Expr for $ty {
|
impl AnyExpr for $ty {
|
||||||
fn is_numeric(&self) -> bool {
|
fn is_numeric(&self) -> bool {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
@ -157,7 +157,7 @@ macro_rules! impl_bool_expr {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
($ty:ty, [$args:ident]) => {
|
($ty:ty, [$args:ident]) => {
|
||||||
impl Expr for $ty {
|
impl AnyExpr for $ty {
|
||||||
fn is_numeric(&self) -> bool {
|
fn is_numeric(&self) -> bool {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,19 +2,19 @@
|
||||||
|
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
|
|
||||||
use super::{Expr, ExprRef};
|
use super::{AnyExpr, ExprRef};
|
||||||
|
|
||||||
/// Iterator that starts from some root [`Expr`] and travels down to it's leaf
|
/// Iterator that starts from some root [`AnyExpr`] and travels down to it's leaf
|
||||||
/// expressions.
|
/// expressions.
|
||||||
///
|
///
|
||||||
/// This essentially implements breadth-first search over the expression tree rooted at
|
/// This essentially implements breadth-first search over the expression tree rooted at
|
||||||
/// the given [`Expr`].
|
/// the given [`AnyExpr`].
|
||||||
pub struct AstIter<'a> {
|
pub struct AstIter<'a> {
|
||||||
queue: VecDeque<ExprRef<'a>>,
|
queue: VecDeque<ExprRef<'a>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> AstIter<'a> {
|
impl<'a> AstIter<'a> {
|
||||||
/// Create an iterator that traverses an [`Expr`] from root to leaf.
|
/// Create an iterator that traverses an [`AnyExpr`] from root to leaf.
|
||||||
pub fn new(root: ExprRef<'a>) -> Self {
|
pub fn new(root: ExprRef<'a>) -> Self {
|
||||||
let mut queue = VecDeque::new();
|
let mut queue = VecDeque::new();
|
||||||
queue.push_back(root);
|
queue.push_back(root);
|
||||||
|
|
@ -28,7 +28,7 @@ impl<'a> Iterator for AstIter<'a> {
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
let expr_ref = self.queue.pop_front()?;
|
let expr_ref = self.queue.pop_front()?;
|
||||||
|
|
||||||
let expr: &dyn Expr = match expr_ref {
|
let expr: &dyn AnyExpr = match expr_ref {
|
||||||
ExprRef::Bool(expr) => expr,
|
ExprRef::Bool(expr) => expr,
|
||||||
ExprRef::Num(expr) => expr,
|
ExprRef::Num(expr) => expr,
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
//! Numeric expression types
|
//! Numeric expression types
|
||||||
|
|
||||||
use super::{Expr, NumExpr};
|
use super::{AnyExpr, NumExpr};
|
||||||
|
|
||||||
// TODO(anand): Can I implement this within argus_derive?
|
// TODO(anand): Can I implement this within argus_derive?
|
||||||
macro_rules! impl_num_expr {
|
macro_rules! impl_num_expr {
|
||||||
($ty:ty$(, $($arg:ident),* )? ) => {
|
($ty:ty$(, $($arg:ident),* )? ) => {
|
||||||
impl Expr for $ty {
|
impl AnyExpr for $ty {
|
||||||
fn is_numeric(&self) -> bool {
|
fn is_numeric(&self) -> bool {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
@ -20,7 +20,7 @@ macro_rules! impl_num_expr {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
($ty:ty, [$args:ident]) => {
|
($ty:ty, [$args:ident]) => {
|
||||||
impl Expr for $ty {
|
impl AnyExpr for $ty {
|
||||||
fn is_numeric(&self) -> bool {
|
fn is_numeric(&self) -> bool {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ use super::{BoolExpr, ExprRef, NumExpr};
|
||||||
|
|
||||||
/// A trait representing expressions
|
/// A trait representing expressions
|
||||||
#[enum_dispatch]
|
#[enum_dispatch]
|
||||||
pub trait Expr {
|
pub trait AnyExpr {
|
||||||
/// Check if the given expression is a numeric expression
|
/// Check if the given expression is a numeric expression
|
||||||
fn is_numeric(&self) -> bool;
|
fn is_numeric(&self) -> bool;
|
||||||
/// Check if the given expression is a boolean expression
|
/// Check if the given expression is a boolean expression
|
||||||
|
|
@ -17,7 +17,7 @@ pub trait Expr {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Marker trait for numeric expressions
|
/// Marker trait for numeric expressions
|
||||||
pub trait IsNumExpr: Expr + Into<NumExpr> {}
|
pub trait IsNumExpr: AnyExpr + Into<NumExpr> {}
|
||||||
|
|
||||||
/// Marker trait for Boolean expressions
|
/// Marker trait for Boolean expressions
|
||||||
pub trait IsBoolExpr: Expr + Into<BoolExpr> {}
|
pub trait IsBoolExpr: AnyExpr + Into<BoolExpr> {}
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,19 @@
|
||||||
use std::{env, fmt, fs};
|
use std::{env, fmt, fs};
|
||||||
|
|
||||||
use ariadne::{sources, Color, Label, Report, ReportKind};
|
use ariadne::{sources, Color, Label, Report, ReportKind};
|
||||||
use chumsky::{input::SpannedInput, prelude::*};
|
use chumsky::input::SpannedInput;
|
||||||
|
use chumsky::prelude::*;
|
||||||
|
|
||||||
use crate::lexer::{lexer, Span, Token};
|
use crate::lexer::{lexer, Error as LexError, Span, Token};
|
||||||
|
|
||||||
pub type Spanned<T> = (T, Span);
|
pub type Spanned<T> = (T, Span);
|
||||||
|
|
||||||
// The type of the input that our parser operates on. The input is the `&[(Token, Span)]` token buffer generated by the
|
// The type of the input that our parser operates on. The input is the `&[(Token,
|
||||||
// lexer, wrapped in a `SpannedInput` which 'splits' it apart into its constituent parts, tokens and spans, for chumsky
|
// Span)]` token buffer generated by the lexer, wrapped in a `SpannedInput` which
|
||||||
|
// 'splits' it apart into its constituent parts, tokens and spans, for chumsky
|
||||||
// to understand.
|
// to understand.
|
||||||
type ParserInput<'tokens, 'src> = SpannedInput<Token<'src>, Span, &'tokens [(Token<'src>, Span)]>;
|
type ParserInput<'tokens, 'src> = SpannedInput<Token<'src>, Span, &'tokens [(Token<'src>, Span)]>;
|
||||||
|
|
||||||
pub fn parser<'tokens, 'src: 'tokens>(
|
pub fn parser<'tokens, 'src: 'tokens>(
|
||||||
) -> impl Parser<'tokens, ParserInput<'tokens, 'src>, Spanned<Expr<'src>>, extra::Err<Rich<'tokens, Token<'src>, Span>>>
|
) -> impl Parser<'tokens, ParserInput<'tokens, 'src>, Spanned<Expr<'src>>, LexError<'src>> + Clone {
|
||||||
+ Clone {
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue