Compare commits
	
		
			No commits in common. "d5ac6dfc2d2a1319371b193e5b6e75c4077ac781" and "e578250ee652b5f00f71700464070edd0484cefd" have entirely different histories.
		
	
	
		
			d5ac6dfc2d
			...
			e578250ee6
		
	
		
| @ -36,8 +36,8 @@ pub fn make_struct_ast_node_impl(spec: &StructSpec) -> TokenStream { | |||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|                 MemberChildBuild::Boolean(_) => None, |                 MemberChildBuild::Boolean(_) => None, | ||||||
|  |                 MemberChildBuild::Special(_) => None, | ||||||
|             }, |             }, | ||||||
|             StructChild::Special(_) => None, |  | ||||||
|         }) |         }) | ||||||
|         .filter(Option::is_some) |         .filter(Option::is_some) | ||||||
|         .map(Option::unwrap) |         .map(Option::unwrap) | ||||||
|  | |||||||
| @ -1,44 +1,8 @@ | |||||||
| use crate::deserialize::util::{make_build_fn_name, make_build_pair}; | use crate::deserialize::util::{make_build_fn_name, make_build_pair}; | ||||||
| use crate::spec::struct_spec::{MemberChildBuild, NodeMemberBuild, SpecialChild, SpecialChildKind, StructChild, StructSpec, VecChild, VecChildBuild}; | use crate::spec::struct_spec::{MemberChildBuild, NodeMemberBuild, SpecialMemberBuild, StructChild, StructSpec, VecChild, VecChildBuild}; | ||||||
| use proc_macro2::{Ident, TokenStream}; | use proc_macro2::{Ident, TokenStream}; | ||||||
| use quote::{format_ident, quote}; | use quote::{format_ident, quote}; | ||||||
| 
 | 
 | ||||||
| fn make_preamble(spec: &StructSpec, pair_ident: &Ident) -> TokenStream { |  | ||||||
|     if spec.children().any(StructChild::is_special) { |  | ||||||
|         quote! { |  | ||||||
|             let as_span = #pair_ident.as_span(); |  | ||||||
|         } |  | ||||||
|     } else { |  | ||||||
|         quote! {} |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| fn make_special_children(spec: &StructSpec) -> Vec<TokenStream> { |  | ||||||
|     spec.children() |  | ||||||
|         .map(StructChild::unwrap_special) |  | ||||||
|         .filter(Option::is_some) |  | ||||||
|         .map(Option::unwrap) |  | ||||||
|         .map(|special_child| { |  | ||||||
|             let child_ident = format_ident!("{}", special_child.name()); |  | ||||||
|             match special_child.kind() { |  | ||||||
|                 SpecialChildKind::FileId => { |  | ||||||
|                     quote! { |  | ||||||
|                         let #child_ident = file_id |  | ||||||
|                     } |  | ||||||
|                 } |  | ||||||
|                 SpecialChildKind::Range => { |  | ||||||
|                     quote! { |  | ||||||
|                         let #child_ident = Range { |  | ||||||
|                             start: as_span.start(), |  | ||||||
|                             end: as_span.end() |  | ||||||
|                         } |  | ||||||
|                     } |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|         }) |  | ||||||
|         .collect::<Vec<_>>() |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| fn make_vec_child_holder(vec_child: &VecChild) -> TokenStream { | fn make_vec_child_holder(vec_child: &VecChild) -> TokenStream { | ||||||
|     let child_ident = format_ident!("{}", vec_child.name()); |     let child_ident = format_ident!("{}", vec_child.name()); | ||||||
|     match vec_child.build() { |     match vec_child.build() { | ||||||
| @ -80,8 +44,8 @@ fn make_child_holder(child_spec: &StructChild) -> Option<TokenStream> { | |||||||
|                 Some(make_node_child_holder(member_child.name(), node_child)) |                 Some(make_node_child_holder(member_child.name(), node_child)) | ||||||
|             } |             } | ||||||
|             MemberChildBuild::Boolean(_) => Some(make_boolean_child_holder(member_child.name())), |             MemberChildBuild::Boolean(_) => Some(make_boolean_child_holder(member_child.name())), | ||||||
|  |             MemberChildBuild::Special(_) => None, | ||||||
|         }, |         }, | ||||||
|         StructChild::Special(_) => None, |  | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -120,12 +84,7 @@ fn make_boolean_member_child_match_action(name: &str) -> TokenStream { | |||||||
| 
 | 
 | ||||||
| fn make_rule_matcher(child_spec: &StructChild) -> Option<TokenStream> {    
 | fn make_rule_matcher(child_spec: &StructChild) -> Option<TokenStream> {    
 | ||||||
|     match child_spec { |     match child_spec { | ||||||
|         StructChild::SkipChild(skip_child) => { |         StructChild::SkipChild(_) => None, | ||||||
|             let rule_ident = format_ident!("{}", skip_child.rule()); |  | ||||||
|             Some(quote! { |  | ||||||
|                 Rule::#rule_ident => {} |  | ||||||
|             }) |  | ||||||
|         }, |  | ||||||
|         StructChild::VecChild(vec_child) => { |         StructChild::VecChild(vec_child) => { | ||||||
|             let rule_ident = format_ident!("{}", vec_child.rule()); |             let rule_ident = format_ident!("{}", vec_child.rule()); | ||||||
|             let action = make_vec_child_match_action(vec_child); |             let action = make_vec_child_match_action(vec_child); | ||||||
| @ -152,9 +111,9 @@ fn make_rule_matcher(child_spec: &StructChild) -> Option<TokenStream> { | |||||||
|                         Rule::#rule_ident => { #action } |                         Rule::#rule_ident => { #action } | ||||||
|                     }) |                     }) | ||||||
|                 } |                 } | ||||||
|  |                 MemberChildBuild::Special(_) => None | ||||||
|             } |             } | ||||||
|         }, |         } | ||||||
|         StructChild::Special(_) => None |  | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -187,11 +146,6 @@ fn make_boolean_member_child_arg(name: &str) -> TokenStream { | |||||||
|     quote! { #child_ident } |     quote! { #child_ident } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| fn make_special_child_arg(special_child: &SpecialChild) -> TokenStream { |  | ||||||
|     let child_ident = format_ident!("{}", special_child.name()); |  | ||||||
|     quote! { #child_ident } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| fn make_child_arg(child_spec: &StructChild, pair_ident: &Ident) -> Option<TokenStream> { | fn make_child_arg(child_spec: &StructChild, pair_ident: &Ident) -> Option<TokenStream> { | ||||||
|     match child_spec { |     match child_spec { | ||||||
|         StructChild::SkipChild(_) => None, |         StructChild::SkipChild(_) => None, | ||||||
| @ -205,8 +159,22 @@ fn make_child_arg(child_spec: &StructChild, pair_ident: &Ident) -> Option<TokenS | |||||||
|             MemberChildBuild::Boolean(_) => { |             MemberChildBuild::Boolean(_) => { | ||||||
|                 Some(make_boolean_member_child_arg(member_child.name())) |                 Some(make_boolean_member_child_arg(member_child.name())) | ||||||
|             }, |             }, | ||||||
|  |             MemberChildBuild::Special(special_member_build) => { | ||||||
|  |                 match special_member_build { | ||||||
|  |                     SpecialMemberBuild::FileId => { | ||||||
|  |                         Some(quote! { file_id }) | ||||||
|  |                     } | ||||||
|  |                     SpecialMemberBuild::Range => { | ||||||
|  |                         Some(quote! { 
 | ||||||
|  |                             Range { | ||||||
|  |                                 start: #pair_ident.as_span().start(), | ||||||
|  |                                 end: #pair_ident.as_span().end(), | ||||||
|  |                             } | ||||||
|  |                         }) | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |             }, | ||||||
|         }, |         }, | ||||||
|         StructChild::Special(special_child) => Some(make_special_child_arg(special_child)), |  | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -230,10 +198,6 @@ pub fn make_struct_build_fn(build_spec: &StructSpec) -> TokenStream { | |||||||
|     let build_fn_ident = format_ident!("{}", make_build_fn_name(build_spec.build())); |     let build_fn_ident = format_ident!("{}", make_build_fn_name(build_spec.build())); | ||||||
|     let pair_ident = format_ident!("{}", make_build_pair(build_spec.build())); |     let pair_ident = format_ident!("{}", make_build_pair(build_spec.build())); | ||||||
|     let return_type_ident = format_ident!("{}", build_spec.build()); |     let return_type_ident = format_ident!("{}", build_spec.build()); | ||||||
|     
 |  | ||||||
|     let preamble = make_preamble(build_spec, &pair_ident); |  | ||||||
|     
 |  | ||||||
|     let special_children = make_special_children(build_spec); |  | ||||||
| 
 | 
 | ||||||
|     let child_holders = build_spec |     let child_holders = build_spec | ||||||
|         .children() |         .children() | ||||||
| @ -260,10 +224,6 @@ pub fn make_struct_build_fn(build_spec: &StructSpec) -> TokenStream { | |||||||
| 
 | 
 | ||||||
|     quote! { |     quote! { | ||||||
|         fn #build_fn_ident(file_id: usize, #pair_ident: Pair<Rule>) -> #return_type_ident { |         fn #build_fn_ident(file_id: usize, #pair_ident: Pair<Rule>) -> #return_type_ident { | ||||||
|             #preamble |  | ||||||
|             
 |  | ||||||
|             #(#special_children;)* |  | ||||||
|             
 |  | ||||||
|             #(#child_holders;)* |             #(#child_holders;)* | ||||||
| 
 | 
 | ||||||
|             #iter_stream |             #iter_stream | ||||||
|  | |||||||
| @ -56,6 +56,12 @@ fn deserialize_member_build(child_name: &str, rule: &str, props: &Yaml) -> Membe | |||||||
|         } else { |         } else { | ||||||
|             panic!("Expected 'on' in 'boolean' in 'build' in {}", child_name); |             panic!("Expected 'on' in 'boolean' in 'build' in {}", child_name); | ||||||
|         } |         } | ||||||
|  |     } else if props["special"].is_hash() { | ||||||
|  |         match props["special"]["kind"].as_str().unwrap() { | ||||||
|  |             "file_id" => MemberChildBuild::Special(SpecialMemberBuild::FileId), | ||||||
|  |             "range" => MemberChildBuild::Special(SpecialMemberBuild::Range), | ||||||
|  |             _ => panic!(), | ||||||
|  |         } | ||||||
|     } else { |     } else { | ||||||
|         panic!( |         panic!( | ||||||
|             "Expected one of 'node', 'boolean', or 'special' in 'build' in {}", |             "Expected one of 'node', 'boolean', or 'special' in 'build' in {}", | ||||||
| @ -92,14 +98,6 @@ fn deserialize_member_child(child_name: &str, props: &Yaml) -> StructChild { | |||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| fn deserialize_special_child(name: &str, props: &Yaml) -> StructChild { |  | ||||||
|     match props["kind"].as_str().unwrap() { |  | ||||||
|         "file_id" => StructChild::Special(SpecialChild::new(name, SpecialChildKind::FileId)), |  | ||||||
|         "range" => StructChild::Special(SpecialChild::new(name, SpecialChildKind::Range)), |  | ||||||
|         _ => panic!("Invalid special child kind {} in {}", props["kind"].as_str().unwrap(), name), |  | ||||||
|     }    
 |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| fn deserialize_hash_child(name: &str, props: &Yaml) -> StructChild { | fn deserialize_hash_child(name: &str, props: &Yaml) -> StructChild { | ||||||
|     if props["skip"].is_hash() { |     if props["skip"].is_hash() { | ||||||
|         deserialize_skip_child(&props["skip"]) |         deserialize_skip_child(&props["skip"]) | ||||||
| @ -107,8 +105,6 @@ fn deserialize_hash_child(name: &str, props: &Yaml) -> StructChild { | |||||||
|         deserialize_vec_child(name, &props["vec"]) |         deserialize_vec_child(name, &props["vec"]) | ||||||
|     } else if props["member"].is_hash() { |     } else if props["member"].is_hash() { | ||||||
|         deserialize_member_child(name, &props["member"]) |         deserialize_member_child(name, &props["member"]) | ||||||
|     } else if props["special"].is_hash() { |  | ||||||
|         deserialize_special_child(name, &props["special"])    
 |  | ||||||
|     } else { |     } else { | ||||||
|         panic!("Expected 'skip' or 'vec' in 'member' in {}", name); |         panic!("Expected 'skip' or 'vec' in 'member' in {}", name); | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -231,8 +231,8 @@ fn make_struct_p2_impl(struct_build_spec: &StructSpec) -> TokenStream { | |||||||
|                         writer.writeln_indented(&format!(#format_string, self.#child_ident()))?; |                         writer.writeln_indented(&format!(#format_string, self.#child_ident()))?; | ||||||
|                     }) |                     }) | ||||||
|                 } |                 } | ||||||
|  |                 MemberChildBuild::Special(_) => None | ||||||
|             }, |             }, | ||||||
|             StructChild::Special(_) => None |  | ||||||
|         }) |         }) | ||||||
|         .filter(Option::is_some) |         .filter(Option::is_some) | ||||||
|         .map(Option::unwrap) |         .map(Option::unwrap) | ||||||
|  | |||||||
| @ -26,25 +26,6 @@ pub enum StructChild { | |||||||
|     SkipChild(SkipChild), |     SkipChild(SkipChild), | ||||||
|     VecChild(VecChild), |     VecChild(VecChild), | ||||||
|     MemberChild(MemberChild), |     MemberChild(MemberChild), | ||||||
|     Special(SpecialChild), |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| impl StructChild { |  | ||||||
|     pub fn is_special(&self) -> bool { |  | ||||||
|         match self { |  | ||||||
|             StructChild::Special(_) => true, |  | ||||||
|             _ => false, |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|     
 |  | ||||||
|     pub fn unwrap_special(&self) -> Option<&SpecialChild> { |  | ||||||
|         match self { |  | ||||||
|             StructChild::Special(special_child) => { |  | ||||||
|                 Some(special_child) |  | ||||||
|             }, |  | ||||||
|             _ => None |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| pub struct SkipChild { | pub struct SkipChild { | ||||||
| @ -179,6 +160,7 @@ impl MemberChild { | |||||||
| pub enum MemberChildBuild { | pub enum MemberChildBuild { | ||||||
|     Node(NodeMemberBuild), |     Node(NodeMemberBuild), | ||||||
|     Boolean(BooleanMemberBuild), |     Boolean(BooleanMemberBuild), | ||||||
|  |     Special(SpecialMemberBuild), | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #[derive(Debug)] | #[derive(Debug)] | ||||||
| @ -233,30 +215,7 @@ pub enum BooleanMemberBuildOn { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #[derive(Debug)] | #[derive(Debug)] | ||||||
| pub struct SpecialChild { | pub enum SpecialMemberBuild { | ||||||
|     name: String, |  | ||||||
|     kind: SpecialChildKind, |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| impl SpecialChild { |  | ||||||
|     pub fn new(name: &str, kind: SpecialChildKind) -> Self { |  | ||||||
|         Self { |  | ||||||
|             name: name.to_string(), |  | ||||||
|             kind |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|     
 |  | ||||||
|     pub fn name(&self) -> &str { |  | ||||||
|         &self.name |  | ||||||
|     } |  | ||||||
|     
 |  | ||||||
|     pub fn kind(&self) -> &SpecialChildKind { |  | ||||||
|         &self.kind |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| #[derive(Debug)] |  | ||||||
| pub enum SpecialChildKind { |  | ||||||
|     FileId, |     FileId, | ||||||
|     Range, |     Range, | ||||||
| } | } | ||||||
|  | |||||||
| @ -1,6 +1,6 @@ | |||||||
| use crate::spec::struct_spec::{ | use crate::spec::struct_spec::{ | ||||||
|     MemberChild, MemberChildBuild, SpecialChild, SpecialChildKind, StructChild, StructSpec, |     MemberChild, MemberChildBuild, SpecialMemberBuild, StructChild, StructSpec, VecChild, | ||||||
|     VecChild, VecChildBuild, |     VecChildBuild, | ||||||
| }; | }; | ||||||
| use proc_macro2::{Ident, TokenStream}; | use proc_macro2::{Ident, TokenStream}; | ||||||
| use quote::{format_ident, quote}; | use quote::{format_ident, quote}; | ||||||
| @ -76,26 +76,22 @@ fn make_member_child_accessors(member_child: &MemberChild) -> TokenStream { | |||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     } |         MemberChildBuild::Special(special_member_build) => match special_member_build { | ||||||
| } |             SpecialMemberBuild::FileId => { | ||||||
| 
 |                 quote! { | ||||||
| fn make_special_child_accessors(special_child: &SpecialChild) -> TokenStream { |                     pub fn file_id(&self) -> usize { | ||||||
|     let child_ident = format_ident!("{}", special_child.name()); |                         self.file_id | ||||||
|     match special_child.kind() { |                     } | ||||||
|         SpecialChildKind::FileId => { |  | ||||||
|             quote! { |  | ||||||
|                 pub fn #child_ident(&self) -> usize { |  | ||||||
|                     self.#child_ident |  | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|         } |             SpecialMemberBuild::Range => { | ||||||
|         SpecialChildKind::Range => { |                 quote! { | ||||||
|             quote! { |                     pub fn range(&self) -> Range<usize> { | ||||||
|                 pub fn #child_ident(&self) -> Range<usize> { |                         self.range | ||||||
|                     self.#child_ident |                     } | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|         } |         }, | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -104,7 +100,6 @@ fn make_accessors(child: &StructChild) -> Option<TokenStream> { | |||||||
|         StructChild::SkipChild(_) => None, |         StructChild::SkipChild(_) => None, | ||||||
|         StructChild::VecChild(vec_child) => Some(make_vec_child_accessors(vec_child)), |         StructChild::VecChild(vec_child) => Some(make_vec_child_accessors(vec_child)), | ||||||
|         StructChild::MemberChild(member_child) => Some(make_member_child_accessors(member_child)), |         StructChild::MemberChild(member_child) => Some(make_member_child_accessors(member_child)), | ||||||
|         StructChild::Special(special_child) => Some(make_special_child_accessors(special_child)), |  | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -113,7 +108,6 @@ fn make_member_ident(child: &StructChild) -> Option<Ident> { | |||||||
|         StructChild::SkipChild(_) => None, |         StructChild::SkipChild(_) => None, | ||||||
|         StructChild::VecChild(vec_child) => Some(format_ident!("{}", vec_child.name())), |         StructChild::VecChild(vec_child) => Some(format_ident!("{}", vec_child.name())), | ||||||
|         StructChild::MemberChild(member_child) => Some(format_ident!("{}", member_child.name())), |         StructChild::MemberChild(member_child) => Some(format_ident!("{}", member_child.name())), | ||||||
|         StructChild::Special(special_child) => Some(format_ident!("{}", special_child.name())), |  | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -141,6 +135,10 @@ fn make_member_child_type_ident(member_child: &MemberChild) -> TokenStream { | |||||||
|         MemberChildBuild::Boolean(_) => { |         MemberChildBuild::Boolean(_) => { | ||||||
|             quote! { bool } |             quote! { bool } | ||||||
|         } |         } | ||||||
|  |         MemberChildBuild::Special(special_member_build) => match special_member_build { | ||||||
|  |             SpecialMemberBuild::FileId => quote! { usize }, | ||||||
|  |             SpecialMemberBuild::Range => quote! { Range<usize> }, | ||||||
|  |         }, | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -158,17 +156,6 @@ fn make_member_child_annotated_member(member_child: &MemberChild) -> TokenStream | |||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| fn make_special_child_annotated_member(special_child: &SpecialChild) -> TokenStream { |  | ||||||
|     let child_ident = format_ident!("{}", special_child.name()); |  | ||||||
|     let child_type_ident = match special_child.kind() { |  | ||||||
|         SpecialChildKind::FileId => quote! { usize }, |  | ||||||
|         SpecialChildKind::Range => quote! { Range<usize> }, |  | ||||||
|     }; |  | ||||||
|     quote! { |  | ||||||
|         #child_ident: #child_type_ident |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| fn make_annotated_member(child: &StructChild) -> Option<TokenStream> { | fn make_annotated_member(child: &StructChild) -> Option<TokenStream> { | ||||||
|     match child { |     match child { | ||||||
|         StructChild::SkipChild(_) => None, |         StructChild::SkipChild(_) => None, | ||||||
| @ -176,9 +163,6 @@ fn make_annotated_member(child: &StructChild) -> Option<TokenStream> { | |||||||
|         StructChild::MemberChild(member_child) => { |         StructChild::MemberChild(member_child) => { | ||||||
|             Some(make_member_child_annotated_member(member_child)) |             Some(make_member_child_annotated_member(member_child)) | ||||||
|         } |         } | ||||||
|         StructChild::Special(special_child) => { |  | ||||||
|             Some(make_special_child_annotated_member(special_child)) |  | ||||||
|         } |  | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -1,4 +1,3 @@ | |||||||
| fn main() | fn main() | ||||||
|     let n = 1 + 2 * 3 + 4 |     1 + 2 * 3 + 4 | ||||||
|     println n |  | ||||||
| end | end | ||||||
| @ -1,5 +0,0 @@ | |||||||
| fn main() -> Void |  | ||||||
|     $0 = 2 * 3 |  | ||||||
|     $1 = 1 + $0 |  | ||||||
|     $2 = $1 + 4 |  | ||||||
|     call std::core::println($2) |  | ||||||
| @ -1,89 +0,0 @@ | |||||||
| struct World |  | ||||||
|     pub String* name |  | ||||||
|     pub String* color |  | ||||||
| end |  | ||||||
| 
 |  | ||||||
| void World::ctor(World *self, String* name, String* color) |  | ||||||
|     self.name = move name |  | ||||||
|     self.color = move color |  | ||||||
| end |  | ||||||
| 
 |  | ||||||
| const String %s0 = 'Mercury' |  | ||||||
| const String %s1 = 'Red' |  | ||||||
| const String %s2 = 'Earth' |  | ||||||
| const String %s3 = 'Blue' |  | ||||||
| const String %s4 = 'Jupiter' |  | ||||||
| const String %s5 = 'Orange' |  | ||||||
| 
 |  | ||||||
| List<World> *getWorlds() |  | ||||||
|     List<World> *$0 = alloc std::list::ArrayList |  | ||||||
|     call std::list::ArrayList::ctor($0) |  | ||||||
|     World *$1 = alloc World |  | ||||||
|     call World::ctor($1, %s0, %s1) |  | ||||||
|     call std::list::ArrayList::add($0, $1) |  | ||||||
|     World *$2 = alloc World |  | ||||||
|     call World::ctor($2, %s2, %s3) |  | ||||||
|     call std::list::ArrayList::add($0, $2) |  | ||||||
|     World *$3 = alloc World |  | ||||||
|     call World::ctor($3, %s4, %s5) |  | ||||||
|     call std::list::ArrayList::add($0, $3) |  | ||||||
|     ret $0 |  | ||||||
| end |  | ||||||
| 
 |  | ||||||
| struct __findWorldByColor__cl0_captures |  | ||||||
|     pub String* color |  | ||||||
| end |  | ||||||
| 
 |  | ||||||
| Boolean __findWorldByColor_cl0(__findWorldByColor__cl0_captures *__captures, World *it) |  | ||||||
|     String *$0 = it.color |  | ||||||
|     String *$1 = __captures.color |  | ||||||
|     Boolean $2 = *$0 == *$1 |  | ||||||
|     ret $2 |  | ||||||
| end |  | ||||||
| 
 |  | ||||||
| String* __findWorldByColor_cl1(World* it) |  | ||||||
|     $0 = it.name |  | ||||||
|     ret $0 |  | ||||||
| end |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| String *findWorldByColor(List<World> *worlds, String *color) |  | ||||||
|     __findWorldByColor__cl0_captures *$0 = alloc __findWorldByColor__cl0_captures |  | ||||||
|     $0.color = color |  | ||||||
|     Closure(__findWorldByColor__cl0_captures*)(World*)<Boolean> $1 |  | ||||||
|         = closure(__findWorldByColor_cl0, $0) |  | ||||||
|     List<World> $2 = call std::list::ArrayList_impl_Find::find(worlds, $1) |  | ||||||
|     Closure()(World*)<String*> $3 = closure(__findWorldByColor_cl1) |  | ||||||
|     Option<String*> $4 = call std::list::ArrayList_impl_Monad($2, $3) |  | ||||||
| 
 |  | ||||||
|     Display*[1] $5 = alloc Display[1] |  | ||||||
|     $5[0] = color |  | ||||||
|     DString *$6 = alloc DString |  | ||||||
|     call DString::ctor($6, { }, $5) |  | ||||||
|     String *$7 = call DString::toString($6) |  | ||||||
| 
 |  | ||||||
|     String* $8 = call option::Option::expect($4, $7) |  | ||||||
| 
 |  | ||||||
|     drop $0 |  | ||||||
|     drop $1 |  | ||||||
|     drop $2 |  | ||||||
|     drop $3 |  | ||||||
|     drop $5 |  | ||||||
|     drop $6 |  | ||||||
| 
 |  | ||||||
|     ret $8 |  | ||||||
| end |  | ||||||
| 
 |  | ||||||
| const String %s7 = 'Blue' |  | ||||||
| const String[2] %sa0 = { 'Hello, ', '!' } |  | ||||||
| 
 |  | ||||||
| void main() |  | ||||||
|     List<World> *$0 = call getWorlds() |  | ||||||
|     World *$1 = call findWorldByColor($0, %s7) |  | ||||||
|     Display[1] $2 = alloc Display[1] |  | ||||||
|     $2[0] = move $1 |  | ||||||
|     std::string::DString *$3 = alloc std::string::DString |  | ||||||
|     call std::string::DString::ctor($3, %sa0, $2) |  | ||||||
|     String *$4 = call std::DString::toString($3) |  | ||||||
|     call std::core::println($4) |  | ||||||
| end |  | ||||||
| @ -5,14 +5,14 @@ use deimos::ast::build::build_ast; | |||||||
| use deimos::name_analysis::analyze_names; | use deimos::name_analysis::analyze_names; | ||||||
| use deimos::name_analysis::symbol_table::SymbolTable; | use deimos::name_analysis::symbol_table::SymbolTable; | ||||||
| use deimos::parser::{DeimosParser, Rule}; | use deimos::parser::{DeimosParser, Rule}; | ||||||
| use deimos::std_core::add_std_core_symbols; |  | ||||||
| use pest::Parser; | use pest::Parser; | ||||||
| use std::path::PathBuf; | use std::path::PathBuf; | ||||||
|  | use deimos::std_core::add_std_core_symbols; | ||||||
| 
 | 
 | ||||||
| pub fn name_analysis(paths: &Vec<PathBuf>) -> Result<(), Box<dyn std::error::Error>> { | pub fn name_analysis(paths: &Vec<PathBuf>) -> Result<(), Box<dyn std::error::Error>> { | ||||||
|     let mut compilation_units = vec![]; |     let mut compilation_units = vec![]; | ||||||
|     let mut files: SimpleFiles<String, String> = SimpleFiles::new(); |     let mut files = SimpleFiles::new(); | ||||||
| 
 |     
 | ||||||
|     for path in paths { |     for path in paths { | ||||||
|         let src = std::fs::read_to_string(path).unwrap(); |         let src = std::fs::read_to_string(path).unwrap(); | ||||||
|         let parse_result = DeimosParser::parse(Rule::CompilationUnit, &src); |         let parse_result = DeimosParser::parse(Rule::CompilationUnit, &src); | ||||||
| @ -30,11 +30,14 @@ pub fn name_analysis(paths: &Vec<PathBuf>) -> Result<(), Box<dyn std::error::Err | |||||||
| 
 | 
 | ||||||
|     let mut symbol_table = SymbolTable::new(); |     let mut symbol_table = SymbolTable::new(); | ||||||
|     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(compilation_units.as_mut_slice(), &files, &mut symbol_table); |     let diagnostics = analyze_names( | ||||||
|  |         compilation_units.as_mut_slice(), | ||||||
|  |         &mut symbol_table | ||||||
|  |     ); | ||||||
|     if diagnostics.is_empty() { |     if diagnostics.is_empty() { | ||||||
|         println!("Name analysis complete."); |         println!("Name analysis complete."); | ||||||
|         println!("{}", symbol_table); |         println!("Symbol table\n-------\n{}", symbol_table); | ||||||
|     } else { |     } else { | ||||||
|         let writer = StandardStream::stderr(ColorChoice::Always); |         let writer = StandardStream::stderr(ColorChoice::Always); | ||||||
|         let config = term::Config::default(); |         let config = term::Config::default(); | ||||||
| @ -42,6 +45,6 @@ pub fn name_analysis(paths: &Vec<PathBuf>) -> Result<(), Box<dyn std::error::Err | |||||||
|             term::emit(&mut writer.lock(), &config, &files, &diagnostic)?; |             term::emit(&mut writer.lock(), &config, &files, &diagnostic)?; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 |     
 | ||||||
|     Ok(()) |     Ok(()) | ||||||
| } | } | ||||||
|  | |||||||
							
								
								
									
										199
									
								
								src/ir/mod.rs
									
									
									
									
									
								
							
							
						
						
									
										199
									
								
								src/ir/mod.rs
									
									
									
									
									
								
							| @ -1,199 +0,0 @@ | |||||||
| pub enum DvmIr { |  | ||||||
|     Struct(Box<DvmIrStruct>), |  | ||||||
|     Function(DvmIrFunction), |  | ||||||
|     Const(DvmIrConst), |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| pub struct DvmIrStruct { |  | ||||||
|     name: String, |  | ||||||
|     kind: Box<DvmIrKind>, |  | ||||||
|     is_public: bool, |  | ||||||
|     members: Vec<Box<DvmIrStructMember>> |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| pub struct DvmIrStructMember { |  | ||||||
|     name: String, |  | ||||||
|     kind: Box<DvmIrKind>, |  | ||||||
|     is_public: bool, |  | ||||||
|     is_mut: bool, |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| pub enum DvmIrKind { |  | ||||||
|     Primitive(Box<DvmIrPrimitiveKind>), |  | ||||||
|     Struct(Box<DvmIrStructKind>), |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| pub enum DvmIrPrimitiveKind { |  | ||||||
|     I8, |  | ||||||
|     I16, |  | ||||||
|     I32, |  | ||||||
|     I64, |  | ||||||
|     I128, |  | ||||||
|     ISize, |  | ||||||
|     U8, |  | ||||||
|     U16, |  | ||||||
|     U32, |  | ||||||
|     U64, |  | ||||||
|     U128, |  | ||||||
|     USize, |  | ||||||
|     Boolean, |  | ||||||
|     Array(Box<DvmIrKind>), |  | ||||||
|     String, |  | ||||||
|     Closure(Box<DvmIrClosureKind>), |  | ||||||
|     Ref(Box<DvmIrKind>), |  | ||||||
|     Void, |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| pub struct DvmIrStructKind { |  | ||||||
|     name: String, |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| pub struct DvmIrClosureKind { |  | ||||||
|     captures_name: String, |  | ||||||
|     parameters: Vec<Box<DvmIrKind>>, |  | ||||||
|     return_type: Box<DvmIrKind>, |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| pub struct DvmIrFunction { |  | ||||||
|     name: String, |  | ||||||
|     parameters: Vec<Box<DvmIrKind>>, |  | ||||||
|     return_type: Box<DvmIrKind>, |  | ||||||
|     statements: Vec<Box<DvmIrStatement>>, |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| pub enum DvmIrStatement { |  | ||||||
|     Alloc(DvmIrAlloc), |  | ||||||
|     Call(DvmIrCallStmt), |  | ||||||
|     Ret(DvmIrRet), |  | ||||||
|     Assign(DvmIrAssign), |  | ||||||
|     MakeClosure(DvmIrMakeClosure), |  | ||||||
|     Drop(DvmIrDrop), |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| pub enum DvmIrAllocable { |  | ||||||
|     Struct(Box<DvmIrStructKind>), |  | ||||||
|     Array(Box<DvmIrArrayKind>), |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| pub enum DvmIrArrayKind { |  | ||||||
|     StaticSize(Box<DvmIrStaticArrayKind>), |  | ||||||
|     DynamicSize(Box<DvmIrDynamicArrayKind>) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| pub struct DvmIrStaticArrayKind { |  | ||||||
|     inner_kind: Box<DvmIrKind>, |  | ||||||
|     size: usize, |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| pub struct DvmIrDynamicArrayKind { |  | ||||||
|     inner_kind: Box<DvmIrKind>, |  | ||||||
|     size_expr: Box<DvmIrExpr> |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| pub struct DvmIrAlloc { |  | ||||||
|     declared_kind: Box<DvmIrAllocable>, |  | ||||||
|     name: String, |  | ||||||
|     kind_to_alloc: Box<DvmIrAllocable>, |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| pub enum DvmIrConst { |  | ||||||
|     String(DvmIrStringConst), |  | ||||||
|     StringArray(DvmIrStringArrayConst), |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| pub struct DvmIrStringConst { |  | ||||||
|     name: String, |  | ||||||
|     value: String, |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| pub struct DvmIrStringArrayConst { |  | ||||||
|     name: String, |  | ||||||
|     value: Vec<String>, |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| pub enum DvmIrExpr { |  | ||||||
|     Call(Box<DvmIrCallExpr>), |  | ||||||
|     Variable(Box<DvmIrVariable>), |  | ||||||
|     ConstRef(Box<DvmIrConstRef>), |  | ||||||
|     Literal(Box<DvmIrLiteral>) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| pub struct DvmIrVariable { |  | ||||||
|     name: String, |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| pub struct DvmIrConstRef { |  | ||||||
|     name: String,    
 |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| pub enum DvmIrLiteral { |  | ||||||
|     I8(i8), |  | ||||||
|     I16(i16), |  | ||||||
|     I32(i32), |  | ||||||
|     I64(i64), |  | ||||||
|     I128(i128), |  | ||||||
|     ISize(isize), |  | ||||||
|     U8(u8), |  | ||||||
|     U16(u16), |  | ||||||
|     U32(u32), |  | ||||||
|     U64(u64), |  | ||||||
|     U128(u128), |  | ||||||
|     USize(usize), |  | ||||||
|     Boolean(bool), |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| pub struct DvmIrCallStmt { |  | ||||||
|     declared_type: Box<DvmIrKind>, |  | ||||||
|     name: String, |  | ||||||
|     call_expr: Box<DvmIrCallExpr>, |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| pub struct DvmIrCallExpr { |  | ||||||
|     name: String, |  | ||||||
|     arguments: Vec<Box<DvmIrExpr>>, |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| pub struct DvmIrAssign { |  | ||||||
|     lhs: Box<DvmIrAssignLhs>, |  | ||||||
|     rhs: Box<DvmIrExpr> |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| pub struct DvmIrAssignLhs { |  | ||||||
|     base: Box<DvmIrVariable>, |  | ||||||
|     suffixes: Vec<Box<DvmIrAssignLhsSuffix>> |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| pub enum DvmIrAssignLhsSuffix { |  | ||||||
|     Index(DvmIrAssignLhsIndex), |  | ||||||
|     Property(DvmIrAssignLhsProperty) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| pub struct DvmIrAssignLhsIndex { |  | ||||||
|     expr: Box<DvmIrExpr>, |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| pub struct DvmIrAssignLhsProperty { |  | ||||||
|     name: String, |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| pub struct DvmIrRet { |  | ||||||
|     value: Box<DvmIrReturnable> |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| pub enum DvmIrReturnable { |  | ||||||
|     Variable(DvmIrVariable), |  | ||||||
|     Literal(DvmIrLiteral) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| pub struct DvmIrMakeClosure { |  | ||||||
|     captures_kind: Option<Box<DvmIrStructKind>>, |  | ||||||
|     parameters: Vec<Box<DvmIrKind>>, |  | ||||||
|     return_type: Box<DvmIrKind>, |  | ||||||
|     name: String, |  | ||||||
|     fn_name: String, |  | ||||||
|     captures_variable: Box<DvmIrVariable>, |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| pub struct DvmIrDrop { |  | ||||||
|     variable: Box<DvmIrVariable>, |  | ||||||
| } |  | ||||||
| @ -11,4 +11,3 @@ pub mod parser; | |||||||
| pub mod std_core; | pub mod std_core; | ||||||
| pub mod util; | pub mod util; | ||||||
| pub mod vm; | pub mod vm; | ||||||
| pub mod ir; |  | ||||||
|  | |||||||
| @ -1,4 +1,4 @@ | |||||||
| pub struct FqnContext { | pub(super) struct FqnContext { | ||||||
|     stack: Vec<String>, |     stack: Vec<String>, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -1,76 +1,62 @@ | |||||||
| use crate::ast::ast_node::{AstNode, AstNodeRef}; | use crate::ast::ast_node::{AstNode, AstNodeRef}; | ||||||
| use crate::ast::node::{ | use crate::ast::node::{CompilationUnit, Identifier, UseStatement, UseStatementSuffix}; | ||||||
|     Class, CompilationUnit, Function, FunctionBlockBody, FunctionBody, Identifier, Interface, |  | ||||||
|     Module, Namespace, Statement, UseStatement, UseStatementSuffix, VariableDeclaration, |  | ||||||
| }; |  | ||||||
| use crate::diagnostic::DmDiagnostic; | use crate::diagnostic::DmDiagnostic; | ||||||
| use crate::name_analysis::fqn_context::FqnContext; |  | ||||||
| use crate::name_analysis::symbol::function_symbol::FunctionSymbol; |  | ||||||
| use crate::name_analysis::symbol::module_symbol::ModuleSymbol; |  | ||||||
| use crate::name_analysis::symbol::source_definition::SourceDefinition; | use crate::name_analysis::symbol::source_definition::SourceDefinition; | ||||||
| use crate::name_analysis::symbol::type_symbol::{ | use crate::name_analysis::symbol::use_symbol::StarUseStatementSymbol; | ||||||
|     ConcreteTypeSymbol, ConcreteTypeSymbolKind, TypeSymbol, | use crate::name_analysis::symbol::UseStatementSymbol; | ||||||
| }; | use crate::name_analysis::symbol_table::SymbolTable; | ||||||
| use crate::name_analysis::symbol::use_symbol::{ConcreteUseSymbol, StarUseSymbol}; | use std::collections::HashMap; | ||||||
| use crate::name_analysis::symbol::variable_symbol::VariableSymbol; |  | ||||||
| use crate::name_analysis::symbol_table::{SymbolInsertError, SymbolTable}; |  | ||||||
| use codespan_reporting::diagnostic::{Diagnostic, Label}; |  | ||||||
| use std::range::Range; |  | ||||||
| 
 | 
 | ||||||
| fn handle_insert_error( | fn gather_identifier( | ||||||
|     err: SymbolInsertError, |     identifier: &Identifier, | ||||||
|     error_symbol_name: &str, |     symbol_table: &SymbolTable, | ||||||
|     error_file_id: usize, |     identifier_scope_ids: &mut HashMap<Identifier, usize>, | ||||||
|     error_range: Range<usize>, | ) { | ||||||
|     symbol_types: &str, |     identifier_scope_ids.insert(identifier.clone(), symbol_table.current_scope_id()); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | fn gather_use_statement( | ||||||
|  |     use_statement: &UseStatement, | ||||||
|  |     symbol_table: &mut SymbolTable, | ||||||
|     diagnostics: &mut Vec<DmDiagnostic>, |     diagnostics: &mut Vec<DmDiagnostic>, | ||||||
| ) { | ) { | ||||||
|     match err { |     let mut fully_qualified_name = String::new(); | ||||||
|         SymbolInsertError::SymbolAlreadyDefined(s) => { |     for prefix in use_statement.prefixes() { | ||||||
|             let mut diagnostic = Diagnostic::error() |         fully_qualified_name.push_str(&format!("{}::", prefix.identifier().name())); | ||||||
|                 .with_message(format!( |     } | ||||||
|                     "{} symbol '{}' already defined in the current scope.", |     match use_statement.suffix() { | ||||||
|                     symbol_types, error_symbol_name, |         UseStatementSuffix::Identifier(identifier) => {} | ||||||
|                 )) |         UseStatementSuffix::Star => { | ||||||
|                 .with_label( |             let symbol_inner = StarUseStatementSymbol::new( | ||||||
|                     Label::primary(error_file_id, error_range) |                 &fully_qualified_name, | ||||||
|                         .with_message("Symbol duplicated here."), |                 Some(SourceDefinition::from_use_statement(use_statement)), | ||||||
|                 ); |             ); | ||||||
| 
 |             let symbol = UseStatementSymbol::Star(symbol_inner); | ||||||
|             if let Some(source_definition) = s.definition() { |             symbol_table.insert_use_statement_symbol(symbol); | ||||||
|                 diagnostic = diagnostic.with_label( |             todo!() | ||||||
|                     Label::secondary(source_definition.file_id(), source_definition.range()) |  | ||||||
|                         .with_message("Symbol defined here."), |  | ||||||
|                 ); |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             diagnostics.push(diagnostic); |  | ||||||
|         } |         } | ||||||
|  |         UseStatementSuffix::UseList(use_list) => {} | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| fn gather_node_children( | fn gather_node_children( | ||||||
|     node: &impl AstNode, |     node: &impl AstNode, | ||||||
|     symbol_table: &mut SymbolTable, |     symbol_table: &mut SymbolTable, | ||||||
|     fqn_context: &mut FqnContext, |  | ||||||
|     diagnostics: &mut Vec<DmDiagnostic>, |     diagnostics: &mut Vec<DmDiagnostic>, | ||||||
| ) { | ) { | ||||||
|     for child in node.children() { |     for child in node.children() { | ||||||
|         gather_node(child, symbol_table, fqn_context, diagnostics); |         gather_node(child, symbol_table, diagnostics); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| fn gather_node( | fn gather_node( | ||||||
|     node: AstNodeRef, |     node: AstNodeRef, | ||||||
|     symbol_table: &mut SymbolTable, |     symbol_table: &mut SymbolTable, | ||||||
|     fqn_context: &mut FqnContext, |  | ||||||
|     diagnostics: &mut Vec<DmDiagnostic>, |     diagnostics: &mut Vec<DmDiagnostic>, | ||||||
| ) { | ) { | ||||||
|     match node { |     match node { | ||||||
|         AstNodeRef::Operator(_) => {} |         AstNodeRef::Operator(_) => {} | ||||||
|         AstNodeRef::Identifier(_) => { |         AstNodeRef::Identifier(_) => {} | ||||||
|             unreachable!() |  | ||||||
|         } |  | ||||||
|         AstNodeRef::FullyQualifiedName(_) => {} |         AstNodeRef::FullyQualifiedName(_) => {} | ||||||
|         AstNodeRef::TypeUseList(_) => {} |         AstNodeRef::TypeUseList(_) => {} | ||||||
|         AstNodeRef::IdentifierList(_) => {} |         AstNodeRef::IdentifierList(_) => {} | ||||||
| @ -89,114 +75,36 @@ fn gather_node( | |||||||
|         AstNodeRef::Parameter(_) => {} |         AstNodeRef::Parameter(_) => {} | ||||||
|         AstNodeRef::ReturnType(_) => {} |         AstNodeRef::ReturnType(_) => {} | ||||||
|         AstNodeRef::CompilationUnit(compilation_unit) => { |         AstNodeRef::CompilationUnit(compilation_unit) => { | ||||||
|             gather_node_children(compilation_unit, symbol_table, fqn_context, diagnostics); |             gather_node_children(compilation_unit, symbol_table, diagnostics); | ||||||
|         } |  | ||||||
|         AstNodeRef::Namespace(namespace) => { |  | ||||||
|             gather_namespace(namespace, fqn_context); |  | ||||||
|         } |         } | ||||||
|  |         AstNodeRef::ParentMod(_) => {} | ||||||
|         AstNodeRef::UseStatement(use_statement) => { |         AstNodeRef::UseStatement(use_statement) => { | ||||||
|             gather_use_statement(use_statement, symbol_table, diagnostics); |             gather_use_statement(use_statement, symbol_table, diagnostics); | ||||||
|         } |         } | ||||||
|         AstNodeRef::UseStatementPrefix(_) => { |         AstNodeRef::UseStatementPrefix(_) => {} | ||||||
|             unreachable!() |         AstNodeRef::UseStatementSuffix(_) => {} | ||||||
|         } |         AstNodeRef::UseList(_) => {} | ||||||
|         AstNodeRef::UseStatementSuffix(_) => { |         AstNodeRef::ModuleLevelDeclaration(_) => {} | ||||||
|             unreachable!() |         AstNodeRef::InterfaceLevelDeclaration(_) => {} | ||||||
|         } |         AstNodeRef::ClassLevelDeclaration(_) => {} | ||||||
|         AstNodeRef::UseList(_) => { |         AstNodeRef::Module(_) => {} | ||||||
|             unreachable!() |         AstNodeRef::CompanionModule(_) => {} | ||||||
|         } |         AstNodeRef::Interface(_) => {} | ||||||
|         AstNodeRef::ModuleLevelDeclaration(module_level_declaration) => { |         AstNodeRef::Class(_) => {} | ||||||
|             gather_node_children( |         AstNodeRef::Function(_) => {} | ||||||
|                 module_level_declaration, |  | ||||||
|                 symbol_table, |  | ||||||
|                 fqn_context, |  | ||||||
|                 diagnostics, |  | ||||||
|             ); |  | ||||||
|         } |  | ||||||
|         AstNodeRef::InterfaceLevelDeclaration(interface_level_declaration) => { |  | ||||||
|             gather_node_children( |  | ||||||
|                 interface_level_declaration, |  | ||||||
|                 symbol_table, |  | ||||||
|                 fqn_context, |  | ||||||
|                 diagnostics, |  | ||||||
|             ); |  | ||||||
|         } |  | ||||||
|         AstNodeRef::ClassLevelDeclaration(class_level_declaration) => { |  | ||||||
|             gather_node_children( |  | ||||||
|                 class_level_declaration, |  | ||||||
|                 symbol_table, |  | ||||||
|                 fqn_context, |  | ||||||
|                 diagnostics, |  | ||||||
|             ); |  | ||||||
|         } |  | ||||||
|         AstNodeRef::Module(module) => { |  | ||||||
|             gather_module(module, symbol_table, fqn_context, diagnostics); |  | ||||||
|         } |  | ||||||
|         AstNodeRef::Interface(interface) => { |  | ||||||
|             gather_interface(interface, symbol_table, fqn_context, diagnostics); |  | ||||||
|         } |  | ||||||
|         AstNodeRef::Class(class) => { |  | ||||||
|             gather_class(class, symbol_table, fqn_context, diagnostics); |  | ||||||
|         } |  | ||||||
|         AstNodeRef::Function(function) => { |  | ||||||
|             gather_function(function, symbol_table, fqn_context, diagnostics); |  | ||||||
|         } |  | ||||||
|         AstNodeRef::OperatorFunction(_) => {} |         AstNodeRef::OperatorFunction(_) => {} | ||||||
|         AstNodeRef::PlatformFunction(_) => {} |         AstNodeRef::PlatformFunction(_) => {} | ||||||
|         AstNodeRef::InterfaceFunction(_) => {} |         AstNodeRef::InterfaceFunction(_) => {} | ||||||
|         AstNodeRef::InterfaceDefaultFunction(_) => {} |         AstNodeRef::InterfaceDefaultFunction(_) => {} | ||||||
|         AstNodeRef::InterfaceOperatorFunction(_) => {} |         AstNodeRef::InterfaceOperatorFunction(_) => {} | ||||||
|         AstNodeRef::InterfaceDefaultOperatorFunction(_) => {} |         AstNodeRef::InterfaceDefaultOperatorFunction(_) => {} | ||||||
|         AstNodeRef::FunctionBody(function_body) => match function_body { |         AstNodeRef::FunctionBody(_) => {} | ||||||
|             FunctionBody::FunctionAliasBody(alias_body) => { |  | ||||||
|                 gather_node( |  | ||||||
|                     alias_body.as_node_ref(), |  | ||||||
|                     symbol_table, |  | ||||||
|                     fqn_context, |  | ||||||
|                     diagnostics, |  | ||||||
|                 ); |  | ||||||
|             } |  | ||||||
|             FunctionBody::FunctionEqualsBody(equals_body) => { |  | ||||||
|                 gather_node( |  | ||||||
|                     equals_body.as_node_ref(), |  | ||||||
|                     symbol_table, |  | ||||||
|                     fqn_context, |  | ||||||
|                     diagnostics, |  | ||||||
|                 ); |  | ||||||
|             } |  | ||||||
|             FunctionBody::FunctionBlockBody(block_body) => { |  | ||||||
|                 gather_node( |  | ||||||
|                     block_body.as_node_ref(), |  | ||||||
|                     symbol_table, |  | ||||||
|                     fqn_context, |  | ||||||
|                     diagnostics, |  | ||||||
|                 ); |  | ||||||
|             } |  | ||||||
|         }, |  | ||||||
|         AstNodeRef::FunctionEqualsBody(_) => {} |         AstNodeRef::FunctionEqualsBody(_) => {} | ||||||
|         AstNodeRef::FunctionAliasBody(_) => {} |         AstNodeRef::FunctionAliasBody(_) => {} | ||||||
|         AstNodeRef::FunctionBlockBody(block_body) => { |         AstNodeRef::FunctionBlockBody(_) => {} | ||||||
|             gather_function_block_body(block_body, symbol_table, fqn_context, diagnostics); |  | ||||||
|         } |  | ||||||
|         AstNodeRef::ClassConstructor(_) => {} |         AstNodeRef::ClassConstructor(_) => {} | ||||||
|         AstNodeRef::Member(_) => {} |         AstNodeRef::Member(_) => {} | ||||||
|         AstNodeRef::Statement(statement) => match statement { |         AstNodeRef::Statement(_) => {} | ||||||
|             Statement::VariableDeclaration(variable_declaration) => { |  | ||||||
|                 gather_node( |  | ||||||
|                     variable_declaration.as_node_ref(), |  | ||||||
|                     symbol_table, |  | ||||||
|                     fqn_context, |  | ||||||
|                     diagnostics, |  | ||||||
|                 ); |  | ||||||
|             } |  | ||||||
|             Statement::AssignmentStatement(_) => {} |  | ||||||
|             Statement::ExpressionStatement(_) => {} |  | ||||||
|             Statement::UseStatement(_) => {} |  | ||||||
|             Statement::IfStatement(_) => {} |  | ||||||
|             Statement::WhileStatement(_) => {} |  | ||||||
|             Statement::ForStatement(_) => {} |  | ||||||
|         }, |  | ||||||
|         AstNodeRef::VariableDeclaration(_) => {} |         AstNodeRef::VariableDeclaration(_) => {} | ||||||
|         AstNodeRef::AssignmentStatement(_) => {} |         AstNodeRef::AssignmentStatement(_) => {} | ||||||
|         AstNodeRef::ExpressionStatement(_) => {} |         AstNodeRef::ExpressionStatement(_) => {} | ||||||
| @ -249,284 +157,9 @@ fn gather_node( | |||||||
| 
 | 
 | ||||||
| pub fn gather_compilation_unit( | pub fn gather_compilation_unit( | ||||||
|     compilation_unit: &mut CompilationUnit, |     compilation_unit: &mut CompilationUnit, | ||||||
|     file_name: &str, |  | ||||||
|     symbol_table: &mut SymbolTable, |     symbol_table: &mut SymbolTable, | ||||||
|  |     identifier_scope_ids: &mut HashMap<Identifier, usize>, | ||||||
|     diagnostics: &mut Vec<DmDiagnostic>, |     diagnostics: &mut Vec<DmDiagnostic>, | ||||||
| ) { | ) { | ||||||
|     let mut fqn_context = FqnContext::new(); |     gather_node(compilation_unit.as_node_ref(), symbol_table, diagnostics); | ||||||
|     symbol_table.push_scope(&format!("FileScope {}", file_name)); |  | ||||||
|     gather_node( |  | ||||||
|         compilation_unit.as_node_ref(), |  | ||||||
|         symbol_table, |  | ||||||
|         &mut fqn_context, |  | ||||||
|         diagnostics, |  | ||||||
|     ); |  | ||||||
|     symbol_table.pop_scope(); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| fn gather_namespace(namespace: &Namespace, fqn_context: &mut FqnContext) { |  | ||||||
|     for identifier in namespace.fqn().identifiers() { |  | ||||||
|         fqn_context.push(identifier.name()); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| fn gather_use_statement( |  | ||||||
|     use_statement: &UseStatement, |  | ||||||
|     symbol_table: &mut SymbolTable, |  | ||||||
|     diagnostics: &mut Vec<DmDiagnostic>, |  | ||||||
| ) { |  | ||||||
|     let base_fqn = use_statement |  | ||||||
|         .prefixes() |  | ||||||
|         .map(|prefix| prefix.identifier().name()) |  | ||||||
|         .collect::<Vec<_>>() |  | ||||||
|         .join("::"); |  | ||||||
| 
 |  | ||||||
|     match use_statement.suffix() { |  | ||||||
|         UseStatementSuffix::Identifier(identifier) => { |  | ||||||
|             gather_concrete_use_symbol(&base_fqn, identifier, symbol_table, diagnostics); |  | ||||||
|         } |  | ||||||
|         UseStatementSuffix::Star => { |  | ||||||
|             let symbol = StarUseSymbol::new( |  | ||||||
|                 &base_fqn, |  | ||||||
|                 Some(SourceDefinition::from_use_statement(use_statement)), |  | ||||||
|             ); |  | ||||||
|             let insert_result = symbol_table.insert_star_use_symbol(symbol); |  | ||||||
|             if let Err(error) = insert_result { |  | ||||||
|                 handle_insert_error( |  | ||||||
|                     error, |  | ||||||
|                     &base_fqn, |  | ||||||
|                     use_statement.file_id(), |  | ||||||
|                     use_statement.range(), |  | ||||||
|                     "Use Statement", |  | ||||||
|                     diagnostics, |  | ||||||
|                 ); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|         UseStatementSuffix::UseList(use_list) => { |  | ||||||
|             for identifier in use_list.identifiers() { |  | ||||||
|                 gather_concrete_use_symbol(&base_fqn, identifier, symbol_table, diagnostics); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| fn gather_concrete_use_symbol( |  | ||||||
|     base_fqn: &str, |  | ||||||
|     identifier: &Identifier, |  | ||||||
|     symbol_table: &mut SymbolTable, |  | ||||||
|     diagnostics: &mut Vec<DmDiagnostic>, |  | ||||||
| ) { |  | ||||||
|     let symbol = ConcreteUseSymbol::new( |  | ||||||
|         base_fqn, |  | ||||||
|         identifier.name(), |  | ||||||
|         Some(SourceDefinition::from_identifier(identifier)), |  | ||||||
|     ); |  | ||||||
|     if let Err(insert_error) = symbol_table.insert_concrete_use_symbol(symbol) { |  | ||||||
|         handle_insert_error( |  | ||||||
|             insert_error, |  | ||||||
|             &base_fqn, |  | ||||||
|             identifier.file_id(), |  | ||||||
|             identifier.range(), |  | ||||||
|             "Use Statement", |  | ||||||
|             diagnostics, |  | ||||||
|         ); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| fn gather_module( |  | ||||||
|     module: &Module, |  | ||||||
|     symbol_table: &mut SymbolTable, |  | ||||||
|     fqn_context: &mut FqnContext, |  | ||||||
|     diagnostics: &mut Vec<DmDiagnostic>, |  | ||||||
| ) { |  | ||||||
|     let module_symbol = ModuleSymbol::new( |  | ||||||
|         &fqn_context.resolve(module.identifier().name()), |  | ||||||
|         module.identifier().name(), |  | ||||||
|         module.is_public(), |  | ||||||
|         Some(SourceDefinition::from_identifier(module.identifier())), |  | ||||||
|     ); |  | ||||||
|     if let Err(symbol_insert_error) = symbol_table.insert_module_symbol(module_symbol) { |  | ||||||
|         handle_insert_error( |  | ||||||
|             symbol_insert_error, |  | ||||||
|             module.identifier().name(), |  | ||||||
|             module.identifier().file_id(), |  | ||||||
|             module.identifier().range(), |  | ||||||
|             "Module", |  | ||||||
|             diagnostics, |  | ||||||
|         ); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     fqn_context.push(module.identifier().name()); |  | ||||||
|     symbol_table.push_scope(&format!("ModuleScope {}", module.identifier().name())); |  | ||||||
| 
 |  | ||||||
|     for declaration in module.declarations() { |  | ||||||
|         gather_node( |  | ||||||
|             declaration.as_node_ref(), |  | ||||||
|             symbol_table, |  | ||||||
|             fqn_context, |  | ||||||
|             diagnostics, |  | ||||||
|         ); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     symbol_table.pop_scope(); |  | ||||||
|     fqn_context.pop(); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| fn gather_interface( |  | ||||||
|     interface: &Interface, |  | ||||||
|     symbol_table: &mut SymbolTable, |  | ||||||
|     fqn_context: &mut FqnContext, |  | ||||||
|     diagnostics: &mut Vec<DmDiagnostic>, |  | ||||||
| ) { |  | ||||||
|     let type_symbol = ConcreteTypeSymbol::new( |  | ||||||
|         &fqn_context.resolve(interface.identifier().name()), |  | ||||||
|         interface.identifier().name(), |  | ||||||
|         interface.is_public(), |  | ||||||
|         ConcreteTypeSymbolKind::Interface, |  | ||||||
|         Some(SourceDefinition::from_identifier(interface.identifier())), |  | ||||||
|     ); |  | ||||||
|     if let Err(symbol_insert_error) = |  | ||||||
|         symbol_table.insert_type_symbol(TypeSymbol::Concrete(type_symbol)) |  | ||||||
|     { |  | ||||||
|         handle_insert_error( |  | ||||||
|             symbol_insert_error, |  | ||||||
|             interface.identifier().name(), |  | ||||||
|             interface.identifier().file_id(), |  | ||||||
|             interface.identifier().range(), |  | ||||||
|             "Interface", |  | ||||||
|             diagnostics, |  | ||||||
|         ); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     fqn_context.push(interface.identifier().name()); |  | ||||||
|     symbol_table.push_scope(&format!("InterfaceScope {}", interface.identifier().name())); |  | ||||||
| 
 |  | ||||||
|     for declaration in interface.declarations() { |  | ||||||
|         gather_node( |  | ||||||
|             declaration.as_node_ref(), |  | ||||||
|             symbol_table, |  | ||||||
|             fqn_context, |  | ||||||
|             diagnostics, |  | ||||||
|         ); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     symbol_table.pop_scope(); |  | ||||||
|     fqn_context.pop(); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| fn gather_class( |  | ||||||
|     class: &Class, |  | ||||||
|     symbol_table: &mut SymbolTable, |  | ||||||
|     fqn_context: &mut FqnContext, |  | ||||||
|     diagnostics: &mut Vec<DmDiagnostic>, |  | ||||||
| ) { |  | ||||||
|     let class_symbol = ConcreteTypeSymbol::new( |  | ||||||
|         &fqn_context.resolve(class.identifier().name()), |  | ||||||
|         class.identifier().name(), |  | ||||||
|         class.is_public(), |  | ||||||
|         ConcreteTypeSymbolKind::Class, |  | ||||||
|         Some(SourceDefinition::from_identifier(class.identifier())), |  | ||||||
|     ); |  | ||||||
|     if let Err(symbol_insert_error) = |  | ||||||
|         symbol_table.insert_type_symbol(TypeSymbol::Concrete(class_symbol)) |  | ||||||
|     { |  | ||||||
|         handle_insert_error( |  | ||||||
|             symbol_insert_error, |  | ||||||
|             class.identifier().name(), |  | ||||||
|             class.identifier().file_id(), |  | ||||||
|             class.identifier().range(), |  | ||||||
|             "Class", |  | ||||||
|             diagnostics, |  | ||||||
|         ); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     fqn_context.push(class.identifier().name()); |  | ||||||
|     symbol_table.push_scope(&format!("ClassScope {}", class.identifier().name())); |  | ||||||
| 
 |  | ||||||
|     for declaration in class.class_level_declarations() { |  | ||||||
|         gather_node( |  | ||||||
|             declaration.as_node_ref(), |  | ||||||
|             symbol_table, |  | ||||||
|             fqn_context, |  | ||||||
|             diagnostics, |  | ||||||
|         ); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     symbol_table.pop_scope(); |  | ||||||
|     fqn_context.pop(); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| fn gather_function( |  | ||||||
|     function: &Function, |  | ||||||
|     symbol_table: &mut SymbolTable, |  | ||||||
|     fqn_context: &mut FqnContext, |  | ||||||
|     diagnostics: &mut Vec<DmDiagnostic>, |  | ||||||
| ) { |  | ||||||
|     let function_symbol = FunctionSymbol::without_parameters_or_return_type( |  | ||||||
|         &fqn_context.resolve(function.identifier().name()), |  | ||||||
|         function.identifier().name(), |  | ||||||
|         function.is_public(), |  | ||||||
|         false, |  | ||||||
|         Some(SourceDefinition::from_identifier(function.identifier())), |  | ||||||
|     ); |  | ||||||
|     if let Err(insert_error) = symbol_table.insert_function_symbol(function_symbol) { |  | ||||||
|         handle_insert_error( |  | ||||||
|             insert_error, |  | ||||||
|             function.identifier().name(), |  | ||||||
|             function.identifier().file_id(), |  | ||||||
|             function.identifier().range(), |  | ||||||
|             "Function", |  | ||||||
|             diagnostics, |  | ||||||
|         ); |  | ||||||
|     } |  | ||||||
|     gather_node( |  | ||||||
|         function.function_body().as_node_ref(), |  | ||||||
|         symbol_table, |  | ||||||
|         fqn_context, |  | ||||||
|         diagnostics, |  | ||||||
|     ); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| fn gather_function_block_body( |  | ||||||
|     function_block_body: &FunctionBlockBody, |  | ||||||
|     symbol_table: &mut SymbolTable, |  | ||||||
|     fqn_context: &mut FqnContext, |  | ||||||
|     diagnostics: &mut Vec<DmDiagnostic>, |  | ||||||
| ) { |  | ||||||
|     symbol_table.push_scope("FunctionBlockBody"); |  | ||||||
|     gather_node_children(function_block_body, symbol_table, fqn_context, diagnostics); |  | ||||||
|     symbol_table.pop_scope(); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| fn gather_variable_declaration( |  | ||||||
|     variable_declaration: &VariableDeclaration, |  | ||||||
|     symbol_table: &mut SymbolTable, |  | ||||||
|     fqn_context: &mut FqnContext, |  | ||||||
|     diagnostics: &mut Vec<DmDiagnostic>, |  | ||||||
| ) { |  | ||||||
|     let variable_symbol = VariableSymbol::new( |  | ||||||
|         variable_declaration.identifier().name(), |  | ||||||
|         variable_declaration.is_mut(), |  | ||||||
|         Some(SourceDefinition::from_identifier( |  | ||||||
|             variable_declaration.identifier(), |  | ||||||
|         )), |  | ||||||
|     ); |  | ||||||
|     if let Err(insert_error) = symbol_table.insert_variable_symbol(variable_symbol) { |  | ||||||
|         handle_insert_error( |  | ||||||
|             insert_error, |  | ||||||
|             variable_declaration.identifier().name(), |  | ||||||
|             variable_declaration.identifier().file_id(), |  | ||||||
|             variable_declaration.identifier().range(), |  | ||||||
|             "Variable", |  | ||||||
|             diagnostics, |  | ||||||
|         ); |  | ||||||
|     } |  | ||||||
|     if let Some(expression) = variable_declaration.expression() { |  | ||||||
|         gather_node( |  | ||||||
|             expression.as_node_ref(), |  | ||||||
|             symbol_table, |  | ||||||
|             fqn_context, |  | ||||||
|             diagnostics, |  | ||||||
|         ); |  | ||||||
|     } |  | ||||||
| } | } | ||||||
|  | |||||||
| @ -24,18 +24,16 @@ 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 codespan_reporting::files::Files; |  | ||||||
| use std::collections::HashMap; | use std::collections::HashMap; | ||||||
| 
 | 
 | ||||||
| pub(self) 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<'a, F: Files<'a, FileId = usize, Name = String>>( | pub fn analyze_names( | ||||||
|     compilation_units: &mut [Box<CompilationUnit>], |     compilation_units: &mut [Box<CompilationUnit>], | ||||||
|     files: &'a F, |  | ||||||
|     symbol_table: &mut SymbolTable, |     symbol_table: &mut SymbolTable, | ||||||
| ) -> Vec<DmDiagnostic> { | ) -> Vec<DmDiagnostic> { | ||||||
|     let mut diagnostics = vec![]; |     let mut diagnostics = vec![]; | ||||||
| @ -43,8 +41,12 @@ pub fn analyze_names<'a, F: Files<'a, FileId = usize, Name = String>>( | |||||||
| 
 | 
 | ||||||
|     // gather symbols
 |     // gather symbols
 | ||||||
|     for compilation_unit in compilation_units.iter_mut() { |     for compilation_unit in compilation_units.iter_mut() { | ||||||
|         let file_name = files.name(compilation_unit.file_id()).unwrap(); |         gather_compilation_unit( | ||||||
|         gather_compilation_unit(compilation_unit, &file_name, symbol_table, &mut diagnostics); |             compilation_unit, | ||||||
|  |             symbol_table, | ||||||
|  |             &mut identifier_scope_ids, | ||||||
|  |             &mut diagnostics, | ||||||
|  |         ); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     // resolve symbols
 |     // resolve symbols
 | ||||||
|  | |||||||
| @ -1,45 +0,0 @@ | |||||||
| use crate::name_analysis::symbol::source_definition::SourceDefinition; |  | ||||||
| use std::fmt::{Debug, Formatter}; |  | ||||||
| 
 |  | ||||||
| #[derive(Clone)] |  | ||||||
| pub struct ClassMemberSymbol { |  | ||||||
|     declared_name: String, |  | ||||||
|     is_field: bool, |  | ||||||
|     source_definition: Option<SourceDefinition>, |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| impl ClassMemberSymbol { |  | ||||||
|     pub fn new( |  | ||||||
|         declared_name: &str, |  | ||||||
|         is_field: bool, |  | ||||||
|         source_definition: Option<SourceDefinition>, |  | ||||||
|     ) -> Self { |  | ||||||
|         Self { |  | ||||||
|             declared_name: declared_name.to_string(), |  | ||||||
|             is_field, |  | ||||||
|             source_definition, |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     pub fn declared_name(&self) -> &str { |  | ||||||
|         &self.declared_name |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     pub fn is_field(&self) -> bool { |  | ||||||
|         self.is_field |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     pub fn source_definition(&self) -> Option<&SourceDefinition> { |  | ||||||
|         self.source_definition.as_ref() |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| impl Debug for ClassMemberSymbol { |  | ||||||
|     fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { |  | ||||||
|         f.debug_struct("ClassMemberSymbol") |  | ||||||
|             .field("declared_name", &self.declared_name) |  | ||||||
|             .field("is_field", &self.is_field) |  | ||||||
|             .field("source_definition", &self.source_definition) |  | ||||||
|             .finish() |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @ -1,101 +0,0 @@ | |||||||
| use crate::name_analysis::symbol::parameter_symbol::ParameterSymbol; |  | ||||||
| use crate::name_analysis::symbol::source_definition::SourceDefinition; |  | ||||||
| use crate::name_analysis::symbol::type_symbol::ConcreteTypeSymbol; |  | ||||||
| use std::fmt::{Debug, Formatter}; |  | ||||||
| 
 |  | ||||||
| #[derive(Clone)] |  | ||||||
| pub struct FunctionSymbol { |  | ||||||
|     fqn: String, |  | ||||||
|     declared_name: String, |  | ||||||
|     is_public: bool, |  | ||||||
|     is_platform: bool, |  | ||||||
|     source_definition: Option<SourceDefinition>, |  | ||||||
|     parameters: Vec<ParameterSymbol>, |  | ||||||
|     return_type: Option<ConcreteTypeSymbol>, // todo: can we use TypeSymbol?
 |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| impl FunctionSymbol { |  | ||||||
|     pub fn without_parameters_or_return_type( |  | ||||||
|         fqn: &str, |  | ||||||
|         declared_name: &str, |  | ||||||
|         is_public: bool, |  | ||||||
|         is_platform: bool, |  | ||||||
|         source_definition: Option<SourceDefinition>, |  | ||||||
|     ) -> FunctionSymbol { |  | ||||||
|         FunctionSymbol { |  | ||||||
|             fqn: fqn.to_string(), |  | ||||||
|             declared_name: declared_name.to_string(), |  | ||||||
|             is_public, |  | ||||||
|             is_platform, |  | ||||||
|             source_definition, |  | ||||||
|             parameters: Vec::new(), |  | ||||||
|             return_type: None, |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     pub fn with_parameters(self, parameters: Vec<ParameterSymbol>) -> Self { |  | ||||||
|         Self { |  | ||||||
|             fqn: self.fqn, |  | ||||||
|             declared_name: self.declared_name, |  | ||||||
|             is_public: self.is_public, |  | ||||||
|             is_platform: self.is_platform, |  | ||||||
|             source_definition: self.source_definition, |  | ||||||
|             parameters, |  | ||||||
|             return_type: self.return_type, |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     pub fn with_return_type(self, return_type: ConcreteTypeSymbol) -> Self { |  | ||||||
|         Self { |  | ||||||
|             fqn: self.fqn, |  | ||||||
|             declared_name: self.declared_name, |  | ||||||
|             is_public: self.is_public, |  | ||||||
|             is_platform: self.is_platform, |  | ||||||
|             source_definition: self.source_definition, |  | ||||||
|             parameters: self.parameters, |  | ||||||
|             return_type: Some(return_type), |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     pub fn fqn(&self) -> &str { |  | ||||||
|         &self.fqn |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     pub fn declared_name(&self) -> &str { |  | ||||||
|         &self.declared_name |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     pub fn is_public(&self) -> bool { |  | ||||||
|         self.is_public |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     pub fn is_platform(&self) -> bool { |  | ||||||
|         self.is_platform |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     pub fn source_definition(&self) -> Option<&SourceDefinition> { |  | ||||||
|         self.source_definition.as_ref() |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     pub fn parameters(&self) -> &[ParameterSymbol] { |  | ||||||
|         &self.parameters |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     pub fn return_type(&self) -> Option<&ConcreteTypeSymbol> { |  | ||||||
|         self.return_type.as_ref() |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| impl Debug for FunctionSymbol { |  | ||||||
|     fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { |  | ||||||
|         f.debug_struct("FunctionSymbol") |  | ||||||
|             .field("fqn", &self.fqn) |  | ||||||
|             .field("declared_name", &self.declared_name) |  | ||||||
|             .field("is_public", &self.is_public) |  | ||||||
|             .field("is_platform", &self.is_platform) |  | ||||||
|             .field("parameters", &self.parameters) |  | ||||||
|             .field("return_type", &self.return_type) |  | ||||||
|             .field("source_definition", &self.source_definition) |  | ||||||
|             .finish() |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @ -1,46 +1,445 @@ | |||||||
| pub(crate) mod class_member_symbol; | pub(super) mod source_definition; | ||||||
| pub(crate) mod function_symbol; | pub(super) mod use_symbol; | ||||||
| pub(crate) mod module_symbol; |  | ||||||
| pub(crate) mod parameter_symbol; |  | ||||||
| pub(crate) mod source_definition; |  | ||||||
| pub(crate) mod type_symbol; |  | ||||||
| pub(crate) mod use_symbol; |  | ||||||
| pub(crate) mod variable_symbol; |  | ||||||
| 
 | 
 | ||||||
| use crate::name_analysis::symbol::use_symbol::{ConcreteUseSymbol, StarUseSymbol}; | use crate::ast::node::Identifier; | ||||||
| use class_member_symbol::ClassMemberSymbol; |  | ||||||
| use function_symbol::FunctionSymbol; |  | ||||||
| use module_symbol::ModuleSymbol; |  | ||||||
| use parameter_symbol::ParameterSymbol; |  | ||||||
| use source_definition::SourceDefinition; | use source_definition::SourceDefinition; | ||||||
| use std::fmt::{Debug, Display}; | use std::cell::RefCell; | ||||||
|  | use std::fmt::{Debug, Display, Formatter}; | ||||||
| use std::ops::Deref; | use std::ops::Deref; | ||||||
| use type_symbol::TypeSymbol; | use std::rc::Rc; | ||||||
| use variable_symbol::VariableSymbol; | 
 | ||||||
|  | pub trait SymbolInner { | ||||||
|  |     fn declared_name(&self) -> &str; | ||||||
|  |     fn definition(&self) -> Option<SourceDefinition>; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* Symbol */ | ||||||
| 
 | 
 | ||||||
| #[derive(Debug, Clone)] | #[derive(Debug, Clone)] | ||||||
| pub enum Symbol { | pub enum Symbol { | ||||||
|     ConcreteUse(ConcreteUseSymbol), |     UseStatement(Rc<RefCell<UseStatementSymbol>>), | ||||||
|     StarUse(StarUseSymbol), |     Module(Rc<ModuleSymbol>), | ||||||
|     Module(ModuleSymbol), |     Type(Rc<TypeSymbol>), | ||||||
|     Type(TypeSymbol), |     Function(Rc<RefCell<FunctionSymbol>>), | ||||||
|     Function(FunctionSymbol), |     Parameter(Rc<ParameterSymbol>), | ||||||
|     Parameter(ParameterSymbol), |     Variable(Rc<VariableSymbol>), | ||||||
|     Variable(VariableSymbol), |     ClassMember(Rc<ClassMemberSymbol>), | ||||||
|     ClassMember(ClassMemberSymbol), |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl Symbol { | impl Symbol { | ||||||
|     pub fn definition(&self) -> Option<&SourceDefinition> { |     pub fn definition(&self) -> Option<SourceDefinition> { | ||||||
|         match self { |         match self { | ||||||
|             Symbol::ConcreteUse(concrete) => concrete.source_definition(), |             Symbol::UseStatement(s) => s.borrow().definition(), | ||||||
|             Symbol::StarUse(star) => star.source_definition(), |             Symbol::Module(s) => s.definition(), | ||||||
|             Symbol::Module(module) => module.source_definition(), |             Symbol::Type(s) => match s.deref() { | ||||||
|             Symbol::Type(type_symbol) => type_symbol.source_definition(), |                 TypeSymbol::Concrete(cts) => cts.definition(), | ||||||
|             Symbol::Function(function_symbol) => function_symbol.source_definition(), |                 TypeSymbol::Generic(gts) => gts.definition(), | ||||||
|             Symbol::Parameter(parameter_symbol) => parameter_symbol.source_definition(), |             }, | ||||||
|             Symbol::Variable(variable_symbol) => variable_symbol.source_definition(), |             Symbol::Function(s) => s.borrow().definition(), | ||||||
|             Symbol::ClassMember(class_member_symbol) => class_member_symbol.source_definition(), |             Symbol::Parameter(s) => s.definition(), | ||||||
|  |             Symbol::Variable(s) => s.definition(), | ||||||
|  |             Symbol::ClassMember(s) => s.definition(), | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     pub fn unwrap_use_statement_symbol(&self) -> Rc<RefCell<UseStatementSymbol>> { | ||||||
|  |         match self { | ||||||
|  |             Symbol::UseStatement(s) => s.clone(), | ||||||
|  |             _ => panic!("unwrap_use_statement_symbol called on non-use statement symbol"), | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | /* Use-statement */ | ||||||
|  | 
 | ||||||
|  | pub struct UseStatementSymbol { | ||||||
|  |     pub fqn: String, | ||||||
|  |     pub declared_name: String, | ||||||
|  |     definition: Option<SourceDefinition>, | ||||||
|  |     referenced_symbol: Option<Box<Symbol>>, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl UseStatementSymbol { | ||||||
|  |     pub fn new(fqn: &str, declared_name: &str, identifier: Option<&Identifier>) -> Self { | ||||||
|  |         UseStatementSymbol { | ||||||
|  |             fqn: fqn.to_string(), | ||||||
|  |             declared_name: declared_name.to_string(), | ||||||
|  |             definition: identifier.map(SourceDefinition::from_identifier), | ||||||
|  |             referenced_symbol: None, | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     pub fn set_referenced_symbol(&mut self, referenced_symbol: Symbol) { | ||||||
|  |         self.referenced_symbol = Some(Box::new(referenced_symbol)); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     pub fn referenced_symbol(&self) -> Option<Box<Symbol>> { | ||||||
|  |         self.referenced_symbol.clone() | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl SymbolInner for UseStatementSymbol { | ||||||
|  |     fn declared_name(&self) -> &str { | ||||||
|  |         &self.declared_name | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fn definition(&self) -> Option<SourceDefinition> { | ||||||
|  |         self.definition.clone() | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl Debug for UseStatementSymbol { | ||||||
|  |     fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { | ||||||
|  |         f.debug_struct("UseStatementSymbol") | ||||||
|  |             .field("fqn", &self.fqn) | ||||||
|  |             .field("declared_name", &self.declared_name) | ||||||
|  |             .field("referenced_symbol", &self.referenced_symbol) | ||||||
|  |             .finish() | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* Module */ | ||||||
|  | 
 | ||||||
|  | pub struct ModuleSymbol { | ||||||
|  |     fqn: String, | ||||||
|  |     declared_name: String, | ||||||
|  |     is_public: bool, | ||||||
|  |     definition: Option<SourceDefinition>, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl ModuleSymbol { | ||||||
|  |     pub fn new( | ||||||
|  |         fqn: &str, | ||||||
|  |         declared_name: &str, | ||||||
|  |         is_public: bool, | ||||||
|  |         identifier: Option<&Identifier>, | ||||||
|  |     ) -> ModuleSymbol { | ||||||
|  |         ModuleSymbol { | ||||||
|  |             fqn: fqn.to_string(), | ||||||
|  |             declared_name: declared_name.to_string(), | ||||||
|  |             is_public, | ||||||
|  |             definition: identifier.map(SourceDefinition::from_identifier), | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl SymbolInner for ModuleSymbol { | ||||||
|  |     fn declared_name(&self) -> &str { | ||||||
|  |         self.declared_name.as_str() | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fn definition(&self) -> Option<SourceDefinition> { | ||||||
|  |         self.definition.clone() | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl Debug for ModuleSymbol { | ||||||
|  |     fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { | ||||||
|  |         f.debug_struct("ModuleSymbol") | ||||||
|  |             .field("fqn", &self.fqn) | ||||||
|  |             .field("declared_name", &self.declared_name) | ||||||
|  |             .field("is_public", &self.is_public) | ||||||
|  |             .finish() | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* TypeSymbol */ | ||||||
|  | 
 | ||||||
|  | #[derive(Debug)] | ||||||
|  | pub enum TypeSymbol { | ||||||
|  |     Concrete(ConcreteTypeSymbol), | ||||||
|  |     Generic(GenericTypeSymbol), | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl TypeSymbol { | ||||||
|  |     pub fn declared_name(&self) -> &str { | ||||||
|  |         match self { | ||||||
|  |             TypeSymbol::Concrete(t) => t.declared_name(), | ||||||
|  |             TypeSymbol::Generic(t) => t.declared_name(), | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | pub struct ConcreteTypeSymbol { | ||||||
|  |     fqn: String, | ||||||
|  |     declared_name: String, | ||||||
|  |     is_public: bool, | ||||||
|  |     definition: Option<SourceDefinition>, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl ConcreteTypeSymbol { | ||||||
|  |     pub fn new( | ||||||
|  |         fqn: &str, | ||||||
|  |         declared_name: &str, | ||||||
|  |         is_public: bool, | ||||||
|  |         identifier: Option<&Identifier>, | ||||||
|  |     ) -> Self { | ||||||
|  |         ConcreteTypeSymbol { | ||||||
|  |             fqn: fqn.to_string(), | ||||||
|  |             declared_name: declared_name.to_string(), | ||||||
|  |             is_public, | ||||||
|  |             definition: identifier.map(SourceDefinition::from_identifier), | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     pub fn fqn(&self) -> &str { | ||||||
|  |         &self.fqn | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     pub fn is_public(&self) -> bool { | ||||||
|  |         self.is_public | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl SymbolInner for ConcreteTypeSymbol { | ||||||
|  |     fn declared_name(&self) -> &str { | ||||||
|  |         &self.declared_name | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fn definition(&self) -> Option<SourceDefinition> { | ||||||
|  |         self.definition.clone() | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl Debug for ConcreteTypeSymbol { | ||||||
|  |     fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { | ||||||
|  |         f.debug_struct("TypeSymbol") | ||||||
|  |             .field("fqn", &self.fqn) | ||||||
|  |             .field("declared_name", &self.declared_name) | ||||||
|  |             .field("is_public", &self.is_public) | ||||||
|  |             .finish() | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | pub struct GenericTypeSymbol { | ||||||
|  |     declared_name: String, | ||||||
|  |     source_definition: SourceDefinition, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl GenericTypeSymbol { | ||||||
|  |     pub fn new(declared_name: &str, source_definition: SourceDefinition) -> Self { | ||||||
|  |         GenericTypeSymbol { | ||||||
|  |             declared_name: declared_name.to_string(), | ||||||
|  |             source_definition, | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl SymbolInner for GenericTypeSymbol { | ||||||
|  |     fn declared_name(&self) -> &str { | ||||||
|  |         self.declared_name.as_str() | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fn definition(&self) -> Option<SourceDefinition> { | ||||||
|  |         Some(self.source_definition.clone()) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl Debug for GenericTypeSymbol { | ||||||
|  |     fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { | ||||||
|  |         f.debug_struct("GenericTypeSymbol") | ||||||
|  |             .field("declared_name", &self.declared_name) | ||||||
|  |             .finish() | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* Function */ | ||||||
|  | 
 | ||||||
|  | pub struct FunctionSymbol { | ||||||
|  |     fqn: String, | ||||||
|  |     declared_name: String, | ||||||
|  |     is_public: bool, | ||||||
|  |     is_platform: bool, | ||||||
|  |     definition: Option<SourceDefinition>, | ||||||
|  |     parameters: Vec<Rc<ParameterSymbol>>, | ||||||
|  |     return_type: Option<Rc<ConcreteTypeSymbol>>, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl FunctionSymbol { | ||||||
|  |     pub fn new( | ||||||
|  |         fqn: &str, | ||||||
|  |         declared_name: &str, | ||||||
|  |         is_public: bool, | ||||||
|  |         is_platform: bool, | ||||||
|  |         identifier: Option<&Identifier>, | ||||||
|  |     ) -> FunctionSymbol { | ||||||
|  |         FunctionSymbol { | ||||||
|  |             fqn: fqn.to_string(), | ||||||
|  |             declared_name: declared_name.to_string(), | ||||||
|  |             is_public, | ||||||
|  |             is_platform, | ||||||
|  |             definition: identifier.map(SourceDefinition::from_identifier), | ||||||
|  |             parameters: Vec::new(), | ||||||
|  |             return_type: None, | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     pub fn with_parameters(self, parameters: Vec<ParameterSymbol>) -> Self { | ||||||
|  |         Self { | ||||||
|  |             fqn: self.fqn, | ||||||
|  |             declared_name: self.declared_name, | ||||||
|  |             is_public: self.is_public, | ||||||
|  |             is_platform: self.is_platform, | ||||||
|  |             definition: self.definition, | ||||||
|  |             parameters: parameters | ||||||
|  |                 .into_iter() | ||||||
|  |                 .map(|parameter| Rc::new(parameter)) | ||||||
|  |                 .collect(), | ||||||
|  |             return_type: self.return_type, | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     pub fn with_return_type(self, return_type: ConcreteTypeSymbol) -> Self { | ||||||
|  |         Self { | ||||||
|  |             fqn: self.fqn, | ||||||
|  |             declared_name: self.declared_name, | ||||||
|  |             is_public: self.is_public, | ||||||
|  |             is_platform: self.is_platform, | ||||||
|  |             definition: self.definition, | ||||||
|  |             parameters: self.parameters, | ||||||
|  |             return_type: Some(Rc::new(return_type)), | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     pub fn fqn(&self) -> &str { | ||||||
|  |         &self.fqn | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     pub fn set_parameters(&mut self, parameters: Vec<Rc<ParameterSymbol>>) { | ||||||
|  |         self.parameters = parameters; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     pub fn set_return_type(&mut self, return_type: Rc<ConcreteTypeSymbol>) { | ||||||
|  |         self.return_type = Some(return_type); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl SymbolInner for FunctionSymbol { | ||||||
|  |     fn declared_name(&self) -> &str { | ||||||
|  |         self.declared_name.as_str() | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fn definition(&self) -> Option<SourceDefinition> { | ||||||
|  |         self.definition.clone() | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl Debug for FunctionSymbol { | ||||||
|  |     fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { | ||||||
|  |         f.debug_struct("FunctionSymbol") | ||||||
|  |             .field("fqn", &self.fqn) | ||||||
|  |             .field("declared_name", &self.declared_name) | ||||||
|  |             .field("is_public", &self.is_public) | ||||||
|  |             .field("is_platform", &self.is_platform) | ||||||
|  |             .field("parameters", &self.parameters) | ||||||
|  |             .field("return_type", &self.return_type) | ||||||
|  |             .finish() | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* Parameter */ | ||||||
|  | 
 | ||||||
|  | pub struct ParameterSymbol { | ||||||
|  |     declared_name: String, | ||||||
|  |     definition: Option<SourceDefinition>, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl ParameterSymbol { | ||||||
|  |     pub fn new(declared_name: &str, identifier: Option<&Identifier>) -> Self { | ||||||
|  |         ParameterSymbol { | ||||||
|  |             declared_name: declared_name.to_string(), | ||||||
|  |             definition: identifier.map(SourceDefinition::from_identifier), | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl SymbolInner for ParameterSymbol { | ||||||
|  |     fn declared_name(&self) -> &str { | ||||||
|  |         &self.declared_name | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fn definition(&self) -> Option<SourceDefinition> { | ||||||
|  |         self.definition.clone() | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl Debug for ParameterSymbol { | ||||||
|  |     fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { | ||||||
|  |         f.debug_struct("ParameterSymbol") | ||||||
|  |             .field("declared_name", &self.declared_name) | ||||||
|  |             .finish() | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* Variable */ | ||||||
|  | 
 | ||||||
|  | pub struct VariableSymbol { | ||||||
|  |     declared_name: String, | ||||||
|  |     is_mutable: bool, | ||||||
|  |     definition: Option<SourceDefinition>, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl VariableSymbol { | ||||||
|  |     pub fn new(declared_name: &str, is_mutable: bool, identifier: Option<&Identifier>) -> Self { | ||||||
|  |         VariableSymbol { | ||||||
|  |             declared_name: declared_name.to_string(), | ||||||
|  |             is_mutable, | ||||||
|  |             definition: identifier.map(SourceDefinition::from_identifier), | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl SymbolInner for VariableSymbol { | ||||||
|  |     fn declared_name(&self) -> &str { | ||||||
|  |         self.declared_name.as_str() | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fn definition(&self) -> Option<SourceDefinition> { | ||||||
|  |         self.definition.clone() | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl Debug for VariableSymbol { | ||||||
|  |     fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { | ||||||
|  |         f.debug_struct("VariableSymbol") | ||||||
|  |             .field("declared_name", &self.declared_name) | ||||||
|  |             .field("is_mutable", &self.is_mutable) | ||||||
|  |             .finish() | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* Class Member */ | ||||||
|  | 
 | ||||||
|  | pub struct ClassMemberSymbol { | ||||||
|  |     declared_name: String, | ||||||
|  |     is_field: bool, | ||||||
|  |     definition: Option<SourceDefinition>, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl ClassMemberSymbol { | ||||||
|  |     pub fn new(declared_name: &str, is_field: bool, definition: Option<SourceDefinition>) -> Self { | ||||||
|  |         ClassMemberSymbol { | ||||||
|  |             declared_name: declared_name.to_string(), | ||||||
|  |             is_field, | ||||||
|  |             definition, | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl SymbolInner for ClassMemberSymbol { | ||||||
|  |     fn declared_name(&self) -> &str { | ||||||
|  |         self.declared_name.as_str() | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fn definition(&self) -> Option<SourceDefinition> { | ||||||
|  |         self.definition.clone() | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl Debug for ClassMemberSymbol { | ||||||
|  |     fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { | ||||||
|  |         f.debug_struct("ClassMemberSymbol") | ||||||
|  |             .field("declared_name", &self.declared_name) | ||||||
|  |             .finish() | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | |||||||
| @ -1,53 +0,0 @@ | |||||||
| use crate::name_analysis::symbol::source_definition::SourceDefinition; |  | ||||||
| use std::fmt::{Debug, Formatter}; |  | ||||||
| 
 |  | ||||||
| #[derive(Clone)] |  | ||||||
| pub struct ModuleSymbol { |  | ||||||
|     fqn: String, |  | ||||||
|     declared_name: String, |  | ||||||
|     is_public: bool, |  | ||||||
|     source_definition: Option<SourceDefinition>, |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| impl ModuleSymbol { |  | ||||||
|     pub fn new( |  | ||||||
|         fqn: &str, |  | ||||||
|         declared_name: &str, |  | ||||||
|         is_public: bool, |  | ||||||
|         source_definition: Option<SourceDefinition>, |  | ||||||
|     ) -> Self { |  | ||||||
|         Self { |  | ||||||
|             fqn: fqn.to_string(), |  | ||||||
|             declared_name: declared_name.to_string(), |  | ||||||
|             is_public, |  | ||||||
|             source_definition, |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     pub fn fqn(&self) -> &str { |  | ||||||
|         &self.fqn |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     pub fn declared_name(&self) -> &str { |  | ||||||
|         &self.declared_name |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     pub fn is_public(&self) -> bool { |  | ||||||
|         self.is_public |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     pub fn source_definition(&self) -> Option<&SourceDefinition> { |  | ||||||
|         self.source_definition.as_ref() |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| impl Debug for ModuleSymbol { |  | ||||||
|     fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { |  | ||||||
|         f.debug_struct("ModuleSymbol") |  | ||||||
|             .field("fqn", &self.fqn) |  | ||||||
|             .field("declared_name", &self.declared_name) |  | ||||||
|             .field("is_public", &self.is_public) |  | ||||||
|             .field("source_definition", &self.source_definition) |  | ||||||
|             .finish() |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @ -1,34 +0,0 @@ | |||||||
| use crate::name_analysis::symbol::source_definition::SourceDefinition; |  | ||||||
| use std::fmt::{Debug, Formatter}; |  | ||||||
| 
 |  | ||||||
| #[derive(Clone)] |  | ||||||
| pub struct ParameterSymbol { |  | ||||||
|     declared_name: String, |  | ||||||
|     source_definition: Option<SourceDefinition>, |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| impl ParameterSymbol { |  | ||||||
|     pub fn new(declared_name: &str, source_definition: Option<SourceDefinition>) -> Self { |  | ||||||
|         ParameterSymbol { |  | ||||||
|             declared_name: declared_name.to_string(), |  | ||||||
|             source_definition, |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|     
 |  | ||||||
|     pub fn declared_name(&self) -> &str { |  | ||||||
|         &self.declared_name |  | ||||||
|     } |  | ||||||
|     
 |  | ||||||
|     pub fn source_definition(&self) -> Option<&SourceDefinition> { |  | ||||||
|         self.source_definition.as_ref() |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| impl Debug for ParameterSymbol { |  | ||||||
|     fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { |  | ||||||
|         f.debug_struct("ParameterSymbol") |  | ||||||
|             .field("declared_name", &self.declared_name) |  | ||||||
|             .field("source_definition", &self.source_definition) |  | ||||||
|             .finish() |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @ -1,121 +0,0 @@ | |||||||
| use crate::name_analysis::symbol::source_definition::SourceDefinition; |  | ||||||
| use std::fmt::{Debug, Formatter}; |  | ||||||
| 
 |  | ||||||
| #[derive(Clone, Debug)] |  | ||||||
| pub enum TypeSymbol { |  | ||||||
|     Concrete(ConcreteTypeSymbol), |  | ||||||
|     Generic(GenericTypeSymbol), |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| impl TypeSymbol { |  | ||||||
|     pub fn declared_name(&self) -> &str { |  | ||||||
|         match self { |  | ||||||
|             TypeSymbol::Concrete(t) => t.declared_name(), |  | ||||||
|             TypeSymbol::Generic(t) => t.declared_name(), |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|     
 |  | ||||||
|     pub fn source_definition(&self) -> Option<&SourceDefinition> { |  | ||||||
|         match self { |  | ||||||
|             TypeSymbol::Concrete(t) => t.source_definition(), |  | ||||||
|             TypeSymbol::Generic(t) => t.source_definition(), |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| #[derive(Clone)] |  | ||||||
| pub struct ConcreteTypeSymbol { |  | ||||||
|     fqn: String, |  | ||||||
|     declared_name: String, |  | ||||||
|     is_public: bool, |  | ||||||
|     kind: ConcreteTypeSymbolKind, |  | ||||||
|     source_definition: Option<SourceDefinition>, |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| impl ConcreteTypeSymbol { |  | ||||||
|     pub fn new( |  | ||||||
|         fqn: &str, |  | ||||||
|         declared_name: &str, |  | ||||||
|         is_public: bool, |  | ||||||
|         kind: ConcreteTypeSymbolKind, |  | ||||||
|         source_definition: Option<SourceDefinition>, |  | ||||||
|     ) -> Self { |  | ||||||
|         Self { |  | ||||||
|             fqn: fqn.to_string(), |  | ||||||
|             declared_name: declared_name.to_string(), |  | ||||||
|             is_public, |  | ||||||
|             kind, |  | ||||||
|             source_definition |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     pub fn fqn(&self) -> &str { |  | ||||||
|         &self.fqn |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     pub fn is_public(&self) -> bool { |  | ||||||
|         self.is_public |  | ||||||
|     } |  | ||||||
|     
 |  | ||||||
|     pub fn kind(&self) -> &ConcreteTypeSymbolKind { |  | ||||||
|         &self.kind |  | ||||||
|     } |  | ||||||
|     
 |  | ||||||
|     pub fn declared_name(&self) -> &str { |  | ||||||
|         &self.declared_name |  | ||||||
|     } |  | ||||||
|     
 |  | ||||||
|     pub fn source_definition(&self) -> Option<&SourceDefinition> { |  | ||||||
|         self.source_definition.as_ref() |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| impl Debug for ConcreteTypeSymbol { |  | ||||||
|     fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { |  | ||||||
|         f.debug_struct("TypeSymbol") |  | ||||||
|             .field("fqn", &self.fqn) |  | ||||||
|             .field("declared_name", &self.declared_name) |  | ||||||
|             .field("is_public", &self.is_public) |  | ||||||
|             .field("kind", &self.kind) |  | ||||||
|             .field("source_definition", &self.source_definition) |  | ||||||
|             .finish() |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| #[derive(Clone, Debug)] |  | ||||||
| pub enum ConcreteTypeSymbolKind { |  | ||||||
|     Interface, |  | ||||||
|     Class |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| #[derive(Clone)] |  | ||||||
| pub struct GenericTypeSymbol { |  | ||||||
|     declared_name: String, |  | ||||||
|     source_definition: Option<SourceDefinition>, |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| impl GenericTypeSymbol { |  | ||||||
|     pub fn new(declared_name: &str, source_definition: Option<SourceDefinition>) -> Self { |  | ||||||
|         GenericTypeSymbol { |  | ||||||
|             declared_name: declared_name.to_string(), |  | ||||||
|             source_definition, |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|     
 |  | ||||||
|     pub fn declared_name(&self) -> &str { |  | ||||||
|         &self.declared_name |  | ||||||
|     } |  | ||||||
|     
 |  | ||||||
|     pub fn source_definition(&self) -> Option<&SourceDefinition> { |  | ||||||
|         self.source_definition.as_ref() |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| impl Debug for GenericTypeSymbol { |  | ||||||
|     fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { |  | ||||||
|         f.debug_struct("GenericTypeSymbol") |  | ||||||
|             .field("declared_name", &self.declared_name) |  | ||||||
|             .field("source_definition", &self.source_definition) |  | ||||||
|             .finish() |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @ -1,56 +1,16 @@ | |||||||
| use crate::name_analysis::symbol::source_definition::SourceDefinition; | use crate::name_analysis::symbol::source_definition::SourceDefinition; | ||||||
| use std::fmt::{Debug, Formatter}; |  | ||||||
| 
 | 
 | ||||||
| #[derive(Clone)] | pub enum UseStatementSymbol { | ||||||
| pub struct ConcreteUseSymbol { |     Concrete, | ||||||
|     base_fqn: String, |     Star(StarUseStatementSymbol), | ||||||
|     declared_name: String, |  | ||||||
|     source_definition: Option<SourceDefinition>, |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl ConcreteUseSymbol { | pub struct StarUseStatementSymbol { | ||||||
|     pub fn new( |  | ||||||
|         base_fqn: &str, |  | ||||||
|         declared_name: &str, |  | ||||||
|         source_definition: Option<SourceDefinition>, |  | ||||||
|     ) -> Self { |  | ||||||
|         Self { |  | ||||||
|             base_fqn: base_fqn.to_string(), |  | ||||||
|             declared_name: declared_name.to_string(), |  | ||||||
|             source_definition, |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     pub fn base_fqn(&self) -> &str { |  | ||||||
|         &self.base_fqn |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     pub fn declared_name(&self) -> &str { |  | ||||||
|         &self.declared_name |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     pub fn source_definition(&self) -> Option<&SourceDefinition> { |  | ||||||
|         self.source_definition.as_ref() |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| impl Debug for ConcreteUseSymbol { |  | ||||||
|     fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { |  | ||||||
|         f.debug_struct("ConcreteUseStatementSymbol") |  | ||||||
|             .field("base_fqn", &self.base_fqn) |  | ||||||
|             .field("declared_name", &self.declared_name) |  | ||||||
|             .field("source_definition", &self.source_definition) |  | ||||||
|             .finish() |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| #[derive(Clone)] |  | ||||||
| pub struct StarUseSymbol { |  | ||||||
|     base_fqn: String, |     base_fqn: String, | ||||||
|     source_definition: Option<SourceDefinition>, |     source_definition: Option<SourceDefinition>, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl StarUseSymbol { | impl StarUseStatementSymbol { | ||||||
|     pub fn new(base_fqn: &str, source_definition: Option<SourceDefinition>) -> Self { |     pub fn new(base_fqn: &str, source_definition: Option<SourceDefinition>) -> Self { | ||||||
|         Self { |         Self { | ||||||
|             base_fqn: base_fqn.to_string(), |             base_fqn: base_fqn.to_string(), | ||||||
| @ -66,12 +26,3 @@ impl StarUseSymbol { | |||||||
|         self.source_definition.as_ref() |         self.source_definition.as_ref() | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 |  | ||||||
| impl Debug for StarUseSymbol { |  | ||||||
|     fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { |  | ||||||
|         f.debug_struct("StarUseStatementSymbol") |  | ||||||
|             .field("base_fqn", &self.base_fqn) |  | ||||||
|             .field("source_definition", &self.source_definition) |  | ||||||
|             .finish() |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  | |||||||
| @ -1,41 +0,0 @@ | |||||||
| use crate::name_analysis::symbol::source_definition::SourceDefinition; |  | ||||||
| use std::fmt::{Debug, Formatter}; |  | ||||||
| 
 |  | ||||||
| #[derive(Clone)] |  | ||||||
| pub struct VariableSymbol { |  | ||||||
|     declared_name: String, |  | ||||||
|     is_mutable: bool, |  | ||||||
|     source_definition: Option<SourceDefinition>, |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| impl VariableSymbol { |  | ||||||
|     pub fn new(declared_name: &str, is_mutable: bool, source_definition: Option<SourceDefinition>) -> Self { |  | ||||||
|         VariableSymbol { |  | ||||||
|             declared_name: declared_name.to_string(), |  | ||||||
|             is_mutable, |  | ||||||
|             source_definition, |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     pub fn declared_name(&self) -> &str { |  | ||||||
|         &self.declared_name |  | ||||||
|     } |  | ||||||
|     
 |  | ||||||
|     pub fn is_mutable(&self) -> bool { |  | ||||||
|         self.is_mutable |  | ||||||
|     } |  | ||||||
|     
 |  | ||||||
|     pub fn source_definition(&self) -> Option<&SourceDefinition> { |  | ||||||
|         self.source_definition.as_ref() |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| impl Debug for VariableSymbol { |  | ||||||
|     fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { |  | ||||||
|         f.debug_struct("VariableSymbol") |  | ||||||
|             .field("declared_name", &self.declared_name) |  | ||||||
|             .field("is_mutable", &self.is_mutable) |  | ||||||
|             .field("source_definition", &self.source_definition) |  | ||||||
|             .finish() |  | ||||||
|     } |  | ||||||
| } |  | ||||||
							
								
								
									
										468
									
								
								src/name_analysis/symbol_table.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										468
									
								
								src/name_analysis/symbol_table.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,468 @@ | |||||||
|  | use crate::name_analysis::symbol::*; | ||||||
|  | use crate::name_analysis::symbol_table::SymbolInsertError::SymbolAlreadyDefined; | ||||||
|  | use crate::name_analysis::symbol_table::SymbolLookupError::NoDefinition; | ||||||
|  | use std::cell::RefCell; | ||||||
|  | use std::collections::HashMap; | ||||||
|  | use std::fmt::Display; | ||||||
|  | use std::ops::Deref; | ||||||
|  | use std::rc::Rc; | ||||||
|  | 
 | ||||||
|  | /* Scope */ | ||||||
|  | 
 | ||||||
|  | #[derive(Debug)] | ||||||
|  | struct Scope { | ||||||
|  |     parent: Option<usize>, | ||||||
|  |     use_statement_symbols: HashMap<String, Rc<RefCell<UseStatementSymbol>>>, | ||||||
|  |     module_symbols: HashMap<String, Rc<ModuleSymbol>>, | ||||||
|  |     type_symbols: HashMap<String, Rc<TypeSymbol>>, | ||||||
|  |     function_symbols: HashMap<String, Rc<RefCell<FunctionSymbol>>>, | ||||||
|  |     parameter_symbols: HashMap<String, Rc<ParameterSymbol>>, | ||||||
|  |     variable_symbols: HashMap<String, Rc<VariableSymbol>>, | ||||||
|  |     class_member_symbols: HashMap<String, Rc<ClassMemberSymbol>>, | ||||||
|  |     debug_name: String, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl Scope { | ||||||
|  |     pub fn new(parent: Option<usize>, debug_name: String) -> Scope { | ||||||
|  |         Scope { | ||||||
|  |             parent, | ||||||
|  |             use_statement_symbols: HashMap::new(), | ||||||
|  |             module_symbols: HashMap::new(), | ||||||
|  |             type_symbols: HashMap::new(), | ||||||
|  |             function_symbols: HashMap::new(), | ||||||
|  |             parameter_symbols: HashMap::new(), | ||||||
|  |             variable_symbols: HashMap::new(), | ||||||
|  |             class_member_symbols: HashMap::new(), | ||||||
|  |             debug_name, | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fn get_module_symbol_by_declared_name(&self, name: &str) -> Option<Rc<ModuleSymbol>> { | ||||||
|  |         for module_symbol in self.module_symbols.values() { | ||||||
|  |             if module_symbol.declared_name() == name { | ||||||
|  |                 return Some(module_symbol.clone()); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         None | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fn get_type_symbol_by_declared_name(&self, declared_name: &str) -> Option<Rc<TypeSymbol>> { | ||||||
|  |         if let Some(type_symbol) = self.type_symbols.get(declared_name) { | ||||||
|  |             Some(type_symbol.clone()) | ||||||
|  |         } else { | ||||||
|  |             for use_statement_symbol in self.use_statement_symbols.values() { | ||||||
|  |                 let borrowed = use_statement_symbol.borrow(); | ||||||
|  |                 if borrowed.declared_name() == declared_name { | ||||||
|  |                     if let Some(referenced_symbol) = borrowed.referenced_symbol() { | ||||||
|  |                         match *referenced_symbol { | ||||||
|  |                             Symbol::Type(type_symbol) => return Some(type_symbol.clone()), | ||||||
|  |                             _ => continue, | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             None | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fn get_type_symbol_by_fqn(&self, fqn: &str) -> Option<Rc<TypeSymbol>> { | ||||||
|  |         self.type_symbols | ||||||
|  |             .values() | ||||||
|  |             .find(|s| match s.deref().deref() { | ||||||
|  |                 TypeSymbol::Concrete(cts) => cts.fqn() == fqn, | ||||||
|  |                 _ => false, | ||||||
|  |             }) | ||||||
|  |             .cloned() | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fn get_usable_symbol_by_fqn(&self, fqn: &str) -> Option<Symbol> { | ||||||
|  |         for function_symbol in self.function_symbols.values() { | ||||||
|  |             if function_symbol.borrow().fqn() == fqn { | ||||||
|  |                 return Some(Symbol::Function(function_symbol.clone())); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         for type_symbol in self.type_symbols.values() { | ||||||
|  |             match type_symbol.deref() { | ||||||
|  |                 TypeSymbol::Concrete(concrete_type_symbol) => { | ||||||
|  |                     if concrete_type_symbol.fqn() == fqn { | ||||||
|  |                         return Some(Symbol::Type(type_symbol.clone())); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |                 _ => continue, | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         None | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fn get_usable_symbol_by_declared_name(&self, declared_name: &str) -> Option<Symbol> { | ||||||
|  |         for function_symbol in self.function_symbols.values() { | ||||||
|  |             if function_symbol.borrow().declared_name() == declared_name { | ||||||
|  |                 return Some(Symbol::Function(function_symbol.clone())); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         for type_symbol in self.type_symbols.values() { | ||||||
|  |             if type_symbol.declared_name() == declared_name { | ||||||
|  |                 return Some(Symbol::Type(type_symbol.clone())); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         None | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fn get_value_symbol_by_declared_name(&self, declared_name: &str) -> Option<Symbol> { | ||||||
|  |         for variable_symbol in self.variable_symbols.values() { | ||||||
|  |             if variable_symbol.declared_name() == declared_name { | ||||||
|  |                 return Some(Symbol::Variable(variable_symbol.clone())); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         for parameter_symbol in self.parameter_symbols.values() { | ||||||
|  |             if parameter_symbol.declared_name() == declared_name { | ||||||
|  |                 return Some(Symbol::Parameter(parameter_symbol.clone())); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         None | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fn get_expressible_by_declared_name(&self, declared_name: &str) -> Option<Symbol> { | ||||||
|  |         self.variable_symbols | ||||||
|  |             .get(declared_name) | ||||||
|  |             .map(|s| Symbol::Variable(s.clone())) | ||||||
|  |             .or_else(|| { | ||||||
|  |                 self.parameter_symbols | ||||||
|  |                     .get(declared_name) | ||||||
|  |                     .map(|p| Symbol::Parameter(p.clone())) | ||||||
|  |             }) | ||||||
|  |             .or_else(|| { | ||||||
|  |                 self.class_member_symbols | ||||||
|  |                     .get(declared_name) | ||||||
|  |                     .map(|cms| Symbol::ClassMember(cms.clone())) | ||||||
|  |             }) | ||||||
|  |             .or_else(|| { | ||||||
|  |                 self.function_symbols | ||||||
|  |                     .get(declared_name) | ||||||
|  |                     .map(|f| Symbol::Function(f.clone())) | ||||||
|  |             }) | ||||||
|  |             .or_else(|| { | ||||||
|  |                 self.type_symbols | ||||||
|  |                     .get(declared_name) | ||||||
|  |                     .map(|t| Symbol::Type(t.clone())) | ||||||
|  |             }) | ||||||
|  |             .or_else(|| { | ||||||
|  |                 self.use_statement_symbols | ||||||
|  |                     .get(declared_name) | ||||||
|  |                     .map(|us| Symbol::UseStatement(us.clone())) | ||||||
|  |             }) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fn get_expressible_by_fqn(&self, fqn: &str) -> Option<Symbol> { | ||||||
|  |         self.function_symbols | ||||||
|  |             .values() | ||||||
|  |             .find(|fs| fs.borrow().fqn() == fqn) | ||||||
|  |             .map(|f| Symbol::Function(f.clone())) | ||||||
|  |             .or_else(|| { | ||||||
|  |                 self.get_type_symbol_by_fqn(fqn) | ||||||
|  |                     .map(|ts| Symbol::Type(ts.clone())) | ||||||
|  |             }) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* Symbol table */ | ||||||
|  | 
 | ||||||
|  | #[derive(Debug)] | ||||||
|  | pub enum SymbolInsertError { | ||||||
|  |     SymbolAlreadyDefined(Symbol), | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #[derive(Debug)] | ||||||
|  | pub enum SymbolLookupError { | ||||||
|  |     NoDefinition, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #[derive(Debug)] | ||||||
|  | pub struct SymbolTable { | ||||||
|  |     scopes: Vec<Scope>, | ||||||
|  |     current_scope_id: usize, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /// Contains a vec of scopes, like a flattened tree
 | ||||||
|  | impl SymbolTable { | ||||||
|  |     pub fn new() -> Self { | ||||||
|  |         let mut t = SymbolTable { | ||||||
|  |             scopes: vec![Scope::new(None, String::from("GlobalScope"))], | ||||||
|  |             current_scope_id: 0, | ||||||
|  |         }; | ||||||
|  |         t | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     pub fn current_scope_id(&self) -> usize { | ||||||
|  |         self.current_scope_id | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     pub fn scopes(&self) -> &Vec<Scope> { | ||||||
|  |         &self.scopes | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     pub fn push_scope(&mut self, debug_name: &str) { | ||||||
|  |         let id = self.scopes.len(); | ||||||
|  |         self.scopes.push(Scope::new( | ||||||
|  |             Some(self.current_scope_id), | ||||||
|  |             debug_name.to_string(), | ||||||
|  |         )); | ||||||
|  |         self.current_scope_id = id; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     pub fn pop_scope(&mut self) { | ||||||
|  |         if let Some(parent_id) = self.scopes[self.current_scope_id].parent { | ||||||
|  |             self.current_scope_id = parent_id; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     pub fn insert_use_statement_symbol( | ||||||
|  |         &mut self, | ||||||
|  |         use_statement_symbol: UseStatementSymbol, | ||||||
|  |     ) -> Result<Rc<RefCell<UseStatementSymbol>>, SymbolInsertError> { | ||||||
|  |         let current_scope = self.scopes.get_mut(self.current_scope_id).unwrap(); | ||||||
|  |         if let Some(defined_symbol) = | ||||||
|  |             current_scope.get_usable_symbol_by_declared_name(use_statement_symbol.declared_name()) | ||||||
|  |         { | ||||||
|  |             Err(SymbolAlreadyDefined(defined_symbol)) | ||||||
|  |         } else { | ||||||
|  |             let declared_name = use_statement_symbol.declared_name().to_string(); | ||||||
|  |             let to_insert = Rc::new(RefCell::new(use_statement_symbol)); | ||||||
|  |             let to_return = to_insert.clone(); | ||||||
|  |             current_scope | ||||||
|  |                 .use_statement_symbols | ||||||
|  |                 .insert(declared_name, to_insert); | ||||||
|  |             Ok(to_return) | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     pub fn insert_module_symbol( | ||||||
|  |         &mut self, | ||||||
|  |         module_symbol: ModuleSymbol, | ||||||
|  |     ) -> Result<(), SymbolInsertError> { | ||||||
|  |         let current_scope = self.scopes.get_mut(self.current_scope_id).unwrap(); | ||||||
|  |         if let Some(defined_symbol) = | ||||||
|  |             current_scope.get_module_symbol_by_declared_name(module_symbol.declared_name()) | ||||||
|  |         { | ||||||
|  |             Err(SymbolAlreadyDefined(Symbol::Module(defined_symbol.clone()))) | ||||||
|  |         } else { | ||||||
|  |             current_scope.module_symbols.insert( | ||||||
|  |                 module_symbol.declared_name().to_string(), | ||||||
|  |                 Rc::new(module_symbol), | ||||||
|  |             ); | ||||||
|  |             Ok(()) | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     pub fn insert_type_symbol(&mut self, type_symbol: TypeSymbol) -> Result<(), SymbolInsertError> { | ||||||
|  |         let current_scope = self.scopes.get_mut(self.current_scope_id).unwrap(); | ||||||
|  |         if let Some(defined_symbol) = | ||||||
|  |             current_scope.get_usable_symbol_by_declared_name(type_symbol.declared_name()) | ||||||
|  |         { | ||||||
|  |             Err(SymbolAlreadyDefined(defined_symbol)) | ||||||
|  |         } else { | ||||||
|  |             current_scope.type_symbols.insert( | ||||||
|  |                 type_symbol.declared_name().to_string(), | ||||||
|  |                 Rc::new(type_symbol), | ||||||
|  |             ); | ||||||
|  |             Ok(()) | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     pub fn insert_function_symbol( | ||||||
|  |         &mut self, | ||||||
|  |         function_symbol: FunctionSymbol, | ||||||
|  |     ) -> Result<Rc<RefCell<FunctionSymbol>>, SymbolInsertError> { | ||||||
|  |         let current_scope = self.scopes.get_mut(self.current_scope_id).unwrap(); | ||||||
|  |         if let Some(defined_symbol) = | ||||||
|  |             current_scope.get_usable_symbol_by_declared_name(function_symbol.declared_name()) | ||||||
|  |         { | ||||||
|  |             Err(SymbolAlreadyDefined(defined_symbol)) | ||||||
|  |         } else { | ||||||
|  |             let declared_name = function_symbol.declared_name().to_string(); | ||||||
|  |             let to_insert = Rc::new(RefCell::new(function_symbol)); | ||||||
|  |             let to_return = to_insert.clone(); | ||||||
|  |             current_scope | ||||||
|  |                 .function_symbols | ||||||
|  |                 .insert(declared_name, to_insert); | ||||||
|  |             Ok(to_return) | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     pub fn insert_parameter_symbol( | ||||||
|  |         &mut self, | ||||||
|  |         parameter_symbol: ParameterSymbol, | ||||||
|  |     ) -> Result<Rc<ParameterSymbol>, SymbolInsertError> { | ||||||
|  |         let current_scope = self.scopes.get_mut(self.current_scope_id).unwrap(); | ||||||
|  |         if let Some(defined_symbol) = | ||||||
|  |             current_scope.get_value_symbol_by_declared_name(parameter_symbol.declared_name()) | ||||||
|  |         { | ||||||
|  |             Err(SymbolAlreadyDefined(defined_symbol)) | ||||||
|  |         } else { | ||||||
|  |             let to_insert = Rc::new(parameter_symbol); | ||||||
|  |             let to_return = to_insert.clone(); | ||||||
|  |             current_scope | ||||||
|  |                 .parameter_symbols | ||||||
|  |                 .insert(to_insert.declared_name().to_string(), to_insert); | ||||||
|  |             Ok(to_return) | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     pub fn insert_variable_symbol( | ||||||
|  |         &mut self, | ||||||
|  |         variable_symbol: VariableSymbol, | ||||||
|  |     ) -> Result<Rc<VariableSymbol>, SymbolInsertError> { | ||||||
|  |         let current_scope = self.scopes.get_mut(self.current_scope_id).unwrap(); | ||||||
|  |         if let Some(defined_symbol) = | ||||||
|  |             current_scope.get_value_symbol_by_declared_name(variable_symbol.declared_name()) | ||||||
|  |         { | ||||||
|  |             Err(SymbolAlreadyDefined(defined_symbol)) | ||||||
|  |         } else { | ||||||
|  |             let declared_name = variable_symbol.declared_name().to_string(); | ||||||
|  |             let to_insert = Rc::new(variable_symbol); | ||||||
|  |             let to_return = to_insert.clone(); | ||||||
|  |             current_scope | ||||||
|  |                 .variable_symbols | ||||||
|  |                 .insert(declared_name, to_insert); | ||||||
|  |             Ok(to_return) | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     pub fn insert_class_member_symbol( | ||||||
|  |         &mut self, | ||||||
|  |         class_member_symbol: ClassMemberSymbol, | ||||||
|  |     ) -> Result<(), SymbolInsertError> { | ||||||
|  |         let current_scope = self.scopes.get_mut(self.current_scope_id).unwrap(); | ||||||
|  |         if let Some(defined_symbol) = | ||||||
|  |             current_scope.get_expressible_by_declared_name(class_member_symbol.declared_name()) | ||||||
|  |         { | ||||||
|  |             Err(SymbolAlreadyDefined(defined_symbol)) | ||||||
|  |         } else { | ||||||
|  |             current_scope.class_member_symbols.insert( | ||||||
|  |                 class_member_symbol.declared_name().to_string(), | ||||||
|  |                 Rc::new(class_member_symbol), | ||||||
|  |             ); | ||||||
|  |             Ok(()) | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     pub fn lookup_type_by_declared_name( | ||||||
|  |         &self, | ||||||
|  |         declared_name: &str, | ||||||
|  |         scope_id: usize, | ||||||
|  |     ) -> Result<Rc<TypeSymbol>, SymbolLookupError> { | ||||||
|  |         let mut scope_opt = Some(&self.scopes[scope_id]); | ||||||
|  |         while let Some(scope) = scope_opt { | ||||||
|  |             if let Some(symbol) = scope.get_type_symbol_by_declared_name(declared_name) { | ||||||
|  |                 return Ok(symbol); | ||||||
|  |             } | ||||||
|  |             scope_opt = if let Some(parent_id) = scope.parent { | ||||||
|  |                 Some(&self.scopes[parent_id]) | ||||||
|  |             } else { | ||||||
|  |                 None | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         Err(NoDefinition) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     pub fn lookup_type_by_fqn( | ||||||
|  |         &self, | ||||||
|  |         fqn: &str, | ||||||
|  |         scope_id: usize, | ||||||
|  |     ) -> Result<Rc<TypeSymbol>, SymbolLookupError> { | ||||||
|  |         let mut scope_opt = Some(&self.scopes[scope_id]); | ||||||
|  |         while let Some(scope) = scope_opt { | ||||||
|  |             if let Some(symbol) = scope.get_type_symbol_by_fqn(fqn) { | ||||||
|  |                 return Ok(symbol); | ||||||
|  |             } | ||||||
|  |             scope_opt = if let Some(parent_id) = scope.parent { | ||||||
|  |                 Some(&self.scopes[parent_id]) | ||||||
|  |             } else { | ||||||
|  |                 None | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         Err(NoDefinition) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     pub fn lookup_usable_by_fqn( | ||||||
|  |         &self, | ||||||
|  |         fully_qualified_name: &str, | ||||||
|  |         scope_id: usize, | ||||||
|  |     ) -> Result<Symbol, SymbolLookupError> { | ||||||
|  |         for scope in &self.scopes { | ||||||
|  |             if let Some(symbol) = scope.get_usable_symbol_by_fqn(fully_qualified_name) { | ||||||
|  |                 return Ok(symbol); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         Err(NoDefinition) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     pub fn lookup_expressible_by_declared_name( | ||||||
|  |         &self, | ||||||
|  |         declared_name: &str, | ||||||
|  |         scope_id: usize, | ||||||
|  |     ) -> Result<Symbol, SymbolLookupError> { | ||||||
|  |         let mut scope_opt = Some(&self.scopes[scope_id]); | ||||||
|  |         while let Some(scope) = scope_opt { | ||||||
|  |             if let Some(symbol) = scope.get_expressible_by_declared_name(declared_name) { | ||||||
|  |                 return Ok(symbol); | ||||||
|  |             } | ||||||
|  |             scope_opt = if let Some(parent_id) = scope.parent { | ||||||
|  |                 Some(&self.scopes[parent_id]) | ||||||
|  |             } else { | ||||||
|  |                 None | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         Err(NoDefinition) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     pub fn lookup_expressible_by_fqn( | ||||||
|  |         &self, | ||||||
|  |         fqn: &str, | ||||||
|  |         scope_id: usize, | ||||||
|  |     ) -> Result<Symbol, SymbolLookupError> { | ||||||
|  |         let mut scope_opt = Some(&self.scopes[scope_id]); | ||||||
|  |         while let Some(scope) = scope_opt { | ||||||
|  |             if let Some(symbol) = scope.get_expressible_by_fqn(fqn) { | ||||||
|  |                 return Ok(symbol); | ||||||
|  |             } | ||||||
|  |             scope_opt = if let Some(parent_id) = scope.parent { | ||||||
|  |                 Some(&self.scopes[parent_id]) | ||||||
|  |             } else { | ||||||
|  |                 None | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         Err(NoDefinition) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl Display for SymbolTable { | ||||||
|  |     fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||||||
|  |         writeln!(f, "SymbolTable(current_scope = {})", self.current_scope_id)?; | ||||||
|  |         for (i, scope) in self.scopes.iter().enumerate() { | ||||||
|  |             writeln!(f, "----Scope {} {}----", i, scope.debug_name)?; | ||||||
|  |             for symbol in scope.use_statement_symbols.values() { | ||||||
|  |                 writeln!(f, "{:#?}", symbol.borrow())?; | ||||||
|  |             } | ||||||
|  |             for symbol in scope.module_symbols.values() { | ||||||
|  |                 writeln!(f, "{:#?}", symbol)?; | ||||||
|  |             } | ||||||
|  |             for symbol in scope.type_symbols.values() { | ||||||
|  |                 writeln!(f, "{:#?}", symbol)?; | ||||||
|  |             } | ||||||
|  |             for symbol in scope.function_symbols.values() { | ||||||
|  |                 writeln!(f, "{:#?}", symbol.borrow())?; | ||||||
|  |             } | ||||||
|  |             for symbol in scope.parameter_symbols.values() { | ||||||
|  |                 writeln!(f, "{:#?}", symbol)?; | ||||||
|  |             } | ||||||
|  |             for symbol in scope.variable_symbols.values() { | ||||||
|  |                 writeln!(f, "{:#?}", symbol)?; | ||||||
|  |             } | ||||||
|  |             for symbol in scope.class_member_symbols.values() { | ||||||
|  |                 writeln!(f, "{:#?}", symbol)?; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         Ok(()) | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -1,333 +0,0 @@ | |||||||
| use crate::name_analysis::symbol::class_member_symbol::ClassMemberSymbol; |  | ||||||
| use crate::name_analysis::symbol::function_symbol::FunctionSymbol; |  | ||||||
| use crate::name_analysis::symbol::module_symbol::ModuleSymbol; |  | ||||||
| use crate::name_analysis::symbol::parameter_symbol::ParameterSymbol; |  | ||||||
| use crate::name_analysis::symbol::type_symbol::TypeSymbol; |  | ||||||
| use crate::name_analysis::symbol::use_symbol::{ConcreteUseSymbol, StarUseSymbol}; |  | ||||||
| use crate::name_analysis::symbol::variable_symbol::VariableSymbol; |  | ||||||
| use crate::name_analysis::symbol::*; |  | ||||||
| use crate::name_analysis::symbol_table::SymbolInsertError::SymbolAlreadyDefined; |  | ||||||
| use crate::name_analysis::symbol_table::SymbolLookupError::NoDefinition; |  | ||||||
| use scope::Scope; |  | ||||||
| use std::fmt::Display; |  | ||||||
| use std::ops::Deref; |  | ||||||
| 
 |  | ||||||
| mod scope; |  | ||||||
| 
 |  | ||||||
| #[derive(Debug)] |  | ||||||
| pub enum SymbolInsertError { |  | ||||||
|     SymbolAlreadyDefined(Symbol), |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| #[derive(Debug)] |  | ||||||
| pub enum SymbolLookupError { |  | ||||||
|     NoDefinition, |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| #[derive(Debug)] |  | ||||||
| pub struct SymbolTable { |  | ||||||
|     scopes: Vec<Scope>, |  | ||||||
|     current_scope_id: usize, |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /// Contains a vec of scopes, like a flattened tree
 |  | ||||||
| impl SymbolTable { |  | ||||||
|     pub fn new() -> Self { |  | ||||||
|         Self { |  | ||||||
|             scopes: vec![Scope::new(None, 0, String::from("GlobalScope"))], |  | ||||||
|             current_scope_id: 0, |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     pub fn current_scope_id(&self) -> usize { |  | ||||||
|         self.current_scope_id |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     pub fn push_scope(&mut self, debug_name: &str) { |  | ||||||
|         let id = self.scopes.len(); |  | ||||||
|         self.scopes |  | ||||||
|             .push(Scope::new(Some(self.current_scope_id), id, debug_name.to_string())); |  | ||||||
|         self.current_scope_id = id; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     pub fn pop_scope(&mut self) { |  | ||||||
|         if let Some(parent_id) = self.scopes[self.current_scope_id].parent() { |  | ||||||
|             self.current_scope_id = parent_id; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     fn current_scope(&self) -> &Scope { |  | ||||||
|         self.scopes.last().unwrap() |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     fn current_scope_mut(&mut self) -> &mut Scope { |  | ||||||
|         self.scopes.last_mut().unwrap() |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     fn find_current_scope_concrete_use_symbol( |  | ||||||
|         &self, |  | ||||||
|         declared_name: &str, |  | ||||||
|     ) -> Option<&ConcreteUseSymbol> { |  | ||||||
|         self.current_scope() |  | ||||||
|             .concrete_use_symbols() |  | ||||||
|             .get(declared_name) |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     fn find_current_scope_star_use_symbol(&self, base_fqn: &str) -> Option<&StarUseSymbol> { |  | ||||||
|         self.current_scope().star_use_symbols().get(base_fqn) |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     fn find_current_scope_type_symbol(&self, declared_name: &str) -> Option<&TypeSymbol> { |  | ||||||
|         self.current_scope().type_symbols().get(declared_name) |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     fn find_current_scope_module_symbol(&self, declared_name: &str) -> Option<&ModuleSymbol> { |  | ||||||
|         self.current_scope().module_symbols().get(declared_name) |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     fn find_current_scope_parameter_symbol(&self, declared_name: &str) -> Option<&ParameterSymbol> { |  | ||||||
|         self.current_scope().parameter_symbols().get(declared_name) |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     fn find_current_scope_variable_symbol(&self, declared_name: &str) -> Option<&VariableSymbol> { |  | ||||||
|         self.current_scope().variable_symbols().get(declared_name) |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     fn find_current_scope_class_member_symbol( |  | ||||||
|         &self, |  | ||||||
|         declared_name: &str, |  | ||||||
|     ) -> Option<&ClassMemberSymbol> { |  | ||||||
|         self.current_scope() |  | ||||||
|             .class_member_symbols() |  | ||||||
|             .get(declared_name) |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     fn find_current_scope_variable_or_parameter_symbol( |  | ||||||
|         &self, |  | ||||||
|         declared_name: &str, |  | ||||||
|     ) -> Option<Symbol> { |  | ||||||
|         self.find_current_scope_variable_symbol(declared_name) |  | ||||||
|             .map(|variable_symbol| Symbol::Variable(variable_symbol.clone())) |  | ||||||
|             .or_else(|| { |  | ||||||
|                 self.find_current_scope_parameter_symbol(declared_name) |  | ||||||
|                     .map(|parameter_symbol| Symbol::Parameter(parameter_symbol.clone())) |  | ||||||
|             }) |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     fn find_current_scope_usable_symbol(&self, declared_name: &str) -> Option<Symbol> { |  | ||||||
|         self.find_current_scope_concrete_use_symbol(declared_name) |  | ||||||
|             .map(|concrete_use_symbol| Symbol::ConcreteUse(concrete_use_symbol.clone())) |  | ||||||
|             .or_else(|| { |  | ||||||
|                 self.find_current_scope_type_symbol(declared_name) |  | ||||||
|                     .map(|type_symbol| Symbol::Type(type_symbol.clone())) |  | ||||||
|             }) |  | ||||||
|             .or_else(|| { |  | ||||||
|                 self.find_current_scope_module_symbol(declared_name) |  | ||||||
|                     .map(|module_symbol| Symbol::Module(module_symbol.clone())) |  | ||||||
|             }) |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     pub fn insert_concrete_use_symbol( |  | ||||||
|         &mut self, |  | ||||||
|         concrete_use_symbol: ConcreteUseSymbol, |  | ||||||
|     ) -> Result<(), SymbolInsertError> { |  | ||||||
|         if let Some(defined_symbol) = |  | ||||||
|             self.find_current_scope_usable_symbol(concrete_use_symbol.declared_name()) |  | ||||||
|         { |  | ||||||
|             Err(SymbolAlreadyDefined(defined_symbol)) |  | ||||||
|         } else { |  | ||||||
|             self.current_scope_mut().concrete_use_symbols_mut().insert( |  | ||||||
|                 concrete_use_symbol.declared_name().to_string(), |  | ||||||
|                 concrete_use_symbol, |  | ||||||
|             ); |  | ||||||
|             Ok(()) |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     pub fn insert_star_use_symbol( |  | ||||||
|         &mut self, |  | ||||||
|         star_use_symbol: StarUseSymbol, |  | ||||||
|     ) -> Result<(), SymbolInsertError> { |  | ||||||
|         if let Some(defined_symbol) = |  | ||||||
|             self.find_current_scope_star_use_symbol(star_use_symbol.base_fqn()) |  | ||||||
|         { |  | ||||||
|             Err(SymbolAlreadyDefined(Symbol::StarUse( |  | ||||||
|                 defined_symbol.clone(), |  | ||||||
|             ))) |  | ||||||
|         } else { |  | ||||||
|             self.current_scope_mut() |  | ||||||
|                 .star_use_symbols_mut() |  | ||||||
|                 .insert(star_use_symbol.base_fqn().to_string(), star_use_symbol); |  | ||||||
|             Ok(()) |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     pub fn insert_module_symbol( |  | ||||||
|         &mut self, |  | ||||||
|         module_symbol: ModuleSymbol, |  | ||||||
|     ) -> Result<(), SymbolInsertError> { |  | ||||||
|         if let Some(defined_symbol) = |  | ||||||
|             self.find_current_scope_usable_symbol(module_symbol.declared_name()) |  | ||||||
|         { |  | ||||||
|             Err(SymbolAlreadyDefined(defined_symbol)) |  | ||||||
|         } else { |  | ||||||
|             self.current_scope_mut() |  | ||||||
|                 .module_symbols_mut() |  | ||||||
|                 .insert(module_symbol.declared_name().to_string(), module_symbol); |  | ||||||
|             Ok(()) |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     pub fn insert_type_symbol(&mut self, type_symbol: TypeSymbol) -> Result<(), SymbolInsertError> { |  | ||||||
|         if let Some(defined_symbol) = |  | ||||||
|             self.find_current_scope_usable_symbol(type_symbol.declared_name()) |  | ||||||
|         { |  | ||||||
|             Err(SymbolAlreadyDefined(defined_symbol)) |  | ||||||
|         } else { |  | ||||||
|             self.current_scope_mut() |  | ||||||
|                 .type_symbols_mut() |  | ||||||
|                 .insert(type_symbol.declared_name().to_string(), type_symbol); |  | ||||||
|             Ok(()) |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     pub fn insert_function_symbol( |  | ||||||
|         &mut self, |  | ||||||
|         function_symbol: FunctionSymbol, |  | ||||||
|     ) -> Result<(), SymbolInsertError> { |  | ||||||
|         if let Some(defined_symbol) = |  | ||||||
|             self.find_current_scope_usable_symbol(function_symbol.declared_name()) |  | ||||||
|         { |  | ||||||
|             Err(SymbolAlreadyDefined(defined_symbol)) |  | ||||||
|         } else { |  | ||||||
|             self.current_scope_mut() |  | ||||||
|                 .function_symbols_mut() |  | ||||||
|                 .insert(function_symbol.declared_name().to_string(), function_symbol); |  | ||||||
|             Ok(()) |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     pub fn insert_parameter_symbol( |  | ||||||
|         &mut self, |  | ||||||
|         parameter_symbol: ParameterSymbol, |  | ||||||
|     ) -> Result<(), SymbolInsertError> { |  | ||||||
|         if let Some(defined_symbol) = |  | ||||||
|             self.find_current_scope_parameter_symbol(parameter_symbol.declared_name()) |  | ||||||
|         { |  | ||||||
|             Err(SymbolAlreadyDefined(Symbol::Parameter( |  | ||||||
|                 defined_symbol.clone(), |  | ||||||
|             ))) |  | ||||||
|         } else { |  | ||||||
|             self.current_scope_mut().parameter_symbols_mut().insert( |  | ||||||
|                 parameter_symbol.declared_name().to_string(), |  | ||||||
|                 parameter_symbol, |  | ||||||
|             ); |  | ||||||
|             Ok(()) |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     pub fn insert_variable_symbol( |  | ||||||
|         &mut self, |  | ||||||
|         variable_symbol: VariableSymbol, |  | ||||||
|     ) -> Result<(), SymbolInsertError> { |  | ||||||
|         if let Some(defined_symbol) = |  | ||||||
|             self.find_current_scope_variable_or_parameter_symbol(variable_symbol.declared_name()) |  | ||||||
|         { |  | ||||||
|             Err(SymbolAlreadyDefined(defined_symbol)) |  | ||||||
|         } else { |  | ||||||
|             self.current_scope_mut() |  | ||||||
|                 .variable_symbols_mut() |  | ||||||
|                 .insert(variable_symbol.declared_name().to_string(), variable_symbol); |  | ||||||
|             Ok(()) |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     pub fn insert_class_member_symbol( |  | ||||||
|         &mut self, |  | ||||||
|         class_member_symbol: ClassMemberSymbol, |  | ||||||
|     ) -> Result<(), SymbolInsertError> { |  | ||||||
|         if let Some(defined_symbol) = |  | ||||||
|             self.find_current_scope_class_member_symbol(class_member_symbol.declared_name()) |  | ||||||
|         { |  | ||||||
|             Err(SymbolAlreadyDefined(Symbol::ClassMember( |  | ||||||
|                 defined_symbol.clone(), |  | ||||||
|             ))) |  | ||||||
|         } else { |  | ||||||
|             self.current_scope_mut().class_member_symbols_mut().insert( |  | ||||||
|                 class_member_symbol.declared_name().to_string(), |  | ||||||
|                 class_member_symbol, |  | ||||||
|             ); |  | ||||||
|             Ok(()) |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     fn lookup_type_in_scope_by_declared_name<'a>( |  | ||||||
|         scope: &'a Scope, |  | ||||||
|         declared_name: &str, |  | ||||||
|     ) -> Option<&'a TypeSymbol> { |  | ||||||
|         scope.type_symbols().get(declared_name) |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     pub fn lookup_type_by_declared_name( |  | ||||||
|         &self, |  | ||||||
|         declared_name: &str, |  | ||||||
|         scope_id: usize, |  | ||||||
|     ) -> Result<&TypeSymbol, SymbolLookupError> { |  | ||||||
|         let mut scope_opt = Some(&self.scopes[scope_id]); |  | ||||||
|         while let Some(scope) = scope_opt { |  | ||||||
|             if let Some(symbol) = Self::lookup_type_in_scope_by_declared_name(scope, declared_name) |  | ||||||
|             { |  | ||||||
|                 return Ok(symbol); |  | ||||||
|             } |  | ||||||
|             scope_opt = if let Some(parent_id) = scope.parent() { |  | ||||||
|                 Some(&self.scopes[parent_id]) |  | ||||||
|             } else { |  | ||||||
|                 None |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|         Err(NoDefinition) |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     fn lookup_type_in_scope_by_fqn<'a>(scope: &'a Scope, fqn: &str) -> Option<&'a TypeSymbol> { |  | ||||||
|         for type_symbol in scope.type_symbols().values() { |  | ||||||
|             match type_symbol { |  | ||||||
|                 TypeSymbol::Concrete(concrete_type_symbol) => { |  | ||||||
|                     if concrete_type_symbol.fqn() == fqn { |  | ||||||
|                         return Some(type_symbol); |  | ||||||
|                     } |  | ||||||
|                 } |  | ||||||
|                 TypeSymbol::Generic(_) => {} |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|         None |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     pub fn lookup_type_by_fqn( |  | ||||||
|         &self, |  | ||||||
|         fqn: &str, |  | ||||||
|         scope_id: usize, |  | ||||||
|     ) -> Result<&TypeSymbol, SymbolLookupError> { |  | ||||||
|         let mut scope_opt = Some(&self.scopes[scope_id]); |  | ||||||
|         while let Some(scope) = scope_opt { |  | ||||||
|             if let Some(type_symbol) = Self::lookup_type_in_scope_by_fqn(scope, fqn) { |  | ||||||
|                 return Ok(type_symbol); |  | ||||||
|             } |  | ||||||
|             scope_opt = if let Some(parent_id) = scope.parent() { |  | ||||||
|                 Some(&self.scopes[parent_id]) |  | ||||||
|             } else { |  | ||||||
|                 None |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|         Err(NoDefinition) |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| impl Display for SymbolTable { |  | ||||||
|     fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { |  | ||||||
|         writeln!(f, "SymbolTable(current_scope = {})", self.current_scope_id)?; |  | ||||||
|         for scope in &self.scopes { |  | ||||||
|             writeln!(f, "{}", scope)?; |  | ||||||
|         } |  | ||||||
|         Ok(()) |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @ -1,141 +0,0 @@ | |||||||
| use crate::name_analysis::symbol::class_member_symbol::ClassMemberSymbol; |  | ||||||
| use crate::name_analysis::symbol::function_symbol::FunctionSymbol; |  | ||||||
| use crate::name_analysis::symbol::module_symbol::ModuleSymbol; |  | ||||||
| use crate::name_analysis::symbol::parameter_symbol::ParameterSymbol; |  | ||||||
| use crate::name_analysis::symbol::type_symbol::TypeSymbol; |  | ||||||
| use crate::name_analysis::symbol::use_symbol::{ConcreteUseSymbol, StarUseSymbol}; |  | ||||||
| use crate::name_analysis::symbol::variable_symbol::VariableSymbol; |  | ||||||
| use std::collections::HashMap; |  | ||||||
| use std::fmt::{Display, Formatter}; |  | ||||||
| 
 |  | ||||||
| #[derive(Debug)] |  | ||||||
| pub struct Scope { |  | ||||||
|     parent: Option<usize>, |  | ||||||
|     id: usize, |  | ||||||
|     concrete_use_symbols: HashMap<String, ConcreteUseSymbol>, |  | ||||||
|     star_use_symbols: HashMap<String, StarUseSymbol>, |  | ||||||
|     module_symbols: HashMap<String, ModuleSymbol>, |  | ||||||
|     type_symbols: HashMap<String, TypeSymbol>, |  | ||||||
|     function_symbols: HashMap<String, FunctionSymbol>, |  | ||||||
|     parameter_symbols: HashMap<String, ParameterSymbol>, |  | ||||||
|     variable_symbols: HashMap<String, VariableSymbol>, |  | ||||||
|     class_member_symbols: HashMap<String, ClassMemberSymbol>, |  | ||||||
|     debug_name: String, |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| impl Scope { |  | ||||||
|     pub fn new(parent: Option<usize>, id: usize, debug_name: String) -> Self { |  | ||||||
|         Self { |  | ||||||
|             parent, |  | ||||||
|             id, |  | ||||||
|             concrete_use_symbols: HashMap::new(), |  | ||||||
|             star_use_symbols: HashMap::new(), |  | ||||||
|             module_symbols: HashMap::new(), |  | ||||||
|             type_symbols: HashMap::new(), |  | ||||||
|             function_symbols: HashMap::new(), |  | ||||||
|             parameter_symbols: HashMap::new(), |  | ||||||
|             variable_symbols: HashMap::new(), |  | ||||||
|             class_member_symbols: HashMap::new(), |  | ||||||
|             debug_name, |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     pub fn parent(&self) -> Option<usize> { |  | ||||||
|         self.parent |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     pub fn id(&self) -> usize { |  | ||||||
|         self.id |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     pub fn concrete_use_symbols(&self) -> &HashMap<String, ConcreteUseSymbol> { |  | ||||||
|         &self.concrete_use_symbols |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     pub fn concrete_use_symbols_mut(&mut self) -> &mut HashMap<String, ConcreteUseSymbol> { |  | ||||||
|         &mut self.concrete_use_symbols |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     pub fn star_use_symbols(&self) -> &HashMap<String, StarUseSymbol> { |  | ||||||
|         &self.star_use_symbols |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     pub fn star_use_symbols_mut(&mut self) -> &mut HashMap<String, StarUseSymbol> { |  | ||||||
|         &mut self.star_use_symbols |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     pub fn module_symbols(&self) -> &HashMap<String, ModuleSymbol> { |  | ||||||
|         &self.module_symbols |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     pub fn module_symbols_mut(&mut self) -> &mut HashMap<String, ModuleSymbol> { |  | ||||||
|         &mut self.module_symbols |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     pub fn type_symbols(&self) -> &HashMap<String, TypeSymbol> { |  | ||||||
|         &self.type_symbols |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     pub fn type_symbols_mut(&mut self) -> &mut HashMap<String, TypeSymbol> { |  | ||||||
|         &mut self.type_symbols |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     pub fn function_symbols(&self) -> &HashMap<String, FunctionSymbol> { |  | ||||||
|         &self.function_symbols |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     pub fn function_symbols_mut(&mut self) -> &mut HashMap<String, FunctionSymbol> { |  | ||||||
|         &mut self.function_symbols |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     pub fn parameter_symbols(&self) -> &HashMap<String, ParameterSymbol> { |  | ||||||
|         &self.parameter_symbols |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     pub fn parameter_symbols_mut(&mut self) -> &mut HashMap<String, ParameterSymbol> { |  | ||||||
|         &mut self.parameter_symbols |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     pub fn variable_symbols(&self) -> &HashMap<String, VariableSymbol> { |  | ||||||
|         &self.variable_symbols |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     pub fn variable_symbols_mut(&mut self) -> &mut HashMap<String, VariableSymbol> { |  | ||||||
|         &mut self.variable_symbols |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     pub fn class_member_symbols(&self) -> &HashMap<String, ClassMemberSymbol> { |  | ||||||
|         &self.class_member_symbols |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     pub fn class_member_symbols_mut(&mut self) -> &mut HashMap<String, ClassMemberSymbol> { |  | ||||||
|         &mut self.class_member_symbols |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     pub fn debug_name(&self) -> &str { |  | ||||||
|         &self.debug_name |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| macro_rules! write_symbols { |  | ||||||
|     ( $f:expr, $symbols:expr ) => { |  | ||||||
|         for symbol in $symbols.values() { |  | ||||||
|             writeln!($f, "{:#?}", symbol)?; |  | ||||||
|         } |  | ||||||
|     }; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| impl Display for Scope { |  | ||||||
|     fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { |  | ||||||
|         writeln!(f, "----Scope {} {}----", self.id(), self.debug_name())?; |  | ||||||
|         write_symbols!(f, self.concrete_use_symbols()); |  | ||||||
|         write_symbols!(f, self.star_use_symbols()); |  | ||||||
|         write_symbols!(f, self.module_symbols()); |  | ||||||
|         write_symbols!(f, self.type_symbols()); |  | ||||||
|         write_symbols!(f, self.function_symbols()); |  | ||||||
|         write_symbols!(f, self.parameter_symbols()); |  | ||||||
|         write_symbols!(f, self.variable_symbols()); |  | ||||||
|         write_symbols!(f, self.class_member_symbols()); |  | ||||||
|         Ok(()) |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @ -88,7 +88,6 @@ $defs: | |||||||
|       - $ref: "#/$defs/StructChildSkipHash" |       - $ref: "#/$defs/StructChildSkipHash" | ||||||
|       - $ref: "#/$defs/StructChildVecHash" |       - $ref: "#/$defs/StructChildVecHash" | ||||||
|       - $ref: "#/$defs/StructChildMemberHash" |       - $ref: "#/$defs/StructChildMemberHash" | ||||||
|       - $ref: "#/$defs/StructChildSpecialHash" |  | ||||||
|   StructChildSkipHash: |   StructChildSkipHash: | ||||||
|     type: object |     type: object | ||||||
|     additionalProperties: false |     additionalProperties: false | ||||||
| @ -149,6 +148,7 @@ $defs: | |||||||
|     oneOf: |     oneOf: | ||||||
|       - $ref: "#/$defs/StructChildMemberBuildNodeHash" |       - $ref: "#/$defs/StructChildMemberBuildNodeHash" | ||||||
|       - $ref: "#/$defs/StructChildMemberBuildBooleanHash" |       - $ref: "#/$defs/StructChildMemberBuildBooleanHash" | ||||||
|  |       - $ref: "#/$defs/StructChildMemberBuildSpecialHash" | ||||||
|   StructChildMemberBuildNodeHash: |   StructChildMemberBuildNodeHash: | ||||||
|     type: object |     type: object | ||||||
|     additionalProperties: false |     additionalProperties: false | ||||||
| @ -191,7 +191,7 @@ $defs: | |||||||
|           - rule_present |           - rule_present | ||||||
|     required: |     required: | ||||||
|       - on |       - on | ||||||
|   StructChildSpecialHash: |   StructChildMemberBuildSpecialHash: | ||||||
|     type: object |     type: object | ||||||
|     additionalProperties: false |     additionalProperties: false | ||||||
|     description: A special member to be built. |     description: A special member to be built. | ||||||
|  | |||||||
| @ -181,7 +181,7 @@ ReturnType: | |||||||
| CompilationUnit: | CompilationUnit: | ||||||
|   struct: |   struct: | ||||||
|     children: |     children: | ||||||
|       - namespace: |       - parent_mod: | ||||||
|           member: |           member: | ||||||
|             optional: true |             optional: true | ||||||
|       - use_statements: |       - use_statements: | ||||||
| @ -193,15 +193,12 @@ CompilationUnit: | |||||||
|       - eoi: |       - eoi: | ||||||
|           skip: |           skip: | ||||||
|             rule: EOI |             rule: EOI | ||||||
|       - file_id: | ParentMod: | ||||||
|           special: |  | ||||||
|             kind: file_id |  | ||||||
| Namespace: |  | ||||||
|   struct: |   struct: | ||||||
|     children: |     children: | ||||||
|       - ns_kw: |       - mod_kw: | ||||||
|           skip: |           skip: | ||||||
|             rule: Ns |             rule: Mod | ||||||
|       - fqn: |       - fqn: | ||||||
|           member: |           member: | ||||||
|             rule: FullyQualifiedName |             rule: FullyQualifiedName | ||||||
| @ -218,11 +215,15 @@ UseStatement: | |||||||
|           member: |           member: | ||||||
|             rule: UseStatementSuffix |             rule: UseStatementSuffix | ||||||
|       - file_id: |       - file_id: | ||||||
|           special: |           member:  | ||||||
|             kind: file_id |             build: | ||||||
|  |               special: | ||||||
|  |                 kind: file_id | ||||||
|       - range: |       - range: | ||||||
|           special: |           member:  | ||||||
|             kind: range |             build: | ||||||
|  |               special: | ||||||
|  |                 kind: range | ||||||
| UseStatementPrefix: | UseStatementPrefix: | ||||||
|   struct: |   struct: | ||||||
|     children: |     children: | ||||||
| @ -253,6 +254,7 @@ ModuleLevelDeclaration: | |||||||
| InterfaceLevelDeclaration: | InterfaceLevelDeclaration: | ||||||
|   tree_enum: |   tree_enum: | ||||||
|     rules: |     rules: | ||||||
|  |       - CompanionModule | ||||||
|       - Interface |       - Interface | ||||||
|       - Class |       - Class | ||||||
|       - InterfaceFunction |       - InterfaceFunction | ||||||
| @ -262,6 +264,7 @@ InterfaceLevelDeclaration: | |||||||
| ClassLevelDeclaration: | ClassLevelDeclaration: | ||||||
|   tree_enum: |   tree_enum: | ||||||
|     rules: |     rules: | ||||||
|  |       - CompanionModule | ||||||
|       - Interface |       - Interface | ||||||
|       - Class |       - Class | ||||||
|       - Function |       - Function | ||||||
| @ -288,6 +291,21 @@ Module: | |||||||
|       - end_kw: |       - end_kw: | ||||||
|           skip: |           skip: | ||||||
|             rule: End |             rule: End | ||||||
|  | CompanionModule: | ||||||
|  |   struct: | ||||||
|  |     children: | ||||||
|  |       - companion_kw: | ||||||
|  |           skip: | ||||||
|  |             rule: Companion | ||||||
|  |       - mod_kw: | ||||||
|  |           skip: | ||||||
|  |             rule: Mod | ||||||
|  |       - declarations: | ||||||
|  |           vec: | ||||||
|  |             rule: ModuleLevelDeclaration | ||||||
|  |       - end_kw: | ||||||
|  |           skip: | ||||||
|  |             rule: End | ||||||
| Interface: | Interface: | ||||||
|   struct: |   struct: | ||||||
|     children: |     children: | ||||||
|  | |||||||
| @ -307,13 +307,13 @@ ReturnType = { | |||||||
| 
 | 
 | ||||||
| CompilationUnit = { | CompilationUnit = { | ||||||
|       SOI |       SOI | ||||||
|     ~ Namespace? |     ~ ParentMod? | ||||||
|     ~ ( UseStatement | ModuleLevelDeclaration )* |     ~ ( UseStatement | ModuleLevelDeclaration )* | ||||||
|     ~ EOI |     ~ EOI | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| Namespace = { | ParentMod = { | ||||||
|       Ns |       Mod | ||||||
|     ~ FullyQualifiedName |     ~ FullyQualifiedName | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -352,7 +352,8 @@ ModuleLevelDeclaration = { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| InterfaceLevelDeclaration = { | InterfaceLevelDeclaration = { | ||||||
|       Interface |       CompanionModule | ||||||
|  |     | Interface | ||||||
|     | Class |     | Class | ||||||
|     | InterfaceFunction |     | InterfaceFunction | ||||||
|     | InterfaceDefaultFunction |     | InterfaceDefaultFunction | ||||||
| @ -361,7 +362,8 @@ InterfaceLevelDeclaration = { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| ClassLevelDeclaration = { | ClassLevelDeclaration = { | ||||||
|       Interface |       CompanionModule | ||||||
|  |     | Interface | ||||||
|     | Class |     | Class | ||||||
|     | Function |     | Function | ||||||
|     | OperatorFunction |     | OperatorFunction | ||||||
| @ -378,6 +380,13 @@ Module = { | |||||||
|     ~ End |     ~ End | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | CompanionModule = { | ||||||
|  |       Companion | ||||||
|  |     ~ Mod | ||||||
|  |     ~ ModuleLevelDeclaration* | ||||||
|  |     ~ End | ||||||
|  | } | ||||||
|  | 
 | ||||||
| Interface = { | Interface = { | ||||||
|       Pub? |       Pub? | ||||||
|     ~ IntKw |     ~ IntKw | ||||||
|  | |||||||
| @ -1,27 +1,14 @@ | |||||||
| use crate::name_analysis::symbol::function_symbol::FunctionSymbol; | use crate::name_analysis::symbol::{FunctionSymbol, ParameterSymbol}; | ||||||
| use crate::name_analysis::symbol::parameter_symbol::ParameterSymbol; |  | ||||||
| use crate::name_analysis::symbol_table::{SymbolInsertError, SymbolTable}; | use crate::name_analysis::symbol_table::{SymbolInsertError, SymbolTable}; | ||||||
| 
 | 
 | ||||||
| pub fn add_std_core_symbols(symbol_table: &mut SymbolTable) -> Result<(), SymbolInsertError> { | pub fn add_std_core_symbols(symbol_table: &mut SymbolTable) -> Result<(), SymbolInsertError> { | ||||||
|     symbol_table.insert_function_symbol( |     symbol_table.insert_function_symbol( | ||||||
|         FunctionSymbol::without_parameters_or_return_type( |         FunctionSymbol::new("std::core::println", "println", true, true, None) | ||||||
|             "std::core::println", |             .with_parameters(vec![ParameterSymbol::new("msg", None)]), | ||||||
|             "println", |  | ||||||
|             true, |  | ||||||
|             true, |  | ||||||
|             None, |  | ||||||
|         ) |  | ||||||
|         .with_parameters(vec![ParameterSymbol::new("msg", None)]), |  | ||||||
|     )?; |     )?; | ||||||
|     symbol_table.insert_function_symbol( |     symbol_table.insert_function_symbol( | ||||||
|         FunctionSymbol::without_parameters_or_return_type( |         FunctionSymbol::new("std::core::print", "print", true, true, None) | ||||||
|             "std::core::print", |             .with_parameters(vec![ParameterSymbol::new("msg", None)]), | ||||||
|             "print", |  | ||||||
|             true, |  | ||||||
|             true, |  | ||||||
|             None, |  | ||||||
|         ) |  | ||||||
|         .with_parameters(vec![ParameterSymbol::new("msg", None)]), |  | ||||||
|     )?; |     )?; | ||||||
|     Ok(()) |     Ok(()) | ||||||
| } | } | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user