Squash bugs with ast gen.
This commit is contained in:
parent
608d89645e
commit
ac9ff6ecec
@ -10,19 +10,21 @@ fn make_var_name(s: &str) -> String {
|
||||
|
||||
fn make_vec_child_holder(vec_child: &VecChild) -> TokenStream {
|
||||
let child_ident = format_ident!("{}", vec_child.name());
|
||||
let child_type_ident = match vec_child.build() {
|
||||
match vec_child.build() {
|
||||
VecChildToBuild::Node(node_child) => {
|
||||
format_ident!("{}", node_child.build())
|
||||
},
|
||||
VecChildToBuild::String => format_ident!("{}", "String")
|
||||
};
|
||||
let child_type_ident = format_ident!("{}", node_child.build());
|
||||
quote! {
|
||||
let mut #child_ident: Vec<Box<#child_type_ident >> = vec![]
|
||||
}
|
||||
},
|
||||
VecChildToBuild::String => quote! {
|
||||
let mut #child_ident: Vec<String> = vec![]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn make_node_child_holder(node_child: &NodeChildToBuild) -> TokenStream {
|
||||
let child_ident = format_ident!("{}", make_var_name(node_child.build()));
|
||||
fn make_node_child_holder(name: &str, node_child: &NodeChildToBuild) -> TokenStream {
|
||||
let child_ident = format_ident!("{}", name);
|
||||
let child_type_ident = format_ident!("{}", node_child.build());
|
||||
quote! {
|
||||
let mut #child_ident: Option<Box<#child_type_ident>> = None
|
||||
@ -42,7 +44,7 @@ fn make_child_holder(child_spec: &StructChildSpec) -> Option<TokenStream> {
|
||||
StructChildSpec::VecChild(vec_child) => Some(make_vec_child_holder(vec_child)),
|
||||
StructChildSpec::MemberChild(member_child) => match member_child.build() {
|
||||
MemberChildToBuild::Node(node_child) => {
|
||||
Some(make_node_child_holder(node_child))
|
||||
Some(make_node_child_holder(member_child.name(), node_child))
|
||||
}
|
||||
MemberChildToBuild::Boolean(boolean_child) => {
|
||||
Some(make_boolean_child_holder(boolean_child))
|
||||
@ -53,21 +55,24 @@ fn make_child_holder(child_spec: &StructChildSpec) -> Option<TokenStream> {
|
||||
|
||||
fn make_vec_child_match_action(vec_child: &VecChild) -> TokenStream {
|
||||
let child_name_ident = format_ident!("{}", vec_child.name());
|
||||
let build_fn_ident = match vec_child.build() {
|
||||
match vec_child.build() {
|
||||
VecChildToBuild::Node(vec_node_child) => {
|
||||
format_ident!("{}", make_build_fn_name(vec_node_child.build()))
|
||||
},
|
||||
VecChildToBuild::String => {
|
||||
format_ident!("{}", make_build_fn_name(vec_child.rule()))
|
||||
}
|
||||
};
|
||||
let build_fn_ident = format_ident!("{}", make_build_fn_name(vec_node_child.build()));
|
||||
quote! {
|
||||
#child_name_ident.push(Box::new(#build_fn_ident(inner_pair)))
|
||||
}
|
||||
},
|
||||
VecChildToBuild::String => {
|
||||
let build_fn_ident = format_ident!("{}", make_build_fn_name(vec_child.rule()));
|
||||
quote! {
|
||||
#child_name_ident.push(#build_fn_ident(inner_pair))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn make_node_member_child_match_action(node_child: &NodeChildToBuild) -> TokenStream {
|
||||
let child_name_ident = format_ident!("{}", make_var_name(node_child.build()));
|
||||
fn make_node_member_child_match_action(name: &str, node_child: &NodeChildToBuild) -> TokenStream {
|
||||
let child_name_ident = format_ident!("{}", name);
|
||||
let build_fn_ident = format_ident!("{}", make_build_fn_name(node_child.build()));
|
||||
quote! {
|
||||
#child_name_ident = Some(Box::new(#build_fn_ident(inner_pair)))
|
||||
@ -87,9 +92,9 @@ fn make_match_action(child_spec: &StructChildSpec) -> TokenStream {
|
||||
StructChildSpec::VecChild(vec_child) => {
|
||||
make_vec_child_match_action(vec_child)
|
||||
}
|
||||
StructChildSpec::MemberChild(single_child) => match single_child.build() {
|
||||
StructChildSpec::MemberChild(member_child) => match member_child.build() {
|
||||
MemberChildToBuild::Node(node_child) => {
|
||||
make_node_member_child_match_action(node_child)
|
||||
make_node_member_child_match_action(member_child.name(), node_child)
|
||||
}
|
||||
MemberChildToBuild::Boolean(boolean_child) => {
|
||||
make_boolean_member_child_match_action(boolean_child)
|
||||
|
||||
@ -1,5 +1,8 @@
|
||||
use convert_case::{Case, Casing};
|
||||
use crate::spec::{BooleanChildToBuild, BuildSpec, EnumBuildSpec, EnumRuleChildKind, LeafEnumBuildSpec, LeafStructBuildSpec, LeafStructMemberKind, MemberChildToBuild, NodeChildToBuild, StructBuildSpec, StructChildSpec, VecChild, VecChildToBuild};
|
||||
use crate::spec::{
|
||||
BooleanChildToBuild, BuildSpec, EnumBuildSpec, EnumRuleChildKind, LeafEnumBuildSpec,
|
||||
LeafStructBuildSpec, LeafStructMemberKind, MemberChildToBuild, NodeChildToBuild,
|
||||
StructBuildSpec, StructChildSpec, VecChild, VecChildToBuild,
|
||||
};
|
||||
use proc_macro2::{Ident, TokenStream};
|
||||
use quote::{format_ident, quote};
|
||||
|
||||
@ -12,7 +15,7 @@ fn make_enum_type(build_spec: &EnumBuildSpec) -> TokenStream {
|
||||
let child_type_ident = match enum_rule_child.kind() {
|
||||
EnumRuleChildKind::Node(node_child) => {
|
||||
format_ident!("{}", node_child.build())
|
||||
},
|
||||
}
|
||||
EnumRuleChildKind::Int => format_ident!("i32"),
|
||||
EnumRuleChildKind::Long => format_ident!("i64"),
|
||||
EnumRuleChildKind::Double => format_ident!("f64"),
|
||||
@ -61,11 +64,12 @@ fn handle_vec_child(
|
||||
vec_child: &VecChild,
|
||||
member_names: &mut Vec<Ident>,
|
||||
annotated_members: &mut Vec<TokenStream>,
|
||||
member_args: &mut Vec<TokenStream>,
|
||||
accessors: &mut Vec<TokenStream>,
|
||||
) {
|
||||
let (child_ident, child_ident_mut) = (
|
||||
format_ident!("{}", vec_child.name()),
|
||||
format_ident!("{}", vec_child.name()),
|
||||
format_ident!("{}_mut", vec_child.name()),
|
||||
);
|
||||
let child_type_ident = match vec_child.build() {
|
||||
VecChildToBuild::Node(vec_node_child) => format_ident!("{}", vec_node_child.build()),
|
||||
@ -73,9 +77,28 @@ fn handle_vec_child(
|
||||
};
|
||||
|
||||
member_names.push(child_ident.clone());
|
||||
|
||||
match vec_child.build() {
|
||||
VecChildToBuild::Node(_) => {
|
||||
annotated_members.push(quote! {
|
||||
#child_ident: Vec<Box<#child_type_ident>>
|
||||
});
|
||||
member_args.push(quote! {
|
||||
#child_ident: Vec<Box<#child_type_ident>>
|
||||
});
|
||||
}
|
||||
VecChildToBuild::String => {
|
||||
annotated_members.push(quote! {
|
||||
#child_ident: Vec<String>
|
||||
});
|
||||
member_args.push(quote! {
|
||||
#child_ident: Vec<String>
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
match vec_child.build() {
|
||||
VecChildToBuild::Node(_) => {
|
||||
accessors.push(quote! {
|
||||
pub fn #child_ident(&self) -> impl Iterator<Item = &#child_type_ident> {
|
||||
self.#child_ident.iter().map(Box::as_ref)
|
||||
@ -86,15 +109,24 @@ fn handle_vec_child(
|
||||
}
|
||||
});
|
||||
}
|
||||
VecChildToBuild::String => accessors.push(quote! {
|
||||
pub fn #child_ident(&self) -> impl Iterator<Item = &str> {
|
||||
self.#child_ident.iter().map(String::as_str)
|
||||
}
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_node_child(
|
||||
name: &str,
|
||||
node_child: &NodeChildToBuild,
|
||||
member_names: &mut Vec<Ident>,
|
||||
annotated_members: &mut Vec<TokenStream>,
|
||||
member_args: &mut Vec<TokenStream>,
|
||||
accessors: &mut Vec<TokenStream>,
|
||||
) {
|
||||
let child_ident = format_ident!("{}", node_child.build().to_case(Case::Snake));
|
||||
let child_ident_mut = format_ident!("{}_mut", child_ident);
|
||||
let child_ident = format_ident!("{}", name);
|
||||
let child_ident_mut = format_ident!("{}_mut", name);
|
||||
let child_type_ident = format_ident!("{}", node_child.build());
|
||||
|
||||
member_names.push(child_ident.clone());
|
||||
@ -103,9 +135,15 @@ fn handle_node_child(
|
||||
annotated_members.push(quote! {
|
||||
#child_ident: Option<Box<#child_type_ident>>
|
||||
});
|
||||
member_args.push(quote! {
|
||||
#child_ident: Option<Box<#child_type_ident>>
|
||||
});
|
||||
} else {
|
||||
annotated_members.push(quote! {
|
||||
#child_ident: Box<#child_type_ident>
|
||||
});
|
||||
member_args.push(quote! {
|
||||
#child_ident: Box<#child_type_ident>
|
||||
})
|
||||
}
|
||||
if node_child.optional() {
|
||||
@ -125,7 +163,7 @@ fn handle_node_child(
|
||||
None
|
||||
}
|
||||
}
|
||||
})
|
||||
});
|
||||
} else {
|
||||
accessors.push(quote! {
|
||||
pub fn #child_ident(&self) -> &#child_type_ident {
|
||||
@ -143,6 +181,7 @@ fn handle_boolean_child(
|
||||
single_boolean_child: &BooleanChildToBuild,
|
||||
member_names: &mut Vec<Ident>,
|
||||
annotated_members: &mut Vec<TokenStream>,
|
||||
member_args: &mut Vec<TokenStream>,
|
||||
accessors: &mut Vec<TokenStream>,
|
||||
) {
|
||||
let child_ident = format_ident!("{}", single_boolean_child.name());
|
||||
@ -150,16 +189,20 @@ fn handle_boolean_child(
|
||||
annotated_members.push(quote! {
|
||||
#child_ident: bool
|
||||
});
|
||||
member_args.push(quote! {
|
||||
#child_ident: bool
|
||||
});
|
||||
accessors.push(quote! {
|
||||
pub fn #child_ident(&self) -> bool {
|
||||
self.#child_ident
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
fn make_struct_type(build_spec: &StructBuildSpec) -> TokenStream {
|
||||
let mut member_names: Vec<Ident> = vec![];
|
||||
let mut annotated_members: Vec<TokenStream> = vec![];
|
||||
let mut member_args: Vec<TokenStream> = vec![];
|
||||
let mut accessors: Vec<TokenStream> = vec![];
|
||||
|
||||
for child_spec in build_spec.children() {
|
||||
@ -170,6 +213,7 @@ fn make_struct_type(build_spec: &StructBuildSpec) -> TokenStream {
|
||||
vec_child,
|
||||
&mut member_names,
|
||||
&mut annotated_members,
|
||||
&mut member_args,
|
||||
&mut accessors,
|
||||
);
|
||||
}
|
||||
@ -177,9 +221,11 @@ fn make_struct_type(build_spec: &StructBuildSpec) -> TokenStream {
|
||||
match member_child.build() {
|
||||
MemberChildToBuild::Node(node_child) => {
|
||||
handle_node_child(
|
||||
member_child.name(),
|
||||
node_child,
|
||||
&mut member_names,
|
||||
&mut annotated_members,
|
||||
&mut member_args,
|
||||
&mut accessors,
|
||||
);
|
||||
}
|
||||
@ -188,6 +234,7 @@ fn make_struct_type(build_spec: &StructBuildSpec) -> TokenStream {
|
||||
boolean_child,
|
||||
&mut member_names,
|
||||
&mut annotated_members,
|
||||
&mut member_args,
|
||||
&mut accessors,
|
||||
);
|
||||
}
|
||||
@ -231,9 +278,30 @@ fn make_leaf_struct_type(build_spec: &LeafStructBuildSpec) -> TokenStream {
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let member_names = build_spec
|
||||
let member_args = build_spec.members().map(|member| {
|
||||
let name_ident = format_ident!("{}", member.name());
|
||||
let type_stream = match member.kind() {
|
||||
LeafStructMemberKind::String => {
|
||||
quote! { &str }
|
||||
}
|
||||
};
|
||||
quote! {
|
||||
#name_ident: #type_stream
|
||||
}
|
||||
});
|
||||
|
||||
let initializers = build_spec
|
||||
.members()
|
||||
.map(|leaf_struct_child| format_ident!("{}", leaf_struct_child.name()))
|
||||
.map(|leaf_struct_member| {
|
||||
let member_ident = format_ident!("{}", leaf_struct_member.name());
|
||||
match leaf_struct_member.kind() {
|
||||
LeafStructMemberKind::String => {
|
||||
quote! {
|
||||
#member_ident: #member_ident.to_string()
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let accessors = build_spec
|
||||
@ -258,9 +326,9 @@ fn make_leaf_struct_type(build_spec: &LeafStructBuildSpec) -> TokenStream {
|
||||
}
|
||||
|
||||
impl #type_ident {
|
||||
pub fn new(#(#annotated_members),*) -> Self {
|
||||
pub fn new(#(#member_args),*) -> Self {
|
||||
Self {
|
||||
#(#member_names),*
|
||||
#(#initializers),*
|
||||
}
|
||||
}
|
||||
|
||||
@ -272,11 +340,13 @@ fn make_leaf_struct_type(build_spec: &LeafStructBuildSpec) -> TokenStream {
|
||||
pub fn make_type(build_spec: &BuildSpec) -> Option<TokenStream> {
|
||||
match build_spec {
|
||||
BuildSpec::Enum(enum_build_spec) => Some(make_enum_type(enum_build_spec)),
|
||||
BuildSpec::LeafEnum(leaf_enum_build_spec) => Some(make_leaf_enum_type(leaf_enum_build_spec)),
|
||||
BuildSpec::LeafEnum(leaf_enum_build_spec) => {
|
||||
Some(make_leaf_enum_type(leaf_enum_build_spec))
|
||||
}
|
||||
BuildSpec::Struct(struct_build_spec) => Some(make_struct_type(struct_build_spec)),
|
||||
BuildSpec::LeafStruct(leaf_struct_build_spec) => {
|
||||
Some(make_leaf_struct_type(leaf_struct_build_spec))
|
||||
},
|
||||
BuildSpec::Production(production_build_spec) => None
|
||||
}
|
||||
BuildSpec::Production(_) => None,
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,14 +1,14 @@
|
||||
use crate::name_analysis::symbol::{FunctionSymbol, ParameterSymbol};
|
||||
use crate::name_analysis::symbol_table::{SymbolInsertError, SymbolTable};
|
||||
|
||||
pub fn add_std_core_symbols(symbol_table: &mut SymbolTable) -> Result<(), SymbolInsertError> {
|
||||
symbol_table.insert_function_symbol(
|
||||
FunctionSymbol::new("std::core::println", "println", true, true, None)
|
||||
.with_parameters(vec![ParameterSymbol::new("msg", None)]),
|
||||
)?;
|
||||
symbol_table.insert_function_symbol(
|
||||
FunctionSymbol::new("std::core::print", "print", true, true, None)
|
||||
.with_parameters(vec![ParameterSymbol::new("msg", None)]),
|
||||
)?;
|
||||
Ok(())
|
||||
}
|
||||
// use crate::name_analysis::symbol::{FunctionSymbol, ParameterSymbol};
|
||||
// use crate::name_analysis::symbol_table::{SymbolInsertError, SymbolTable};
|
||||
//
|
||||
// pub fn add_std_core_symbols(symbol_table: &mut SymbolTable) -> Result<(), SymbolInsertError> {
|
||||
// symbol_table.insert_function_symbol(
|
||||
// FunctionSymbol::new("std::core::println", "println", true, true, None)
|
||||
// .with_parameters(vec![ParameterSymbol::new("msg", None)]),
|
||||
// )?;
|
||||
// symbol_table.insert_function_symbol(
|
||||
// FunctionSymbol::new("std::core::print", "print", true, true, None)
|
||||
// .with_parameters(vec![ParameterSymbol::new("msg", None)]),
|
||||
// )?;
|
||||
// Ok(())
|
||||
// }
|
||||
|
||||
Loading…
Reference in New Issue
Block a user