def update_messages(self, trans_operation: CommonTree, defer_msg_list_dependent_var: List[str], message_objects: List[PCCObject]) -> List[CommonTree]: local_update_operations = [] children = trans_operation.getChildren() defer_var_name = MurphiModular.vdeferpref + str( children[0]) + "_" + str(children[2].children[1]) in_msg_name = str(children[2].children[1]) # Update the variables in the deferred message retrieved from buffer if len(children[2].children) > 4: # Not a base message payload = children[2].children[4:] # Get the index of the dependent variable in message constructor for var_ind in range(0, len(payload)): local_var_name = str(payload[var_ind]) # Check if there exists a message dependency if local_var_name in defer_msg_list_dependent_var: # Find the message constructor for message_object in message_objects: # The right constructor was found if str(message_object) == str(children[2].children[0]): msg_object = message_object.structure.children[ var_ind + 1] msg_var = str(msg_object) local_update_operations.append( self.generate_update_assignement( defer_var_name, msg_var, local_var_name, in_msg_name)) return local_update_operations
def process_operation(self, operation: CommonTree, arch: str, transition: Transition): inmsgtype = transition.getrefguard() if transition.getrefguard( ) else transition.getguard() if operation.getText() == self.tASSIGN: return self._genArchAssignment(operation, arch, inmsgtype, transition) if operation.getText() == self.tMODSTATEFUNC: return self._gen_mod_state_func(operation, arch) + self.end if operation.getChildren()[0].getText() == self.iState: return self._genArchAccess(transition) if operation.getText() == self.tSEND: return self._genSendFunction(operation) + self.end if operation.getText() == self.tMCAST: return self._genMCastFunction(operation) + self.end if operation.getText() == self.tBCAST: return self._genBCastFunction(operation) + self.end # For every if cond=true, there exists an else (if cond=false) if operation.getText() == self.tCOND: return self._genIfCondFunction(operation, 0, arch, inmsgtype) + self.nl if operation.getText() == self.tNCOND: return self._genIfCondFunction(operation, 1, arch, inmsgtype) + self.nl if operation.getText() == self.tSETFUNC: return self._genSetFunction(operation, arch, inmsgtype) + self.end # DEFER FUNCTION FUNCTIONALITY if operation.getText() == self.tPUSH_HL_DEFER: msg_name = str(operation.children[1]) if msg_name in self.messageslist: msg_name = self.cinmsg return self._genmsgDeferpush(arch, msg_name, MurphiTokens.iHL_Defer) if operation.getText() == self.tPUSH_LL_DEFER: msg_name = str(operation.children[1]) if msg_name in self.messageslist: msg_name = self.cinmsg return self._genmsgDeferpush(arch, msg_name, MurphiTokens.iLL_Defer) if operation.getText() == self.tPUSH_STALL_DEFER: msg_name = str(operation.children[1]) if msg_name in self.messageslist: msg_name = self.cinmsg return self._genmsgDeferpush(arch, msg_name, MurphiTokens.iStall_Defer)
def _CreateMsgObj(self, obj: CommonTree): self.msgNode.append(PCCObject(obj)) msgformat = obj.getChildren() msgtype = "" for ind in range(0, len(msgformat)): if ind == 0: msgtype = msgformat[ind].getText() else: if msgformat[ind].getText() == self.Data: self.dataMsgTypes.append(msgtype)
def send_base_message(self, trans_operation: CommonTree, transition: Transition, var_names: Dict[str, str]) -> List[CommonTree]: ret_operation = trans_operation children = trans_operation.getChildren() if str(children[1]) in var_names: tmp_operation = copy.deepcopy(trans_operation) tmp_operation.token.text = MurphiModular.tPUSH_HL_DEFER tmp_operation.children[1].token.text = var_names[str(children[1])] transition.operation = copy.copy(transition.operation) transition.operation[transition.operation.index( trans_operation)] = tmp_operation return [ret_operation] return []
def defer_base_message(self, trans_operation: CommonTree, transition: Transition, var_names: Dict[str, str]) -> List[CommonTree]: local_defer_operations = [] children = trans_operation.getChildren() defer_var_name = MurphiModular.vdeferpref + str(children[0]) + "_" + \ str(children[2].children[1]) # Records the variable name of the child var_names[str(children[0])] = defer_var_name # Recover next deferred operation tmp_operation = copy.deepcopy(trans_operation) tmp_children = tmp_operation.getChildren() defer_var_name = MurphiModular.vdeferpref + str(tmp_children[0]) + "_" + \ str(tmp_children[2].children[1]) tmp_children[0].token.text = defer_var_name tmp_children[2].token.text = MurphiModular.tPOP_HL_DEFER local_defer_operations.append(tmp_operation) # Construct Original Message from deferred operation tmp_operation = copy.deepcopy(trans_operation) tmp_children = tmp_operation.getChildren() tmp_children[2].token.text = MurphiModular.tSEND_BASE_DEFER tmp_children[2].children[1].token.text = defer_var_name for ind in range(2, len(MurphiModular.BaseMsg)): tmp_children[2].children.pop(2) local_defer_operations.append(tmp_operation) tmp_operation = copy.deepcopy(trans_operation) tmp_children = tmp_operation.getChildren() # Generate BaseMessage that is deferred tmp_children[0].token.text = defer_var_name tmp_children[2].token.text = MurphiModular.tSEND_BASE_DEFER tmp_children[2].children[0].token.text = MurphiModular.rbasemessage for ind in range(len(MurphiModular.BaseMsg), len(tmp_children[2].getChildren())): tmp_children[2].children.pop(len(MurphiModular.BaseMsg)) # Update the transition transition.operation = copy.copy(transition.operation) transition.operation[transition.operation.index( trans_operation)] = tmp_operation return local_defer_operations
def defer_left_dependent_operations( self, trans_operation: CommonTree, defer_msg_var_names: Dict[str, str], dependent_defer_msg_vars: Dict[str, str], defer_message_operation_dict: Dict[str, List[CommonTree]]): children = trans_operation.getChildren() cur_var_name = str(children[0]) # Left assignment # Remove [ASSIGN, var_name, = ] assignment_list = toStringList(trans_operation)[3:] # Variable reassignment e.g. new Msg object assigned to same var if cur_var_name in defer_msg_var_names and cur_var_name not in assignment_list: remove_var = defer_msg_var_names.pop(cur_var_name) del defer_message_operation_dict[cur_var_name] remove_key_list = [] # Clear dependent variables for dependent_var_name in dependent_defer_msg_vars: if dependent_defer_msg_vars[dependent_var_name] == remove_var: remove_key_list.append(dependent_var_name) for key in remove_key_list: del dependent_defer_msg_vars[key] else: for var_name in defer_msg_var_names: # Current value of variable is used in an assignment if var_name in assignment_list: dependent_defer_msg_vars[(children[0])] = var_name defer_message_operation_dict[var_name].append( trans_operation) continue for dependent_var_name in dependent_defer_msg_vars: if dependent_var_name in assignment_list: dependent_defer_msg_vars[(children[0])] = var_name defer_message_operation_dict[var_name].append( trans_operation)
def defer_msg_assignment( self, trans_operation: CommonTree, defer_msg_list_dependent_var: List[str], message_objects: List[PCCObject]) -> List[CommonTree]: local_defer_operations = [] children = trans_operation.getChildren() # Retrieve deferred operation tmp_operation = copy.deepcopy(trans_operation) tmp_children = tmp_operation.getChildren() defer_var_name = MurphiModular.vdeferpref + str(children[0]) + "_" + \ str(children[2].children[1]) tmp_children[0].token.text = defer_var_name tmp_children[2].token.text = MurphiModular.tPOP_HL_DEFER local_defer_operations.append(tmp_operation) local_defer_operations += self.update_messages( trans_operation, defer_msg_list_dependent_var, message_objects) return local_defer_operations
def _CreateConstant(self, obj: CommonTree): data = obj.getChildren() self.constNode[str(data[0])] = str(data[1])