blr-lang 0.1.0

A language implementation that provides type safe dataframes
Documentation
use std::collections::HashMap;

use super::TypeScheme;

#[derive(Debug, PartialEq, Eq, Clone, Default, PartialOrd, Ord, Hash)]
pub struct Symbol {
    // Fully qualitfied path to the module
    pub module: String,
    pub field: String,
}

#[derive(Debug, PartialEq, Eq, Clone, PartialOrd, Ord, Copy, Hash)]
pub struct ItemId(pub usize);

/// Responsible for all the metadata our type checker wants about Items.
/// We could imagine this would be produced as the result of parsing and name resolution in a more
/// complete compiler.
/// But for our purposes, we presume something like that has already happened and present the
/// metadata in a format easy to digest for our typechecker.
#[derive(Debug, Default, Clone)]
pub struct ItemSource {
    pub types: HashMap<ItemId, TypeScheme>,
    symbols: HashMap<Symbol, ItemId>,
    next: usize,
}
impl ItemSource {
    pub fn type_of_item(&self, item_id: ItemId) -> TypeScheme {
        // We make a simplifying assumption here: item_id will always be present in types
        // This is reasonable, even in a real compiler. If during name resolution we produce an
        // SymbolId without a corresponding type either:
        // 1) that's an error, we're referring to an undefined item.
        // 2) Our language should infer the type for that item.
        // Our language won't handle case 2) because our items are required to always have
        // signatures. So we're safe to assume this will always succeed.
        self.types[&item_id].clone()
    }
    pub fn register(&mut self, symbol: Symbol, type_scheme: TypeScheme) -> ItemId {
        let item_id = ItemId(self.next);
        self.next += 1;
        self.symbols.insert(symbol.clone(), item_id);
        self.types.insert(item_id, type_scheme);
        item_id
    }
    pub fn resolve(&self, symbol: &Symbol) -> ItemId {
        *self
            .symbols
            .get(symbol)
            .unwrap_or_else(|| panic!("{symbol:?} should be defined"))
    }
    pub fn types(&self) -> &HashMap<ItemId, TypeScheme> {
        &self.types
    }
    pub fn symbols(&self) -> &HashMap<Symbol, ItemId> {
        &self.symbols
    }
}