diff --git a/crates/ailang-core/src/lib.rs b/crates/ailang-core/src/lib.rs index b366c6e..9471f6b 100644 --- a/crates/ailang-core/src/lib.rs +++ b/crates/ailang-core/src/lib.rs @@ -59,6 +59,7 @@ pub mod canonical; pub mod desugar; pub mod hash; pub mod pretty; +pub mod primitives; pub mod workspace; pub use ast::{ diff --git a/crates/ailang-core/src/primitives.rs b/crates/ailang-core/src/primitives.rs new file mode 100644 index 0000000..24418f6 --- /dev/null +++ b/crates/ailang-core/src/primitives.rs @@ -0,0 +1,35 @@ +//! The primitive-name set: `Int`, `Bool`, `Str`, `Unit`. Single +//! source of truth for "is this name a built-in zero-arity type +//! constructor?" Every typecheck and codegen site that gates +//! behaviour on the primitive set goes through this module. +//! +//! Adding a primitive: append to BOTH functions below; the four +//! consumers compile-fail-loudly if the predicate is forgotten +//! (the failure is a missed branch, not a panic), but +//! `primitive_surface_name` will silently return `None` for the +//! new name unless its `match` is extended too. Keep the two +//! functions in lockstep. + +/// Returns `true` iff `name` is one of the built-in zero-arity +/// primitive type constructors. Cross-crate predicate consumed by +/// `ailang-check` (`linearity::is_heap_type`, `lib::check_type_well_formed`, +/// `lib::qualify_local_types`) and `ailang-codegen` +/// (`subst::qualify_local_types_codegen`). +pub fn is_primitive_name(name: &str) -> bool { + matches!(name, "Int" | "Bool" | "Str" | "Unit") +} + +/// Returns the static-lifetime surface name iff `name` is a +/// primitive. Used by `mono::primitive_surface_name` to embed the +/// human-readable form in monomorphised symbol names; the static +/// lifetime is what makes the symbol-builder's `&'static str` +/// signature work. +pub fn primitive_surface_name(name: &str) -> Option<&'static str> { + match name { + "Int" => Some("Int"), + "Bool" => Some("Bool"), + "Str" => Some("Str"), + "Unit" => Some("Unit"), + _ => None, + } +}