96 lines
3.4 KiB
Rust
96 lines
3.4 KiB
Rust
use crate::spec::{ProductionBuildSpec, ProductionKind, ProductionStringFrom};
|
|
use crate::util::{make_build_fn_name, make_build_pair};
|
|
use proc_macro2::TokenStream;
|
|
use quote::{format_ident, quote};
|
|
|
|
pub fn make_production_build_fn(production_build_spec: &ProductionBuildSpec) -> TokenStream {
|
|
let build_fn_ident = format_ident!("{}", make_build_fn_name(production_build_spec.rule()));
|
|
let return_type_ident = match production_build_spec.kind() {
|
|
ProductionKind::Int => format_ident!("i32"),
|
|
ProductionKind::Long => format_ident!("i64"),
|
|
ProductionKind::Double => format_ident!("f64"),
|
|
ProductionKind::String(_) => format_ident!("String"),
|
|
ProductionKind::Boolean => format_ident!("bool"),
|
|
ProductionKind::Node(node_type) => format_ident!("{}", node_type),
|
|
};
|
|
let pair_ident = format_ident!("{}", make_build_pair(production_build_spec.rule()));
|
|
|
|
let pair_mapper = match production_build_spec.kind() {
|
|
ProductionKind::Int => quote! {
|
|
let number_base_pair = #pair_ident.into_inner()
|
|
.next()
|
|
.unwrap();
|
|
let inner_number_base_pair = number_base_pair.into_inner()
|
|
.next()
|
|
.unwrap();
|
|
match inner_number_base_pair.as_rule() {
|
|
Rule::BinaryBase => {
|
|
todo!()
|
|
}
|
|
Rule::HexadecimalBase => {
|
|
todo!()
|
|
}
|
|
Rule::DecimalBase => {
|
|
inner_number_base_pair.as_str().parse::<i32>().unwrap()
|
|
}
|
|
_ => panic!()
|
|
}
|
|
},
|
|
ProductionKind::Long => quote! {
|
|
let number_base_pair = #pair_ident.into_inner()
|
|
.next()
|
|
.unwrap();
|
|
let inner_number_base_pair = number_base_pair.into_inner()
|
|
.next()
|
|
.unwrap();
|
|
match inner_number_base_pair.as_rule() {
|
|
Rule::BinaryBase => {
|
|
todo!()
|
|
}
|
|
Rule::HexadecimalBase => {
|
|
todo!()
|
|
}
|
|
Rule::DecimalBase => {
|
|
inner_number_base_pair.as_str().parse::<i64>().unwrap()
|
|
}
|
|
_ => panic!()
|
|
}
|
|
},
|
|
ProductionKind::Double => quote! {
|
|
#pair_ident.as_str().parse::<f64>().unwrap()
|
|
},
|
|
ProductionKind::String(from) => match from {
|
|
ProductionStringFrom::StringInner => {
|
|
quote! {
|
|
#pair_ident.into_inner()
|
|
.next()
|
|
.unwrap()
|
|
.as_str()
|
|
.to_string()
|
|
}
|
|
}
|
|
ProductionStringFrom::WholePair => {
|
|
quote! {
|
|
#pair_ident.as_str().to_string()
|
|
}
|
|
}
|
|
},
|
|
ProductionKind::Boolean => quote! {
|
|
#pair_ident.as_str().parse::<bool>().unwrap()
|
|
},
|
|
ProductionKind::Node(node_type) => {
|
|
let build_fn_ident = format_ident!("{}", make_build_fn_name(node_type));
|
|
quote! {
|
|
let inner_pair = #pair_ident.into_inner().next().unwrap();
|
|
#build_fn_ident(inner_pair)
|
|
}
|
|
}
|
|
};
|
|
|
|
quote! {
|
|
fn #build_fn_ident(#pair_ident: Pair<Rule>) -> #return_type_ident {
|
|
#pair_mapper
|
|
}
|
|
}
|
|
}
|