fprime-gds 4.0.2a3__py3-none-any.whl → 4.0.2a5__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.
Files changed (36) hide show
  1. fprime_gds/common/communication/ccsds/apid.py +12 -10
  2. fprime_gds/common/communication/ccsds/space_packet.py +7 -2
  3. fprime_gds/common/communication/framing.py +2 -2
  4. fprime_gds/common/distributor/distributor.py +9 -6
  5. fprime_gds/common/encoders/encoder.py +1 -0
  6. fprime_gds/common/fpy/README.md +190 -42
  7. fprime_gds/common/fpy/SPEC.md +153 -39
  8. fprime_gds/common/fpy/bytecode/assembler.py +62 -0
  9. fprime_gds/common/fpy/bytecode/directives.py +620 -294
  10. fprime_gds/common/fpy/codegen.py +687 -910
  11. fprime_gds/common/fpy/grammar.lark +44 -9
  12. fprime_gds/common/fpy/main.py +27 -4
  13. fprime_gds/common/fpy/model.py +799 -0
  14. fprime_gds/common/fpy/parser.py +29 -34
  15. fprime_gds/common/fpy/test_helpers.py +119 -0
  16. fprime_gds/common/fpy/types.py +563 -0
  17. fprime_gds/common/pipeline/standard.py +1 -1
  18. fprime_gds/common/testing_fw/pytest_integration.py +2 -1
  19. fprime_gds/common/utils/data_desc_type.py +1 -0
  20. fprime_gds/executables/cli.py +11 -2
  21. fprime_gds/executables/comm.py +0 -2
  22. fprime_gds/executables/run_deployment.py +2 -0
  23. fprime_gds/flask/app.py +17 -2
  24. fprime_gds/flask/default_settings.py +1 -0
  25. fprime_gds/flask/static/index.html +7 -4
  26. fprime_gds/flask/static/js/config.js +9 -1
  27. fprime_gds/flask/static/js/vue-support/channel.js +16 -0
  28. fprime_gds/flask/static/js/vue-support/event.js +1 -0
  29. fprime_gds/flask/static/js/vue-support/fp-row.js +25 -1
  30. {fprime_gds-4.0.2a3.dist-info → fprime_gds-4.0.2a5.dist-info}/METADATA +1 -1
  31. {fprime_gds-4.0.2a3.dist-info → fprime_gds-4.0.2a5.dist-info}/RECORD +36 -32
  32. {fprime_gds-4.0.2a3.dist-info → fprime_gds-4.0.2a5.dist-info}/entry_points.txt +2 -1
  33. {fprime_gds-4.0.2a3.dist-info → fprime_gds-4.0.2a5.dist-info}/WHEEL +0 -0
  34. {fprime_gds-4.0.2a3.dist-info → fprime_gds-4.0.2a5.dist-info}/licenses/LICENSE.txt +0 -0
  35. {fprime_gds-4.0.2a3.dist-info → fprime_gds-4.0.2a5.dist-info}/licenses/NOTICE.txt +0 -0
  36. {fprime_gds-4.0.2a3.dist-info → fprime_gds-4.0.2a5.dist-info}/top_level.txt +0 -0
@@ -1,89 +1,153 @@
1
- from dataclasses import astuple, dataclass
1
+ from __future__ import annotations
2
+ import typing
3
+ from typing import Any
4
+
5
+ # This makes the code forward-compatible. In Python 3.10+, the `|` operator
6
+ # creates a types.UnionType. In 3.9, only typing.Union exists.
7
+ try:
8
+ from types import UnionType
9
+
10
+ UNION_TYPES = (typing.Union, UnionType)
11
+ except ImportError:
12
+ UNION_TYPES = (typing.Union,)
13
+
14
+ from dataclasses import dataclass, fields, astuple
15
+ from typing import ClassVar
16
+ import typing
17
+ from typing import Union
2
18
  from pathlib import Path
3
19
  import struct
4
- from typing import ClassVar
5
20
  import zlib
6
- from fprime.common.models.serialize.time_type import TimeType
21
+ from fprime.common.models.serialize.type_base import BaseType
7
22
  from fprime.common.models.serialize.numerical_types import (
8
23
  U32Type,
9
24
  U16Type,
10
25
  U64Type,
11
26
  U8Type,
12
27
  I64Type,
28
+ I16Type,
29
+ I32Type,
30
+ I8Type,
31
+ F32Type,
32
+ F64Type,
13
33
  )
14
34
  from fprime.common.models.serialize.bool_type import BoolType
15
35
  from enum import Enum
16
36
 
37
+
38
+ def get_union_members(type_hint: type) -> list[type]:
39
+ """
40
+ If the type_hint is a Union, returns a list of its member types.
41
+ Otherwise, returns the original type_hint.
42
+ """
43
+ # get_origin returns the base type (e.g., Union for Union[int, str])
44
+ # or None if it's a simple type like int.
45
+ origin = typing.get_origin(type_hint)
46
+
47
+ if origin in UNION_TYPES:
48
+ # get_args returns the type arguments (e.g., (int, str))
49
+ return list(typing.get_args(type_hint))
50
+
51
+ # Not a Union, so return the type itself
52
+ return [type_hint]
53
+
54
+
17
55
  FwSizeType = U64Type
18
56
  FwChanIdType = U32Type
19
57
  FwPrmIdType = U32Type
20
58
  FwOpcodeType = U32Type
21
59
 
22
- MAX_SERIALIZABLE_REGISTER_SIZE = 512 - 4 - 4
23
-
24
60
 
25
- class DirectiveOpcode(Enum):
61
+ class DirectiveId(Enum):
26
62
  INVALID = 0
27
63
  WAIT_REL = 1
28
64
  WAIT_ABS = 2
29
- SET_SER_REG = 3
30
65
  GOTO = 4
31
66
  IF = 5
32
67
  NO_OP = 6
33
- GET_TLM = 7
34
- GET_PRM = 8
35
- CMD = 9
36
- SET_REG = 10
37
- DESER_SER_REG_8 = 11
38
- DESER_SER_REG_4 = 12
39
- DESER_SER_REG_2 = 13
40
- DESER_SER_REG_1 = 14
41
- # binary reg op directives
42
- # all of these are handled at the CPP level by one BinaryRegOpDirective
68
+ STORE_TLM_VAL = 7
69
+ STORE_PRM = 8
70
+ CONST_CMD = 9
71
+ # stack op directives
72
+ # all of these are handled at the CPP level by one StackOpDirective
43
73
  # boolean ops
44
- OR = 15
45
- AND = 16
74
+ OR = 10
75
+ AND = 11
46
76
  # integer equalities
47
- IEQ = 17
48
- INE = 18
77
+ IEQ = 12
78
+ INE = 13
49
79
  # unsigned integer inequalities
50
- ULT = 19
51
- ULE = 20
52
- UGT = 21
53
- UGE = 22
80
+ ULT = 14
81
+ ULE = 15
82
+ UGT = 16
83
+ UGE = 17
54
84
  # signed integer inequalities
55
- SLT = 23
56
- SLE = 24
57
- SGT = 25
58
- SGE = 26
85
+ SLT = 18
86
+ SLE = 19
87
+ SGT = 20
88
+ SGE = 21
59
89
  # floating point equalities
60
- FEQ = 27
61
- FNE = 28
90
+ FEQ = 22
91
+ FNE = 23
62
92
  # floating point inequalities
63
- FLT = 29
64
- FLE = 30
65
- FGT = 31
66
- FGE = 32
67
- # end binary reg op directives
68
-
69
- # unary reg op dirs
70
- NOT = 33
71
- # floating point extension and truncation
72
- FPEXT = 34
73
- FPTRUNC = 35
93
+ FLT = 24
94
+ FLE = 25
95
+ FGT = 26
96
+ FGE = 27
97
+ NOT = 28
74
98
  # floating point conversion to signed/unsigned integer,
75
99
  # and vice versa
76
- FPTOSI = 36
77
- FPTOUI = 37
78
- SITOFP = 38
79
- UITOFP = 39
80
- # end unary reg op dirs
81
-
82
- EXIT = 40
100
+ FPTOSI = 29
101
+ FPTOUI = 30
102
+ SITOFP = 31
103
+ UITOFP = 32
104
+ # integer arithmetic
105
+ IADD = 33
106
+ ISUB = 34
107
+ IMUL = 35
108
+ UDIV = 36
109
+ SDIV = 37
110
+ UMOD = 38
111
+ SMOD = 39
112
+ # float arithmetic
113
+ FADD = 40
114
+ FSUB = 41
115
+ FMUL = 42
116
+ FDIV = 43
117
+ FLOAT_FLOOR_DIV = 44
118
+ FPOW = 45
119
+ FLOG = 46
120
+ FMOD = 47
121
+ # floating point bitwidth conversions
122
+ FPEXT = 48
123
+ FPTRUNC = 49
124
+ # integer bitwidth conversions
125
+ # signed integer extend
126
+ SIEXT_8_64 = 50
127
+ SIEXT_16_64 = 51
128
+ SIEXT_32_64 = 52
129
+ # zero (unsigned) integer extend
130
+ ZIEXT_8_64 = 53
131
+ ZIEXT_16_64 = 54
132
+ ZIEXT_32_64 = 55
133
+ # integer truncate
134
+ ITRUNC_64_8 = 56
135
+ ITRUNC_64_16 = 57
136
+ ITRUNC_64_32 = 58
137
+ # end stack op dirs
138
+
139
+ EXIT = 59
140
+ ALLOCATE = 60
141
+ STORE = 61
142
+ LOAD = 62
143
+ PUSH_VAL = 63
144
+ DISCARD = 64
145
+ MEMCMP = 65
146
+ STACK_CMD = 66
83
147
 
84
148
 
85
149
  class Directive:
86
- opcode: ClassVar[DirectiveOpcode] = DirectiveOpcode.INVALID
150
+ opcode: ClassVar[DirectiveId] = DirectiveId.INVALID
87
151
 
88
152
  def serialize(self) -> bytes:
89
153
  arg_bytes = self.serialize_args()
@@ -95,396 +159,658 @@ class Directive:
95
159
  return output
96
160
 
97
161
  def serialize_args(self) -> bytes:
98
- raise NotImplementedError("serialize_args not implemented")
162
+ output = bytes()
163
+
164
+ for field in fields(self):
165
+ value = getattr(self, field.name)
166
+ if isinstance(value, BaseType):
167
+ # it is already an fprime type instance
168
+ # so we can serialize it
169
+ output += value.serialize()
170
+ continue
171
+
172
+ if isinstance(value, bytes):
173
+ # it is just raw bytes
174
+ output += value
175
+ continue
176
+
177
+ # okay, it is not a primitive type or bytes
178
+ field_type = typing.get_type_hints(self.__class__)[field.name]
179
+ union_members = get_union_members(field_type)
180
+ primitive_type = None
181
+ # find out which primitive type it is
182
+ for arg in union_members:
183
+ if issubclass(arg, BaseType):
184
+ # it is a primitive type
185
+ primitive_type = arg
186
+ break
187
+ if primitive_type is None:
188
+ raise NotImplementedError(
189
+ "Unknown how to serialize field", field.name, "for", self
190
+ )
191
+
192
+ output += primitive_type(value).serialize()
99
193
 
194
+ return output
100
195
 
101
- HEADER_FORMAT = "!BBBBBHI"
102
- HEADER_SIZE = struct.calcsize(HEADER_FORMAT)
196
+ def __repr__(self):
197
+ r = self.__class__.__old_repr__(self)
198
+ name = self.__class__.__name__.replace("Directive", "").upper()
199
+ value = "".join(r.split("(")[1:])
200
+ return name + "(" + value
201
+
202
+ @classmethod
203
+ def deserialize(cls, data: bytes, offset: int) -> tuple[int, "Directive"] | None:
204
+ if len(data) - offset < 3:
205
+ # insufficient space
206
+ return None
207
+ opcode = struct.unpack_from(">B", data, offset)[0]
208
+ arg_size = struct.unpack_from(">H", data, offset + 1)[0]
209
+ offset += 3
210
+ if len(data) - offset < arg_size:
211
+ # insufficient space
212
+ return None
213
+ args = data[offset : (offset + arg_size)]
214
+ offset += arg_size
215
+ dir_type = [
216
+ c
217
+ for c in (Directive.__subclasses__() + StackOpDirective.__subclasses__())
218
+ if c.opcode.value == opcode
219
+ ]
220
+ if len(dir_type) != 1:
221
+ return None
222
+
223
+ arg_offset = 0
224
+ dir_type = dir_type[0]
225
+ arg_values = []
226
+
227
+ # go through each field in the type of the directive
228
+ for field in fields(dir_type):
229
+ field_type = typing.get_type_hints(dir_type)[field.name]
230
+ # get a list of all union members of the field type
231
+ # or a list containing just the type if it is not a union
232
+ union_types = get_union_members(field_type)
233
+
234
+ base_type = None
235
+ for t in union_types:
236
+ if issubclass(t, BaseType):
237
+ base_type = t
238
+
239
+ # if one of the members of the union was a sub of basetype
240
+ if base_type is not None:
241
+ # deserialize using that basetype and add to arg value list
242
+ instance = base_type()
243
+ instance.deserialize(args, arg_offset)
244
+ arg_values.append(instance.val)
245
+ arg_offset += instance.getSize()
246
+ continue
247
+ # none of the args were base types. the only other thing we could be
248
+ # is a byte array. assert that that's true
249
+ assert len(union_types) == 1 and union_types[0] == bytes
250
+ # it is just raw bytes. deserialize until the end
251
+ arg_values.append(args[arg_offset:])
252
+ arg_offset = len(args)
253
+ continue
254
+
255
+ dir = dir_type(*arg_values)
256
+ return offset, dir
103
257
 
104
258
 
105
259
  @dataclass
106
- class Header:
107
- majorVersion: int
108
- minorVersion: int
109
- patchVersion: int
110
- schemaVersion: int
111
- argumentCount: int
112
- statementCount: int
113
- bodySize: int
260
+ class StackOpDirective(Directive):
261
+ """the argument types this dir pops off the stack"""
262
+
263
+ stack_output_type: ClassVar[type[BaseType]] = BaseType
264
+ """the type this dir pushes to the stack"""
114
265
 
115
266
 
116
- FOOTER_FORMAT = "!I"
117
- FOOTER_SIZE = struct.calcsize(FOOTER_FORMAT)
267
+ @dataclass
268
+ class StackCmdDirective(Directive):
269
+ opcode: ClassVar[DirectiveId] = DirectiveId.STACK_CMD
270
+
271
+ args_size: Union[int, U32Type]
118
272
 
119
273
 
120
274
  @dataclass
121
- class Footer:
122
- crc: int
275
+ class MemCompareDirective(Directive):
276
+ opcode: ClassVar[DirectiveId] = DirectiveId.MEMCMP
277
+ size: Union[int, U32Type]
123
278
 
124
279
 
125
- def serialize_directives(dirs: list[Directive], output: Path = None):
126
- output_bytes = bytes()
280
+ @dataclass
281
+ class LoadDirective(Directive):
282
+ opcode: ClassVar[DirectiveId] = DirectiveId.LOAD
127
283
 
128
- for dir in dirs:
129
- output_bytes += dir.serialize()
284
+ lvar_offset: Union[int, U32Type]
285
+ size: Union[int, U32Type]
130
286
 
131
- header = Header(0, 0, 0, 1, 0, len(dirs), len(output_bytes))
132
- output_bytes = struct.pack(HEADER_FORMAT, *astuple(header)) + output_bytes
133
287
 
134
- crc = zlib.crc32(output_bytes) % (1 << 32)
135
- footer = Footer(crc)
136
- output_bytes += struct.pack(FOOTER_FORMAT, *astuple(footer))
288
+ @dataclass
289
+ class IntegerSignedExtend8To64Directive(StackOpDirective):
290
+ opcode: ClassVar[DirectiveId] = DirectiveId.SIEXT_8_64
291
+ stack_output_type: ClassVar[type[BaseType]] = I64Type
137
292
 
138
- if output is None:
139
- output = input.with_suffix(".bin")
140
293
 
141
- output.write_bytes(output_bytes)
294
+ @dataclass
295
+ class IntegerSignedExtend16To64Directive(StackOpDirective):
296
+ opcode: ClassVar[DirectiveId] = DirectiveId.SIEXT_16_64
297
+ stack_output_type: ClassVar[type[BaseType]] = I64Type
142
298
 
143
299
 
144
300
  @dataclass
145
- class WaitRelDirective(Directive):
146
- opcode: ClassVar[DirectiveOpcode] = DirectiveOpcode.WAIT_REL
147
- seconds: int
148
- useconds: int
301
+ class IntegerSignedExtend32To64Directive(StackOpDirective):
302
+ opcode: ClassVar[DirectiveId] = DirectiveId.SIEXT_32_64
303
+ stack_output_type: ClassVar[type[BaseType]] = I64Type
149
304
 
150
- def serialize_args(self) -> bytes:
151
- return U32Type(self.seconds).serialize() + U32Type(self.useconds).serialize()
305
+
306
+ @dataclass
307
+ class IntegerZeroExtend8To64Directive(StackOpDirective):
308
+ opcode: ClassVar[DirectiveId] = DirectiveId.ZIEXT_8_64
309
+ stack_output_type: ClassVar[type[BaseType]] = U64Type
152
310
 
153
311
 
154
312
  @dataclass
155
- class WaitAbsDirective(Directive):
156
- opcode: ClassVar[DirectiveOpcode] = DirectiveOpcode.WAIT_ABS
157
- wakeup_time: TimeType
313
+ class IntegerZeroExtend16To64Directive(StackOpDirective):
314
+ opcode: ClassVar[DirectiveId] = DirectiveId.ZIEXT_16_64
315
+ stack_output_type: ClassVar[type[BaseType]] = U64Type
158
316
 
159
- def serialize_args(self) -> bytes:
160
- return self.wakeup_time.serialize()
317
+
318
+ @dataclass
319
+ class IntegerZeroExtend32To64Directive(StackOpDirective):
320
+ opcode: ClassVar[DirectiveId] = DirectiveId.ZIEXT_32_64
321
+ stack_output_type: ClassVar[type[BaseType]] = U64Type
161
322
 
162
323
 
163
324
  @dataclass
164
- class SetSerRegDirective(Directive):
165
- opcode: ClassVar[DirectiveOpcode] = DirectiveOpcode.SET_SER_REG
325
+ class IntegerTruncate64To8Directive(StackOpDirective):
326
+ opcode: ClassVar[DirectiveId] = DirectiveId.ITRUNC_64_8
327
+ stack_output_type: ClassVar[type[BaseType]] = I8Type
166
328
 
167
- index: int
168
- """U8: The index of the local variable to set."""
169
- value: bytes
170
- """[Fpy.MAX_SERIALIZABLE_REGISTER_SIZE] U8: The value of the local variable."""
171
329
 
172
- def serialize_args(self) -> bytes:
173
- data = bytearray()
174
- data.extend(U8Type(self.index).serialize())
175
- data.extend(self.value)
176
- return bytes(data)
330
+ @dataclass
331
+ class IntegerTruncate64To16Directive(StackOpDirective):
332
+ opcode: ClassVar[DirectiveId] = DirectiveId.ITRUNC_64_16
333
+ stack_output_type: ClassVar[type[BaseType]] = I16Type
177
334
 
178
335
 
179
336
  @dataclass
180
- class GotoDirective(Directive):
181
- opcode: ClassVar[DirectiveOpcode] = DirectiveOpcode.GOTO
182
- statement_index: int
183
- """U32: The statement index to execute next."""
337
+ class IntegerTruncate64To32Directive(StackOpDirective):
338
+ opcode: ClassVar[DirectiveId] = DirectiveId.ITRUNC_64_32
339
+ stack_output_type: ClassVar[type[BaseType]] = I32Type
184
340
 
185
- def serialize_args(self) -> bytes:
186
- return U32Type(self.statement_index).serialize()
341
+
342
+ @dataclass
343
+ class AllocateDirective(Directive):
344
+ opcode: ClassVar[DirectiveId] = DirectiveId.ALLOCATE
345
+
346
+ size: Union[int, U32Type]
187
347
 
188
348
 
189
349
  @dataclass
190
- class IfDirective(Directive):
191
- opcode: ClassVar[DirectiveOpcode] = DirectiveOpcode.IF
192
- conditional_reg: int
193
- """U8: The register to branch based off of (interpreted as a C++ boolean)."""
194
- false_goto_stmt_index: int
195
- """U32: The statement index to go to if the register is false."""
350
+ class StoreDirective(Directive):
351
+ opcode: ClassVar[DirectiveId] = DirectiveId.STORE
196
352
 
197
- def serialize_args(self) -> bytes:
198
- return (
199
- U8Type(self.conditional_reg).serialize()
200
- + U32Type(self.false_goto_stmt_index).serialize()
201
- )
353
+ lvar_offset: Union[int, U32Type]
354
+ size: Union[int, U32Type]
202
355
 
203
356
 
204
357
  @dataclass
205
- class NoOpDirective(Directive):
206
- opcode: ClassVar[DirectiveOpcode] = DirectiveOpcode.NO_OP
358
+ class DiscardDirective(Directive):
359
+ opcode: ClassVar[DirectiveId] = DirectiveId.DISCARD
207
360
 
208
- def serialize_args(self) -> bytes:
209
- return bytes()
361
+ size: Union[int, U32Type]
210
362
 
211
363
 
212
364
  @dataclass
213
- class GetTlmDirective(Directive):
214
- opcode: ClassVar[DirectiveOpcode] = DirectiveOpcode.GET_TLM
215
- value_dest_sreg: int
216
- """U8: The local variable to store the telemetry value in."""
217
- time_dest_sreg: int
218
- """U8: The local variable to store the telemetry time in."""
219
- chan_id: int
220
- """FwChanIdType: The telemetry channel ID to get."""
365
+ class PushValDirective(Directive):
366
+ opcode: ClassVar[DirectiveId] = DirectiveId.PUSH_VAL
221
367
 
222
- def serialize_args(self) -> bytes:
223
- data = bytearray()
224
- data.extend(U8Type(self.value_dest_sreg).serialize())
225
- data.extend(U8Type(self.time_dest_sreg).serialize())
226
- data.extend(FwChanIdType(self.chan_id).serialize())
227
- return bytes(data)
368
+ val: bytes
228
369
 
229
370
 
230
371
  @dataclass
231
- class GetPrmDirective(Directive):
232
- opcode: ClassVar[DirectiveOpcode] = DirectiveOpcode.GET_PRM
233
- dest_sreg_index: int
234
- """U8: The local variable to store the parameter value in."""
235
- prm_id: int
236
- """FwPrmIdType: The parameter ID to get the value of."""
372
+ class ConstCmdDirective(Directive):
373
+ opcode: ClassVar[DirectiveId] = DirectiveId.CONST_CMD
237
374
 
238
- def serialize_args(self) -> bytes:
239
- return (
240
- U8Type(self.dest_sreg_index).serialize()
241
- + FwPrmIdType(self.prm_id).serialize()
242
- )
375
+ cmd_opcode: Union[int, FwOpcodeType]
376
+ args: bytes
243
377
 
244
378
 
245
379
  @dataclass
246
- class CmdDirective(Directive):
247
- opcode: ClassVar[DirectiveOpcode] = DirectiveOpcode.CMD
248
- op_code: int
249
- """FwOpcodeType: The opcode of the command."""
250
- arg_buf: bytes
251
- """[Fpy.MAX_SERIALIZABLE_REGISTER_SIZE] U8: The argument buffer of the command."""
380
+ class FloatModuloDirective(StackOpDirective):
381
+ opcode: ClassVar[DirectiveId] = DirectiveId.FMOD
382
+ stack_output_type: ClassVar[type[BaseType]] = F64Type
252
383
 
253
- def serialize_args(self) -> bytes:
254
- data = bytearray()
255
- data.extend(FwOpcodeType(self.op_code).serialize())
256
- data.extend(self.arg_buf)
257
- return bytes(data)
384
+
385
+ @dataclass
386
+ class SignedModuloDirective(StackOpDirective):
387
+ opcode: ClassVar[DirectiveId] = DirectiveId.SMOD
388
+ stack_output_type: ClassVar[type[BaseType]] = I64Type
258
389
 
259
390
 
260
391
  @dataclass
261
- class _DeserSerRegDirective(Directive):
262
- """
263
- Deserializes up to 8 bytes from a local variable into a register.
264
- """
392
+ class UnsignedModuloDirective(StackOpDirective):
393
+ opcode: ClassVar[DirectiveId] = DirectiveId.UMOD
394
+ stack_output_type: ClassVar[type[BaseType]] = U64Type
265
395
 
266
- src_sreg_idx: int
267
- """U8: The local variable to deserialize from."""
268
- src_offset: int
269
- """FwSizeType: The starting offset to deserialize from."""
270
- dest_reg: int
271
- """U8: The destination register to deserialize into."""
272
396
 
273
- def serialize_args(self) -> bytes:
274
- data = bytearray()
275
- data.extend(U8Type(self.src_sreg_idx).serialize())
276
- data.extend(FwSizeType(self.src_offset).serialize())
277
- data.extend(U8Type(self.dest_reg).serialize())
278
- return bytes(data)
397
+ @dataclass
398
+ class IntAddDirective(StackOpDirective):
399
+ opcode: ClassVar[DirectiveId] = DirectiveId.IADD
400
+ stack_output_type: ClassVar[type[BaseType]] = I64Type
279
401
 
280
402
 
281
- class DeserSerReg8Directive(_DeserSerRegDirective):
282
- opcode: ClassVar[DirectiveOpcode] = DirectiveOpcode.DESER_SER_REG_8
403
+ @dataclass
404
+ class IntSubtractDirective(StackOpDirective):
405
+ opcode: ClassVar[DirectiveId] = DirectiveId.ISUB
406
+ stack_output_type: ClassVar[type[BaseType]] = I64Type
283
407
 
284
408
 
285
- class DeserSerReg4Directive(_DeserSerRegDirective):
286
- opcode: ClassVar[DirectiveOpcode] = DirectiveOpcode.DESER_SER_REG_4
409
+ @dataclass
410
+ class IntMultiplyDirective(StackOpDirective):
411
+ opcode: ClassVar[DirectiveId] = DirectiveId.IMUL
412
+ stack_output_type: ClassVar[type[BaseType]] = I64Type
287
413
 
288
414
 
289
- class DeserSerReg2Directive(_DeserSerRegDirective):
290
- opcode: ClassVar[DirectiveOpcode] = DirectiveOpcode.DESER_SER_REG_2
415
+ @dataclass
416
+ class UnsignedIntDivideDirective(StackOpDirective):
417
+ opcode: ClassVar[DirectiveId] = DirectiveId.UDIV
418
+ stack_output_type: ClassVar[type[BaseType]] = U64Type
291
419
 
292
420
 
293
- class DeserSerReg1Directive(_DeserSerRegDirective):
294
- opcode: ClassVar[DirectiveOpcode] = DirectiveOpcode.DESER_SER_REG_1
421
+ @dataclass
422
+ class SignedIntDivideDirective(StackOpDirective):
423
+ opcode: ClassVar[DirectiveId] = DirectiveId.SDIV
424
+ stack_output_type: ClassVar[type[BaseType]] = I64Type
295
425
 
296
426
 
297
427
  @dataclass
298
- class SetRegDirective(Directive):
299
- opcode: ClassVar[DirectiveOpcode] = DirectiveOpcode.SET_REG
428
+ class FloatAddDirective(StackOpDirective):
429
+ opcode: ClassVar[DirectiveId] = DirectiveId.FADD
430
+ stack_output_type: ClassVar[type[BaseType]] = F64Type
300
431
 
301
- dest: int
302
- """U8: The register to store the value in."""
303
- value: int
304
- """I64: The value to store in the register."""
305
432
 
306
- def serialize_args(self) -> bytes:
307
- return U8Type(self.dest).serialize() + I64Type(self.value).serialize()
433
+ @dataclass
434
+ class FloatSubtractDirective(StackOpDirective):
435
+ opcode: ClassVar[DirectiveId] = DirectiveId.FSUB
436
+ stack_output_type: ClassVar[type[BaseType]] = F64Type
308
437
 
309
438
 
310
439
  @dataclass
311
- class _BinaryRegOpDirective(Directive):
312
- lhs: int
313
- """U8: The left-hand side register for comparison."""
314
- rhs: int
315
- """U8: The right-hand side register for comparison."""
316
- res: int
317
- """U8: The destination register for the boolean result."""
440
+ class FloatMultiplyDirective(StackOpDirective):
441
+ opcode: ClassVar[DirectiveId] = DirectiveId.FMUL
442
+ stack_output_type: ClassVar[type[BaseType]] = F64Type
443
+
444
+
445
+ @dataclass
446
+ class FloatExponentDirective(StackOpDirective):
447
+ opcode: ClassVar[DirectiveId] = DirectiveId.FPOW
448
+ stack_output_type: ClassVar[type[BaseType]] = F64Type
449
+
450
+
451
+ @dataclass
452
+ class FloatDivideDirective(StackOpDirective):
453
+ opcode: ClassVar[DirectiveId] = DirectiveId.FDIV
454
+ stack_output_type: ClassVar[type[BaseType]] = F64Type
455
+
456
+
457
+ @dataclass
458
+ class FloatFloorDivideDirective(StackOpDirective):
459
+ opcode: ClassVar[DirectiveId] = DirectiveId.FLOAT_FLOOR_DIV
460
+ stack_output_type: ClassVar[type[BaseType]] = F64Type
461
+
462
+
463
+ @dataclass
464
+ class FloatLogDirective(StackOpDirective):
465
+ opcode: ClassVar[DirectiveId] = DirectiveId.FLOG
466
+ stack_output_type: ClassVar[type[BaseType]] = F64Type
318
467
 
319
- def serialize_args(self) -> bytes:
320
- data = bytearray()
321
- data.extend(U8Type(self.lhs).serialize())
322
- data.extend(U8Type(self.rhs).serialize())
323
- data.extend(U8Type(self.res).serialize())
324
- return bytes(data)
468
+
469
+ @dataclass
470
+ class WaitRelDirective(Directive):
471
+ opcode: ClassVar[DirectiveId] = DirectiveId.WAIT_REL
472
+ # seconds and useconds are implicit
473
+
474
+
475
+ @dataclass
476
+ class WaitAbsDirective(Directive):
477
+ opcode: ClassVar[DirectiveId] = DirectiveId.WAIT_ABS
478
+ # time base, time context, seconds and useconds are implicit
325
479
 
326
480
 
327
- class OrDirective(_BinaryRegOpDirective):
328
- opcode: ClassVar[DirectiveOpcode] = DirectiveOpcode.OR
481
+ @dataclass
482
+ class GotoDirective(Directive):
483
+ opcode: ClassVar[DirectiveId] = DirectiveId.GOTO
484
+ dir_idx: Union[int, U32Type]
329
485
 
330
486
 
331
- class AndDirective(_BinaryRegOpDirective):
332
- opcode: ClassVar[DirectiveOpcode] = DirectiveOpcode.AND
487
+ @dataclass
488
+ class IfDirective(Directive):
489
+ opcode: ClassVar[DirectiveId] = DirectiveId.IF
490
+ false_goto_dir_index: Union[int, U32Type]
491
+ """U32: The dir index to go to if the top of stack is false."""
333
492
 
334
493
 
335
- class IntEqualDirective(_BinaryRegOpDirective):
336
- opcode: ClassVar[DirectiveOpcode] = DirectiveOpcode.IEQ
494
+ @dataclass
495
+ class NoOpDirective(Directive):
496
+ opcode: ClassVar[DirectiveId] = DirectiveId.NO_OP
337
497
 
338
498
 
339
- class IntNotEqualDirective(_BinaryRegOpDirective):
340
- opcode: ClassVar[DirectiveOpcode] = DirectiveOpcode.INE
499
+ @dataclass
500
+ class StoreTlmValDirective(Directive):
501
+ opcode: ClassVar[DirectiveId] = DirectiveId.STORE_TLM_VAL
502
+ chan_id: Union[int, FwChanIdType]
503
+ """FwChanIdType: The telemetry channel ID to get."""
504
+ lvar_offset: Union[int, U32Type]
341
505
 
342
506
 
343
- class UnsignedLessThanDirective(_BinaryRegOpDirective):
344
- opcode: ClassVar[DirectiveOpcode] = DirectiveOpcode.ULT
507
+ @dataclass
508
+ class StorePrmDirective(Directive):
509
+ opcode: ClassVar[DirectiveId] = DirectiveId.STORE_PRM
510
+ prm_id: Union[int, FwPrmIdType]
511
+ """FwPrmIdType: The parameter ID to get the value of."""
512
+ lvar_offset: Union[int, U32Type]
345
513
 
346
514
 
347
- class UnsignedLessThanOrEqualDirective(_BinaryRegOpDirective):
348
- opcode: ClassVar[DirectiveOpcode] = DirectiveOpcode.ULE
515
+ @dataclass
516
+ class OrDirective(StackOpDirective):
517
+ opcode: ClassVar[DirectiveId] = DirectiveId.OR
518
+ stack_args: ClassVar[list[type[BaseType]]] = [BoolType, BoolType]
519
+ stack_output_type: ClassVar[type[BaseType]] = BoolType
349
520
 
350
521
 
351
- class UnsignedGreaterThanDirective(_BinaryRegOpDirective):
352
- opcode: ClassVar[DirectiveOpcode] = DirectiveOpcode.UGT
522
+ @dataclass
523
+ class AndDirective(StackOpDirective):
524
+ opcode: ClassVar[DirectiveId] = DirectiveId.AND
525
+ stack_args: ClassVar[list[type[BaseType]]] = [BoolType, BoolType]
526
+ stack_output_type: ClassVar[type[BaseType]] = BoolType
353
527
 
354
528
 
355
- class UnsignedGreaterThanOrEqualDirective(_BinaryRegOpDirective):
356
- opcode: ClassVar[DirectiveOpcode] = DirectiveOpcode.UGE
529
+ @dataclass
530
+ class IntEqualDirective(StackOpDirective):
531
+ opcode: ClassVar[DirectiveId] = DirectiveId.IEQ
532
+ stack_args: ClassVar[list[type[BaseType]]] = [
533
+ Union[I64Type, U64Type],
534
+ Union[I64Type, U64Type],
535
+ ]
536
+ stack_output_type: ClassVar[type[BaseType]] = BoolType
357
537
 
358
538
 
359
- class SignedLessThanDirective(_BinaryRegOpDirective):
360
- opcode: ClassVar[DirectiveOpcode] = DirectiveOpcode.SLT
539
+ @dataclass
540
+ class IntNotEqualDirective(StackOpDirective):
541
+ opcode: ClassVar[DirectiveId] = DirectiveId.INE
542
+ stack_args: ClassVar[list[type[BaseType]]] = [
543
+ Union[I64Type, U64Type],
544
+ Union[I64Type, U64Type],
545
+ ]
546
+ stack_output_type: ClassVar[type[BaseType]] = BoolType
361
547
 
362
548
 
363
- class SignedLessThanOrEqualDirective(_BinaryRegOpDirective):
364
- opcode: ClassVar[DirectiveOpcode] = DirectiveOpcode.SLE
549
+ @dataclass
550
+ class UnsignedLessThanDirective(StackOpDirective):
551
+ opcode: ClassVar[DirectiveId] = DirectiveId.ULT
552
+ stack_args: ClassVar[list[type[BaseType]]] = [U64Type, U64Type]
553
+ stack_output_type: ClassVar[type[BaseType]] = BoolType
365
554
 
366
555
 
367
- class SignedGreaterThanDirective(_BinaryRegOpDirective):
368
- opcode: ClassVar[DirectiveOpcode] = DirectiveOpcode.SGT
556
+ @dataclass
557
+ class UnsignedLessThanOrEqualDirective(StackOpDirective):
558
+ opcode: ClassVar[DirectiveId] = DirectiveId.ULE
559
+ stack_args: ClassVar[list[type[BaseType]]] = [U64Type, U64Type]
560
+ stack_output_type: ClassVar[type[BaseType]] = BoolType
369
561
 
370
562
 
371
- class SignedGreaterThanOrEqualDirective(_BinaryRegOpDirective):
372
- opcode: ClassVar[DirectiveOpcode] = DirectiveOpcode.SGE
563
+ @dataclass
564
+ class UnsignedGreaterThanDirective(StackOpDirective):
565
+ opcode: ClassVar[DirectiveId] = DirectiveId.UGT
566
+ stack_args: ClassVar[list[type[BaseType]]] = [U64Type, U64Type]
567
+ stack_output_type: ClassVar[type[BaseType]] = BoolType
373
568
 
374
569
 
375
- class FloatGreaterThanOrEqualDirective(_BinaryRegOpDirective):
376
- opcode: ClassVar[DirectiveOpcode] = DirectiveOpcode.FGE
570
+ @dataclass
571
+ class UnsignedGreaterThanOrEqualDirective(StackOpDirective):
572
+ opcode: ClassVar[DirectiveId] = DirectiveId.UGE
573
+ stack_args: ClassVar[list[type[BaseType]]] = [U64Type, U64Type]
574
+ stack_output_type: ClassVar[type[BaseType]] = BoolType
377
575
 
378
576
 
379
- class FloatLessThanOrEqualDirective(_BinaryRegOpDirective):
380
- opcode: ClassVar[DirectiveOpcode] = DirectiveOpcode.FLE
577
+ @dataclass
578
+ class SignedLessThanDirective(StackOpDirective):
579
+ opcode: ClassVar[DirectiveId] = DirectiveId.SLT
580
+ stack_args: ClassVar[list[type[BaseType]]] = [I64Type, I64Type]
581
+ stack_output_type: ClassVar[type[BaseType]] = BoolType
381
582
 
382
583
 
383
- class FloatLessThanDirective(_BinaryRegOpDirective):
384
- opcode: ClassVar[DirectiveOpcode] = DirectiveOpcode.FLT
584
+ @dataclass
585
+ class SignedLessThanOrEqualDirective(StackOpDirective):
586
+ opcode: ClassVar[DirectiveId] = DirectiveId.SLE
587
+ stack_args: ClassVar[list[type[BaseType]]] = [I64Type, I64Type]
588
+ stack_output_type: ClassVar[type[BaseType]] = BoolType
385
589
 
386
590
 
387
- class FloatGreaterThanDirective(_BinaryRegOpDirective):
388
- opcode: ClassVar[DirectiveOpcode] = DirectiveOpcode.FGT
591
+ @dataclass
592
+ class SignedGreaterThanDirective(StackOpDirective):
593
+ opcode: ClassVar[DirectiveId] = DirectiveId.SGT
594
+ stack_args: ClassVar[list[type[BaseType]]] = [I64Type, I64Type]
595
+ stack_output_type: ClassVar[type[BaseType]] = BoolType
389
596
 
390
597
 
391
- class FloatEqualDirective(_BinaryRegOpDirective):
392
- opcode: ClassVar[DirectiveOpcode] = DirectiveOpcode.FEQ
598
+ @dataclass
599
+ class SignedGreaterThanOrEqualDirective(StackOpDirective):
600
+ opcode: ClassVar[DirectiveId] = DirectiveId.SGE
601
+ stack_args: ClassVar[list[type[BaseType]]] = [I64Type, I64Type]
602
+ stack_output_type: ClassVar[type[BaseType]] = BoolType
393
603
 
394
604
 
395
- class FloatNotEqualDirective(_BinaryRegOpDirective):
396
- opcode: ClassVar[DirectiveOpcode] = DirectiveOpcode.FNE
605
+ @dataclass
606
+ class FloatGreaterThanOrEqualDirective(StackOpDirective):
607
+ opcode: ClassVar[DirectiveId] = DirectiveId.FGE
608
+ stack_args: ClassVar[list[type[BaseType]]] = [F64Type, F64Type]
609
+ stack_output_type: ClassVar[type[BaseType]] = BoolType
397
610
 
398
611
 
399
612
  @dataclass
400
- class _UnaryRegOpDirective(Directive):
401
- src: int
402
- res: int
613
+ class FloatLessThanOrEqualDirective(StackOpDirective):
614
+ opcode: ClassVar[DirectiveId] = DirectiveId.FLE
615
+ stack_args: ClassVar[list[type[BaseType]]] = [F64Type, F64Type]
616
+ stack_output_type: ClassVar[type[BaseType]] = BoolType
403
617
 
404
- def serialize_args(self) -> bytes:
405
- data = bytearray()
406
- data.extend(U8Type(self.src).serialize())
407
- data.extend(U8Type(self.res).serialize())
408
- return bytes(data)
618
+
619
+ @dataclass
620
+ class FloatLessThanDirective(StackOpDirective):
621
+ opcode: ClassVar[DirectiveId] = DirectiveId.FLT
622
+ stack_args: ClassVar[list[type[BaseType]]] = [F64Type, F64Type]
623
+ stack_output_type: ClassVar[type[BaseType]] = BoolType
409
624
 
410
625
 
411
626
  @dataclass
412
- class NotDirective(_UnaryRegOpDirective):
413
- opcode: ClassVar[DirectiveOpcode] = DirectiveOpcode.NOT
627
+ class FloatGreaterThanDirective(StackOpDirective):
628
+ opcode: ClassVar[DirectiveId] = DirectiveId.FGT
629
+ stack_output_type: ClassVar[type[BaseType]] = BoolType
414
630
 
415
631
 
416
632
  @dataclass
417
- class FloatTruncateDirective(_UnaryRegOpDirective):
418
- opcode: ClassVar[DirectiveOpcode] = DirectiveOpcode.FPTRUNC
633
+ class FloatEqualDirective(StackOpDirective):
634
+ opcode: ClassVar[DirectiveId] = DirectiveId.FEQ
635
+ stack_output_type: ClassVar[type[BaseType]] = BoolType
419
636
 
420
637
 
421
638
  @dataclass
422
- class FloatExtendDirective(_UnaryRegOpDirective):
423
- opcode: ClassVar[DirectiveOpcode] = DirectiveOpcode.FPEXT
639
+ class FloatNotEqualDirective(StackOpDirective):
640
+ opcode: ClassVar[DirectiveId] = DirectiveId.FNE
641
+ stack_output_type: ClassVar[type[BaseType]] = BoolType
424
642
 
425
643
 
426
644
  @dataclass
427
- class FloatToSignedIntDirective(_UnaryRegOpDirective):
428
- opcode: ClassVar[DirectiveOpcode] = DirectiveOpcode.FPTOSI
645
+ class NotDirective(StackOpDirective):
646
+ opcode: ClassVar[DirectiveId] = DirectiveId.NOT
647
+ stack_output_type: ClassVar[type[BaseType]] = BoolType
429
648
 
430
649
 
431
650
  @dataclass
432
- class SignedIntToFloatDirective(_UnaryRegOpDirective):
433
- opcode: ClassVar[DirectiveOpcode] = DirectiveOpcode.SITOFP
651
+ class FloatTruncateDirective(StackOpDirective):
652
+ opcode: ClassVar[DirectiveId] = DirectiveId.FPTRUNC
653
+ stack_output_type: ClassVar[type[BaseType]] = F32Type
434
654
 
435
655
 
436
656
  @dataclass
437
- class FloatToUnsignedIntDirective(_UnaryRegOpDirective):
438
- opcode: ClassVar[DirectiveOpcode] = DirectiveOpcode.FPTOUI
657
+ class FloatExtendDirective(StackOpDirective):
658
+ opcode: ClassVar[DirectiveId] = DirectiveId.FPEXT
659
+ stack_output_type: ClassVar[type[BaseType]] = F64Type
439
660
 
440
661
 
441
662
  @dataclass
442
- class UnsignedIntToFloatDirective(_UnaryRegOpDirective):
443
- opcode: ClassVar[DirectiveOpcode] = DirectiveOpcode.UITOFP
663
+ class FloatToSignedIntDirective(StackOpDirective):
664
+ opcode: ClassVar[DirectiveId] = DirectiveId.FPTOSI
665
+ stack_output_type: ClassVar[type[BaseType]] = I64Type
444
666
 
445
667
 
446
668
  @dataclass
447
- class ExitDirective(Directive):
448
- opcode: ClassVar[DirectiveOpcode] = DirectiveOpcode.EXIT
449
- success: bool
669
+ class SignedIntToFloatDirective(StackOpDirective):
670
+ opcode: ClassVar[DirectiveId] = DirectiveId.SITOFP
671
+ stack_output_type: ClassVar[type[BaseType]] = F64Type
450
672
 
451
- def serialize_args(self):
452
- return BoolType(self.success).serialize()
453
673
 
674
+ @dataclass
675
+ class FloatToUnsignedIntDirective(StackOpDirective):
676
+ opcode: ClassVar[DirectiveId] = DirectiveId.FPTOUI
677
+ stack_output_type: ClassVar[type[BaseType]] = U64Type
454
678
 
455
- INT_EQUALITY_DIRECTIVES: dict[str, type[_BinaryRegOpDirective]] = {
456
- "==": IntEqualDirective,
457
- "!=": IntNotEqualDirective,
458
- }
459
679
 
460
- FLOAT_EQUALITY_DIRECTIVES: dict[str, type[_BinaryRegOpDirective]] = {
461
- "==": FloatEqualDirective,
462
- "!=": FloatNotEqualDirective,
463
- }
680
+ @dataclass
681
+ class UnsignedIntToFloatDirective(StackOpDirective):
682
+ opcode: ClassVar[DirectiveId] = DirectiveId.UITOFP
683
+ stack_output_type: ClassVar[type[BaseType]] = F64Type
684
+ # src implied
464
685
 
465
686
 
466
- INT_SIGNED_INEQUALITY_DIRECTIVES: dict[str, type[_BinaryRegOpDirective]] = {
467
- ">": SignedGreaterThanDirective,
468
- "<": SignedLessThanDirective,
469
- ">=": SignedGreaterThanOrEqualDirective,
470
- "<=": SignedLessThanOrEqualDirective,
471
- }
472
- INT_UNSIGNED_INEQUALITY_DIRECTIVES: dict[str, type[_BinaryRegOpDirective]] = {
473
- ">": UnsignedGreaterThanDirective,
474
- "<": UnsignedLessThanDirective,
475
- ">=": UnsignedGreaterThanOrEqualDirective,
476
- "<=": UnsignedLessThanOrEqualDirective,
687
+ @dataclass
688
+ class ExitDirective(Directive):
689
+ opcode: ClassVar[DirectiveId] = DirectiveId.EXIT
690
+
691
+
692
+ for cls in Directive.__subclasses__():
693
+ cls.__old_repr__ = cls.__repr__
694
+ cls.__repr__ = Directive.__repr__
695
+
696
+ for cls in StackOpDirective.__subclasses__():
697
+ cls.__old_repr__ = cls.__repr__
698
+ cls.__repr__ = Directive.__repr__
699
+
700
+
701
+ class UnaryStackOp(str, Enum):
702
+ NOT = "not"
703
+ IDENTITY = "+"
704
+ NEGATE = "-"
705
+
706
+
707
+ class BinaryStackOp(str, Enum):
708
+ EXPONENT = "**"
709
+ MODULUS = "%"
710
+ ADD = "+"
711
+ SUBTRACT = "-"
712
+ MULTIPLY = "*"
713
+ DIVIDE = "/"
714
+ FLOOR_DIVIDE = "//"
715
+ GREATER_THAN = ">"
716
+ GREATER_THAN_OR_EQUAL = ">="
717
+ LESS_THAN_OR_EQUAL = "<="
718
+ LESS_THAN = "<"
719
+ EQUAL = "=="
720
+ NOT_EQUAL = "!="
721
+ OR = "or"
722
+ AND = "and"
723
+
724
+
725
+ NUMERIC_OPERATORS = {
726
+ UnaryStackOp.IDENTITY,
727
+ UnaryStackOp.NEGATE,
728
+ BinaryStackOp.ADD,
729
+ BinaryStackOp.SUBTRACT,
730
+ BinaryStackOp.MULTIPLY,
731
+ BinaryStackOp.DIVIDE,
732
+ BinaryStackOp.MODULUS,
733
+ BinaryStackOp.EXPONENT,
734
+ BinaryStackOp.FLOOR_DIVIDE,
477
735
  }
478
- FLOAT_INEQUALITY_DIRECTIVES: dict[str, type[_BinaryRegOpDirective]] = {
479
- ">": FloatGreaterThanDirective,
480
- "<": FloatLessThanDirective,
481
- ">=": FloatGreaterThanOrEqualDirective,
482
- "<=": FloatLessThanOrEqualDirective,
736
+ BOOLEAN_OPERATORS = {UnaryStackOp.NOT, BinaryStackOp.OR, BinaryStackOp.AND}
737
+
738
+ UNARY_STACK_OPS: dict[str, dict[type[BaseType], type[StackOpDirective]]] = {
739
+ UnaryStackOp.NOT: {BoolType: NotDirective},
740
+ UnaryStackOp.IDENTITY: {
741
+ I64Type: NoOpDirective,
742
+ U64Type: NoOpDirective,
743
+ F64Type: NoOpDirective,
744
+ },
745
+ UnaryStackOp.NEGATE: {
746
+ I64Type: IntMultiplyDirective,
747
+ U64Type: IntMultiplyDirective,
748
+ F64Type: FloatMultiplyDirective
749
+ },
483
750
  }
484
751
 
485
- BINARY_COMPARISON_DIRECTIVES = {}
486
- BINARY_COMPARISON_DIRECTIVES.update(INT_EQUALITY_DIRECTIVES)
487
- BINARY_COMPARISON_DIRECTIVES.update(INT_SIGNED_INEQUALITY_DIRECTIVES)
488
- BINARY_COMPARISON_DIRECTIVES.update(INT_UNSIGNED_INEQUALITY_DIRECTIVES)
489
- BINARY_COMPARISON_DIRECTIVES.update(FLOAT_EQUALITY_DIRECTIVES)
490
- BINARY_COMPARISON_DIRECTIVES.update(FLOAT_INEQUALITY_DIRECTIVES)
752
+ BINARY_STACK_OPS: dict[str, dict[type[BaseType], type[StackOpDirective]]] = {
753
+ BinaryStackOp.EXPONENT: {F64Type: FloatExponentDirective},
754
+ BinaryStackOp.MODULUS: {
755
+ I64Type: SignedModuloDirective,
756
+ U64Type: UnsignedModuloDirective,
757
+ F64Type: FloatModuloDirective,
758
+ },
759
+ BinaryStackOp.ADD: {
760
+ I64Type: IntAddDirective,
761
+ U64Type: IntAddDirective,
762
+ F64Type: FloatAddDirective,
763
+ },
764
+ BinaryStackOp.SUBTRACT: {
765
+ I64Type: IntSubtractDirective,
766
+ U64Type: IntSubtractDirective,
767
+ F64Type: FloatSubtractDirective,
768
+ },
769
+ BinaryStackOp.MULTIPLY: {
770
+ I64Type: IntMultiplyDirective,
771
+ U64Type: IntMultiplyDirective,
772
+ F64Type: FloatMultiplyDirective,
773
+ },
774
+ BinaryStackOp.DIVIDE: {
775
+ I64Type: SignedIntDivideDirective,
776
+ U64Type: UnsignedIntDivideDirective,
777
+ F64Type: FloatDivideDirective,
778
+ },
779
+ BinaryStackOp.FLOOR_DIVIDE: {
780
+ I64Type: SignedIntDivideDirective,
781
+ U64Type: UnsignedIntDivideDirective,
782
+ F64Type: FloatFloorDivideDirective,
783
+ },
784
+ BinaryStackOp.GREATER_THAN: {
785
+ I64Type: SignedGreaterThanDirective,
786
+ U64Type: UnsignedGreaterThanDirective,
787
+ F64Type: FloatGreaterThanDirective,
788
+ },
789
+ BinaryStackOp.GREATER_THAN_OR_EQUAL: {
790
+ I64Type: SignedGreaterThanOrEqualDirective,
791
+ U64Type: UnsignedGreaterThanOrEqualDirective,
792
+ F64Type: FloatGreaterThanOrEqualDirective,
793
+ },
794
+ BinaryStackOp.LESS_THAN_OR_EQUAL: {
795
+ I64Type: SignedLessThanOrEqualDirective,
796
+ U64Type: UnsignedLessThanOrEqualDirective,
797
+ F64Type: FloatLessThanOrEqualDirective,
798
+ },
799
+ BinaryStackOp.LESS_THAN: {
800
+ I64Type: SignedLessThanDirective,
801
+ U64Type: UnsignedLessThanDirective,
802
+ F64Type: FloatLessThanDirective,
803
+ },
804
+ BinaryStackOp.EQUAL: {
805
+ I64Type: IntEqualDirective,
806
+ U64Type: IntEqualDirective,
807
+ F64Type: FloatEqualDirective,
808
+ },
809
+ BinaryStackOp.NOT_EQUAL: {
810
+ I64Type: IntNotEqualDirective,
811
+ U64Type: IntNotEqualDirective,
812
+ F64Type: FloatNotEqualDirective,
813
+ },
814
+ BinaryStackOp.OR: {BoolType: OrDirective},
815
+ BinaryStackOp.AND: {BoolType: AndDirective},
816
+ }