use std::collections::HashMap; use std::fs; use std::path::PathBuf; use parser::ast::TopLevel; use parser::ast::{ParamList, TypeExpr}; use serde::{Deserialize, Serialize}; #[derive(Clone, Debug, Serialize, Deserialize)] pub struct TypeSymbol(pub String); #[derive(Clone, Debug, Serialize, Deserialize)] pub struct VarSymbol { pub export: bool, pub var_type: TypeSymbol, pub name: String, } #[derive(Clone, Debug, Serialize, Deserialize)] pub struct FunctionSymbol { pub export: bool, pub name: String, pub params: HashMap, pub return_type: Option, } #[derive(Clone, Debug, Serialize, Deserialize)] pub struct StructSymbol { pub export: bool, pub name: String, pub fields: HashMap, pub methods: HashMap, } impl TypeSymbol { pub fn from_ast(expr: TypeExpr) -> Self { TypeSymbol(match expr { TypeExpr::Identifier(i) => i.to_string(), }) } } impl FunctionSymbol { pub fn from_ast( export: bool, name: String, params: ParamList, return_type: Option, ) -> Self { Self { export: export, name: name.clone(), params: params .0 .iter() .map(|(name, (export, v))| { ( name.clone(), VarSymbol { export: *export, name: name.clone(), var_type: TypeSymbol(match v { TypeExpr::Identifier(i) => i.to_string(), }), }, ) }) .collect(), return_type: return_type.map(TypeSymbol::from_ast), } } } impl StructSymbol { pub fn from_ast(export: bool, name: String, fields: ParamList) -> Self { Self { export, name, fields: fields .0 .iter() .map(|(name, (export, v))| { ( name.clone(), VarSymbol { export: *export, name: name.clone(), var_type: TypeSymbol(match v { TypeExpr::Identifier(i) => i.to_string(), }), }, ) }) .collect(), // TODO - parse struct methods methods: HashMap::new(), } } } #[derive(Clone, Debug, Serialize, Deserialize)] pub struct JSONScope { pub structs: HashMap, pub functions: HashMap, pub package_name: String, } type JsonScopeMap = HashMap; #[derive(Clone, Debug)] pub struct TopLevelSymbolScope { pub imports: HashMap, pub structs: HashMap, pub functions: HashMap, } impl TopLevelSymbolScope { pub fn from(path: &PathBuf, top_level: &Vec) -> Self { let mut scope = TopLevelSymbolScope { imports: HashMap::new(), structs: HashMap::new(), functions: HashMap::new(), }; for top in top_level { match top { 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(); scope .imports .insert(json_scope.package_name.clone(), json_scope); } TopLevel::Package(_) => {} TopLevel::FunctionDecl { export, name, params, return_type, .. } => { scope.functions.insert( name.clone(), FunctionSymbol::from_ast( *export, name.clone(), params.clone(), return_type.clone(), ), ); } TopLevel::StructDecl { export, name, fields, } => { scope.structs.insert( name.clone(), StructSymbol::from_ast(*export, name.clone(), fields.clone()), ); } } } scope } }