nsqdriver 0.2.4__py3-none-any.whl → 0.3.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of nsqdriver might be problematic. Click here for more details.
- nsqdriver/NS_CST.py +260 -0
- nsqdriver/NS_MCI.py +21 -9
- nsqdriver/NS_QSYNC.py +20 -1
- nsqdriver/__init__.py +4 -2
- nsqdriver/compiler/__init__.py +0 -0
- nsqdriver/compiler/ns_wave.py +483 -0
- nsqdriver/compiler/py_wave_asm.py +538 -0
- nsqdriver/wrapper/BD_NSMCI.py +310 -0
- {nsqdriver-0.2.4.dist-info → nsqdriver-0.3.0.dist-info}/METADATA +2 -4
- nsqdriver-0.3.0.dist-info/RECORD +17 -0
- nsqdriver-0.2.4.dist-info/RECORD +0 -12
- {nsqdriver-0.2.4.dist-info → nsqdriver-0.3.0.dist-info}/WHEEL +0 -0
- {nsqdriver-0.2.4.dist-info → nsqdriver-0.3.0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,483 @@
|
|
|
1
|
+
import copy
|
|
2
|
+
from typing import Union, List, Dict
|
|
3
|
+
from itertools import chain, repeat
|
|
4
|
+
from enum import IntEnum
|
|
5
|
+
from collections import namedtuple
|
|
6
|
+
|
|
7
|
+
import numpy as np
|
|
8
|
+
import waveforms as wf
|
|
9
|
+
|
|
10
|
+
from .py_wave_asm import *
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class QInsPlaceholder(NSQCommand):
|
|
14
|
+
...
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class Wave(GenTagMixin):
|
|
18
|
+
Identity = namedtuple('Relation', ['frame', 'envelop'])
|
|
19
|
+
|
|
20
|
+
class Tag(IntEnum):
|
|
21
|
+
none = 0
|
|
22
|
+
frame = 1
|
|
23
|
+
envelope = 2
|
|
24
|
+
signal = 3
|
|
25
|
+
|
|
26
|
+
def __init__(self, ins_obj: "InstructionQ", ins_id: dict):
|
|
27
|
+
cls = self.__class__
|
|
28
|
+
self.instruction = ins_obj
|
|
29
|
+
self.id = cls.Identity(**ins_id)
|
|
30
|
+
if ins_id['frame'] != -1 and ins_id['envelop'] != -1:
|
|
31
|
+
self.wtag = cls.Tag.signal
|
|
32
|
+
elif ins_id['frame'] != -1:
|
|
33
|
+
self.wtag = cls.Tag.envelope
|
|
34
|
+
elif ins_id['envelop'] != -1:
|
|
35
|
+
self.wtag = cls.Tag.frame
|
|
36
|
+
else:
|
|
37
|
+
self.wtag = cls.Tag.none
|
|
38
|
+
|
|
39
|
+
def __repr__(self):
|
|
40
|
+
return f'<{self.__class__}::{self.id}::{self.wtag}>'
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
class Frame(Wave):
|
|
44
|
+
def __init__(self, ins_obj: "InstructionQ", ins_id: int, freq: float):
|
|
45
|
+
super().__init__(ins_obj, {'frame': ins_id, 'envelop': -1})
|
|
46
|
+
self.tag = self.generate_tag
|
|
47
|
+
self.freq = freq
|
|
48
|
+
|
|
49
|
+
@property
|
|
50
|
+
def freq(self):
|
|
51
|
+
return self._freq
|
|
52
|
+
|
|
53
|
+
@freq.setter
|
|
54
|
+
def freq(self, value):
|
|
55
|
+
self._freq = value
|
|
56
|
+
self._ins = QInsFrame(freq=value, tag=self.tag)
|
|
57
|
+
|
|
58
|
+
def __mul__(self, other: Wave):
|
|
59
|
+
if isinstance(other, Envelope) or isinstance(other, Signal):
|
|
60
|
+
if other.instruction is not self.instruction:
|
|
61
|
+
raise ValueError(f'隶属于的instruction不同,不能直接相乘')
|
|
62
|
+
res = Signal(self.instruction, {'frame': self.id.frame, 'envelop': other.id.envelop})
|
|
63
|
+
res.frame = self
|
|
64
|
+
res.envelope = other
|
|
65
|
+
return res
|
|
66
|
+
else:
|
|
67
|
+
raise ValueError(f'{self.__class__}不能与{other.__class__}做乘法运算')
|
|
68
|
+
|
|
69
|
+
def format(self):
|
|
70
|
+
return self._ins
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
class Envelope(Wave):
|
|
74
|
+
def __init__(self, ins_obj: "InstructionQ", ins_id: int, content):
|
|
75
|
+
super().__init__(ins_obj, {'frame': -1, 'envelop': ins_id})
|
|
76
|
+
self.tag = self.generate_tag
|
|
77
|
+
self.content = content
|
|
78
|
+
|
|
79
|
+
@property
|
|
80
|
+
def content(self):
|
|
81
|
+
return self._content
|
|
82
|
+
|
|
83
|
+
@content.setter
|
|
84
|
+
def content(self, value):
|
|
85
|
+
self._content = value
|
|
86
|
+
self._ins = QInsEnvelop(envelop=self.content, tag=self.tag)
|
|
87
|
+
|
|
88
|
+
def __mul__(self, other: Wave):
|
|
89
|
+
if isinstance(other, Frame) or isinstance(other, Signal):
|
|
90
|
+
if other.instruction is not self.instruction:
|
|
91
|
+
raise ValueError(f'They belong to different instructions and cannot be directly multiplied')
|
|
92
|
+
res = Signal(self.instruction, {'frame': other.id.frame, 'envelop': self.id.envelop})
|
|
93
|
+
res.frame = other
|
|
94
|
+
res.envelope = self
|
|
95
|
+
return res
|
|
96
|
+
else:
|
|
97
|
+
raise ValueError(f'{self.__class__}不能与{other.__class__}做乘法运算')
|
|
98
|
+
|
|
99
|
+
def format(self):
|
|
100
|
+
return self._ins
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
class Signal(Wave):
|
|
104
|
+
def __init__(self, ins_obj: "InstructionQ", ins_id: dict):
|
|
105
|
+
super().__init__(ins_obj, ins_id)
|
|
106
|
+
self.frame = None
|
|
107
|
+
self.envelope = None
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
class InstructionQ(GenTagMixin):
|
|
111
|
+
"""!
|
|
112
|
+
包含各种具体的指令
|
|
113
|
+
"""
|
|
114
|
+
|
|
115
|
+
def __init__(self, freqs=None, envelopes=None):
|
|
116
|
+
"""!
|
|
117
|
+
|
|
118
|
+
@param freqs:
|
|
119
|
+
@param envelopes:
|
|
120
|
+
"""
|
|
121
|
+
if freqs is None:
|
|
122
|
+
freqs = []
|
|
123
|
+
if envelopes is None:
|
|
124
|
+
envelopes = []
|
|
125
|
+
self.i_set: "List[Union[NSQCommand, InstructionQ]]" = []
|
|
126
|
+
self.f_set: "Dict[int, Frame]" = {}
|
|
127
|
+
self.e_set: "Dict[int, Envelope]" = {}
|
|
128
|
+
self.symbol_set: Dict[str, int] = {}
|
|
129
|
+
self.symbol_idx = -1
|
|
130
|
+
self.is_first_trig = True
|
|
131
|
+
self.last_ins = None
|
|
132
|
+
|
|
133
|
+
for i, f in enumerate(freqs):
|
|
134
|
+
self.ins_frame(f)
|
|
135
|
+
for i, e in enumerate(envelopes):
|
|
136
|
+
self.ins_envelope(e)
|
|
137
|
+
|
|
138
|
+
def __enter__(self):
|
|
139
|
+
return self
|
|
140
|
+
|
|
141
|
+
def __exit__(self, exc_type, exc_val, exc_tb):
|
|
142
|
+
...
|
|
143
|
+
|
|
144
|
+
def clear(self):
|
|
145
|
+
self.i_set.clear()
|
|
146
|
+
self.symbol_set: Dict[str, int] = {}
|
|
147
|
+
self.symbol_idx = -1
|
|
148
|
+
self.is_first_trig = True
|
|
149
|
+
|
|
150
|
+
@property
|
|
151
|
+
def length(self):
|
|
152
|
+
return len(self.i_set)
|
|
153
|
+
|
|
154
|
+
def ins_frame(self, freq, idx=None) -> Frame:
|
|
155
|
+
raise RuntimeError(f'Cannot create a new frame in the branch')
|
|
156
|
+
|
|
157
|
+
def ins_envelope(self, envelope: "Union[np.ndarray, wf.Waveform, str]", idx=None) -> Envelope:
|
|
158
|
+
raise RuntimeError(f'Cannot create a new envelope in the branch')
|
|
159
|
+
|
|
160
|
+
def evlp_gaussian(self, width) -> Envelope:
|
|
161
|
+
wave = wf.gaussian(width) >> (width/2)
|
|
162
|
+
wave.start = 0
|
|
163
|
+
wave.stop = width
|
|
164
|
+
return self.ins_envelope(wave)
|
|
165
|
+
|
|
166
|
+
def evlp_cospulse(self, width) -> Envelope:
|
|
167
|
+
wave = wf.cosPulse(width) >> (width / 2)
|
|
168
|
+
wave.start = 0
|
|
169
|
+
wave.stop = width
|
|
170
|
+
return self.ins_envelope(wave)
|
|
171
|
+
|
|
172
|
+
def evlp_square(self, width) -> Envelope:
|
|
173
|
+
wave = wf.square(width) >> (width / 2)
|
|
174
|
+
wave.start = 0
|
|
175
|
+
wave.stop = width
|
|
176
|
+
return self.ins_envelope(wave)
|
|
177
|
+
|
|
178
|
+
def _append_ins(self, cmd: "Union[NSQCommand, InstructionQ]"):
|
|
179
|
+
self.last_ins = cmd
|
|
180
|
+
self.i_set.append(cmd)
|
|
181
|
+
|
|
182
|
+
def _map_var(self, var):
|
|
183
|
+
if var in self.symbol_set:
|
|
184
|
+
return self.symbol_set[var]
|
|
185
|
+
self.symbol_idx += 1
|
|
186
|
+
if self.symbol_idx >= 16:
|
|
187
|
+
raise RuntimeError(f'Up to 16 variables can be configured')
|
|
188
|
+
self.symbol_set[var] = self.symbol_idx
|
|
189
|
+
return self.symbol_set[var]
|
|
190
|
+
|
|
191
|
+
def wait_for_trigger(self):
|
|
192
|
+
if not self.is_first_trig:
|
|
193
|
+
self.wait()
|
|
194
|
+
cmd = QInsWaitTrig(tag=self.generate_tag)
|
|
195
|
+
self._append_ins(cmd)
|
|
196
|
+
return cmd
|
|
197
|
+
|
|
198
|
+
def ins_variable(self, reg: str, value: int):
|
|
199
|
+
cmd = QInsMov(self._map_var(reg), value, type='=', tag=self.generate_tag)
|
|
200
|
+
self._append_ins(cmd)
|
|
201
|
+
return cmd
|
|
202
|
+
|
|
203
|
+
def ins_add(self, reg: str, value: int):
|
|
204
|
+
cmd = QInsMov(self._map_var(reg), value, type='+', tag=self.generate_tag)
|
|
205
|
+
self._append_ins(cmd)
|
|
206
|
+
return cmd
|
|
207
|
+
|
|
208
|
+
def ins_reset_frame(self, flag, frame=''):
|
|
209
|
+
cmd = QInsResetF(flag, frame, tag=self.generate_tag)
|
|
210
|
+
self._append_ins(cmd)
|
|
211
|
+
return cmd
|
|
212
|
+
|
|
213
|
+
def inc_phase(self, frame, phase):
|
|
214
|
+
cmd = QInsIncPhase(phase, frame.tag, tag=self.generate_tag)
|
|
215
|
+
self._append_ins(cmd)
|
|
216
|
+
return cmd
|
|
217
|
+
|
|
218
|
+
def play_wave(self, wave: Signal, amp=1, freq=0, phase=0):
|
|
219
|
+
if not isinstance(wave, Signal):
|
|
220
|
+
raise RuntimeError(f'The parameter wave should be Signal, not {type(wave)}')
|
|
221
|
+
cmd = QInsPlayWave(wave.frame.tag, wave.envelope.tag, amp, freq, phase, tag=self.generate_tag)
|
|
222
|
+
self._append_ins(cmd)
|
|
223
|
+
return cmd
|
|
224
|
+
|
|
225
|
+
def play_zero(self, width):
|
|
226
|
+
cmd = QInsPlayZero(width, tag=self.generate_tag)
|
|
227
|
+
self._append_ins(cmd)
|
|
228
|
+
return cmd
|
|
229
|
+
|
|
230
|
+
def wait(self):
|
|
231
|
+
cmd = QInsWait(tag=self.generate_tag)
|
|
232
|
+
self._append_ins(cmd)
|
|
233
|
+
return cmd
|
|
234
|
+
|
|
235
|
+
def end(self):
|
|
236
|
+
cmd = QInsEnd(tag=self.generate_tag)
|
|
237
|
+
self._append_ins(cmd)
|
|
238
|
+
return cmd
|
|
239
|
+
|
|
240
|
+
def capture(self, width, delay=0):
|
|
241
|
+
cmd = QInsCapture(width=width, probe_delay=delay, tag=self.generate_tag)
|
|
242
|
+
self._append_ins(cmd)
|
|
243
|
+
return cmd
|
|
244
|
+
|
|
245
|
+
def _compile(self) -> "List[NSQCommand]":
|
|
246
|
+
res = []
|
|
247
|
+
for ins in self.i_set:
|
|
248
|
+
if isinstance(ins, InstructionQ):
|
|
249
|
+
res.extend(ins._compile())
|
|
250
|
+
else:
|
|
251
|
+
res.append(copy.copy(ins))
|
|
252
|
+
return res
|
|
253
|
+
|
|
254
|
+
def compile(self) -> "List[NSQCommand]":
|
|
255
|
+
queue = []
|
|
256
|
+
for idx in sorted(self.f_set.keys()):
|
|
257
|
+
ins = self.f_set[idx]
|
|
258
|
+
queue.append(ins.format())
|
|
259
|
+
for idx in sorted(self.e_set.keys()):
|
|
260
|
+
ins = self.e_set[idx]
|
|
261
|
+
queue.append(ins.format())
|
|
262
|
+
|
|
263
|
+
queue.extend(self._compile())
|
|
264
|
+
# 向指令队列中添加End指令
|
|
265
|
+
if not isinstance(queue[-1], QInsEnd):
|
|
266
|
+
queue.append(self.end())
|
|
267
|
+
|
|
268
|
+
res = []
|
|
269
|
+
for idx, ins in enumerate(queue):
|
|
270
|
+
if isinstance(ins, QInsPlaceholder):
|
|
271
|
+
f_tag = ins.tag
|
|
272
|
+
t_tag = queue[idx+1].tag
|
|
273
|
+
for _ins in queue:
|
|
274
|
+
if getattr(_ins, 'target', '') == f_tag:
|
|
275
|
+
_ins.target = t_tag
|
|
276
|
+
continue
|
|
277
|
+
res.append(ins)
|
|
278
|
+
return res
|
|
279
|
+
|
|
280
|
+
def lookup(self):
|
|
281
|
+
import json
|
|
282
|
+
ins_list = [str(ins) for ins in self.compile()]
|
|
283
|
+
print(json.dumps(ins_list, indent=4))
|
|
284
|
+
|
|
285
|
+
|
|
286
|
+
class InsChannel(InstructionQ):
|
|
287
|
+
def __init__(self, freqs=None, envelopes=None):
|
|
288
|
+
super(InsChannel, self).__init__(freqs, envelopes)
|
|
289
|
+
self.if_stack: "List[InsIF]" = []
|
|
290
|
+
self.looping = False
|
|
291
|
+
|
|
292
|
+
def clear(self):
|
|
293
|
+
super().clear()
|
|
294
|
+
self.looping = False
|
|
295
|
+
|
|
296
|
+
def ins_frame(self, freq, idx=None) -> Frame:
|
|
297
|
+
if idx is None:
|
|
298
|
+
idx = sorted(self.f_set)[-1]+1 if len(self.f_set) != 0 else 0
|
|
299
|
+
if not isinstance(idx, int):
|
|
300
|
+
raise ValueError(f'frame的idx应为整数,而不是{type(idx)}')
|
|
301
|
+
frame = Frame(self, idx, freq)
|
|
302
|
+
self.f_set[idx] = frame
|
|
303
|
+
return frame
|
|
304
|
+
|
|
305
|
+
def ins_envelope(self, envelope: "Union[np.ndarray, wf.Waveform, str]", idx=None) -> Envelope:
|
|
306
|
+
if idx is None:
|
|
307
|
+
idx = sorted(self.e_set)[-1] + 1 if len(self.e_set) != 0 else 0
|
|
308
|
+
if not isinstance(idx, int):
|
|
309
|
+
raise ValueError(f'envelop的idx应为整数,而不是{type(idx)}')
|
|
310
|
+
obj = Envelope(self, idx, envelope)
|
|
311
|
+
self.e_set[idx] = obj
|
|
312
|
+
return obj
|
|
313
|
+
|
|
314
|
+
def ins_if(self, formula) -> "InsIF":
|
|
315
|
+
channel = self if self.__class__ is InsChannel else self.channel
|
|
316
|
+
if_ins = InsIF.from_channel(channel)
|
|
317
|
+
if_ins.formula = formula
|
|
318
|
+
self._append_ins(if_ins)
|
|
319
|
+
self.if_stack.append(if_ins)
|
|
320
|
+
return if_ins
|
|
321
|
+
|
|
322
|
+
def ins_else(self) -> "InsElse":
|
|
323
|
+
# if与else之间不能间隔其它指令
|
|
324
|
+
if not isinstance(self.last_ins, InsIF):
|
|
325
|
+
raise RuntimeError(f'The last call of ins_else must be ins_if, not {type(self.last_ins)}')
|
|
326
|
+
# 不能没有if直接调用else
|
|
327
|
+
if len(self.if_stack) == 0:
|
|
328
|
+
raise RuntimeError(f'Please call if before calling else')
|
|
329
|
+
channel = self if self.__class__ is InsChannel else self.channel
|
|
330
|
+
_if = self.if_stack.pop()
|
|
331
|
+
_else = InsElse.from_channel(channel)
|
|
332
|
+
_else._if = _if
|
|
333
|
+
_if.ins_else = _else
|
|
334
|
+
return _else
|
|
335
|
+
|
|
336
|
+
def ins_loop(self, times) -> "InsLoop":
|
|
337
|
+
if self.looping:
|
|
338
|
+
raise RuntimeError(f'The current object is already in the loop')
|
|
339
|
+
channel = self if self.__class__ is InsChannel else self.channel
|
|
340
|
+
loop_ins = InsLoop.from_channel(channel)
|
|
341
|
+
loop_ins.times = times
|
|
342
|
+
self._append_ins(loop_ins)
|
|
343
|
+
return loop_ins
|
|
344
|
+
|
|
345
|
+
|
|
346
|
+
class InsIF(InsChannel):
|
|
347
|
+
ch_judge_name = {f'FREQ_{i}': 1<<i for i in range(6)}
|
|
348
|
+
|
|
349
|
+
def __init__(self, freqs=None, envelopes=None):
|
|
350
|
+
"""!
|
|
351
|
+
|
|
352
|
+
@param freqs:
|
|
353
|
+
@param envelopes:
|
|
354
|
+
"""
|
|
355
|
+
super().__init__(freqs, envelopes)
|
|
356
|
+
self.channel: "InsChannel" = None
|
|
357
|
+
self.key_ins = None
|
|
358
|
+
self.ins_else = None
|
|
359
|
+
|
|
360
|
+
@classmethod
|
|
361
|
+
def from_channel(cls, channel):
|
|
362
|
+
self = cls()
|
|
363
|
+
self.channel = channel
|
|
364
|
+
return self
|
|
365
|
+
|
|
366
|
+
@property
|
|
367
|
+
def formula(self):
|
|
368
|
+
raise RuntimeError(f'{self.__class__.__name__}.formula is a static property')
|
|
369
|
+
|
|
370
|
+
@formula.setter
|
|
371
|
+
def formula(self, formula: str):
|
|
372
|
+
formula = formula.replace(' ', '')
|
|
373
|
+
ast = formula.split('==')
|
|
374
|
+
if len(ast) != 2:
|
|
375
|
+
raise RuntimeError(f'The format of formula should be [name] == [value]')
|
|
376
|
+
name, value = ast
|
|
377
|
+
if name in self.channel.symbol_set:
|
|
378
|
+
self.key_ins = QInsJumpWithReg(self.channel.symbol_set[name], int(value), None, tag=self.generate_tag)
|
|
379
|
+
elif name in self.ch_judge_name:
|
|
380
|
+
self.key_ins = QInsJumpWithJudge(int(value), self.ch_judge_name[name], None, tag=self.generate_tag)
|
|
381
|
+
else:
|
|
382
|
+
raise RuntimeError(f'The specified variable {name} does not exist')
|
|
383
|
+
|
|
384
|
+
def _compile(self) -> "List[NSQCommand]":
|
|
385
|
+
"""!
|
|
386
|
+
递归生成分支结构,支持结构嵌套
|
|
387
|
+
@return:
|
|
388
|
+
"""
|
|
389
|
+
res = []
|
|
390
|
+
if_group = super()._compile()
|
|
391
|
+
else_group = self.ins_else._compile() if isinstance(self.ins_else, InsElse) else []
|
|
392
|
+
while len(else_group) < 3:
|
|
393
|
+
else_group.append(QInsWait(tag=self.generate_tag))
|
|
394
|
+
if_group.append(QInsPlaceholder(tag=self.generate_tag))
|
|
395
|
+
jump = QInsJump(None, tag=self.generate_tag)
|
|
396
|
+
self.key_ins.target = if_group[0].tag
|
|
397
|
+
jump.target = if_group[-1].tag
|
|
398
|
+
|
|
399
|
+
res.append(self.key_ins)
|
|
400
|
+
res.extend(else_group)
|
|
401
|
+
res.append(jump)
|
|
402
|
+
res.extend(if_group)
|
|
403
|
+
return res
|
|
404
|
+
|
|
405
|
+
def capture(self, width, delay=0):
|
|
406
|
+
raise RuntimeError(f'Capture is not allowed to call in a branch structure')
|
|
407
|
+
|
|
408
|
+
|
|
409
|
+
class InsElse(InsChannel):
|
|
410
|
+
def __init__(self, freqs=None, envelopes=None):
|
|
411
|
+
"""!
|
|
412
|
+
|
|
413
|
+
@param freqs:
|
|
414
|
+
@param envelopes:
|
|
415
|
+
"""
|
|
416
|
+
super().__init__(freqs, envelopes)
|
|
417
|
+
self.channel = None
|
|
418
|
+
self._if = None
|
|
419
|
+
|
|
420
|
+
@classmethod
|
|
421
|
+
def from_channel(cls, channel):
|
|
422
|
+
self = cls()
|
|
423
|
+
self.channel = channel
|
|
424
|
+
return self
|
|
425
|
+
|
|
426
|
+
def capture(self, width, delay=0):
|
|
427
|
+
raise RuntimeError(f'Capture is not allowed to call in a branch structure')
|
|
428
|
+
|
|
429
|
+
|
|
430
|
+
class InsLoop(InsChannel):
|
|
431
|
+
def __init__(self, freqs=None, envelopes=None):
|
|
432
|
+
"""!
|
|
433
|
+
|
|
434
|
+
@param freqs:
|
|
435
|
+
@param envelopes:
|
|
436
|
+
"""
|
|
437
|
+
super().__init__(freqs, envelopes)
|
|
438
|
+
self.channel: "InsChannel" = None
|
|
439
|
+
self.times = None
|
|
440
|
+
self.var = self.generate_tag
|
|
441
|
+
|
|
442
|
+
def __enter__(self):
|
|
443
|
+
self.channel.looping = True
|
|
444
|
+
return self
|
|
445
|
+
|
|
446
|
+
def __exit__(self, exc_type, exc_val, exc_tb):
|
|
447
|
+
self.looping = False
|
|
448
|
+
|
|
449
|
+
@classmethod
|
|
450
|
+
def from_channel(cls, channel):
|
|
451
|
+
self = cls()
|
|
452
|
+
self.channel = channel
|
|
453
|
+
return self
|
|
454
|
+
|
|
455
|
+
def capture(self, width, delay=0):
|
|
456
|
+
raise RuntimeError(f'Calling capture in a loop construct is not allowed')
|
|
457
|
+
|
|
458
|
+
def _compile(self) -> "List[NSQCommand]":
|
|
459
|
+
body = super()._compile()
|
|
460
|
+
res = []
|
|
461
|
+
set_cmd = QInsMov(self.channel._map_var(self.var), 0, type='=', tag=self.generate_tag)
|
|
462
|
+
body.append(QInsMov(self.channel._map_var(self.var), 1, type='+', tag=self.generate_tag))
|
|
463
|
+
placeholder = QInsPlaceholder(tag=self.generate_tag)
|
|
464
|
+
jump = [
|
|
465
|
+
QInsJumpWithReg(self.channel._map_var(self.var), self.times, placeholder.tag, tag=self.generate_tag),
|
|
466
|
+
QInsWait(tag=self.generate_tag),
|
|
467
|
+
QInsWait(tag=self.generate_tag),
|
|
468
|
+
QInsJump(body[0].tag, tag=self.generate_tag),
|
|
469
|
+
placeholder
|
|
470
|
+
]
|
|
471
|
+
res.append(set_cmd)
|
|
472
|
+
res.extend(body)
|
|
473
|
+
res.extend(jump)
|
|
474
|
+
return res
|
|
475
|
+
|
|
476
|
+
# def _compile(self) -> "List[NSQCommand]":
|
|
477
|
+
# ins_list = super()._compile()
|
|
478
|
+
# res = []
|
|
479
|
+
# for ins in chain.from_iterable(repeat(ins_list, self.times)):
|
|
480
|
+
# _ins: "NSQCommand" = copy.copy(ins)
|
|
481
|
+
# _ins.tag = self.generate_tag
|
|
482
|
+
# res.append(_ins)
|
|
483
|
+
# return res
|