// Check pattern (left)*(yielding-proc)*(right)* private void CheckYieldingProcCondition(ParCallCmd parCallCmd) { ParallelCallPhase phase = ParallelCallPhase.BEFORE; foreach (var callCmd in parCallCmd.CallCmds) { var label = CallCmdLabel(callCmd); Debug.Assert(label != N); if (label == P || label == Y && civlTypeChecker.procToYieldInvariant.ContainsKey(callCmd.Proc) ) { continue; } switch (phase) { case ParallelCallPhase.BEFORE: if (label == Y) { phase = ParallelCallPhase.MIDDLE; } else if (label == R) { phase = ParallelCallPhase.AFTER; } break; case ParallelCallPhase.MIDDLE: if (label == Y) { continue; } if (label == L) { civlTypeChecker.Error(parCallCmd, $"Mover types in parallel call do not match (left)*(yielding-proc)*(right)* at layer {currLayerNum}"); } else { phase = ParallelCallPhase.AFTER; } break; case ParallelCallPhase.AFTER: if (label == R || label == B) { continue; } civlTypeChecker.Error(parCallCmd, $"Mover types in parallel call do not match (left)*(yielding-proc)*(right)* at layer {currLayerNum}"); break; } } }
// Check pattern (left)*(non)?(right)* private void CheckNonMoverCondition(ParCallCmd parCallCmd) { ParallelCallPhase phase = ParallelCallPhase.BEFORE; foreach (var callCmd in parCallCmd.CallCmds) { var label = CallCmdLabel(callCmd); Debug.Assert(label != I); if (label == P || label == Y || label == B) { continue; } switch (phase) { case ParallelCallPhase.BEFORE: if (label == L) { continue; } phase = ParallelCallPhase.AFTER; break; case ParallelCallPhase.MIDDLE: Debug.Assert(false); break; case ParallelCallPhase.AFTER: if (label == R) { continue; } @base.checkingContext.Error(parCallCmd, $"Mover types in parallel call do not match (left)*(non)?(right)* at layer {currLayerNum}"); break; } } }