|
2 | 2 | #![allow(clippy::type_complexity)] |
3 | 3 |
|
4 | 4 | //! Parser for Filament programs. |
5 | | -use crate::{self as ast, Attributes, Loc, TimeSub}; |
6 | | -use fil_utils::{self as utils, FilamentResult}; |
7 | | -use fil_utils::{FileIdx, GPosIdx, GlobalPositionTable}; |
| 5 | +use crate::{self as ast, Loc, TimeSub}; |
| 6 | +use fil_utils::{ |
| 7 | + self as utils, AttrCtx, FilamentResult, FileIdx, GPosIdx, |
| 8 | + GlobalPositionTable, |
| 9 | +}; |
8 | 10 | use itertools::Itertools; |
9 | 11 | use pest::pratt_parser::{Assoc, Op, PrattParser}; |
10 | 12 | use pest_consume::{match_nodes, Error, Parser}; |
11 | 13 | use std::fs; |
| 14 | +use std::hash::Hash; |
12 | 15 | use std::path::Path; |
13 | 16 | use std::str::FromStr; |
14 | 17 |
|
@@ -830,29 +833,30 @@ impl FilamentParser { |
830 | 833 | Ok(()) |
831 | 834 | } |
832 | 835 |
|
833 | | - fn attr_bind(input: Node) -> ParseResult<Vec<(ast::Attr, GPosIdx, u64)>> { |
834 | | - match_nodes!( |
835 | | - input.clone().into_children(); |
836 | | - [identifier(name)] => |
837 | | - ast::BoolAttr::from_str(name.as_ref()).map( |
838 | | - |attr| vec![(ast::Attr::Bool(attr), name.pos(), 1)]).map_err( |
839 | | - |_| input.error(format!("Found unknown attribute flag \"{name}\""))), |
840 | | - [not(_), identifier(name)] => |
841 | | - ast::BoolAttr::from_str(name.as_ref()).map( |
842 | | - |attr| vec![(ast::Attr::Bool(attr), name.pos(), 0)]).map_err( |
843 | | - |_| input.error(format!("Found unknown attribute flag \"{name}\""))), |
844 | | - [identifier(name), bitwidth(val)] => |
845 | | - ast::NumAttr::from_str(name.as_ref()).map( |
846 | | - |attr| vec![(ast::Attr::Num(attr), name.pos(), val)]).map_err( |
847 | | - |_| input.error(format!("Found unknown numeric attribute \"{name}\""))), |
848 | | - ) |
849 | | - } |
| 836 | + fn attributes<Bool, Num>( |
| 837 | + input: Node, |
| 838 | + ) -> ParseResult<utils::Attributes<Bool, Num>> |
| 839 | + where |
| 840 | + Bool: FromStr + Hash + Eq + Copy, |
| 841 | + Num: FromStr + Hash + Eq + Copy, |
| 842 | + { |
| 843 | + let mut attrs = utils::Attributes::default(); |
| 844 | + for attr in input.into_children() { |
| 845 | + match_nodes!( |
| 846 | + attr.clone().into_children(); |
| 847 | + [identifier(name)] => Bool::from_str(name.as_ref()).map( |
| 848 | + |attr| attrs.set(attr, true, name.pos())).map_err( |
| 849 | + |_| attr.error(format!("Found unknown attribute flag \"{name}\""))), |
| 850 | + [not(_), identifier(name)] => Bool::from_str(name.as_ref()).map( |
| 851 | + |attr| attrs.set(attr, false, name.pos())).map_err( |
| 852 | + |_| attr.error(format!("Found unknown attribute flag \"{name}\""))), |
| 853 | + [identifier(name), bitwidth(val)] => Num::from_str(name.as_ref()).map( |
| 854 | + |attr| attrs.set(attr, val, name.pos())).map_err( |
| 855 | + |_| attr.error(format!("Found unknown numeric attribute \"{name}\""))), |
| 856 | + )?; |
| 857 | + } |
850 | 858 |
|
851 | | - fn attributes(input: Node) -> ParseResult<Attributes> { |
852 | | - Ok(match_nodes!( |
853 | | - input.into_children(); |
854 | | - [attr_bind(attr)..] => ast::Attributes::new(attr.into_iter().flatten()) |
855 | | - )) |
| 859 | + Ok(attrs) |
856 | 860 | } |
857 | 861 |
|
858 | 862 | fn component(input: Node) -> ParseResult<ast::Component> { |
|
0 commit comments