Add file_id param/prop and Range props.

This commit is contained in:
Jesse Brault 2025-09-25 18:42:02 -05:00
parent 41673a68f8
commit 5b5386c7e3
18 changed files with 147 additions and 86 deletions

View File

@ -19,7 +19,7 @@ pub fn make_leaf_enum_build_fn(leaf_enum_build_spec: &LeafEnumBuildSpec) -> Toke
.collect::<Vec<_>>();
quote! {
fn #build_fn_ident(#pair_ident: Pair<Rule>) -> #return_type_ident {
fn #build_fn_ident(file_id: usize, #pair_ident: Pair<Rule>) -> #return_type_ident {
let inner_pair = #pair_ident.into_inner().next().unwrap();
match inner_pair.as_rule() {
#(#rule_branches,)*

View File

@ -18,6 +18,22 @@ pub fn make_leaf_struct_build_fn(build_spec: &LeafStructBuildSpec) -> TokenStrea
let #child_ident = #pair_ident.as_str()
}
}
LeafStructMemberKind::FileId => {
quote! {
let #child_ident = file_id
}
}
LeafStructMemberKind::Range => {
quote! {
let #child_ident = {
let as_span = #pair_ident.as_span();
Range {
start: as_span.start(),
end: as_span.end()
}
}
}
}
}
})
.collect::<Vec<_>>();
@ -28,7 +44,7 @@ pub fn make_leaf_struct_build_fn(build_spec: &LeafStructBuildSpec) -> TokenStrea
.collect::<Vec<_>>();
quote! {
fn #build_fn_ident(#pair_ident: Pair<Rule>) -> #return_type_ident {
fn #build_fn_ident(file_id: usize, #pair_ident: Pair<Rule>) -> #return_type_ident {
#(#child_builders;)*
#return_type_ident::new(
#(#child_args,)*

View File

@ -10,9 +10,9 @@ pub fn make_node_production_build_fn(spec: &NodeProductionBuildSpec) -> TokenStr
let inner_build_fn_ident = format_ident!("{}", spec.with());
quote! {
fn #build_fn_ident(#pair_ident: Pair<Rule>) -> #return_type_ident {
fn #build_fn_ident(file_id: usize, #pair_ident: Pair<Rule>) -> #return_type_ident {
let inner_pair = #pair_ident.into_inner().next().unwrap();
#inner_build_fn_ident(inner_pair)
#inner_build_fn_ident(file_id, inner_pair)
}
}
}

View File

@ -12,7 +12,7 @@ fn make_pass_through(pass_through: &PolymorphicEnumLoopRulePassThrough) -> Token
let inner_build_fn_ident = format_ident!("{}", pass_through.with());
quote! {
Rule::#rule_ident => {
result = Some(#inner_build_fn_ident(inner_pair))
result = Some(#inner_build_fn_ident(file_id, inner_pair))
}
}
}
@ -20,7 +20,7 @@ fn make_pass_through(pass_through: &PolymorphicEnumLoopRulePassThrough) -> Token
fn make_on_each_child_build(child: &PolymorphicEnumLoopRuleChildOnEach) -> TokenStream {
let child_build_fn_ident = format_ident!("{}", make_build_fn_name(child.rule()));
quote! {
Box::new(#child_build_fn_ident(inner_pair))
Box::new(#child_build_fn_ident(file_id, inner_pair))
}
}
@ -93,7 +93,7 @@ pub fn make_polymorphic_enum_loop_build_fn(spec: &PolymorphicEnumLoopBuildSpec)
.collect::<Vec<_>>();
quote! {
fn #build_fn_ident(#pair_ident: Pair<Rule>) -> #return_type_ident {
fn #build_fn_ident(file_id: usize, #pair_ident: Pair<Rule>) -> #return_type_ident {
let mut result: Option<#return_type_ident> = None;
for inner_pair in #iter_expr {
match inner_pair.as_rule() {

View File

@ -1,5 +1,7 @@
use crate::deserialize::util::{make_build_fn_name, make_build_pair};
use crate::spec::polymorphic_pass_through_spec::{PolymorphicPassThroughBuildSpec, PolymorphicPassThroughVariant};
use crate::spec::polymorphic_pass_through_spec::{
PolymorphicPassThroughBuildSpec, PolymorphicPassThroughVariant,
};
use proc_macro2::TokenStream;
use quote::{format_ident, quote};
@ -10,9 +12,9 @@ pub fn make_polymorphic_pass_through_build_fn(
let pair_ident = format_ident!("{}", make_build_pair(spec.name()));
let return_type_ident = format_ident!("{}", spec.build_kind());
let match_arms = spec.variants()
.map(|variant| {
match variant {
let match_arms = spec
.variants()
.map(|variant| match variant {
PolymorphicPassThroughVariant::Inner { name, kind } => {
let rule_ident = format_ident!("{}", kind);
let variant_ident = format_ident!("{}", name);
@ -21,7 +23,7 @@ pub fn make_polymorphic_pass_through_build_fn(
quote! {
Rule::#rule_ident => {
#return_type_ident::#variant_ident(
#inner_build_fn_ident(inner_pair)
#inner_build_fn_ident(file_id, inner_pair)
)
}
}
@ -31,15 +33,14 @@ pub fn make_polymorphic_pass_through_build_fn(
let inner_build_fn_ident = format_ident!("{}", make_build_fn_name(name));
quote! {
Rule::#rule_ident => #inner_build_fn_ident(inner_pair)
}
Rule::#rule_ident => #inner_build_fn_ident(file_id, inner_pair)
}
}
})
.collect::<Vec<_>>();
quote! {
fn #build_fn_ident(#pair_ident: Pair<Rule>) -> #return_type_ident {
fn #build_fn_ident(file_id: usize, #pair_ident: Pair<Rule>) -> #return_type_ident {
let inner_pair = #pair_ident.into_inner().next().unwrap();
match inner_pair.as_rule() {
#(#match_arms,)*

View File

@ -10,9 +10,9 @@ pub fn make_polymorphic_type_build_fn(build_spec: &PolymorphicTypeBuildSpec) ->
let inner_build_fn_ident = format_ident!("{}", make_build_fn_name(build_spec.kind()));
quote! {
fn #build_fn_ident(#pair_ident: Pair<Rule>) -> #return_type_ident {
fn #build_fn_ident(file_id: usize, #pair_ident: Pair<Rule>) -> #return_type_ident {
let inner_pair = #pair_ident.into_inner().next().unwrap();
#inner_build_fn_ident(inner_pair)
#inner_build_fn_ident(file_id, inner_pair)
}
}
}

View File

@ -80,7 +80,7 @@ pub fn make_production_build_fn(production_build_spec: &ProductionBuildSpec) ->
};
quote! {
fn #build_fn_ident(#pair_ident: Pair<Rule>) -> #return_type_ident {
fn #build_fn_ident(file_id: usize, #pair_ident: Pair<Rule>) -> #return_type_ident {
#pair_mapper
}
}

View File

@ -56,13 +56,13 @@ fn make_vec_child_match_action(vec_child: &VecChild) -> TokenStream {
VecChildBuild::String(string_build) => {
let build_fn_ident = format_ident!("{}", string_build.with());
quote! {
#child_name_ident.push(#build_fn_ident(inner_pair))
#child_name_ident.push(#build_fn_ident(file_id, inner_pair))
}
}
VecChildBuild::Node(node_build) => {
let build_fn_ident = format_ident!("{}", node_build.with());
quote! {
#child_name_ident.push(Box::new(#build_fn_ident(inner_pair)))
#child_name_ident.push(Box::new(#build_fn_ident(file_id, inner_pair)))
}
}
}
@ -72,7 +72,7 @@ fn make_node_member_child_match_action(name: &str, node_child: &NodeMemberBuild)
let child_name_ident = format_ident!("{}", name);
let build_fn_ident = format_ident!("{}", node_child.with());
quote! {
#child_name_ident = Some(Box::new(#build_fn_ident(inner_pair)))
#child_name_ident = Some(Box::new(#build_fn_ident(file_id, inner_pair)))
}
}
@ -204,7 +204,7 @@ pub fn make_struct_build_fn(build_spec: &StructSpec) -> TokenStream {
let new_stream = make_return_value_stream(build_spec);
quote! {
fn #build_fn_ident(#pair_ident: Pair<Rule>) -> #return_type_ident {
fn #build_fn_ident(file_id: usize, #pair_ident: Pair<Rule>) -> #return_type_ident {
#(#child_holders;)*
#iter_stream

View File

@ -17,27 +17,27 @@ pub fn make_enum_build_fn(enum_build_spec: &TreeEnumBuildSpec) -> TokenStream {
EnumRuleChildKind::Node(node_child) => {
let inner_build_fn_ident =
format_ident!("{}", node_child.with());
quote! { #inner_build_fn_ident(inner_pair) }
quote! { #inner_build_fn_ident(file_id, inner_pair) }
}
EnumRuleChildKind::Int(name_and_with) => {
let inner_build_fn_ident = format_ident!("{}", name_and_with.with());
quote! { #inner_build_fn_ident(inner_pair) }
quote! { #inner_build_fn_ident(file_id, inner_pair) }
}
EnumRuleChildKind::Long(name_and_with) => {
let inner_build_fn_ident = format_ident!("{}", name_and_with.with());
quote! { #inner_build_fn_ident(inner_pair) }
quote! { #inner_build_fn_ident(file_id, inner_pair) }
}
EnumRuleChildKind::Double(name_and_with) => {
let inner_build_fn_ident = format_ident!("{}", name_and_with.with());
quote! { #inner_build_fn_ident(inner_pair) }
quote! { #inner_build_fn_ident(file_id, inner_pair) }
}
EnumRuleChildKind::String(name_and_with) => {
let inner_build_fn_ident = format_ident!("{}", name_and_with.with());
quote! { #inner_build_fn_ident(inner_pair) }
quote! { #inner_build_fn_ident(file_id, inner_pair) }
}
EnumRuleChildKind::Boolean(name_and_with) => {
let inner_build_fn_ident = format_ident!("{}", name_and_with.with());
quote! { #inner_build_fn_ident(inner_pair) }
quote! { #inner_build_fn_ident(file_id, inner_pair) }
}
};
quote! {
@ -52,7 +52,7 @@ pub fn make_enum_build_fn(enum_build_spec: &TreeEnumBuildSpec) -> TokenStream {
.collect::<Vec<_>>();
quote! {
fn #build_fn_ident(#pair_ident: Pair<Rule>) -> #return_type_ident {
fn #build_fn_ident(file_id: usize, #pair_ident: Pair<Rule>) -> #return_type_ident {
let inner_pair = #pair_ident.into_inner().next().unwrap();
match inner_pair.as_rule() {
#(#rule_branches,)*

View File

@ -2,8 +2,14 @@ use crate::deserialize::util::unwrap_single_member_hash;
use yaml_rust2::Yaml;
use crate::spec::leaf_struct_spec::{LeafStructBuildSpec, LeafStructMember, LeafStructMemberKind};
fn deserialize_member(member_name: &str) -> LeafStructMember {
LeafStructMember::new(member_name, LeafStructMemberKind::String)
fn deserialize_member(member_name: &str, member_props: &Yaml) -> LeafStructMember {
let kind = match member_props["kind"].as_str().unwrap() {
"string" => LeafStructMemberKind::String,
"file_id" => LeafStructMemberKind::FileId,
"range" => LeafStructMemberKind::Range,
_ => panic!()
};
LeafStructMember::new(member_name, kind)
}
pub fn deserialize_leaf_struct(name: &str, props: &Yaml) -> LeafStructBuildSpec {
@ -12,8 +18,8 @@ pub fn deserialize_leaf_struct(name: &str, props: &Yaml) -> LeafStructBuildSpec
.unwrap()
.iter()
.map(|member_hash| {
let (member_name, _props) = unwrap_single_member_hash(member_hash);
deserialize_member(&member_name)
let (member_name, props) = unwrap_single_member_hash(member_hash);
deserialize_member(&member_name, props)
})
.map(Box::new)
.collect();

View File

@ -85,12 +85,10 @@ fn generate_build_file(build_specs: &[BuildSpec]) -> AstGeneratedFile {
.collect::<Vec<_>>();
let combined = quote! {
//noinspection RsUnusedImport
use crate::parser::Rule;
//noinspection RsUnusedImport
use pest::iterators::Pair;
//noinspection RsUnusedImport
use crate::ast::node::*;
use std::range::Range;
#(#build_fns)*
};
@ -108,6 +106,8 @@ fn generate_node_file(build_specs: &[BuildSpec]) -> AstGeneratedFile {
.filter(Option::is_some)
.collect::<Vec<_>>();
let combined = quote! {
use std::range::Range;
#(#types)*
};
AstGeneratedFile {

View File

@ -1,5 +1,8 @@
use crate::spec::leaf_enum_spec::LeafEnumBuildSpec;
use crate::spec::leaf_struct_spec::{LeafStructBuildSpec, LeafStructMemberKind};
use crate::spec::polymorphic_enum_loop_spec::{
PolymorphicEnumLoopBuildSpec, PolymorphicEnumLoopRule, PolymorphicEnumLoopRuleBuildChild,
};
use crate::spec::polymorphic_type_spec::PolymorphicTypeBuildSpec;
use crate::spec::struct_spec::{MemberChildBuild, StructChild, StructSpec, VecChildBuild};
use crate::spec::tree_enum_spec::{EnumRuleChildKind, TreeEnumBuildSpec};
@ -7,28 +10,25 @@ use crate::spec::BuildSpec;
use convert_case::{Case, Casing};
use proc_macro2::TokenStream;
use quote::{format_ident, quote};
use crate::spec::polymorphic_enum_loop_spec::{PolymorphicEnumLoopBuildSpec, PolymorphicEnumLoopRule, PolymorphicEnumLoopRuleBuildChild};
fn make_polymorphic_enum_loop_p2_impl(spec: &PolymorphicEnumLoopBuildSpec) -> TokenStream {
let type_ident = format_ident!("{}", spec.name());
let type_string = spec.name();
let build = spec.rules()
.find(|rule| {
match rule {
let build = spec
.rules()
.find(|rule| match rule {
PolymorphicEnumLoopRule::Build(_) => true,
_ => false
}
_ => false,
})
.map(|rule| {
match rule {
.map(|rule| match rule {
PolymorphicEnumLoopRule::Build(build) => build,
_ => unreachable!()
}
_ => unreachable!(),
})
.unwrap();
let child_print_statements = build.children()
let child_print_statements = build
.children()
.map(|child| {
let child_ident = match child {
PolymorphicEnumLoopRuleBuildChild::UseCurrent(use_current) => {
@ -159,6 +159,8 @@ fn make_leaf_struct_p2_impl(leaf_struct_build_spec: &LeafStructBuildSpec) -> Tok
.members()
.map(|member| match member.kind() {
LeafStructMemberKind::String => Some("{}"),
LeafStructMemberKind::FileId => None,
LeafStructMemberKind::Range => None,
})
.filter(Option::is_some)
.map(Option::unwrap)
@ -169,12 +171,17 @@ fn make_leaf_struct_p2_impl(leaf_struct_build_spec: &LeafStructBuildSpec) -> Tok
let members = leaf_struct_build_spec
.members()
.map(|member| {
.map(|member| match member.kind() {
LeafStructMemberKind::String => {
let member_ident = format_ident!("{}", member.name());
quote! {
Some(quote! {
self.#member_ident()
}
})
}
_ => None,
})
.filter(Option::is_some)
.map(Option::unwrap)
.collect::<Vec<_>>();
quote! {
@ -260,6 +267,6 @@ pub fn make_pretty_print_impl(build_spec: &BuildSpec) -> Option<TokenStream> {
BuildSpec::PolymorphicPassThrough(_) => None,
BuildSpec::PolymorphicEnumLoop(polymorphic_enum_loop) => {
Some(make_polymorphic_enum_loop_p2_impl(polymorphic_enum_loop))
},
}
}
}

View File

@ -44,4 +44,6 @@ impl LeafStructMember {
pub enum LeafStructMemberKind {
String,
FileId,
Range
}

View File

@ -10,7 +10,9 @@ pub fn make_leaf_struct_type(build_spec: &LeafStructBuildSpec) -> TokenStream {
.map(|member| {
let name_ident = format_ident!("{}", member.name());
let type_ident = match member.kind() {
LeafStructMemberKind::String => format_ident!("{}", "String"),
LeafStructMemberKind::String => quote! { String },
LeafStructMemberKind::FileId => quote! { usize },
LeafStructMemberKind::Range => quote! { Range<usize> },
};
quote! {
#name_ident: #type_ident
@ -24,6 +26,12 @@ pub fn make_leaf_struct_type(build_spec: &LeafStructBuildSpec) -> TokenStream {
LeafStructMemberKind::String => {
quote! { &str }
}
LeafStructMemberKind::FileId => {
quote! { usize }
}
LeafStructMemberKind::Range => {
quote! { Range<usize> }
}
};
quote! {
#name_ident: #type_stream
@ -40,6 +48,7 @@ pub fn make_leaf_struct_type(build_spec: &LeafStructBuildSpec) -> TokenStream {
#member_ident: #member_ident.to_string()
}
}
_ => quote! { #member_ident },
}
})
.collect::<Vec<_>>();
@ -56,6 +65,20 @@ pub fn make_leaf_struct_type(build_spec: &LeafStructBuildSpec) -> TokenStream {
}
}
}
LeafStructMemberKind::FileId => {
quote! {
pub fn #name_ident(&self) -> usize {
self.#name_ident
}
}
}
LeafStructMemberKind::Range => {
quote! {
pub fn #name_ident(&self) -> Range<usize> {
self.#name_ident
}
}
}
}
})
.collect::<Vec<_>>();

View File

@ -49,9 +49,9 @@ pub mod build {
include!(concat!(env!("OUT_DIR"), "/src/ast/build.rs"));
pub fn build_ast(parsed_pairs: &mut Pairs<Rule>) -> Box<CompilationUnit> {
pub fn build_ast(file_id: usize, parsed_pairs: &mut Pairs<Rule>) -> Box<CompilationUnit> {
let compilation_unit_pair = parsed_pairs.next().unwrap();
Box::new(build_compilation_unit(compilation_unit_pair))
Box::new(build_compilation_unit(file_id, compilation_unit_pair))
}
#[cfg(test)]
@ -71,7 +71,7 @@ pub mod build {
Rule::BooleanLiteral,
include_str!("build_tests/boolean_literal/true"),
);
assert_eq!(true, build_boolean_literal(pair));
assert_eq!(true, build_boolean_literal(0, pair));
}
#[test]
@ -80,7 +80,7 @@ pub mod build {
Rule::BooleanLiteral,
include_str!("build_tests/boolean_literal/false"),
);
assert_eq!(false, build_boolean_literal(pair));
assert_eq!(false, build_boolean_literal(0, pair));
}
#[test]
@ -89,7 +89,7 @@ pub mod build {
Rule::BacktickInner,
include_str!("build_tests/backtick_inner/greeting"),
);
assert_eq!("Hello, World!", build_backtick_inner(pair));
assert_eq!("Hello, World!", build_backtick_inner(0, pair));
}
#[test]
@ -98,7 +98,7 @@ pub mod build {
Rule::BacktickString,
include_str!("build_tests/backtick_string/mixed"),
);
let backtick_string = build_backtick_string(pair);
let backtick_string = build_backtick_string(0, pair);
assert_eq!(backtick_string.inners().count(), 2);
assert_eq!(backtick_string.expressions().count(), 1);
}
@ -106,20 +106,20 @@ pub mod build {
#[test]
fn d_string_expression_simple() {
let pair = parse(Rule::DStringExpression, "${thing}");
let d_string_expression = build_d_string_expression(pair);
let d_string_expression = build_d_string_expression(0, pair);
}
#[test]
fn d_string_inner() {
let pair = parse(Rule::DStringInner, "Hello!");
let d_string_inner = build_d_string_inner(pair);
let d_string_inner = build_d_string_inner(0, pair);
assert_eq!("Hello!", d_string_inner);
}
#[test]
fn d_string_mixed() {
let pair = parse(Rule::DString, "\"Hello, ${world}!\"");
let d_string = build_d_string(pair);
let d_string = build_d_string(0, pair);
assert_eq!(d_string.inners().count(), 2);
assert_eq!(d_string.expressions().count(), 1);
}
@ -127,7 +127,7 @@ pub mod build {
#[test]
fn expression_simple_call() {
let pair = parse(Rule::Expression, "hello(42)");
let expression = build_expression(pair);
let expression = build_expression(0, pair);
}
}
}

View File

@ -10,7 +10,7 @@ pub fn pretty_print_parse(path: &PathBuf) {
let parse_result = DeimosParser::parse(Rule::CompilationUnit, &src);
match parse_result {
Ok(mut pairs) => {
let compilation_unit = build_ast(&mut pairs);
let compilation_unit = build_ast(0, &mut pairs);
let mut indent_writer = IndentWriter::new(0, " ", Box::new(std::io::stdout()));
compilation_unit
.pretty_print(&mut indent_writer)

View File

@ -223,6 +223,8 @@ $defs:
kind:
enum:
- string
- file_id
- range
required:
- kind

View File

@ -33,6 +33,10 @@ Identifier:
members:
- name:
kind: string
- file_id:
kind: file_id
- range:
kind: range
FullyQualifiedName:
struct:
children: