wagon_parser/
lib.rs

1#![warn(missing_docs)]
2//! WAGon Parser
3//!
4//! A crate containing the [`Parser`] for the WAGon DSL as well as a checker and associated functions. 
5//! As long as you do not need any extensions to the WAGon DSL itself, this will likely be your main interface to the ecosystem. 
6//! After you have a parsed a full [`Wag`] tree, you can do with it whatever you require.
7
8/// The parser
9pub mod parser;
10/// The checker
11pub mod firstpass;
12
13use std::collections::BTreeMap;
14use std::fmt::Display;
15
16use firstpass::{GetReqAttributes, RewriteToSynth};
17use wagon_lexer::LexerBridge;
18use wagon_utils::{Span, Spannable};
19use crate::parser::{Parser, Parse, ParseResult, wag::Wag};
20use crate::firstpass::{FirstPassState, Rewrite};
21
22/// Parse an input string and check if the resulting WAG is valid.
23///
24/// Given the input string, will either return a full, rewritten, WAG or an error.
25///
26/// # Errors 
27/// Returns a [`WagParseError`](`crate::parser::WagParseError`) if any error occurs during the parsing or checking stage.
28pub fn parse_and_check(date: &str) -> ParseResult<Wag> {
29    let mut parser = Parser::new(date);
30    let mut wag = parser.parse()?;
31    let mut state = FirstPassState::default();
32    wag.rewrite(0, &mut state)?;
33    Ok(wag)
34}
35
36/// A node is anything that implements [`Parse`]. `SpannableNode` then, is a wrapper around this node that holds span information about it.
37/// It is intended to be a mostly see-through wrapper around whatever the inner node is. [`Parse`] is implemented on it in a way that
38/// automatically calculates the span information.
39#[derive(Debug, Clone)]
40pub struct SpannableNode<T: Parse> {
41	node: T,
42	span: Span
43}
44
45impl<T: Parse + PartialEq> PartialEq for SpannableNode<T> {
46    fn eq(&self, other: &Self) -> bool {
47        self.node.eq(&other.node)
48    }
49}
50
51impl<T: Parse + Eq> Eq for SpannableNode<T> {}
52
53impl<T: Parse + std::hash::Hash> std::hash::Hash for SpannableNode<T> {
54    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
55        self.node.hash(state);
56    }
57}
58
59impl<T: Parse + Display> Display for SpannableNode<T> {
60    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
61        self.node.fmt(f)
62    }
63}
64
65impl<T: Parse> From<T> for SpannableNode<T> {
66    fn from(value: T) -> Self {
67        Self::new(value, Span::default())
68    }
69}
70
71impl<T: Parse> SpannableNode<T> {
72    /// Get the inner node, consuming the wrapper.
73	pub fn into_inner(self) -> T {
74		self.node
75	}
76
77    /// Get a reference to the inner node.
78	pub const fn to_inner(&self) -> &T {
79		&self.node
80	}
81
82    /// Get a mutable reference to the inner node.
83    pub fn to_inner_mut(&mut self) -> &mut T {
84        &mut self.node
85    }
86
87	const fn new(node: T, span: Span) -> Self {
88		Self {node, span}
89	}
90
91    /// Get mutable references to both the inner node and the span.
92	pub fn deconstruct(&mut self) -> (&mut T, &mut Span) {
93		(&mut self.node, &mut self.span)
94	}
95}
96
97/// A trait for internal use to automatically convert between nodes and [`SpannableNode`].
98pub trait WrapSpannable<T: Parse, U> {
99    /// Wrap dummy span information around the node.
100	fn wrap_spannable(self) -> U;
101
102    /// Convert the node into a [`SpannableNode`] with the specified [`Span`].
103	fn into_spanned(self, _span: Span) -> U where Self: Sized {
104		unimplemented!()
105	}
106}
107
108impl<T: Parse, U: IntoIterator<Item = SpannableNode<T>> + FromIterator<SpannableNode<T>>, Y: IntoIterator<Item = T>> WrapSpannable<T, U> for Y {
109	fn wrap_spannable(self) -> U {
110		self.into_iter().map(WrapSpannable::wrap_spannable).collect()
111	}
112} 
113
114impl<T: Parse> WrapSpannable<T, Option<SpannableNode<T>>> for Option<T> {
115    fn wrap_spannable(self) -> Option<SpannableNode<T>> {
116		self.map(WrapSpannable::wrap_spannable)
117	}
118}
119
120impl<T: Parse> WrapSpannable<T, Option<Box<SpannableNode<T>>>> for Option<Box<T>> {
121    fn wrap_spannable(self) -> Option<Box<SpannableNode<T>>> {
122        self.map(WrapSpannable::wrap_spannable)
123    }
124}
125
126impl<T: Parse> WrapSpannable<T, Box<SpannableNode<T>>> for Box<T> {
127    fn wrap_spannable(self) -> Box<SpannableNode<T>> {
128        Box::new(SpannableNode::from(*self))
129    }
130}
131
132impl<T: Parse> WrapSpannable<T, SpannableNode<T>> for T {
133    fn wrap_spannable(self) -> SpannableNode<T> {
134        SpannableNode::from(self)
135    }
136
137    fn into_spanned(self, span: Span) -> SpannableNode<T> {
138        SpannableNode::new(self, span)
139    }
140}
141
142impl<T: Parse, U: std::cmp::Ord> WrapSpannable<T, BTreeMap<U, SpannableNode<T>>> for BTreeMap<U, T> {
143    fn wrap_spannable(self) -> BTreeMap<U, SpannableNode<T>> {
144        self.into_iter().map(|(x, y)| (x, y.wrap_spannable())).collect()
145    }
146} 
147
148// impl<T: Parse> Deref for SpannableNode<T> {
149//     type Target = T;
150
151//     fn deref(&self) -> &Self::Target {
152//         &self.node
153//     }
154// }
155
156impl<T: Parse> Spannable for SpannableNode<T> {
157    fn span(&self) -> Span {
158        self.span.clone()
159    }
160
161    fn set_span(&mut self, span: Span) {
162    	self.span = span;
163    }
164}
165
166impl<T: Parse + std::fmt::Debug> Parse for SpannableNode<T> {
167    fn parse(lexer: &mut LexerBridge) -> ParseResult<Self> where Self: Sized {
168    	let start = lexer.span().start;
169    	let node = T::parse(lexer)?;
170    	let span = start..lexer.span().end;
171        Ok(Self::new(node, span))
172    }
173}
174
175impl<U, T: Parse + Rewrite<U>> Rewrite<U> for SpannableNode<T> {
176    fn rewrite(&mut self, depth: usize, state: &mut crate::firstpass::FirstPassState) -> crate::firstpass::FirstPassResult<U> {
177        self.node.rewrite(depth, state)
178    }
179}
180
181impl<T: Parse + quote::ToTokens> quote::ToTokens for SpannableNode<T> {
182    fn to_tokens(&self, tokens: &mut quote::__private::TokenStream) {
183        self.node.to_tokens(tokens);
184    }
185}
186
187impl<T: Parse + GetReqAttributes> GetReqAttributes for SpannableNode<T> {
188    fn get_req_attributes(&self) -> firstpass::ReqAttributes {
189        self.to_inner().get_req_attributes()
190    }
191}
192
193impl<T: Parse + RewriteToSynth> RewriteToSynth for SpannableNode<T> {
194    fn rewrite_to_synth(&mut self) -> firstpass::ReqAttributes {
195        self.to_inner_mut().rewrite_to_synth()
196    }
197}