diff --git a/semantic/src/hir.rs b/semantic/src/hir.rs new file mode 100644 index 0000000..e1b2a7c --- /dev/null +++ b/semantic/src/hir.rs @@ -0,0 +1,148 @@ +use std::{collections::HashMap, sync::Arc}; + +use crate::top_level::{FunctionSymbol, StructSymbol, TopLevelSymbolScope, TypeSymbol, VarSymbol}; + +#[derive(Clone, Debug)] +pub enum TypeRef { + Struct(StructRef), +} + +#[derive(Clone, Debug)] +pub struct VarRef { + pub var_type: Arc, + pub name: String, +} + +#[derive(Clone, Debug)] +pub struct FunctionRef { + pub export: bool, + pub name: String, + pub params: HashMap>, + pub return_type: Option>, +} + +#[derive(Clone, Debug)] +pub struct StructRef { + pub export: bool, + pub name: String, + pub fields: HashMap>, + pub methods: HashMap, +} + +#[derive(Clone, Debug)] +pub struct TopLevelHirScope { + pub types: HashMap>, + pub functions: HashMap>, +} + +impl TopLevelHirScope { + pub fn from_tlss(tlss: &TopLevelSymbolScope) -> Self { + let mut scope = Self { + types: HashMap::new(), + functions: HashMap::new(), + }; + + for (_, symbol) in &tlss.functions { + scope.function_ref(tlss, symbol); + } + + for (_, symbol) in &tlss.structs { + scope.struct_ref(tlss, symbol); + } + + scope + } + + pub fn function_ref( + &mut self, + tlss: &TopLevelSymbolScope, + symbol: &FunctionSymbol, + ) -> Arc { + if let Some(rf) = self.functions.get(&symbol.name) { + rf.clone() + } else { + if let Some(tlss_rf) = tlss.functions.get(&symbol.name) { + let rf = Arc::new(FunctionRef { + export: symbol.export, + name: symbol.name.clone(), + params: symbol + .params + .iter() + .map(|(name, v)| (name.clone(), self.var_ref(tlss, v))) + .collect(), + return_type: symbol + .return_type + .clone() + .map(|rt| self.type_ref(tlss, &rt)), + }); + + self.functions.insert(symbol.name.clone(), rf.clone()); + + rf + } else { + unimplemented!() + } + } + } + + pub fn struct_ref( + &mut self, + tlss: &TopLevelSymbolScope, + symbol: &StructSymbol, + ) -> Arc { + let rf = Arc::new(TypeRef::Struct(StructRef { + export: symbol.export, + name: symbol.name.clone(), + fields: symbol + .fields + .iter() + .map(|(name, v)| (name.clone(), self.var_ref(tlss, v))) + .collect(), + methods: HashMap::new(), + })); + + self.types.insert(symbol.name.clone(), rf.clone()); + + rf + } + + pub fn var_ref(&mut self, tlss: &TopLevelSymbolScope, symbol: &VarSymbol) -> Arc { + Arc::new(VarRef { + var_type: self.type_ref(tlss, &symbol.var_type), + name: symbol.name.clone(), + }) + } + + pub fn type_ref(&mut self, tlss: &TopLevelSymbolScope, symbol: &TypeSymbol) -> Arc { + if let Some(rf) = self.types.get(&symbol.0) { + rf.clone() + } else { + if let Some(tlss_rf) = tlss.structs.get(&symbol.0) { + let rf = Arc::new(TypeRef::Struct(StructRef { + export: tlss_rf.export, + name: tlss_rf.name.clone(), + fields: tlss_rf + .fields + .iter() + .map(|(name, v)| { + ( + name.clone(), + Arc::new(VarRef { + name: name.clone(), + var_type: self.type_ref(tlss, &v.var_type), + }), + ) + }) + .collect(), + methods: HashMap::new(), + })); + + self.types.insert(symbol.0.clone(), rf.clone()); + + rf + } else { + unimplemented!() + } + } + } +} diff --git a/semantic/src/lib.rs b/semantic/src/lib.rs index 1e8d15e..b601db3 100644 --- a/semantic/src/lib.rs +++ b/semantic/src/lib.rs @@ -1,2 +1,3 @@ +pub mod hir; pub mod scope; pub mod top_level; diff --git a/semantic/src/scope.rs b/semantic/src/scope.rs index f4b70e7..da087e6 100644 --- a/semantic/src/scope.rs +++ b/semantic/src/scope.rs @@ -1,14 +1,15 @@ use std::sync::Arc; -use crate::top_level::TopLevelScope; +use crate::{hir::TopLevelHirScope, top_level::TopLevelSymbolScope}; #[derive(Clone, Debug)] pub enum Scope { - TopLevel(TopLevelScope), + TopLevel(TopLevelHirScope), } impl Scope { pub fn from_top(top_level: &Vec) -> Arc { - Arc::new(Self::TopLevel(TopLevelScope::from(top_level))) + let tl = TopLevelSymbolScope::from(top_level); + Arc::new(Self::TopLevel(TopLevelHirScope::from_tlss(&tl))) } } diff --git a/semantic/src/top_level.rs b/semantic/src/top_level.rs index a0caf07..ffcd52d 100644 --- a/semantic/src/top_level.rs +++ b/semantic/src/top_level.rs @@ -76,14 +76,14 @@ impl StructSymbol { } #[derive(Clone, Debug)] -pub struct TopLevelScope { +pub struct TopLevelSymbolScope { pub structs: HashMap, pub functions: HashMap, } -impl TopLevelScope { +impl TopLevelSymbolScope { pub fn from(top_level: &Vec) -> Self { - let mut scope = TopLevelScope { + let mut scope = TopLevelSymbolScope { structs: HashMap::new(), functions: HashMap::new(), };