diff --git a/src/protocol/mod.rs b/src/protocol/mod.rs index 2e46cc167c05753e9aee603c74506c57a3fd5c9b..febb0a5125eee904e53feefb132373f9e78e0c21 100644 --- a/src/protocol/mod.rs +++ b/src/protocol/mod.rs @@ -87,7 +87,7 @@ impl ProtocolDescription { let module_root = module_root.unwrap(); let root = &self.heap[module_root]; - let definition_id = root.get_definition_ident(&self.heap, identifier); + let definition_id = root.get_definition_by_ident(&self.heap, identifier); if definition_id.is_none() { return Err(ComponentCreationError::DefinitionDoesntExist); } @@ -108,7 +108,7 @@ impl ProtocolDescription { // - check number of arguments by retrieving the one instantiated // monomorph let concrete_type = ConcreteType{ parts: vec![ConcreteTypePart::Component(ast_definition.this, 0)] }; - let procedure_type_id = self.types.get_procedure_monomorph_type_id(&definition_id, &concrete_type.parts).unwrap(); + let procedure_type_id = self.types.get_monomorph_type_id(&definition_id, &concrete_type.parts).unwrap(); let procedure_monomorph_index = self.types.get_monomorph(procedure_type_id).variant.as_procedure().monomorph_index; let monomorph_info = &ast_definition.monomorphs[procedure_monomorph_index as usize]; if monomorph_info.argument_types.len() != arguments.values.len() { @@ -130,6 +130,36 @@ impl ProtocolDescription { return Ok(Prompt::new(&self.types, &self.heap, ast_definition.this, procedure_type_id, arguments)); } + /// A somewhat temporary method. Can be used by components to lookup type + /// definitions by their name (to have their implementation somewhat + /// resistant to changes in the standard library) + pub(crate) fn find_type(&self, module_name: &[u8], type_name: &[u8]) -> Option { + // Lookup type definition in module + let root_id = self.lookup_module_root(module_name)?; + let module = &self.heap[root_id]; + let definition_id = module.get_definition_by_ident(&self.heap, type_name)?; + let definition = &self.heap[definition_id]; + + // Make sure type is not polymorphic and is not a procedure + if !definition.poly_vars().is_empty() { + return None; + } + if definition.is_procedure() { + return None; + } + + // Lookup type in type table + let type_parts = [ConcreteTypePart::Instance(definition_id, 0)]; + let type_id = self.types.get_monomorph_type_id(&definition_id, &type_parts) + .expect("type ID for non-polymorphic type"); + let type_monomorph = self.types.get_monomorph(type_id); + + return Some(TypeInspector{ + heap: definition, + type_table: type_monomorph + }); + } + fn lookup_module_root(&self, module_name: &[u8]) -> Option { for module in self.modules.iter() { match &module.name { @@ -255,3 +285,30 @@ impl ProtocolDescriptionBuilder { }); } } + +pub struct TypeInspector<'a> { + heap: &'a Definition, + type_table: &'a MonoType, +} + +impl TypeInspector { + pub fn as_union(&self) -> UnionTypeInspector { + let heap = self.heap.as_union(); + let type_table = self.type_table.variant.as_union(); + return UnionTypeInspector{ heap, type_table }; + } +} + +pub struct UnionTypeInspector<'a> { + heap: &'a UnionDefinition, + type_table: &'a UnionMonomorph, +} + +impl UnionTypeInspector { + /// Retrieves union variant tag value. + pub fn get_variant_tag_value(&self, variant_name: &[u8]) -> Option { + let variant_index = self.heap.variants.iter() + .position(|v| v.identifier.value.as_bytes() == variant_name)?; + return Some(variant_index as i64); + } +} \ No newline at end of file