diff --git a/src/protocol/mod.rs b/src/protocol/mod.rs index c7c4ba07d617734fe1aaab99fcbe75c5634f550b..45f880fbe64dec700ef72086e324877299969e5b 100644 --- a/src/protocol/mod.rs +++ b/src/protocol/mod.rs @@ -16,6 +16,8 @@ use crate::protocol::input_source::*; use crate::protocol::parser::*; use crate::protocol::type_table::*; +pub use parser::type_table::TypeId; + /// A protocol description module pub struct Module { pub(crate) source: InputSource, @@ -92,29 +94,31 @@ impl ProtocolDescription { let definition_id = definition_id.unwrap(); let ast_definition = &self.heap[definition_id]; - if !ast_definition.is_component() { + if !ast_definition.is_procedure() { return Err(ComponentCreationError::DefinitionNotComponent); } // Make sure that the types of the provided value group matches that of // the expected types. - let ast_definition = ast_definition.as_component(); - if !ast_definition.poly_vars.is_empty() { + let ast_definition = ast_definition.as_procedure(); + if !ast_definition.poly_vars.is_empty() || ast_definition.kind == ProcedureKind::Function { return Err(ComponentCreationError::DefinitionNotComponent); } // - check number of arguments by retrieving the one instantiated // monomorph - let concrete_type = ConcreteType{ parts: vec![ConcreteTypePart::Component(definition_id, 0)] }; - let mono_index = self.types.get_procedure_monomorph_index(&definition_id, &concrete_type.parts).unwrap(); - let mono_type = self.types.get_procedure_monomorph(mono_index); - if mono_type.arg_types.len() != arguments.values.len() { + 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_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() { return Err(ComponentCreationError::InvalidNumArguments); } // - for each argument try to make sure the types match for arg_idx in 0..arguments.values.len() { - let expected_type = &mono_type.arg_types[arg_idx]; + let expected_type_id = monomorph_info.argument_types[arg_idx]; + let expected_type = &self.types.get_monomorph(expected_type_id).concrete_type; let provided_value = &arguments.values[arg_idx]; if !self.verify_same_type(expected_type, 0, &arguments, provided_value) { return Err(ComponentCreationError::InvalidArgumentType(arg_idx)); @@ -123,7 +127,7 @@ impl ProtocolDescription { // By now we're sure that all of the arguments are correct. So create // the connector. - return Ok(Prompt::new(&self.types, &self.heap, definition_id, mono_index, arguments)); + return Ok(Prompt::new(&self.types, &self.heap, ast_definition.this, procedure_type_id, arguments)); } fn lookup_module_root(&self, module_name: &[u8]) -> Option { @@ -145,7 +149,7 @@ impl ProtocolDescription { use ConcreteTypePart as CTP; match &expected.parts[expected_idx] { - CTP::Void | CTP::Message | CTP::Slice | CTP::Function(_, _) | CTP::Component(_, _) => unreachable!(), + CTP::Void | CTP::Message | CTP::Slice | CTP::Pointer | CTP::Function(_, _) | CTP::Component(_, _) => unreachable!(), CTP::Bool => if let Value::Bool(_) = argument { true } else { false }, CTP::UInt8 => if let Value::UInt8(_) = argument { true } else { false }, CTP::UInt16 => if let Value::UInt16(_) = argument { true } else { false }, @@ -211,6 +215,7 @@ pub trait RunContext { fn fires(&mut self, port: PortId) -> Option; // None if not yet branched fn performed_fork(&mut self) -> Option; // None if not yet forked fn created_channel(&mut self) -> Option<(Value, Value)>; // None if not yet prepared + fn performed_select_wait(&mut self) -> Option; // None if not yet notified runtime of select blocker } pub struct ProtocolDescriptionBuilder {