wagon_parser/parser/
expression.rs1use std::{fmt::Display, write};
2
3use crate::firstpass::{GetReqAttributes, ReqAttributes, RewriteToSynth};
4
5use super::{Parse, LexerBridge, ParseResult, Tokens, WagParseError, SpannableNode, ResultPeek, ResultNext};
6use wagon_lexer::math::Math;
7
8use wagon_macros::match_error;
9use super::disjunct::Disjunct;
10
11use wagon_macros::new_unspanned;
12
13#[derive(PartialEq, Debug, Eq, Hash, Clone)]
14#[new_unspanned]
15pub enum Expression {
24 Subproc(SpannableNode<String>),
26 If {
28 this: SpannableNode<Disjunct>,
30 then: SpannableNode<Disjunct>,
32 r#else: Option<Box<SpannableNode<Expression>>>
34 },
35 Disjunct(SpannableNode<Disjunct>),
37}
38
39impl Parse for Expression {
40
41 fn parse(lexer: &mut LexerBridge) -> ParseResult<Self> {
42 match lexer.peek_result()? {
43 Tokens::MathToken(Math::If) => {lexer.next(); Self::parse_if(lexer)},
44 Tokens::MathToken(Math::Bash(_)) => Ok(Self::Subproc(SpannableNode::parse(lexer)?)),
45 _ => Ok(Self::Disjunct(SpannableNode::parse(lexer)?))
46 }
47 }
48}
49
50impl Expression {
51
52 fn parse_if(lexer: &mut LexerBridge) -> ParseResult<Self> {
53 let this = SpannableNode::parse(lexer)?;
54 let then = match_error!(match lexer.next_result()? {
55 Tokens::MathToken(Math::Then) => SpannableNode::parse(lexer)
56 })?;
57 let r#else = match lexer.peek_result()? {
58 Tokens::MathToken(Math::Else) => {lexer.next(); Some(Box::new(SpannableNode::parse(lexer)?))},
59 _ => None
60 };
61 Ok(Self::If { this, then, r#else })
62 }
63}
64
65impl RewriteToSynth for Expression {
66 fn rewrite_to_synth(&mut self) -> ReqAttributes {
67 match self {
68 Self::Subproc(_) => ReqAttributes::new(),
69 Self::If { this, then, r#else } => {
70 let mut req = this.rewrite_to_synth();
71 req.extend(then.rewrite_to_synth());
72 if let Some(cont) = r#else {
73 req.extend(cont.node.rewrite_to_synth());
74 }
75 req
76 },
77 Self::Disjunct(d) => d.rewrite_to_synth(),
78 }
79 }
80}
81
82impl GetReqAttributes for Expression {
83 fn get_req_attributes(&self) -> ReqAttributes {
84 match self {
85 Self::Subproc(_) => ReqAttributes::new(),
86 Self::If { this, then, r#else } => {
87 let mut req = this.get_req_attributes();
88 req.extend(then.get_req_attributes());
89 if let Some(cont) = r#else {
90 req.extend(cont.get_req_attributes());
91 }
92 req
93 },
94 Self::Disjunct(d) => d.get_req_attributes(),
95 }
96 }
97}
98
99impl Display for Expression {
100 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
101 match self {
102 Self::Subproc(s) => write!(f, "$({s})"),
103 Self::If { this, then, r#else } => {
104 if let Some(e) = r#else {
105 write!(f, "if {this} {{ {then} }} else {{ {e} }}")
106 } else {
107 write!(f, "if {this} {{ {then} }}")
108 }
109 },
110 Self::Disjunct(d) => write!(f, "{d}"),
111 }
112 }
113}