Add derive for leaf enum spec, fix compilation errors.

This commit is contained in:
Jesse Brault 2025-09-29 12:22:28 -05:00
parent 058b33ece5
commit eaebf8c926
9 changed files with 71 additions and 23 deletions

View File

@ -21,7 +21,7 @@ pub fn make_struct_ast_node_impl(spec: &StructSpec) -> TokenStream {
} }
}, },
StructChild::MemberChild(member_child) => match member_child.build() { StructChild::MemberChild(member_child) => match member_child.build() {
MemberChildBuild::Node(node_child) => { MemberChildBuild::Node(_) => {
let child_ident = format_ident!("{}", member_child.name()); let child_ident = format_ident!("{}", member_child.name());
if member_child.optional() { if member_child.optional() {
Some(quote! { Some(quote! {

View File

@ -23,5 +23,15 @@ pub fn deserialize_leaf_struct(name: &str, props: &Yaml) -> LeafStructBuildSpec
}) })
.map(Box::new) .map(Box::new)
.collect(); .collect();
LeafStructBuildSpec::new(name, members) let derive = props["derive"]
.as_vec()
.map(|derive_yaml| {
derive_yaml.iter()
.map(|trait_yaml| {
trait_yaml.as_str().unwrap().to_string()
}).collect::<Vec<_>>()
})
.unwrap_or_default();
LeafStructBuildSpec::new(name, members, derive)
} }

View File

@ -1,13 +1,15 @@
pub struct LeafStructBuildSpec { pub struct LeafStructBuildSpec {
build: String, build: String,
members: Vec<Box<LeafStructMember>>, members: Vec<Box<LeafStructMember>>,
derive: Vec<String>,
} }
impl LeafStructBuildSpec { impl LeafStructBuildSpec {
pub fn new(build: &str, members: Vec<Box<LeafStructMember>>) -> Self { pub fn new(build: &str, members: Vec<Box<LeafStructMember>>, derive: Vec<String>) -> Self {
Self { Self {
build: build.to_string(), build: build.to_string(),
members, members,
derive,
} }
} }
@ -18,6 +20,10 @@ impl LeafStructBuildSpec {
pub fn members(&self) -> impl Iterator<Item = &LeafStructMember> { pub fn members(&self) -> impl Iterator<Item = &LeafStructMember> {
self.members.iter().map(Box::as_ref) self.members.iter().map(Box::as_ref)
} }
pub fn derive(&self) -> impl Iterator<Item = &str> {
self.derive.iter().map(String::as_str)
}
} }
pub struct LeafStructMember { pub struct LeafStructMember {

View File

@ -83,10 +83,27 @@ pub fn make_leaf_struct_type(build_spec: &LeafStructBuildSpec) -> TokenStream {
}) })
.collect::<Vec<_>>(); .collect::<Vec<_>>();
quote! { let struct_stream = if build_spec.derive().count() > 0 {
pub struct #type_ident { let derives = build_spec.derive().map(|derive| {
#(#annotated_members),* format_ident!("{}", derive)
}).collect::<Vec<_>>();
quote! {
#[derive(#(#derives),*)]
pub struct #type_ident {
#(#annotated_members),*
}
} }
} else {
quote! {
pub struct #type_ident {
#(#annotated_members),*
}
}
};
quote! {
#struct_stream
impl #type_ident { impl #type_ident {
pub fn new(#(#member_args),*) -> Self { pub fn new(#(#member_args),*) -> Self {

View File

@ -32,7 +32,7 @@ pub fn name_analysis(paths: &Vec<PathBuf>) -> Result<(), Box<dyn std::error::Err
add_std_core_symbols(&mut symbol_table).expect("Failed to add std::core symbols."); add_std_core_symbols(&mut symbol_table).expect("Failed to add std::core symbols.");
let diagnostics = analyze_names( let diagnostics = analyze_names(
&mut compilation_units.iter().map(Box::as_mut), compilation_units.as_mut_slice(),
&mut symbol_table &mut symbol_table
); );
if diagnostics.is_empty() { if diagnostics.is_empty() {

View File

@ -5,14 +5,14 @@ use crate::ast::walk::walk_depth_first;
use crate::diagnostic::DmDiagnostic; use crate::diagnostic::DmDiagnostic;
use crate::name_analysis::symbol_table::SymbolTable; use crate::name_analysis::symbol_table::SymbolTable;
fn gather_identifier(identifier: &Identifier, symbol_table: &SymbolTable, identifier_scope_ids: &mut HashMap<&Identifier, usize>) { fn gather_identifier(identifier: &Identifier, symbol_table: &SymbolTable, identifier_scope_ids: &mut HashMap<Identifier, usize>) {
identifier_scope_ids[identifier] = symbol_table.current_scope_id(); identifier_scope_ids.insert(identifier.clone(), symbol_table.current_scope_id());
} }
pub fn gather_compilation_unit( pub fn gather_compilation_unit(
compilation_unit: &mut CompilationUnit, compilation_unit: &mut CompilationUnit,
symbol_table: &mut SymbolTable, symbol_table: &mut SymbolTable,
identifier_scope_ids: &mut HashMap<&Identifier, usize>, identifier_scope_ids: &mut HashMap<Identifier, usize>,
diagnostics: &mut Vec<DmDiagnostic>, diagnostics: &mut Vec<DmDiagnostic>,
) { ) {
walk_depth_first(compilation_unit, &mut |child| match child { walk_depth_first(compilation_unit, &mut |child| match child {

View File

@ -33,11 +33,11 @@ pub mod symbol;
pub mod symbol_table; pub mod symbol_table;
pub fn analyze_names( pub fn analyze_names(
compilation_units: &mut [CompilationUnit], compilation_units: &mut [Box<CompilationUnit>],
symbol_table: &mut SymbolTable, symbol_table: &mut SymbolTable,
) -> Vec<DmDiagnostic> { ) -> Vec<DmDiagnostic> {
let mut diagnostics = vec![]; let mut diagnostics = vec![];
let mut identifier_scope_ids: HashMap<&Identifier, usize> = HashMap::new(); let mut identifier_scope_ids: HashMap<Identifier, usize> = HashMap::new();
// gather symbols // gather symbols
for compilation_unit in compilation_units.iter_mut() { for compilation_unit in compilation_units.iter_mut() {

View File

@ -57,6 +57,11 @@ $defs:
description: Ordered child fields for this node. description: Ordered child fields for this node.
items: items:
$ref: "#/$defs/StructChild" $ref: "#/$defs/StructChild"
derive:
type: array
description: Traits to derive.
items:
type: string
required: required:
- children - children
StructChild: StructChild:
@ -201,6 +206,11 @@ $defs:
description: Ordered members for this node. description: Ordered members for this node.
items: items:
$ref: "#/$defs/LeafStructMemberDefinition" $ref: "#/$defs/LeafStructMemberDefinition"
derive:
type: array
description: Traits to derive.
items:
type: string
required: required:
- members - members
required: required:

View File

@ -37,6 +37,11 @@ Identifier:
kind: file_id kind: file_id
- range: - range:
kind: range kind: range
derive:
- Clone
- PartialEq
- Eq
- Hash
FullyQualifiedName: FullyQualifiedName:
struct: struct:
children: children:
@ -867,8 +872,8 @@ ComparisonRhs:
- expression: - expression:
member: member:
rule: ShiftExpression rule: ShiftExpression
build: build:
node: node:
kind: Expression kind: Expression
with: ShiftExpression with: ShiftExpression
ComparisonOperator: ComparisonOperator:
@ -907,8 +912,8 @@ ShiftRhs:
- expression: - expression:
member: member:
rule: AdditiveExpression rule: AdditiveExpression
build: build:
node: node:
kind: Expression kind: Expression
with: AdditiveExpression with: AdditiveExpression
ShiftOperator: ShiftOperator:
@ -943,8 +948,8 @@ AdditiveRhs:
- expression: - expression:
member: member:
rule: MultiplicativeExpression rule: MultiplicativeExpression
build: build:
node: node:
kind: Expression kind: Expression
with: MultiplicativeExpression with: MultiplicativeExpression
AdditiveOperator: AdditiveOperator:
@ -979,8 +984,8 @@ MultiplicativeRhs:
- expression: - expression:
member: member:
rule: PrefixExpression rule: PrefixExpression
build: build:
node: node:
kind: Expression kind: Expression
with: PrefixExpression with: PrefixExpression
MultiplicativeOperator: MultiplicativeOperator:
@ -999,10 +1004,10 @@ PrefixExpression:
variant: Prefix variant: Prefix
children: children:
- operator: - operator:
on_each: on_each:
rule: PrefixOperator rule: PrefixOperator
- expression: - expression:
use_current: use_current:
kind: Expression kind: Expression
- SuffixExpression: - SuffixExpression:
pass_through: pass_through:
@ -1075,7 +1080,7 @@ ListExpression:
children: children:
- expression_list - expression_list
ParenthesizedExpression: ParenthesizedExpression:
node_production: node_production:
kind: Expression kind: Expression
with: Expression with: Expression