From 0704e7d504f603a650983e4b09bffc15e1a3b3e8 Mon Sep 17 00:00:00 2001 From: Jesse Brault Date: Sun, 14 Sep 2025 09:11:30 -0500 Subject: [PATCH] Skeleton code for leaf_enum specs. --- ast-generator/src/deserialize.rs | 64 ++++++++++++++++++++------------ ast-generator/src/lib.rs | 3 ++ ast-generator/src/spec.rs | 1 + ast-generator/src/type_gen.rs | 1 + 4 files changed, 45 insertions(+), 24 deletions(-) diff --git a/ast-generator/src/deserialize.rs b/ast-generator/src/deserialize.rs index 6230770..647a3ea 100644 --- a/ast-generator/src/deserialize.rs +++ b/ast-generator/src/deserialize.rs @@ -46,7 +46,12 @@ fn get_vec_child(name: &str, rule: &str, build: &Yaml) -> ChildSpec { )) } -fn get_single_child_to_build(name: &str, rule: &str, optional: bool, build: &Yaml) -> SingleChildToBuild { +fn get_single_child_to_build( + name: &str, + rule: &str, + optional: bool, + build: &Yaml, +) -> SingleChildToBuild { if build.is_hash() { match build["type"].as_str() { Some(r#type) => { @@ -62,16 +67,15 @@ fn get_single_child_to_build(name: &str, rule: &str, optional: bool, build: &Yam )) } else { todo!("currently on boolean types with on: rule_present are supported") - } - }, + } + } None => { let or_else = build["or_else"] .as_str() .map(|s| s.to_string()) .or_else(|| { - let or_else_default = build["or_else_default"] - .as_bool() - .unwrap_or_else(|| false); + let or_else_default = + build["or_else_default"].as_bool().unwrap_or_else(|| false); if or_else_default { Some(String::from("default")) } else { @@ -79,16 +83,18 @@ fn get_single_child_to_build(name: &str, rule: &str, optional: bool, build: &Yam } }); SingleChildToBuild::Type(SingleTypeChildToBuild::from_build_or_rule( - rule, - or_else, - optional, + rule, or_else, optional, )) } } } else { match build.as_str() { - Some(s) => SingleChildToBuild::Type(SingleTypeChildToBuild::from_build_or_rule(s, None, optional)), - None => SingleChildToBuild::Type(SingleTypeChildToBuild::from_build_or_rule(rule, None, optional)), + Some(s) => SingleChildToBuild::Type(SingleTypeChildToBuild::from_build_or_rule( + s, None, optional, + )), + None => SingleChildToBuild::Type(SingleTypeChildToBuild::from_build_or_rule( + rule, None, optional, + )), } } } @@ -129,10 +135,8 @@ fn get_child_specs(children: &Yaml) -> Vec { if get_vec(&props["vec"]) { get_vec_child(name, &rule, build) } else { - let optional = props["optional"] - .as_bool() - .unwrap_or_else(|| false); - + let optional = props["optional"].as_bool().unwrap_or_else(|| false); + get_single_child(name, &rule, optional, build) } } else { @@ -142,7 +146,7 @@ fn get_child_specs(children: &Yaml) -> Vec { .collect() } -fn get_enum_rule_specs(rule_specs: &Yaml) -> Vec { +fn get_enum_rules(rule_specs: &Yaml) -> Vec { rule_specs .as_vec() .unwrap() @@ -165,24 +169,36 @@ fn get_enum_rule_specs(rule_specs: &Yaml) -> Vec { .collect() } +fn yaml_is_string(yaml: &Yaml, test: &str) -> bool { + match yaml.as_str() { + Some(s) => s == test, + None => false, + } +} + fn deserialize_build_spec(build_spec_name: &Yaml, build_spec: &Yaml) -> BuildSpec { let build_spec_name_pascal = build_spec_name.as_str().unwrap(); + let node_type = &build_spec["type"]; let children = &build_spec["children"]; + let rules = &build_spec["rules"]; - if children.is_array() { + if yaml_is_string(node_type, "struct") || children.is_array() { let child_specs = get_child_specs(children); BuildSpec::Struct(StructBuildSpec::from_name( build_spec_name_pascal, child_specs, )) + } else if yaml_is_string(node_type, "leaf_enum") && rules.is_array() { + todo!( + "Not yet ready for leaf_enum node: {}", + build_spec_name_pascal + ) + } else if rules.is_array() { + // enum node + let enum_rules = get_enum_rules(rules); + BuildSpec::Enum(EnumBuildSpec::from_name(build_spec_name_pascal, enum_rules)) } else { - let rule_specs = &build_spec["rules"]; - if rule_specs.is_array() { - let enum_rules = get_enum_rule_specs(rule_specs); - BuildSpec::Enum(EnumBuildSpec::from_name(build_spec_name_pascal, enum_rules)) - } else { - panic!("either children or rules must be present on the build spec"); - } + panic!("Expected a node spec for either a struct, enum, or leaf_enum node type."); } } diff --git a/ast-generator/src/lib.rs b/ast-generator/src/lib.rs index 99a98cc..9ee1fa0 100644 --- a/ast-generator/src/lib.rs +++ b/ast-generator/src/lib.rs @@ -16,6 +16,7 @@ fn debug_built_spec(build_spec: &BuildSpec, token_stream: &TokenStream) { BuildSpec::Enum(enum_build_spec) => { println!("Spec name: {}", enum_build_spec.name()); } + BuildSpec::LeafEnum() => todo!(), BuildSpec::Struct(struct_build_spec) => { println!("Spec name: {}", struct_build_spec.name()); } @@ -40,6 +41,7 @@ fn generate_build_file(build_specs: &[BuildSpec]) -> AstGeneratedFile { .map(|build_spec| { match build_spec { BuildSpec::Enum(enum_build_spec) => { quote! {} } + BuildSpec::LeafEnum() => { quote! {} } BuildSpec::Struct(struct_build_spec) => { let struct_build_fn_stream = make_struct_build_fn(struct_build_spec); debug_built_spec(build_spec, &struct_build_fn_stream); @@ -74,6 +76,7 @@ pub fn test_dump() -> String { for build_spec in &build_specs { match build_spec { BuildSpec::Enum(_) => {} + BuildSpec::LeafEnum() => {} BuildSpec::Struct(struct_spec) => { let struct_build_fn_stream = make_struct_build_fn(struct_spec); debug_built_spec(build_spec, &struct_build_fn_stream); diff --git a/ast-generator/src/spec.rs b/ast-generator/src/spec.rs index 96e966a..a96a08f 100644 --- a/ast-generator/src/spec.rs +++ b/ast-generator/src/spec.rs @@ -3,6 +3,7 @@ use convert_case::{Case, Casing}; pub enum BuildSpec { Enum(EnumBuildSpec), + LeafEnum(), Struct(StructBuildSpec), } diff --git a/ast-generator/src/type_gen.rs b/ast-generator/src/type_gen.rs index c8d5ea7..02248ed 100644 --- a/ast-generator/src/type_gen.rs +++ b/ast-generator/src/type_gen.rs @@ -163,6 +163,7 @@ fn make_struct_type(build_spec: &StructBuildSpec) -> TokenStream { pub fn make_type(build_spec: &BuildSpec) -> TokenStream { match build_spec { BuildSpec::Enum(enum_build_spec) => make_enum_type(enum_build_spec), + BuildSpec::LeafEnum() => todo!(), BuildSpec::Struct(struct_build_spec) => make_struct_type(struct_build_spec), } }