Something went wrong. Try again.
The Monad language. Dependent types, functional programming compiled with LLVM. Hobby project. monad-lang.org
dependent-types language compiler programming-language functional-programming
Something went wrong. Try again.
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859/// `String`-keyed `HashMap` helpers, monomorphic on purpose.////// A leaf module: it imports `std.map` and nothing else. That is the whole/// reason it exists separately from `lang/codegen/util.mo`, which is where/// these lived. `util.mo` imports `llvm.ir` (for `LLVMInstruction`/// and friends), so `ir.mo` cannot import `util.mo` back -- and `ir.mo`/// needs a string map of its own for the per-function debug-metadata table/// (`find_dbg_refs` was a linear assoc-list scan, O(F^2) module-wide)./// Extracting them here is what lets both files use one implementation/// instead of two, which duplicate top-level names would make a real/// collision hazard (AGENTS.md item 18), not just a tidiness question.////// `util.mo` re-exports them with `pub use`, so every existing/// `use lang.codegen.util {str_map_*}` importer is unaffected.////// These bypass `Map`'s abstract typeclass dispatch (`Map.insert`//// `Map.lookup`, the `[Hashable K, BOrd K] Map HashMap` instance,/// `std/map.mo`) in favor of `HashMap.bucket_of`/`get_bucket`/`set_bucket`//// `bucket_insert_str`/`bucket_lookup_str` called directly with plain/// `String.hash` (concrete native, no class-method resolution/// at all). Mirrors `lang/scope.mo`'s own `modpath_map_*` helpers, which/// document why: calling through `Map`'s generic dispatch resolves/// `Hashable.hash`/`BOrd.lt`/`BOrd.gt` as abstract class-method references/// INSIDE `HashMap`'s own generic `[K, V]`-parameterized body, and/// AGENTS.md's documented evaluator limitation ("`resolve_class_method_/// instance` picks the FIRST REGISTERED instance", not a type-directed/// lookup) means these can silently resolve to the WRONG instance whenever/// invoked from deep within an already-polymorphic call chain -- confirmed/// as a real, live bug for `ScopeData.def_refs`/`inductives`, not merely/// theoretical. `String.hash`/`String.beq` need no dispatch at all, so this/// sidesteps the whole class of risk rather than hoping it does not fire.use std::map { HashMap, HashMap.bucket_insert_str, HashMap.bucket_lookup_str, HashMap.bucket_of, HashMap.empty_buckets, HashMap.get_bucket, HashMap.set_bucket, map,}#[partial]pub def str_map_empty {V : Type} : HashMap String V := HashMap.map HashMap.empty_buckets#[partial]pub def str_map_insert {V : Type} (key : String) (val : V) (m : HashMap String V) : HashMap String V := match m { HashMap.map buckets => let idx := HashMap.bucket_of (String.hash key) in let bucket := HashMap.get_bucket buckets idx in let new_bucket := HashMap.bucket_insert_str key val bucket in HashMap.map (HashMap.set_bucket buckets idx new_bucket) }#[partial]pub def str_map_lookup {V : Type} (key : String) (m : HashMap String V) : Option V := match m { HashMap.map buckets => let idx := HashMap.bucket_of (String.hash key) in let bucket := HashMap.get_bucket buckets idx in HashMap.bucket_lookup_str key bucket }