diff --git a/semantic/src/hir.rs b/semantic/src/hir.rs index ed5129f..9f390b3 100644 --- a/semantic/src/hir.rs +++ b/semantic/src/hir.rs @@ -6,15 +6,24 @@ use std::{ }, }; -use crate::top_level::{FunctionSymbol, StructSymbol, TopLevelSymbolScope, TypeSymbol, VarSymbol}; +use crate::top_level::{ + FunctionSymbol, JSONScope, StructSymbol, TopLevelSymbolScope, TypeSymbol, VarSymbol, +}; #[derive(Clone, Debug)] pub enum TypeRef { Struct(StructRef), Function(FunctionRef), + Package(PackageRef), Int, } +#[derive(Clone, Debug)] +pub struct PackageRef { + pub name: String, + pub variables: HashMap>, +} + #[derive(Clone, Debug)] pub struct VarRef { pub export: bool, @@ -58,6 +67,17 @@ impl TopLevelHirScope { scope.struct_ref(tlss, symbol); } + for (_, symbol) in &tlss.imports { + scope.variables.insert( + symbol.package_name.clone(), + Arc::new(VarRef { + export: false, + name: symbol.package_name.clone(), + var_type: Arc::new(TypeRef::Package(PackageRef::from_tlss(symbol))), + }), + ); + } + scope } @@ -181,7 +201,130 @@ impl TypeRef { match self { TypeRef::Function(f) => f.name.clone(), TypeRef::Struct(s) => s.name.clone(), + TypeRef::Package(p) => p.name.clone(), TypeRef::Int => "int".to_string(), } } } + +impl PackageRef { + pub fn from_tlss(json_scope: &JSONScope) -> Self { + let mut scope = Self { + name: json_scope.package_name.clone(), + variables: HashMap::new(), + }; + + for (_, symbol) in &json_scope.functions { + scope.function_ref(json_scope, symbol); + } + + for (_, symbol) in &json_scope.structs { + scope.struct_ref(json_scope, symbol); + } + + scope + } + + pub fn function_ref(&mut self, json_scope: &JSONScope, symbol: &FunctionSymbol) { + if self.variables.get(&symbol.name).is_none() { + let name = symbol.name.clone(); + + if let Some(_) = json_scope.functions.get(&symbol.name) { + let rf = FunctionRef { + export: symbol.export, + name: name.clone(), + params: symbol + .params + .iter() + .map(|(name, v)| (name.clone(), self.var_ref(json_scope, v))) + .collect(), + return_type: symbol + .return_type + .clone() + .map(|rt| self.type_ref(json_scope, &rt)), + }; + + self.variables.insert( + symbol.name.clone(), + Arc::new(VarRef { + export: false, + name: name.clone(), + var_type: Arc::new(TypeRef::Function(rf)), + }), + ); + } else { + unimplemented!() + } + } + } + + pub fn struct_ref(&mut self, json_scope: &JSONScope, symbol: &StructSymbol) -> Arc { + if let Some(rf) = self.variables.get(&symbol.name) { + rf.var_type.clone() + } else { + let name = symbol.name.clone(); + + let rf = Arc::new(TypeRef::Struct(StructRef { + export: symbol.export, + name: name.clone(), + fields: symbol + .fields + .iter() + .map(|(name, v)| (name.clone(), self.var_ref(json_scope, v))) + .collect(), + })); + + self.variables.insert( + symbol.name.clone(), + Arc::new(VarRef { + export: symbol.export, + name: name.clone(), + var_type: rf.clone(), + }), + ); + + rf + } + } + + pub fn var_ref(&mut self, json_scope: &JSONScope, symbol: &VarSymbol) -> Arc { + Arc::new(VarRef { + export: symbol.export, + var_type: self.type_ref(json_scope, &symbol.var_type), + name: symbol.name.clone(), + }) + } + + pub fn type_ref(&mut self, json_scope: &JSONScope, symbol: &TypeSymbol) -> Arc { + if let Some(var_ref) = self.variables.get(&symbol.0) { + var_ref.var_type.clone() + } else { + if let Some(json_scope_rf) = json_scope.structs.get(&symbol.0) { + self.struct_ref(json_scope, json_scope_rf) + } else { + match symbol.0.as_str() { + // TODO: This is a hack, we should have a better way to handle built-in types + "int" | "[]any" => { + let var_ref = Arc::new(VarRef { + export: false, + name: symbol.0.clone(), + var_type: Arc::new(TypeRef::Int), + }); + + self.variables.insert(symbol.0.clone(), var_ref.clone()); + + var_ref.var_type.clone() + } + + _ => { + unimplemented!("{:?}", symbol) + } + } + } + } + } + + pub fn get_reference(&self, name: &String) -> Option> { + self.variables.get(name).cloned() + } +} diff --git a/semantic/src/lib.rs b/semantic/src/lib.rs index 3d1128b..80dcc83 100644 --- a/semantic/src/lib.rs +++ b/semantic/src/lib.rs @@ -14,7 +14,7 @@ pub mod top_level; pub fn walk_ast(top_scope: Arc, tl: &mut Vec) { for tl in tl { match tl { - parser::ast::TopLevel::Import(_) => unimplemented!(), + parser::ast::TopLevel::Import(package) => {} parser::ast::TopLevel::Package(_) => {} parser::ast::TopLevel::FunctionDecl { diff --git a/semantic/src/top_level.rs b/semantic/src/top_level.rs index c467fe3..9be616f 100644 --- a/semantic/src/top_level.rs +++ b/semantic/src/top_level.rs @@ -128,7 +128,10 @@ impl TopLevelSymbolScope { TopLevel::Import(package) => { let json = fs::read(path.join("mist.map.json")).unwrap(); let json_scope_map: JsonScopeMap = serde_json::from_slice(&json).unwrap(); - let json_scope = json_scope_map.get(package).unwrap().clone(); + let json_scope = json_scope_map + .get(&package.replace("\"", "")) + .unwrap() + .clone(); scope .imports diff --git a/test/src/main.ms b/test/src/main.ms index 4346ab5..99646a0 100644 --- a/test/src/main.ms +++ b/test/src/main.ms @@ -3,5 +3,5 @@ package main; import "fmt"; function main() { - let a = 10; + fmt.Println("hello"); }