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
@@ -71,7 +71,7 @@ class AstBoolean(Ast):
71
71
  value: TypingLiteral[True] | TypingLiteral[False]
72
72
 
73
73
 
74
- AstLiteral = AstString | AstNumber | AstBoolean
74
+ AstLiteral = Union[AstString, AstNumber, AstBoolean]
75
75
 
76
76
 
77
77
  @dataclass
@@ -92,43 +92,29 @@ class AstFuncCall(Ast):
92
92
  args: list["AstExpr"] | None
93
93
 
94
94
 
95
- @dataclass
96
- class AstInfixOp(Ast):
97
- value: str
98
-
99
-
100
95
  @dataclass()
101
96
  class AstPass(Ast):
102
97
  pass
103
98
 
104
-
105
- @dataclass
106
- class AstComparison(Ast):
107
- lhs: "AstExpr"
108
- op: AstInfixOp
109
- rhs: "AstExpr"
110
-
111
-
112
99
  @dataclass
113
- class AstNot(Ast):
114
- value: "AstExpr"
100
+ class AstBinaryOp(Ast):
101
+ lhs: AstExpr
102
+ op: str
103
+ rhs: AstExpr
115
104
 
116
105
 
117
106
  @dataclass
118
- class AstAnd(Ast):
119
- values: list["AstExpr"]
107
+ class AstUnaryOp(Ast):
108
+ op: str
109
+ val: AstExpr
120
110
 
121
111
 
122
- @dataclass
123
- class AstOr(Ast):
124
- values: list["AstExpr"]
125
-
126
-
127
- AstTest = AstOr | AstAnd | AstNot | AstComparison
128
-
112
+ AstOp = Union[AstBinaryOp, AstUnaryOp]
129
113
 
130
- AstReference = AstGetAttr | AstGetItem | AstVar
131
- AstExpr = Union[AstFuncCall, AstTest, AstLiteral, AstReference]
114
+ AstReference = Union[AstGetAttr, AstGetItem, AstVar]
115
+ AstExpr = Union[
116
+ AstFuncCall, AstLiteral, AstReference, AstOp
117
+ ]
132
118
 
133
119
 
134
120
  @dataclass
@@ -165,9 +151,14 @@ class AstBody(Ast):
165
151
  stmts: list[AstStmt]
166
152
 
167
153
 
154
+ @dataclass
155
+ class AstScopedBody(Ast):
156
+ stmts: list[AstStmt]
157
+
158
+
168
159
  for cls in Ast.__subclasses__():
169
160
  cls.__hash__ = Ast.__hash__
170
- # cls.__repr__ = Ast.__repr__
161
+ cls.__repr__ = Ast.__repr__
171
162
 
172
163
 
173
164
  @v_args(meta=False, inline=False)
@@ -204,7 +195,7 @@ def handle_str(meta, s: str):
204
195
 
205
196
  @v_args(meta=True, inline=True)
206
197
  class FpyTransformer(Transformer):
207
- input = no_inline(AstBody)
198
+ input = no_inline(AstScopedBody)
208
199
  pass_stmt = AstPass
209
200
 
210
201
  assign = AstAssign
@@ -213,11 +204,8 @@ class FpyTransformer(Transformer):
213
204
  elifs = no_inline(AstElifs)
214
205
  elif_ = AstElif
215
206
  body = no_inline(AstBody)
216
- or_test = no_inline(AstOr)
217
- and_test = no_inline(AstAnd)
218
- not_test = AstNot
219
- comparison = AstComparison
220
- comp_op = AstInfixOp
207
+ binary_op = AstBinaryOp
208
+ unary_op = AstUnaryOp
221
209
 
222
210
  func_call = AstFuncCall
223
211
  arguments = no_inline_or_meta(list)
@@ -237,3 +225,10 @@ class FpyTransformer(Transformer):
237
225
  STRING = handle_str
238
226
  CONST_TRUE = lambda a, b: True
239
227
  CONST_FALSE = lambda a, b: False
228
+ ADD_OP: str
229
+ SUB_OP: str
230
+ DIV_OP: str
231
+ MUL_OP: str
232
+ FLOOR_DIV_OP: str
233
+ MOD_OP: str
234
+ POW_OP: str
@@ -0,0 +1,119 @@
1
+ import ast
2
+ from pathlib import Path
3
+ import tempfile
4
+ import traceback
5
+ from fprime.common.models.serialize.type_base import BaseType
6
+ from fprime.common.models.serialize.numerical_types import U32Type, U8Type
7
+ from fprime_gds.common.fpy.bytecode.assembler import deserialize_directives
8
+ from fprime_gds.common.fpy.model import DirectiveErrorCode, FpySequencerModel
9
+ from fprime_gds.common.fpy.bytecode.directives import Directive
10
+ from fprime_gds.common.fpy.codegen import compile, serialize_directives
11
+ from fprime_gds.common.fpy.parser import parse
12
+ from fprime_gds.common.loaders.ch_json_loader import ChJsonLoader
13
+ from fprime_gds.common.loaders.cmd_json_loader import CmdJsonLoader
14
+ from fprime_gds.common.loaders.event_json_loader import EventJsonLoader
15
+ from fprime_gds.common.loaders.prm_json_loader import PrmJsonLoader
16
+ from fprime_gds.common.testing_fw.api import IntegrationTestAPI
17
+
18
+ default_dictionary = str(
19
+ Path(__file__).parent.parent.parent.parent.parent
20
+ / "test"
21
+ / "fprime_gds"
22
+ / "common"
23
+ / "fpy"
24
+ / "RefTopologyDictionary.json"
25
+ )
26
+
27
+
28
+ def compile_seq(fprime_test_api, seq: str) -> list[Directive]:
29
+ return compile(parse(seq), default_dictionary) #fprime_test_api.pipeline.dictionary_path)
30
+
31
+
32
+ def lookup_type(fprime_test_api, type_name: str):
33
+ dictionary = default_dictionary #fprime_test_api.pipeline.dictionary_path
34
+ cmd_json_dict_loader = CmdJsonLoader(dictionary)
35
+ (cmd_id_dict, cmd_name_dict, versions) = cmd_json_dict_loader.construct_dicts(
36
+ dictionary
37
+ )
38
+
39
+ ch_json_dict_loader = ChJsonLoader(dictionary)
40
+ (ch_id_dict, ch_name_dict, versions) = ch_json_dict_loader.construct_dicts(
41
+ dictionary
42
+ )
43
+ prm_json_dict_loader = PrmJsonLoader(dictionary)
44
+ (prm_id_dict, prm_name_dict, versions) = prm_json_dict_loader.construct_dicts(
45
+ dictionary
46
+ )
47
+ event_json_dict_loader = EventJsonLoader(dictionary)
48
+ (event_id_dict, event_name_dict, versions) = event_json_dict_loader.construct_dicts(
49
+ dictionary
50
+ )
51
+ type_name_dict = cmd_json_dict_loader.parsed_types
52
+ type_name_dict.update(ch_json_dict_loader.parsed_types)
53
+ type_name_dict.update(prm_json_dict_loader.parsed_types)
54
+ type_name_dict.update(event_json_dict_loader.parsed_types)
55
+
56
+ return type_name_dict[type_name]
57
+
58
+
59
+ def run_seq(
60
+ fprime_test_api: IntegrationTestAPI,
61
+ dirs: list[Directive],
62
+ tlm: dict[str, bytes] = None,
63
+ ):
64
+ for idx, d in enumerate(dirs):
65
+ print(idx, d)
66
+ if tlm is None:
67
+ tlm = {}
68
+ file = tempfile.NamedTemporaryFile(suffix=".bin", delete=False)
69
+
70
+ serialize_directives(dirs, Path(file.name))
71
+
72
+ # fprime_test_api.send_and_assert_command("Ref.cmdSeq.RUN", [file.name, "BLOCK"], timeout=4)
73
+ # return
74
+
75
+ dictionary = default_dictionary # fprime_test_api.pipeline.dictionary_path
76
+
77
+ deserialized_dirs = deserialize_directives(Path(file.name).read_bytes())
78
+
79
+ model = FpySequencerModel()
80
+ ch_json_dict_loader = ChJsonLoader(dictionary)
81
+ (ch_id_dict, ch_name_dict, versions) = ch_json_dict_loader.construct_dicts(
82
+ dictionary
83
+ )
84
+ tlm_db = {}
85
+ for chan_name, val in tlm.items():
86
+ ch_template = ch_name_dict[chan_name]
87
+ tlm_db[ch_template.get_id()] = val
88
+ ret = model.run(deserialized_dirs, tlm_db)
89
+ if ret != DirectiveErrorCode.NO_ERROR:
90
+ raise RuntimeError("Sequence returned", ret)
91
+
92
+
93
+ def assert_compile_success(fprime_test_api, seq: str):
94
+ compile_seq(fprime_test_api, seq)
95
+
96
+
97
+ def assert_run_success(fprime_test_api, seq: str, tlm: dict[str, bytes] = None):
98
+ seq = compile_seq(fprime_test_api, seq)
99
+
100
+ run_seq(fprime_test_api, seq, tlm)
101
+
102
+
103
+ def assert_compile_failure(fprime_test_api, seq: str):
104
+ try:
105
+ compile_seq(fprime_test_api, seq)
106
+ except BaseException as e:
107
+ traceback.print_exc()
108
+ return
109
+ raise RuntimeError("compile_seq succeeded")
110
+
111
+
112
+ def assert_run_failure(fprime_test_api, seq: str):
113
+ directives = compile_seq(fprime_test_api, seq)
114
+ try:
115
+ run_seq(fprime_test_api, directives)
116
+ except BaseException as e:
117
+ print(e)
118
+ return
119
+ raise RuntimeError("run_seq succeeded")