wagon_parser/parser/
factor.rs

1use std::fmt::Display;
2use std::write;
3use crate::firstpass::{GetReqAttributes, RewriteToSynth};
4
5use super::{Parse, LexerBridge, ParseResult, Tokens, SpannableNode, ResultPeek};
6use super::atom::Atom;
7use wagon_lexer::math::Math;
8
9use wagon_macros::new_unspanned;
10
11#[derive(PartialEq, Debug, Eq, Hash, Clone)]
12#[new_unspanned]
13/// A possible power equation, or just an [`Atom`].
14///
15/// # Grammar
16/// <code>[Factor] -> [Atom] ("**" Factor)?;</code>
17pub enum Factor {
18	/// Just an [`Atom`].
19	Primary(SpannableNode<Atom>),
20	/// A power equation
21	Power {
22		/// The left-hand side.
23		left: SpannableNode<Atom>,
24		/// Whatever to evaluate to the power to.
25		right: Box<SpannableNode<Factor>>
26	}
27}
28
29impl Parse for Factor {
30
31	fn parse(lexer: &mut LexerBridge) -> ParseResult<Self> {
32		let left = SpannableNode::parse(lexer)?;
33		if &Tokens::MathToken(Math::Pow) == lexer.peek_result()? {
34			lexer.next();
35			Ok(
36				Self::Power {
37					left, 
38					right: Box::new(SpannableNode::parse(lexer)?)
39				}
40			)
41		} else {
42			Ok(Self::Primary(left))
43		}
44	}
45}
46
47impl GetReqAttributes for Factor {
48    fn get_req_attributes(&self) -> crate::firstpass::ReqAttributes {
49        match self {
50            Self::Primary(p) => p.get_req_attributes(),
51            Self::Power { left, right } => {
52            	let mut req = left.get_req_attributes();
53            	req.extend(right.get_req_attributes());
54            	req
55            },
56        }
57    }
58}
59
60impl RewriteToSynth for Factor {
61    fn rewrite_to_synth(&mut self) -> crate::firstpass::ReqAttributes {
62        match self {
63            Self::Primary(p) => p.rewrite_to_synth(),
64            Self::Power { left, right } => {
65            	let mut req = left.rewrite_to_synth();
66            	req.extend(right.rewrite_to_synth());
67            	req
68            },
69        }
70    }
71}
72
73impl Display for Factor {
74    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
75        match self {
76            Self::Primary(p) => write!(f, "{p}"),
77            Self::Power { left, right } => write!(f, "{left}^{right}"),
78        }
79    }
80}