Compare commits
	
		
			8 Commits
		
	
	
		
			e79c22db72
			...
			59165f6235
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | 59165f6235 | ||
|   | 4d70765d17 | ||
|   | 0a97cc01b9 | ||
|   | 0adb4bbe0e | ||
|   | 9f3f3e0f0d | ||
|   | 3b07cef209 | ||
|   | a53388155a | ||
|   | 4dcb5ee783 | 
| @ -1,5 +1,6 @@ | ||||
| use crate::spec::{ | ||||
|     BuildBooleanOn, ChildSpec, SingleChildToBuild, StructBuildSpec, VecChildToBuild, | ||||
|     BuildBooleanOn, ChildSpec, SingleBooleanChildToBuild, SingleChildToBuild, | ||||
|     SingleTypeChildToBuild, StructBuildSpec, VecChild, VecChildToBuild, | ||||
| }; | ||||
| use convert_case::{Case, Casing}; | ||||
| use proc_macro2::TokenStream; | ||||
| @ -9,33 +10,45 @@ pub fn make_build_fn_name(s: &str) -> String { | ||||
|     format!("build_{}", s.to_case(Case::Snake)) | ||||
| } | ||||
| 
 | ||||
| fn make_vec_child_holder(vec_child: &VecChild) -> TokenStream { | ||||
|     let (child_ident, child_type_ident) = match vec_child.build() { | ||||
|         VecChildToBuild::Type(vec_type_child) => ( | ||||
|             format_ident!("{}", vec_type_child.var_name()), | ||||
|             format_ident!("{}", vec_type_child.build()), | ||||
|         ), | ||||
|     }; | ||||
|     quote! { | ||||
|         let mut #child_ident: Vec<Box<#child_type_ident>> = vec![] | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| fn make_single_type_child_holder(single_type_child: &SingleTypeChildToBuild) -> TokenStream { | ||||
|     let child_ident = format_ident!("{}", single_type_child.var_name()); | ||||
|     let child_type_ident = format_ident!("{}", single_type_child.build()); | ||||
|     quote! { | ||||
|         let mut #child_ident: Option<Box<#child_type_ident>> = None | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| fn make_single_boolean_child_holder( | ||||
|     single_boolean_child: &SingleBooleanChildToBuild, | ||||
| ) -> TokenStream { | ||||
|     let child_ident = format_ident!("{}", single_boolean_child.var_name()); | ||||
|     quote! { | ||||
|         let mut #child_ident: bool = false | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| fn make_child_holder(child_spec: &ChildSpec) -> Option<TokenStream> { | ||||
|     match child_spec { | ||||
|         ChildSpec::SkipChild(_) => None, | ||||
|         ChildSpec::VecChild(vec_child) => { | ||||
|             let (child_ident, child_type_ident) = match vec_child.build() { | ||||
|                 VecChildToBuild::Type(vec_type_child) => ( | ||||
|                     format_ident!("{}", vec_type_child.var_name()), | ||||
|                     format_ident!("{}", vec_type_child.build()), | ||||
|                 ), | ||||
|             }; | ||||
|             Some(quote! { | ||||
|                 let mut #child_ident: Vec<#child_type_ident> = vec![] | ||||
|             }) | ||||
|         } | ||||
|         ChildSpec::VecChild(vec_child) => Some(make_vec_child_holder(vec_child)), | ||||
|         ChildSpec::SingleChild(single_child) => match single_child.build() { | ||||
|             SingleChildToBuild::Type(single_type_child) => { | ||||
|                 let child_ident = format_ident!("{}", single_type_child.var_name()); | ||||
|                 let child_type_ident = format_ident!("{}", single_type_child.build()); | ||||
|                 Some(quote! { | ||||
|                     let mut #child_ident: Option<#child_type_ident> = None; | ||||
|                 }) | ||||
|                 Some(make_single_type_child_holder(single_type_child)) | ||||
|             } | ||||
|             SingleChildToBuild::Boolean(boolean_child) => { | ||||
|                 let child_ident = format_ident!("{}", boolean_child.var_name()); | ||||
|                 Some(quote! { | ||||
|                     let #child_ident: bool = false | ||||
|                 }) | ||||
|                 Some(make_single_boolean_child_holder(boolean_child)) | ||||
|             } | ||||
|         }, | ||||
|     } | ||||
| @ -52,7 +65,7 @@ fn make_match_action(child_spec: &ChildSpec) -> TokenStream { | ||||
|                 ), | ||||
|             }; | ||||
|             quote! { | ||||
|                 #child_name_ident.push(#build_fn_ident(inner_pair)) | ||||
|                 #child_name_ident.push(Box::new(#build_fn_ident(inner_pair))) | ||||
|             } | ||||
|         } | ||||
|         ChildSpec::SingleChild(single_child) => match single_child.build() { | ||||
| @ -60,7 +73,7 @@ fn make_match_action(child_spec: &ChildSpec) -> TokenStream { | ||||
|                 let child_name_ident = format_ident!("{}", single_type_child.var_name()); | ||||
|                 let build_fn_ident = format_ident!("{}", single_type_child.with()); | ||||
|                 quote! { | ||||
|                     #child_name_ident = Some(#build_fn_ident(inner_pair)) | ||||
|                     #child_name_ident = Some(Box::new(#build_fn_ident(inner_pair))) | ||||
|                 } | ||||
|             } | ||||
|             SingleChildToBuild::Boolean(single_boolean_child) => { | ||||
| @ -90,6 +103,57 @@ fn make_rule_matcher(child_spec: &ChildSpec) -> TokenStream { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| fn make_child_arg(child_spec: &ChildSpec) -> Option<TokenStream> { | ||||
|     match child_spec { | ||||
|         ChildSpec::SkipChild(_) => None, | ||||
|         ChildSpec::VecChild(vec_child) => { | ||||
|             let child_ident = match vec_child.build() { | ||||
|                 VecChildToBuild::Type(vec_type_child) => { | ||||
|                     format_ident!("{}", vec_type_child.var_name()) | ||||
|                 } | ||||
|             }; | ||||
|             Some(quote! { #child_ident }) | ||||
|         } | ||||
|         ChildSpec::SingleChild(single_child) => match single_child.build() { | ||||
|             SingleChildToBuild::Type(single_type_child) => { | ||||
|                 let child_ident = format_ident!("{}", single_type_child.var_name()); | ||||
|                 if single_type_child.optional() { | ||||
|                     Some(quote! { #child_ident }) | ||||
|                 } else if let Some(or_else) = single_type_child.or_else() { | ||||
|                     let child_type_ident = format_ident!("{}", single_type_child.build()); | ||||
|                     let or_else_ident = format_ident!("{}", or_else); | ||||
|                     Some(quote! { | ||||
|                         #child_ident.unwrap_or_else(|| Box::new(#child_type_ident::#or_else_ident())) | ||||
|                     }) | ||||
|                 } else { | ||||
|                     Some(quote! { #child_ident.unwrap() }) | ||||
|                 } | ||||
|             } | ||||
|             SingleChildToBuild::Boolean(single_boolean_child) => { | ||||
|                 let child_ident = format_ident!("{}", single_boolean_child.var_name()); | ||||
|                 Some(quote! { #child_ident }) | ||||
|             } | ||||
|         }, | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| fn make_return_value_stream(build_spec: &StructBuildSpec) -> TokenStream { | ||||
|     let type_ident = format_ident!("{}", build_spec.build()); | ||||
|     let child_args = build_spec | ||||
|         .children() | ||||
|         .iter() | ||||
|         .map(|child| make_child_arg(child)) | ||||
|         .filter(|child_arg| child_arg.is_some()) | ||||
|         .map(|child_arg| child_arg.unwrap()) | ||||
|         .collect::<Vec<_>>(); | ||||
| 
 | ||||
|     quote! { | ||||
|         #type_ident::new( | ||||
|             #(#child_args,)* | ||||
|         ) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| pub fn make_struct_build_fn(build_spec: &StructBuildSpec) -> TokenStream { | ||||
|     let build_fn_ident = format_ident!("{}", build_spec.with()); | ||||
|     let pair_ident = format_ident!("{}_pair", build_spec.build().to_case(Case::Snake)); | ||||
| @ -117,11 +181,66 @@ pub fn make_struct_build_fn(build_spec: &StructBuildSpec) -> TokenStream { | ||||
|         } | ||||
|     }; | ||||
| 
 | ||||
|     let new_stream = make_return_value_stream(build_spec); | ||||
| 
 | ||||
|     quote! { | ||||
|         fn #build_fn_ident(#pair_ident: Pair<Rule>) -> #return_type_ident { | ||||
|             #(#child_holders;)* | ||||
| 
 | ||||
|             #iter_stream | ||||
| 
 | ||||
|             #new_stream | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #[cfg(test)] | ||||
| mod tests { | ||||
|     use super::*; | ||||
|     use crate::spec::VecTypeChildToBuild; | ||||
| 
 | ||||
|     #[test] | ||||
|     fn vec_child_holder() { | ||||
|         let vec_child = VecChild::new( | ||||
|             "test_child", | ||||
|             "Test", | ||||
|             VecChildToBuild::Type(VecTypeChildToBuild::new( | ||||
|                 "TestType", | ||||
|                 "test_child", | ||||
|                 "build_test_child", | ||||
|             )), | ||||
|         ); | ||||
|         assert_eq!( | ||||
|             make_vec_child_holder(&vec_child).to_string(), | ||||
|             quote! { | ||||
|                 let mut test_child: Vec<Box<TestType>> = vec![] | ||||
|             } | ||||
|             .to_string() | ||||
|         ); | ||||
|     } | ||||
| 
 | ||||
|     #[test] | ||||
|     fn single_type_child_holder() { | ||||
|         let single_type_child = SingleTypeChildToBuild::from_build_or_rule("TestType", None, false); | ||||
|         assert_eq!( | ||||
|             make_single_type_child_holder(&single_type_child).to_string(), | ||||
|             quote! { | ||||
|                 let mut test_type: Option<Box<TestType>> = None | ||||
|             } | ||||
|             .to_string() | ||||
|         ); | ||||
|     } | ||||
| 
 | ||||
|     #[test] | ||||
|     fn single_boolean_child_holder() { | ||||
|         let single_boolean_child = | ||||
|             SingleBooleanChildToBuild::new("test_child", BuildBooleanOn::RulePresent); | ||||
|         assert_eq!( | ||||
|             make_single_boolean_child_holder(&single_boolean_child).to_string(), | ||||
|             quote! { | ||||
|                 let mut test_child: bool = false | ||||
|             } | ||||
|             .to_string() | ||||
|         ); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -46,35 +46,58 @@ fn get_vec_child(name: &str, rule: &str, build: &Yaml) -> ChildSpec { | ||||
|     )) | ||||
| } | ||||
| 
 | ||||
| fn get_single_child_to_build(name: &str, rule: &str, build: &Yaml) -> SingleChildToBuild { | ||||
| fn get_single_child_to_build(name: &str, rule: &str, optional: bool, build: &Yaml) -> SingleChildToBuild { | ||||
|     if build.is_hash() { | ||||
|         let r#type = build["type"].as_str().unwrap(); | ||||
|         let var_name = build["var"] | ||||
|             .as_str() | ||||
|             .map(|s| s.to_string()) | ||||
|             .unwrap_or(name.to_string()); | ||||
|         let on = build["on"].as_str().unwrap(); | ||||
|         if r#type.eq("boolean") && on.eq("rule_present") { | ||||
|             SingleChildToBuild::Boolean(SingleBooleanChildToBuild::new( | ||||
|                 &var_name, | ||||
|                 BuildBooleanOn::RulePresent, | ||||
|             )) | ||||
|         } else { | ||||
|             todo!("currently on boolean types with on: rule_present are supported") | ||||
|         match build["type"].as_str() { | ||||
|             Some(r#type) => { | ||||
|                 let var_name = build["var"] | ||||
|                     .as_str() | ||||
|                     .map(|s| s.to_string()) | ||||
|                     .unwrap_or(name.to_string()); | ||||
|                 let on = build["on"].as_str().unwrap(); | ||||
|                 if r#type.eq("boolean") && on.eq("rule_present") { | ||||
|                     SingleChildToBuild::Boolean(SingleBooleanChildToBuild::new( | ||||
|                         &var_name, | ||||
|                         BuildBooleanOn::RulePresent, | ||||
|                     )) | ||||
|                 } 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); | ||||
|                         if or_else_default { | ||||
|                             Some(String::from("default")) | ||||
|                         } else { | ||||
|                             None | ||||
|                         } | ||||
|                     }); | ||||
|                 SingleChildToBuild::Type(SingleTypeChildToBuild::from_build_or_rule( | ||||
|                     rule, | ||||
|                     or_else, | ||||
|                     optional, | ||||
|                 )) | ||||
|             } | ||||
|         } | ||||
|     } else { | ||||
|         match build.as_str() { | ||||
|             Some(s) => SingleChildToBuild::Type(SingleTypeChildToBuild::from_build_or_rule(s)), | ||||
|             None => SingleChildToBuild::Type(SingleTypeChildToBuild::from_build_or_rule(rule)), | ||||
|             Some(s) => SingleChildToBuild::Type(SingleTypeChildToBuild::from_build_or_rule(s, None, optional)), | ||||
|             None => SingleChildToBuild::Type(SingleTypeChildToBuild::from_build_or_rule(rule, None, optional)), | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| fn get_single_child(name: &str, rule: &str, build: &Yaml) -> ChildSpec { | ||||
| fn get_single_child(name: &str, rule: &str, optional: bool, build: &Yaml) -> ChildSpec { | ||||
|     ChildSpec::SingleChild(SingleChild::new( | ||||
|         name, | ||||
|         rule, | ||||
|         get_single_child_to_build(name, rule, build), | ||||
|         get_single_child_to_build(name, rule, optional, build), | ||||
|     )) | ||||
| } | ||||
| 
 | ||||
| @ -92,18 +115,25 @@ fn get_child_specs(children: &Yaml) -> Vec<ChildSpec> { | ||||
|                     .map(|(name, props)| (name.as_str().unwrap(), props)) | ||||
|                     .unwrap(); | ||||
| 
 | ||||
|                 let rule = props["rule"].as_str().unwrap(); | ||||
|                 let rule = props["rule"] | ||||
|                     .as_str() | ||||
|                     .map(|s| s.to_string()) | ||||
|                     .unwrap_or(name.to_case(Case::Pascal)); | ||||
| 
 | ||||
|                 if get_skip(&props["skip"]) { | ||||
|                     return ChildSpec::SkipChild(SkipChild::new(name, rule)); | ||||
|                     return ChildSpec::SkipChild(SkipChild::new(name, &rule)); | ||||
|                 } | ||||
| 
 | ||||
|                 let build = &props["build"]; | ||||
| 
 | ||||
|                 if get_vec(&props["vec"]) { | ||||
|                     get_vec_child(name, rule, build) | ||||
|                     get_vec_child(name, &rule, build) | ||||
|                 } else { | ||||
|                     get_single_child(name, rule, build) | ||||
|                     let optional = props["optional"] | ||||
|                         .as_bool() | ||||
|                         .unwrap_or_else(|| false); | ||||
|                     
 | ||||
|                     get_single_child(name, &rule, optional, build) | ||||
|                 } | ||||
|             } else { | ||||
|                 ChildSpec::SingleChild(SingleChild::from_name_snake(child_spec.as_str().unwrap())) | ||||
|  | ||||
| @ -9,6 +9,7 @@ use proc_macro2::TokenStream; | ||||
| use quote::quote; | ||||
| use spec::BuildSpec; | ||||
| use syn::File; | ||||
| use syn::spanned::Spanned; | ||||
| 
 | ||||
| fn debug_built_spec(build_spec: &BuildSpec, token_stream: &TokenStream) { | ||||
|     println!("*** BuildSpec ***"); | ||||
|  | ||||
| @ -233,6 +233,8 @@ impl SingleChild { | ||||
|             rule: name.to_case(Case::Pascal), | ||||
|             build: SingleChildToBuild::Type(SingleTypeChildToBuild::from_build_or_rule( | ||||
|                 &name.to_case(Case::Pascal), | ||||
|                 None, | ||||
|                 false, | ||||
|             )), | ||||
|         } | ||||
|     } | ||||
| @ -272,14 +274,22 @@ pub struct SingleTypeChildToBuild { | ||||
|     build: String, | ||||
|     var_name: String, | ||||
|     with: String, | ||||
|     or_else: Option<String>, | ||||
|     optional: bool, | ||||
| } | ||||
| 
 | ||||
| impl SingleTypeChildToBuild { | ||||
|     pub fn from_build_or_rule(build_or_rule: &str) -> Self { | ||||
|     pub fn from_build_or_rule( | ||||
|         build_or_rule: &str, | ||||
|         or_else: Option<String>, | ||||
|         optional: bool, | ||||
|     ) -> Self { | ||||
|         Self { | ||||
|             build: build_or_rule.to_string(), | ||||
|             var_name: build_or_rule.to_case(Case::Snake), | ||||
|             with: make_build_fn_name(build_or_rule), | ||||
|             or_else, | ||||
|             optional, | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| @ -297,6 +307,16 @@ impl SingleTypeChildToBuild { | ||||
|     pub fn with(&self) -> &str { | ||||
|         &self.with | ||||
|     } | ||||
| 
 | ||||
|     /// The default fn to call when unwrapping the child (before passing as arg to new).
 | ||||
|     pub fn or_else(&self) -> Option<&str> { | ||||
|         self.or_else.as_deref() | ||||
|     } | ||||
| 
 | ||||
|     /// If the type should be wrapped in an Option.
 | ||||
|     pub fn optional(&self) -> bool { | ||||
|         self.optional | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug)] | ||||
|  | ||||
| @ -64,9 +64,15 @@ fn handle_single_type_child( | ||||
|     let child_ident_mut = format_ident!("{}_mut", single_type_child.var_name()); | ||||
|     let child_type_ident = format_ident!("{}", single_type_child.build()); | ||||
|     member_names.push(child_ident.clone()); | ||||
|     annotated_members.push(quote! { | ||||
|         #child_ident: Box<#child_type_ident> | ||||
|     }); | ||||
|     if single_type_child.optional() { | ||||
|         annotated_members.push(quote! { | ||||
|             #child_ident: Option<Box<#child_type_ident>> | ||||
|         }); | ||||
|     } else { | ||||
|         annotated_members.push(quote! { | ||||
|             #child_ident: Box<#child_type_ident> | ||||
|         }) | ||||
|     } | ||||
|     accessors.push(quote! { | ||||
|         pub fn #child_ident(&self) -> &#child_type_ident { | ||||
|             self.#child_ident.as_ref() | ||||
|  | ||||
							
								
								
									
										5
									
								
								sketching/september_2025/adder/adder.dm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								sketching/september_2025/adder/adder.dm
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,5 @@ | ||||
| use math::add | ||||
| 
 | ||||
| fn main() | ||||
|     println add(1, 2) // 3 | ||||
| end | ||||
							
								
								
									
										3
									
								
								sketching/september_2025/adder/math/add.dm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								sketching/september_2025/adder/math/add.dm
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,3 @@ | ||||
| mod math | ||||
| 
 | ||||
| pub fn add(a: Int, b: Int) = a + b | ||||
| @ -78,18 +78,32 @@ $defs: | ||||
|     properties: | ||||
|       rule: | ||||
|         type: string | ||||
|         description: The type to build, in Pascal case. | ||||
|       optional: | ||||
|         type: boolean | ||||
|         description: If true, this child will be stored as an Option. | ||||
|       build: | ||||
|         oneOf: | ||||
|           - type: string | ||||
|           - $ref: "#/$defs/SingleChildBuildDefinition" | ||||
|     required: | ||||
|       - rule | ||||
|   SingleChildBuildDefinition: | ||||
|     type: object | ||||
|     additionalProperties: false | ||||
|     description: A definition of what exactly to build for a given child rule. | ||||
|     oneOf: | ||||
|       - $ref: "#/$defs/BuildSingleTypeChild" | ||||
|       - $ref: "#/$defs/BuildBooleanChild" | ||||
|   BuildSingleTypeChild: | ||||
|     type: object | ||||
|     additionalProperties: false | ||||
|     description: A definition of a single-type child to build. | ||||
|     properties: | ||||
|       or_else: | ||||
|         type: string | ||||
|         description: The method name to call upon the built-type if the rule is not found. Takes precedence over "or_else_default". | ||||
|       or_else_default: | ||||
|         type: boolean | ||||
|         description: Whether to call the default method on the built-type if the rule is not found. | ||||
|   BuildBooleanChild: | ||||
|     type: object | ||||
|     additionalProperties: false | ||||
|  | ||||
| @ -1,19 +1,21 @@ | ||||
| # $schema: ./ast.schema.yaml | ||||
| # Top-level constructs | ||||
| CompilationUnit: | ||||
|   children: | ||||
|     - namespace | ||||
|     - parent_mod | ||||
|     - use_statements: | ||||
|         rule: UseStatement | ||||
|         vec: true | ||||
|     - module_level_declarations: | ||||
|         rule: ModuleLevelDeclaration | ||||
| Namespace: | ||||
|         vec: true | ||||
| ParentMod: | ||||
|   children: | ||||
|     - ns_kw: | ||||
|         rule: Ns | ||||
|     - mod_kw: | ||||
|         rule: Mod | ||||
|         skip: true | ||||
|     - fqn: | ||||
|         rule: Fqn | ||||
|         rule: FullyQualifiedName | ||||
| UseStatement: | ||||
|   children: | ||||
|     - use_kw: | ||||
| @ -24,17 +26,49 @@ UseStatement: | ||||
|         vec: true | ||||
|     - suffix: | ||||
|         rule: UseStatementSuffix | ||||
| UseStatementPrefix: | ||||
|   children: | ||||
|     - identifier | ||||
| UseStatementSuffix: | ||||
|   rules: | ||||
|     - Identifier | ||||
|     - rule: Star | ||||
|       build: UseStatementStarSuffix | ||||
|     - UseList | ||||
| UseList: | ||||
|   children: | ||||
|     - identifiers: | ||||
|         rule: Identifier | ||||
|         vec: true | ||||
| 
 | ||||
| # Level declarations | ||||
| ModuleLevelDeclaration: | ||||
|   rules: | ||||
|     - rule: Module | ||||
|       build: ModuleDeclaration | ||||
|     - rule: Interface | ||||
|       build: InterfaceDeclaration | ||||
|     - rule: Class | ||||
|       build: ClassDeclaration | ||||
|     - FunctionDefinition | ||||
|     - Module | ||||
|     - Interface | ||||
|     - Class | ||||
|     - Function | ||||
|     - PlatformFunction | ||||
| ModuleDeclaration: | ||||
| InterfaceLevelDeclaration: | ||||
|   rules: | ||||
|     - CompanionModule | ||||
|     - Interface | ||||
|     - Class | ||||
|     - InterfaceFunction | ||||
|     - InterfaceDefaultFunction | ||||
|     - InterfaceOperatorFunction | ||||
|     - InterfaceDefaultOperatorFunction | ||||
| ClassLevelDeclaration: | ||||
|   children: | ||||
|     - CompanionModule | ||||
|     - Interface | ||||
|     - Class | ||||
|     - Function | ||||
|     - OperatorFunction | ||||
|     - PlatformFunction | ||||
| 
 | ||||
| # Main organizational constructs | ||||
| Module: | ||||
|   children: | ||||
|     - is_public: | ||||
|         rule: Pub | ||||
| @ -49,7 +83,47 @@ ModuleDeclaration: | ||||
|     - declarations: | ||||
|         rule: ModuleLevelDeclaration | ||||
|         vec: true | ||||
| ClassDeclaration: | ||||
|     - end_kw: | ||||
|         rule: End | ||||
|         skip: true | ||||
| CompanionModule: | ||||
|   children: | ||||
|     - companion_kw: | ||||
|         rule: Companion | ||||
|         skip: true | ||||
|     - mod_kw: | ||||
|         rule: Mod | ||||
|         skip: true | ||||
|     - declarations: | ||||
|         rule: ModuleLevelDeclaration | ||||
|         vec: true | ||||
|     - end_kw: | ||||
|         rule: End | ||||
|         skip: true | ||||
| Interface: | ||||
|   children: | ||||
|     - is_public: | ||||
|         rule: Pub | ||||
|         build: | ||||
|           type: boolean | ||||
|           on: rule_present | ||||
|     - int_kw: | ||||
|         rule: IntKw | ||||
|         skip: true | ||||
|     - identifier | ||||
|     - generic_parameters: | ||||
|         build: | ||||
|           or_else_default: true | ||||
|     - implements_list: | ||||
|         build: | ||||
|           or_else_default: true | ||||
|     - declarations: | ||||
|         rule: InterfaceLevelDeclaration | ||||
|         vec: true | ||||
|     - end_kw: | ||||
|         rule: End | ||||
|         skip: true | ||||
| Class: | ||||
|   children: | ||||
|     - is_public: | ||||
|         rule: Pub | ||||
| @ -60,22 +134,27 @@ ClassDeclaration: | ||||
|         rule: ClassKw | ||||
|         skip: true | ||||
|     - identifier | ||||
|     - generic_parameters | ||||
|     - class_constructor | ||||
|     - implements_list | ||||
|     - generic_parameters: | ||||
|         build: | ||||
|           or_else_default: true | ||||
|     - class_constructor: | ||||
|         build: | ||||
|           or_else_default: true | ||||
|     - implements_list: | ||||
|         build: | ||||
|           or_else_default: true | ||||
|     - class_level_declarations: | ||||
|         rule: ClassLevelDeclaration | ||||
|         vec: true | ||||
| FunctionDeclaration: | ||||
| 
 | ||||
| # Function constructs | ||||
| Function: | ||||
|   children: | ||||
|     - is_public: | ||||
|         rule: Pub | ||||
|         build: | ||||
|           type: boolean | ||||
|           on: rule_present | ||||
|     - modifier: | ||||
|         rule: Modifier | ||||
|         build: FunctionModifier | ||||
|     - fn_kw: | ||||
|         rule: Fn | ||||
|         skip: true | ||||
| @ -83,5 +162,47 @@ FunctionDeclaration: | ||||
|         rule: GenericParameters | ||||
|     - identifier | ||||
|     - parameters | ||||
|     - return_type | ||||
|     - return_type: | ||||
|         build: | ||||
|           or_else: void | ||||
|     - function_body | ||||
| OperatorFunction: | ||||
|   children: | ||||
|     - is_public: | ||||
|         rule: Pub | ||||
|         build: | ||||
|           type: boolean | ||||
|           on: rule_present | ||||
|     - op_kw: | ||||
|         rule: Op | ||||
|         skip: true | ||||
|     - generics: | ||||
|         rule: GenericParameters | ||||
|         build: | ||||
|           or_else_default: true | ||||
|     - operator | ||||
|     - parameters | ||||
|     - return_type: | ||||
|         build: | ||||
|           or_else: void | ||||
|     - function_body | ||||
| PlatformFunction: | ||||
|   children: | ||||
|     - is_public: | ||||
|         rule: Pub | ||||
|         build: | ||||
|           type: boolean | ||||
|           on: rule_present | ||||
|     - platform_kw: | ||||
|         rule: Platform | ||||
|         skip: true | ||||
|     - fn_kw: | ||||
|         rule: Fn | ||||
|         skip: true | ||||
|     - generics: | ||||
|         rule: GenericParameters | ||||
|         build: | ||||
|           or_else_default: true | ||||
|     - identifier | ||||
|     - parameters | ||||
|     - return_type | ||||
|  | ||||
| @ -30,6 +30,8 @@ Alias = { "alias" } | ||||
| True = { "true" } | ||||
| False = { "false" } | ||||
| Use = { "use" } | ||||
| End = { "end" } | ||||
| Companion = { "comp" } | ||||
| 
 | ||||
| // Keywords: primitive types | ||||
| Byte = { "Byte" } | ||||
| @ -322,22 +324,31 @@ RefList = { | ||||
| 
 | ||||
| CompilationUnit = { | ||||
|       SOI | ||||
|     ~ ( Namespace ~ Semicolon )? | ||||
|     ~ ( UseStatement ~ Semicolon )* | ||||
|     ~ ModuleLevelDeclaration* | ||||
|     ~ ParentMod? | ||||
|     ~ ( UseStatement | ModuleLevelDeclaration )* | ||||
|     ~ EOI | ||||
| } | ||||
| 
 | ||||
| Namespace = { | ||||
|       Ns | ||||
| ParentMod = { | ||||
|       Mod | ||||
|     ~ FullyQualifiedName | ||||
| } | ||||
| 
 | ||||
| UseStatement = { | ||||
|       Use | ||||
|     ~ Identifier | ||||
|     ~ ( "::" ~ Identifier )* | ||||
|     ~ ( "::" ~ ( Star | UseList ) )? | ||||
|     ~ UseStatementPrefix* | ||||
|     ~ UseStatementSuffix | ||||
| } | ||||
| 
 | ||||
| UseStatementPrefix = { | ||||
|       Identifier | ||||
|     ~ "::" | ||||
| } | ||||
| 
 | ||||
| UseStatementSuffix = { | ||||
|       Identifier | ||||
|     | Star | ||||
|     | UseList | ||||
| } | ||||
| 
 | ||||
| UseList = { | ||||
| @ -353,12 +364,12 @@ ModuleLevelDeclaration = { | ||||
|       Module | ||||
|     | Interface | ||||
|     | Class | ||||
|     | FunctionDefinition | ||||
|     | Function | ||||
|     | PlatformFunction | ||||
| } | ||||
| 
 | ||||
| InterfaceLevelDeclaration = { | ||||
|       Module | ||||
|       CompanionModule | ||||
|     | Interface | ||||
|     | Class | ||||
|     | InterfaceFunction | ||||
| @ -368,14 +379,12 @@ InterfaceLevelDeclaration = { | ||||
| } | ||||
| 
 | ||||
| ClassLevelDeclaration = { | ||||
|       Module | ||||
|       CompanionModule | ||||
|     | Interface | ||||
|     | Class | ||||
|     | FunctionDefinition | ||||
|     | OperatorFunctionDefinition | ||||
|     | Function | ||||
|     | OperatorFunction | ||||
|     | PlatformFunction | ||||
|     | Property | ||||
|     | Field | ||||
| } | ||||
| 
 | ||||
| // Main organizational constructs | ||||
| @ -384,7 +393,15 @@ Module = { | ||||
|       Pub? | ||||
|     ~ Mod | ||||
|     ~ Identifier | ||||
|     ~ "{" ~ ModuleLevelDeclaration* ~ "}" | ||||
|     ~ ModuleLevelDeclaration* | ||||
|     ~ End | ||||
| } | ||||
| 
 | ||||
| CompanionModule = { | ||||
|       Companion | ||||
|     ~ Mod | ||||
|     ~ ModuleLevelDeclaration* | ||||
|     ~ End | ||||
| } | ||||
| 
 | ||||
| Interface = { | ||||
| @ -393,7 +410,8 @@ Interface = { | ||||
|     ~ Identifier | ||||
|     ~ GenericParameters? | ||||
|     ~ ImplementsList? | ||||
|     ~ ( "{" ~ InterfaceLevelDeclaration* ~ "}" )? | ||||
|     ~ InterfaceLevelDeclaration* | ||||
|     ~ End | ||||
| } | ||||
| 
 | ||||
| Class = { | ||||
| @ -403,14 +421,14 @@ Class = { | ||||
|     ~ GenericParameters? | ||||
|     ~ ClassConstructor? | ||||
|     ~ ImplementsList? | ||||
|     ~ ( "{" ~ ClassLevelDeclaration* ~ "}" )? | ||||
|     ~ ClassLevelDeclaration* | ||||
|     ~ End | ||||
| } | ||||
| 
 | ||||
| // Function constructs | ||||
| 
 | ||||
| FunctionDefinition = { | ||||
| Function = { | ||||
|       Pub? | ||||
|     ~ FunctionModifier? | ||||
|     ~ Fn | ||||
|     ~ GenericParameters? | ||||
|     ~ Identifier | ||||
| @ -419,9 +437,8 @@ FunctionDefinition = { | ||||
|     ~ FunctionBody | ||||
| } | ||||
| 
 | ||||
| OperatorFunctionDefinition = { | ||||
| OperatorFunction = { | ||||
|       Pub? | ||||
|     ~ FunctionModifier? | ||||
|     ~ Op | ||||
|     ~ GenericParameters? | ||||
|     ~ Operator | ||||
| @ -432,14 +449,12 @@ OperatorFunctionDefinition = { | ||||
| 
 | ||||
| PlatformFunction = { | ||||
|       Pub? | ||||
|     ~ FunctionModifier? | ||||
|     ~ Platform | ||||
|     ~ Fn | ||||
|     ~ GenericParameters? | ||||
|     ~ Identifier | ||||
|     ~ Parameters | ||||
|     ~ ReturnType | ||||
|     ~ ";" | ||||
| } | ||||
| 
 | ||||
| InterfaceFunction = { | ||||
| @ -482,13 +497,7 @@ InterfaceDefaultOperatorFunction = { | ||||
|     ~ FunctionBody | ||||
| } | ||||
| 
 | ||||
| FunctionModifier = { | ||||
|       Static | ||||
|     | Cons | ||||
|     | Mut ~ Ref | ||||
|     | Mut | ||||
|     | Ref | ||||
| } | ||||
| // Function Components | ||||
| 
 | ||||
| FunctionBody = { | ||||
|       FunctionAliasBody | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user