use { chumsky::{ prelude::*, text::* }, std::sync::{Arc, RwLock}, laddertypes::{TypeDict, BimapTypeDict, parser::*}, crate::morphism::LdmcPrimCMorphism }; /* morphism-base text format: * NAME '(' [TYPE-ARG-NAME ':' KIND] ')' * SRC-TYPE * '-->' DST-TYPE * ``` * TEMPLATE-CODE * ``` */ pub fn morphism_base_parser( type_dict: Arc<RwLock< BimapTypeDict >> ) -> impl Parser<char, (String, Vec<LdmcPrimCMorphism>), Error = Simple<char>> { just("```") .then(take_until(just("```"))) .map( move |(a, (b, c))| { b.iter().collect() } ) // morph name .then( ident().padded() // type args .then( ident().padded() .then_ignore(just(":").padded()) .then(none_of(",)").repeated().padded()) .separated_by(just(",").padded()) .delimited_by(just("("), just(")")) ) // newline .then_ignore(just('\n')) // src type .then(take_until(just("-->").ignored())) // dst_type .then(take_until(just("```"))) // c sourcecode template .then(take_until(just("```"))) .map( move |((((symbol, type_args), (src_type, _)), (dst_type, _)), (c_source, _))| { let c_source = c_source.iter().collect(); let mut type_dict = type_dict.write().unwrap(); let type_args : Vec<_> = type_args.into_iter().map(|(v,k)| (v,k.into_iter().collect())).collect(); let mut ty_args = Vec::new(); for (var, kind) in type_args.into_iter() { let var_id = type_dict.add_varname(var.clone()); ty_args.push((var_id, kind)); } let mut src_type = type_dict.parse(&src_type.iter().collect::<String>()).expect("couldnt parse src type"); let mut dst_type = type_dict.parse(&dst_type.iter().collect::<String>()).expect("couldnt parse dst type"); LdmcPrimCMorphism { symbol, type_args: ty_args, src_type, dst_type, c_source } }) .separated_by(text::newline()) ) }