use std::{ collections::{HashMap, HashSet}, sync::Arc, }; use parking_lot::{Mutex, RwLock}; use nac3core::{ codegen::{CodeGenContext, CodeGenerator}, nac3parser::ast::{self, StrRef}, symbol_resolver::{SymbolResolver, SymbolValue, ValueEnum}, toplevel::{DefinitionId, TopLevelDef}, typecheck::{ type_inferencer::PrimitiveStore, typedef::{Type, Unifier}, }, }; pub struct ResolverInternal { pub id_to_type: Mutex>, pub id_to_def: Mutex>, pub module_globals: Mutex>, pub str_store: Mutex>, } impl ResolverInternal { pub fn add_id_def(&self, id: StrRef, def: DefinitionId) { self.id_to_def.lock().insert(id, def); } pub fn add_id_type(&self, id: StrRef, ty: Type) { self.id_to_type.lock().insert(id, ty); } pub fn add_module_global(&self, id: StrRef, val: SymbolValue) { self.module_globals.lock().insert(id, val); } } pub struct Resolver(pub Arc); impl SymbolResolver for Resolver { fn get_default_param_value(&self, expr: &ast::Expr) -> Option { match &expr.node { ast::ExprKind::Name { id, .. } => self.0.module_globals.lock().get(id).cloned(), _ => unimplemented!("other type of expr not supported at {}", expr.location), } } fn get_symbol_type( &self, _: &mut Unifier, _: &[Arc>], _: &PrimitiveStore, str: StrRef, ) -> Result { self.0.id_to_type.lock().get(&str).copied().ok_or(format!("cannot get type of {str}")) } fn get_symbol_value<'ctx>( &self, _: StrRef, _: &mut CodeGenContext<'ctx, '_>, _: &mut dyn CodeGenerator, ) -> Option> { unimplemented!() } fn get_identifier_def(&self, id: StrRef) -> Result> { self.0 .id_to_def .lock() .get(&id) .copied() .ok_or_else(|| HashSet::from([format!("Undefined identifier `{id}`")])) } fn get_string_id(&self, s: &str) -> i32 { let mut str_store = self.0.str_store.lock(); if let Some(id) = str_store.get(s) { *id } else { let id = i32::try_from(str_store.len()) .expect("Symbol resolver string store size exceeds max capacity (i32::MAX)"); str_store.insert(s.to_string(), id); id } } fn get_exception_id(&self, _: usize) -> usize { unimplemented!() } }