Compare commits

..

No commits in common. "eaebf8c926df80f64f3930d69e1532c6a635addc" and "df8e2279dcd7621ae7a158743ec823e7a81b096e" have entirely different histories.

20 changed files with 1406 additions and 1813 deletions

View File

@ -1,50 +1,6 @@
use convert_case::{Case, Casing}; use crate::spec::tree_enum_spec::TreeEnumBuildSpec;
use crate::spec::tree_enum_spec::{EnumRuleChildKind, TreeEnumBuildSpec};
use proc_macro2::TokenStream; use proc_macro2::TokenStream;
use quote::{format_ident, quote};
pub fn make_enum_ast_node_impl(enum_spec: &TreeEnumBuildSpec) -> TokenStream { pub fn make_enum_ast_node_impl(enum_spec: &TreeEnumBuildSpec) -> TokenStream {
let type_ident = format_ident!("{}", enum_spec.build()); todo!()
let match_arms = enum_spec
.rules()
.map(|rule| {
let rule_ident = format_ident!("{}", rule.rule());
match rule.child() {
Some(child) => {
match child.kind() {
EnumRuleChildKind::Node(node_child) => {
let child_ident = format_ident!("{}", node_child.node_kind().to_case(Case::Snake));
quote! {
#type_ident::#rule_ident(#child_ident) => vec![
#child_ident.as_node_ref()
]
}
}
_ => quote! {
#type_ident::#rule_ident(_) => vec![]
}
}
},
None => {
quote! {
#type_ident::#rule_ident => vec![]
}
}
}
})
.collect::<Vec<_>>();
quote! {
impl AstNode for #type_ident {
fn children(&self) -> Vec<AstNodeRef> {
match self {
#(#match_arms,)*
}
}
fn as_node_ref(&self) -> AstNodeRef {
AstNodeRef::#type_ident(&self)
}
}
}
} }

View File

@ -1,18 +1,6 @@
use proc_macro2::TokenStream; use proc_macro2::TokenStream;
use quote::{format_ident, quote};
use crate::spec::leaf_enum_spec::LeafEnumBuildSpec; use crate::spec::leaf_enum_spec::LeafEnumBuildSpec;
pub fn make_leaf_enum_ast_node_impl(spec: &LeafEnumBuildSpec) -> TokenStream { pub fn make_leaf_enum_ast_node_impl(spec: &LeafEnumBuildSpec) -> TokenStream {
let type_ident = format_ident!("{}", spec.build()); todo!()
quote! {
impl AstNode for #type_ident {
fn children(&self) -> Vec<AstNodeRef> {
vec![]
}
fn as_node_ref(&self) -> AstNodeRef {
AstNodeRef::#type_ident(&self)
}
}
}
} }

View File

@ -1,18 +1,6 @@
use crate::spec::leaf_struct_spec::LeafStructBuildSpec;
use proc_macro2::TokenStream; use proc_macro2::TokenStream;
use quote::{format_ident, quote}; use crate::spec::leaf_struct_spec::LeafStructBuildSpec;
pub fn make_leaf_struct_ast_node_impl(spec: &LeafStructBuildSpec) -> TokenStream { pub fn make_leaf_struct_ast_node_impl(spec: &LeafStructBuildSpec) -> TokenStream {
let type_ident = format_ident!("{}", spec.build()); todo!()
quote! {
impl AstNode for #type_ident {
fn children(&self) -> Vec<AstNodeRef> {
vec![]
}
fn as_node_ref(&self) -> AstNodeRef {
AstNodeRef::#type_ident(&self)
}
}
}
} }

View File

@ -44,30 +44,9 @@ pub fn make_ast_node_impl(build_spec: &BuildSpec) -> Option<TokenStream> {
pub fn make_ast_enum_member(build_spec: &BuildSpec) -> Option<TokenStream> { pub fn make_ast_enum_member(build_spec: &BuildSpec) -> Option<TokenStream> {
match build_spec { match build_spec {
BuildSpec::Struct(struct_spec) => { BuildSpec::Struct(struct_spec) => {
Some(format_ident!("{}", struct_spec.build())) let type_ident = format_ident!("{}", struct_spec.build());
Some(quote! { #type_ident(#type_ident) })
} }
BuildSpec::LeafStruct(leaf_struct) => { _ => None,
Some(format_ident!("{}", leaf_struct.build()))
}
BuildSpec::Enum(enum_spec) => {
Some(format_ident!("{}", enum_spec.build()))
}
BuildSpec::LeafEnum(leaf_enum) => {
Some(format_ident!("{}", leaf_enum.build()))
}
BuildSpec::PolymorphicType(polymorphic_type) => {
Some(format_ident!("{}", polymorphic_type.name()))
},
BuildSpec::PolymorphicEnumLoop(polymorphic_enum_loop) => {
Some(format_ident!("{}", polymorphic_enum_loop.name()))
}
BuildSpec::PolymorphicPassThrough(_) => None,
BuildSpec::Production(_) => None,
BuildSpec::NodeProduction(_) => None,
} }
.map(|type_ident| {
quote! {
#type_ident(&'a #type_ident)
}
})
} }

View File

@ -1,49 +1,6 @@
use crate::spec::polymorphic_enum_loop_spec::{
PolymorphicEnumLoopBuildSpec, PolymorphicEnumLoopRule, PolymorphicEnumLoopRuleBuildChild,
};
use proc_macro2::TokenStream; use proc_macro2::TokenStream;
use quote::{format_ident, quote}; use crate::spec::polymorphic_enum_loop_spec::PolymorphicEnumLoopBuildSpec;
pub fn make_polymorphic_enum_loop_ast_node_impl( pub fn make_polymorphic_enum_loop_ast_node_impl(spec: &PolymorphicEnumLoopBuildSpec) -> TokenStream {
spec: &PolymorphicEnumLoopBuildSpec, todo!()
) -> TokenStream {
let type_ident = format_ident!("{}", spec.name());
let build_rule = spec
.rules()
.filter_map(|rule| match rule {
PolymorphicEnumLoopRule::PassThrough(_) => None,
PolymorphicEnumLoopRule::Build(build_rule) => Some(build_rule),
})
.next()
.unwrap();
let child_adders = build_rule
.children()
.map(|child| {
let child_ident = match child {
PolymorphicEnumLoopRuleBuildChild::UseCurrent(use_current) => {
format_ident!("{}", use_current.name())
}
PolymorphicEnumLoopRuleBuildChild::OnEach(on_each) => {
format_ident!("{}", on_each.name())
}
};
quote! {
children.push(self.#child_ident().as_node_ref())
}
})
.collect::<Vec<_>>();
quote! {
impl AstNode for #type_ident {
fn children(&self) -> Vec<AstNodeRef> {
let mut children: Vec<AstNodeRef> = vec![];
#(#child_adders;)*
children
}
fn as_node_ref(&self) -> AstNodeRef {
AstNodeRef::#type_ident(&self)
}
}
}
} }

View File

@ -1,32 +1,6 @@
use crate::spec::polymorphic_type_spec::PolymorphicTypeBuildSpec;
use convert_case::{Case, Casing};
use proc_macro2::TokenStream; use proc_macro2::TokenStream;
use quote::{format_ident, quote}; use crate::spec::polymorphic_type_spec::PolymorphicTypeBuildSpec;
pub fn make_polymorphic_type_ast_node_impl(spec: &PolymorphicTypeBuildSpec) -> TokenStream { pub fn make_polymorphic_type_ast_node_impl(spec: &PolymorphicTypeBuildSpec) -> TokenStream {
let type_ident = format_ident!("{}", spec.name()); todo!()
let match_arms = spec
.variants()
.map(|variant| {
let variant_ident = format_ident!("{}", variant.name());
let child_ident = format_ident!("{}", variant.inner_kind().to_case(Case::Snake));
quote! {
#type_ident::#variant_ident(#child_ident) => vec![#child_ident.as_node_ref()]
}
})
.collect::<Vec<_>>();
quote! {
impl AstNode for #type_ident {
fn children(&self) -> Vec<AstNodeRef> {
match self {
#(#match_arms,)*
}
}
fn as_node_ref(&self) -> AstNodeRef {
AstNodeRef::#type_ident(&self)
}
}
}
} }

View File

@ -8,35 +8,32 @@ pub fn make_struct_ast_node_impl(spec: &StructSpec) -> TokenStream {
.children() .children()
.map(|child| match child { .map(|child| match child {
StructChild::SkipChild(_) => None, StructChild::SkipChild(_) => None,
StructChild::VecChild(vec_child) => match vec_child.build() { StructChild::VecChild(vec_child) => {
VecChildBuild::String(_) => None, match vec_child.build() {
VecChildBuild::Node(_) => { VecChildBuild::String(_) => None,
let child_ident = format_ident!("{}", vec_child.name()); VecChildBuild::Node(_) => {
let children_stream = quote! { let child_ident = format_ident!("{}", vec_child.name());
for child in self.#child_ident().map(AstNode::as_node_ref) { let children_stream = quote! {
children.push(child); for child in self.#child_ident().map(AstNode::as_node_ref).collect() {
} children.push(child);
};
Some(children_stream)
}
},
StructChild::MemberChild(member_child) => match member_child.build() {
MemberChildBuild::Node(_) => {
let child_ident = format_ident!("{}", member_child.name());
if member_child.optional() {
Some(quote! {
if let Some(#child_ident) = self.#child_ident() {
children.push(#child_ident.as_node_ref());
} }
}) };
} else { Some(children_stream)
Some(quote! {
children.push(self.#child_ident().as_node_ref())
})
} }
} }
MemberChildBuild::Boolean(_) => None, }
}, StructChild::MemberChild(member_child) => {
match member_child.build() {
MemberChildBuild::Node(_) => {
let child_ident = format_ident!("{}", member_child.name());
let child_stream = quote! {
children.add(self.#child_ident().as_node_ref())
};
Some(child_stream)
}
MemberChildBuild::Boolean(_) => None
}
}
}) })
.filter(Option::is_some) .filter(Option::is_some)
.map(Option::unwrap) .map(Option::unwrap)
@ -45,7 +42,7 @@ pub fn make_struct_ast_node_impl(spec: &StructSpec) -> TokenStream {
quote! { quote! {
impl AstNode for #type_ident { impl AstNode for #type_ident {
fn children(&self) -> Vec<AstNodeRef> { fn children(&self) -> Vec<AstNodeRef> {
let mut children: Vec<AstNodeRef> = vec![]; let children: Vec<AstNodeRef> = vec![];
#(#child_adders;)* #(#child_adders;)*
children children
} }

View File

@ -23,15 +23,5 @@ pub fn deserialize_leaf_struct(name: &str, props: &Yaml) -> LeafStructBuildSpec
}) })
.map(Box::new) .map(Box::new)
.collect(); .collect();
let derive = props["derive"] LeafStructBuildSpec::new(name, members)
.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

@ -4,14 +4,12 @@ mod deserialize;
mod pretty_print; mod pretty_print;
mod spec; mod spec;
mod type_gen; mod type_gen;
mod walk;
use crate::ast_node::{make_ast_enum_member, make_ast_node_impl}; use crate::ast_node::{make_ast_enum_member, make_ast_node_impl};
use crate::build_fn::make_build_fn; use crate::build_fn::make_build_fn;
use crate::deserialize::deserialize_yaml_spec; use crate::deserialize::deserialize_yaml_spec;
use crate::pretty_print::make_pretty_print_impl; use crate::pretty_print::make_pretty_print_impl;
use crate::type_gen::make_type; use crate::type_gen::make_type;
use crate::walk::make_walk_fn;
use proc_macro2::TokenStream; use proc_macro2::TokenStream;
use quote::quote; use quote::quote;
use spec::BuildSpec; use spec::BuildSpec;
@ -168,7 +166,7 @@ fn generate_ast_node_file(build_specs: &[BuildSpec]) -> AstGeneratedFile {
let combined = quote! { let combined = quote! {
use crate::ast::node::*; use crate::ast::node::*;
pub enum AstNodeRef<'a> { pub enum AstNodeRef {
#(#ast_enum_members,)* #(#ast_enum_members,)*
} }
@ -186,14 +184,6 @@ fn generate_ast_node_file(build_specs: &[BuildSpec]) -> AstGeneratedFile {
} }
} }
fn generate_walk_file(build_specs: &[BuildSpec]) -> AstGeneratedFile {
let stream = make_walk_fn(build_specs);
AstGeneratedFile {
name: String::from("walk.rs"),
contents: token_stream_to_string(stream),
}
}
pub fn get_build_specs(yaml: &str) -> Vec<BuildSpec> { pub fn get_build_specs(yaml: &str) -> Vec<BuildSpec> {
deserialize_yaml_spec(yaml) deserialize_yaml_spec(yaml)
} }
@ -204,6 +194,5 @@ pub fn generate_files(build_specs: &[BuildSpec]) -> Vec<AstGeneratedFile> {
generate_node_file(build_specs), generate_node_file(build_specs),
generate_pretty_print_file(build_specs), generate_pretty_print_file(build_specs),
generate_ast_node_file(build_specs), generate_ast_node_file(build_specs),
generate_walk_file(build_specs),
] ]
} }

View File

@ -1,15 +1,13 @@
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>>, derive: Vec<String>) -> Self { pub fn new(build: &str, members: Vec<Box<LeafStructMember>>) -> Self {
Self { Self {
build: build.to_string(), build: build.to_string(),
members, members,
derive,
} }
} }
@ -20,10 +18,6 @@ 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,27 +83,10 @@ pub fn make_leaf_struct_type(build_spec: &LeafStructBuildSpec) -> TokenStream {
}) })
.collect::<Vec<_>>(); .collect::<Vec<_>>();
let struct_stream = if build_spec.derive().count() > 0 {
let derives = build_spec.derive().map(|derive| {
format_ident!("{}", derive)
}).collect::<Vec<_>>();
quote! {
#[derive(#(#derives),*)]
pub struct #type_ident {
#(#annotated_members),*
}
}
} else {
quote! {
pub struct #type_ident {
#(#annotated_members),*
}
}
};
quote! { quote! {
#struct_stream pub struct #type_ident {
#(#annotated_members),*
}
impl #type_ident { impl #type_ident {
pub fn new(#(#member_args),*) -> Self { pub fn new(#(#member_args),*) -> Self {

View File

@ -1,61 +0,0 @@
use crate::spec::BuildSpec;
use convert_case::{Case, Casing};
use proc_macro2::TokenStream;
use quote::{format_ident, quote};
pub fn make_walk_fn(specs: &[BuildSpec]) -> TokenStream {
let child_match_arms = specs
.iter()
.map(|spec| match spec {
BuildSpec::Enum(enum_spec) => Some((
format_ident!("{}", enum_spec.build()),
format_ident!("{}", enum_spec.build().to_case(Case::Snake)),
)),
BuildSpec::LeafEnum(leaf_enum) => Some((
format_ident!("{}", leaf_enum.build()),
format_ident!("{}", leaf_enum.build().to_case(Case::Snake)),
)),
BuildSpec::Struct(struct_spec) => Some((
format_ident!("{}", struct_spec.build()),
format_ident!("{}", struct_spec.build().to_case(Case::Snake)),
)),
BuildSpec::LeafStruct(leaf_struct) => Some((
format_ident!("{}", leaf_struct.build()),
format_ident!("{}", leaf_struct.build().to_case(Case::Snake)),
)),
BuildSpec::Production(_) => None,
BuildSpec::NodeProduction(_) => None,
BuildSpec::PolymorphicType(polymorphic_type) => Some((
format_ident!("{}", polymorphic_type.name()),
format_ident!("{}", polymorphic_type.name().to_case(Case::Snake)),
)),
BuildSpec::PolymorphicEnumLoop(polymorphic_enum_loop) => Some((
format_ident!("{}", polymorphic_enum_loop.name()),
format_ident!("{}", polymorphic_enum_loop.name().to_case(Case::Snake)),
)),
BuildSpec::PolymorphicPassThrough(_) => None,
})
.filter(Option::is_some)
.map(Option::unwrap)
.map(|(type_ident, inner_ident)| {
quote! {
#type_ident(#inner_ident) => walk_depth_first(#inner_ident, f)
}
})
.collect::<Vec<_>>();
quote! {
use crate::ast::node::*;
use crate::ast::ast_node::*;
pub fn walk_depth_first(node: &impl AstNode, f: &mut impl FnMut(AstNodeRef)) {
use AstNodeRef::*;
for child in node.children() {
match child {
#(#child_match_arms,)*
}
}
f(node.as_node_ref());
}
}
}

View File

@ -161,7 +161,3 @@ pub mod ast_node {
} }
} }
} }
pub mod walk {
include!(concat!(env!("OUT_DIR"), "/src/ast/walk.rs"));
}

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(
compilation_units.as_mut_slice(), &mut compilation_units.iter().map(Box::as_mut),
&mut symbol_table &mut symbol_table
); );
if diagnostics.is_empty() { if diagnostics.is_empty() {

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -19,39 +19,32 @@ The resolve phase has one main responsibility: resolve all references based on t
`scope_id` property. `scope_id` property.
*/ */
use crate::ast::node::{CompilationUnit, Identifier}; use crate::ast::node::CompilationUnit;
use crate::diagnostic::DmDiagnostic; use crate::diagnostic::DmDiagnostic;
use crate::name_analysis::gather::gather_compilation_unit; use crate::name_analysis::gather::gather_compilation_unit;
// use crate::name_analysis::resolve::resolve_compilation_unit; use crate::name_analysis::resolve::resolve_compilation_unit;
use crate::name_analysis::symbol_table::SymbolTable; use crate::name_analysis::symbol_table::SymbolTable;
use std::collections::HashMap;
mod fqn_context; mod fqn_context;
mod gather; mod gather;
// mod resolve; mod resolve;
pub mod symbol; pub mod symbol;
pub mod symbol_table; pub mod symbol_table;
pub fn analyze_names( pub fn analyze_names(
compilation_units: &mut [Box<CompilationUnit>], compilation_units: &mut [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();
// gather symbols // gather symbols
for compilation_unit in compilation_units.iter_mut() { for compilation_unit in compilation_units.iter_mut() {
gather_compilation_unit( gather_compilation_unit(compilation_unit, symbol_table, &mut diagnostics);
compilation_unit,
symbol_table,
&mut identifier_scope_ids,
&mut diagnostics,
);
} }
// resolve symbols // resolve symbols
for compilation_unit in compilation_units.iter_mut() { for compilation_unit in compilation_units.iter_mut() {
// resolve_compilation_unit(compilation_unit, symbol_table, &mut diagnostics); resolve_compilation_unit(compilation_unit, symbol_table, &mut diagnostics);
} }
diagnostics.into() diagnostics.into()

View File

@ -57,11 +57,6 @@ $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:
@ -206,11 +201,6 @@ $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,11 +37,6 @@ Identifier:
kind: file_id kind: file_id
- range: - range:
kind: range kind: range
derive:
- Clone
- PartialEq
- Eq
- Hash
FullyQualifiedName: FullyQualifiedName:
struct: struct:
children: children: