diff --git a/src/protocol/mod.rs b/src/protocol/mod.rs index d0dd2453c06c9f49d1cce7f935c3c0f092dba0ce..f628e7c21f64a040f7dea4b0fe7c027f60cb40bc 100644 --- a/src/protocol/mod.rs +++ b/src/protocol/mod.rs @@ -160,6 +160,32 @@ impl ProtocolDescription { }); } + /// Again a somewhat temporary method. Can be used by components to look up + /// the definition of a particular procedure. Intended use is to find the + /// DefinitionId/TypeId of builtin components. + pub(crate) fn find_procedure(&self, module_name: &[u8], proc_name: &[u8]) -> Option<(ProcedureDefinitionId, TypeId)> { + // 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, proc_name)?; + let definition = &self.heap[definition_id]; + + // Make sure the procedure is not polymorphic + if !definition.poly_vars().is_empty() { + return None; + } + if !definition.is_procedure() { + return None; + } + + // Lookup in type table + let definition = definition.as_procedure(); + let type_parts = [ConcreteTypePart::Component(definition.this, 0)]; + let type_id = self.types.get_monomorph_type_id(&definition.this.upcast(), &type_parts) + .expect("type ID for non-polymorphic procedure"); + return Some((definition.this, type_id)); + } + fn lookup_module_root(&self, module_name: &[u8]) -> Option { for module in self.modules.iter() { match &module.name { @@ -296,6 +322,12 @@ impl<'a> TypeInspector<'a> { let type_table = self.type_table.variant.as_union(); return UnionTypeInspector{ heap, type_table }; } + + pub fn as_struct(&'a self) -> StructTypeInspector<'a> { + let heap = self.heap.as_struct(); + let type_table = self.type_table.variant.as_struct(); + return StructTypeInspector{ heap, type_table }; + } } pub struct UnionTypeInspector<'a> { @@ -310,4 +342,23 @@ impl UnionTypeInspector<'_> { .position(|v| v.identifier.value.as_bytes() == variant_name)?; return Some(variant_index as i64); } +} + +pub struct StructTypeInspector<'a> { + heap: &'a StructDefinition, + type_table: &'a StructMonomorph, +} + +impl StructTypeInspector<'_> { + /// Retrieves number of struct fields + pub fn get_num_struct_fields(&self) -> usize { + return self.heap.fields.len(); + } + + /// Retrieves struct field index + pub fn get_struct_field_index(&self, field_name: &[u8]) -> Option { + let field_index = self.heap.fields.iter() + .position(|v| v.field.value.as_bytes() == field_name)?; + return Some(field_index); + } } \ No newline at end of file