logicaffeine_language/analysis/
registry.rs1use std::collections::HashMap;
14use logicaffeine_base::{Interner, Symbol};
15
16#[derive(Debug, Clone, PartialEq, Eq)]
18pub enum FieldType {
19 Primitive(Symbol),
21 Named(Symbol),
23 Generic { base: Symbol, params: Vec<FieldType> },
25 TypeParam(Symbol),
27}
28
29#[derive(Debug, Clone, PartialEq, Eq)]
31pub struct FieldDef {
32 pub name: Symbol,
33 pub ty: FieldType,
34 pub is_public: bool,
35}
36
37#[derive(Debug, Clone, PartialEq, Eq)]
39pub struct VariantDef {
40 pub name: Symbol,
41 pub fields: Vec<FieldDef>, }
43
44#[derive(Debug, Clone, PartialEq, Eq)]
45pub enum TypeDef {
46 Primitive,
48 Struct {
53 fields: Vec<FieldDef>,
54 generics: Vec<Symbol>, is_portable: bool, is_shared: bool, },
58 Enum {
63 variants: Vec<VariantDef>,
64 generics: Vec<Symbol>, is_portable: bool, is_shared: bool, },
68 Generic { param_count: usize },
70 Alias { target: Symbol },
72}
73
74#[derive(Debug, Default, Clone)]
75pub struct TypeRegistry {
76 types: HashMap<Symbol, TypeDef>,
77}
78
79impl TypeRegistry {
80 pub fn new() -> Self {
81 Self::default()
82 }
83
84 pub fn register(&mut self, name: Symbol, def: TypeDef) {
86 self.types.insert(name, def);
87 }
88
89 pub fn is_type(&self, name: Symbol) -> bool {
91 self.types.contains_key(&name)
92 }
93
94 pub fn is_generic(&self, name: Symbol) -> bool {
96 match self.types.get(&name) {
97 Some(TypeDef::Generic { .. }) => true,
98 Some(TypeDef::Struct { generics, .. }) => !generics.is_empty(),
99 Some(TypeDef::Enum { generics, .. }) => !generics.is_empty(),
100 _ => false,
101 }
102 }
103
104 pub fn get_generics(&self, name: Symbol) -> Option<&[Symbol]> {
106 match self.types.get(&name)? {
107 TypeDef::Struct { generics, .. } => Some(generics),
108 TypeDef::Enum { generics, .. } => Some(generics),
109 _ => None,
110 }
111 }
112
113 pub fn get(&self, name: Symbol) -> Option<&TypeDef> {
115 self.types.get(&name)
116 }
117
118 pub fn iter_types(&self) -> impl Iterator<Item = (&Symbol, &TypeDef)> {
120 self.types.iter()
121 }
122
123 pub fn find_variant(&self, variant_name: Symbol) -> Option<(Symbol, &VariantDef)> {
126 for (enum_name, type_def) in &self.types {
127 if let TypeDef::Enum { variants, .. } = type_def {
128 for variant in variants {
129 if variant.name == variant_name {
130 return Some((*enum_name, variant));
131 }
132 }
133 }
134 }
135 None
136 }
137
138 pub fn is_variant(&self, name: Symbol) -> bool {
140 self.find_variant(name).is_some()
141 }
142
143 pub fn with_primitives(interner: &mut Interner) -> Self {
145 let mut reg = Self::new();
146
147 reg.register(interner.intern("Nat"), TypeDef::Primitive);
149 reg.register(interner.intern("Int"), TypeDef::Primitive);
150 reg.register(interner.intern("Text"), TypeDef::Primitive);
151 reg.register(interner.intern("Bool"), TypeDef::Primitive);
152 reg.register(interner.intern("Boolean"), TypeDef::Primitive);
153 reg.register(interner.intern("Unit"), TypeDef::Primitive);
154 reg.register(interner.intern("Real"), TypeDef::Primitive); reg.register(interner.intern("Char"), TypeDef::Primitive); reg.register(interner.intern("Byte"), TypeDef::Primitive); reg.register(interner.intern("List"), TypeDef::Generic { param_count: 1 });
160 reg.register(interner.intern("Seq"), TypeDef::Generic { param_count: 1 }); reg.register(interner.intern("Map"), TypeDef::Generic { param_count: 2 }); reg.register(interner.intern("Set"), TypeDef::Generic { param_count: 1 }); reg.register(interner.intern("Option"), TypeDef::Generic { param_count: 1 });
164 reg.register(interner.intern("Result"), TypeDef::Generic { param_count: 2 });
165
166 reg
167 }
168}
169
170#[cfg(test)]
171mod tests {
172 use super::*;
173
174 #[test]
175 fn registry_stores_and_retrieves() {
176 let mut interner = Interner::new();
177 let mut registry = TypeRegistry::new();
178 let foo = interner.intern("Foo");
179 registry.register(foo, TypeDef::Primitive);
180 assert!(registry.is_type(foo));
181 assert!(!registry.is_generic(foo));
182 }
183}