ldmc/src/parser.rs

80 lines
2.1 KiB
Rust

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())
)
}