fprime-gds 4.0.0a7__py3-none-any.whl → 4.0.0a9__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.
@@ -0,0 +1,88 @@
1
+ # Adapted from: https://docs.python.org/3/reference/grammar.html and the Lark Python grammar
2
+
3
+ input: (_NEWLINE | _stmt)*
4
+
5
+ _literal: number | string | boolean
6
+
7
+ _stmt: _small_stmt [_NEWLINE] | _compound_stmt
8
+ _small_stmt: (_expr_stmt | assign | pass_stmt )
9
+ _compound_stmt: if_stmt
10
+ pass_stmt: "pass"
11
+
12
+ _expr_stmt: _expr
13
+
14
+
15
+ # assignment
16
+
17
+ # can currently only assign constant values to vars
18
+ # for some reason if i use _reference here i don't get a None in the optional spot
19
+ assign: var [":" (get_attr | get_item | var)] "=" _expr
20
+
21
+
22
+
23
+ # branching
24
+
25
+ if_stmt: "if" _expr ":" body elifs ["else" ":" body]
26
+ elifs: elif_*
27
+ elif_: "elif" _expr ":" body
28
+ body: _NEWLINE _INDENT _stmt+ _DEDENT
29
+
30
+ _expr: _test
31
+
32
+ # logical tests
33
+ _test: or_test
34
+ ?or_test: and_test ("or" and_test)*
35
+ ?and_test: not_test_ ("and" not_test_)*
36
+ ?not_test_: "not" not_test_ -> not_test
37
+ | comparison
38
+ | atom
39
+ comparison: atom comp_op atom
40
+ comp_op: COMPARISON_OP
41
+
42
+ arguments: _expr ("," _expr)*
43
+
44
+ ?atom: _reference "(" [arguments] ")" -> func_call
45
+ | _reference
46
+ | _literal
47
+ | "(" _expr ")"
48
+
49
+ get_item: _reference "[" number "]"
50
+ get_attr: _reference "." name
51
+ var: name
52
+
53
+ _reference: get_item | get_attr | var
54
+
55
+ # not used in grammar, but may appear in "node" passed from Parser to Compiler
56
+ encoding_decl: name
57
+
58
+ number: DEC_NUMBER | FLOAT_NUMBER
59
+ string: STRING
60
+ boolean: CONST_FALSE | CONST_TRUE
61
+
62
+ # Other terminals
63
+
64
+ _NEWLINE: ( /\r?\n[\t ]*/ | COMMENT )+
65
+
66
+ %ignore /[\t \f]+/ // WS
67
+ %ignore /\\[\t \f]*\r?\n/ // LINE_CONT
68
+ %ignore COMMENT
69
+ %declare _INDENT _DEDENT
70
+
71
+
72
+ # Python terminals
73
+
74
+ !name: NAME
75
+ NAME: /[^\W\d]\w*/
76
+ COMMENT: /#[^\n]*/
77
+ CONST_TRUE: "True"
78
+ CONST_FALSE: "False"
79
+ COMPARISON_OP: ">" | "<" | "<=" | ">=" | "==" | "!="
80
+
81
+ STRING: /("(?!"").*?(?<!\\)(\\\\)*?"|'(?!'').*?(?<!\\)(\\\\)*?')/i
82
+
83
+ _SPECIAL_DEC: "0".."9" ("_"? "0".."9" )*
84
+ DEC_NUMBER: "-"? "1".."9" ("_"? "0".."9" )*
85
+ | "-"? "0" ("_"? "0" )* /(?![1-9])/
86
+
87
+ DECIMAL: "." _SPECIAL_DEC | _SPECIAL_DEC "." _SPECIAL_DEC?
88
+ FLOAT_NUMBER.2: "-"? _SPECIAL_DEC DECIMAL ["e" ["-"] _SPECIAL_DEC]
@@ -0,0 +1,40 @@
1
+ import argparse
2
+ from pathlib import Path
3
+
4
+ from fprime_gds.common.fpy.parser import parse
5
+ from fprime_gds.common.fpy.codegen import compile
6
+ from fprime_gds.common.fpy.bytecode.directives import serialize_directives
7
+
8
+
9
+ def main():
10
+ arg_parser = argparse.ArgumentParser()
11
+ arg_parser.add_argument("input", type=Path, help="The input .fpy file")
12
+ arg_parser.add_argument(
13
+ "-o",
14
+ "--output",
15
+ type=Path,
16
+ required=False,
17
+ default=None,
18
+ help="The output .bin path",
19
+ )
20
+ arg_parser.add_argument(
21
+ "-d",
22
+ "--dictionary",
23
+ type=Path,
24
+ required=True,
25
+ help="The FPrime dictionary .json file",
26
+ )
27
+
28
+ args = arg_parser.parse_args()
29
+
30
+ if not args.input.exists():
31
+ print(f"Input file {args.input} does not exist")
32
+ exit(-1)
33
+
34
+ body = parse(args.input.read_text())
35
+ directives = compile(body, args.dictionary)
36
+ output = args.output
37
+ if output is None:
38
+ output = args.input.with_suffix(".bin")
39
+ serialize_directives(directives, output)
40
+ print("Done")
@@ -0,0 +1,239 @@
1
+ from __future__ import annotations
2
+ from dataclasses import dataclass, field
3
+ from pathlib import Path
4
+ from typing import Literal as TypingLiteral, Union
5
+ from lark.indenter import PythonIndenter
6
+ from lark import Lark, Transformer, v_args
7
+ from lark.tree import Meta
8
+
9
+ fpy_grammar_str = (Path(__file__).parent / "grammar.lark").read_text()
10
+
11
+ input_text = None
12
+
13
+
14
+ def parse(text: str):
15
+ parser = Lark(
16
+ fpy_grammar_str,
17
+ start="input",
18
+ parser="lalr",
19
+ postlex=PythonIndenter(),
20
+ propagate_positions=True,
21
+ maybe_placeholders=True,
22
+ )
23
+
24
+ global input_text
25
+ input_text = text
26
+ tree = parser.parse(text, on_error=lambda x: print("Error"))
27
+ transformed = FpyTransformer().transform(tree)
28
+ return transformed
29
+
30
+
31
+ @dataclass
32
+ class Ast:
33
+ meta: Meta = field(repr=False)
34
+ id: int = field(init=False, repr=False, default=None)
35
+ node_text: str = field(init=False, repr=False, default=None)
36
+
37
+ def __post_init__(self):
38
+ if not hasattr(self.meta, "start_pos"):
39
+ self.node_text = ""
40
+ return
41
+ self.node_text = (
42
+ input_text[self.meta.start_pos : self.meta.end_pos]
43
+ .replace("\n", " ")
44
+ .strip()
45
+ )
46
+
47
+ def __hash__(self):
48
+ return hash(self.id)
49
+
50
+ def __repr__(self):
51
+ return f"{self.__class__.__name__}({self.node_text})"
52
+
53
+
54
+ @dataclass
55
+ class AstVar(Ast):
56
+ var: str
57
+
58
+
59
+ @dataclass()
60
+ class AstString(Ast):
61
+ value: str
62
+
63
+
64
+ @dataclass
65
+ class AstNumber(Ast):
66
+ value: int | float
67
+
68
+
69
+ @dataclass
70
+ class AstBoolean(Ast):
71
+ value: TypingLiteral[True] | TypingLiteral[False]
72
+
73
+
74
+ AstLiteral = AstString | AstNumber | AstBoolean
75
+
76
+
77
+ @dataclass
78
+ class AstGetAttr(Ast):
79
+ parent: "AstReference"
80
+ attr: str
81
+
82
+
83
+ @dataclass
84
+ class AstGetItem(Ast):
85
+ parent: "AstReference"
86
+ item: AstNumber
87
+
88
+
89
+ @dataclass
90
+ class AstFuncCall(Ast):
91
+ func: "AstReference"
92
+ args: list["AstExpr"] | None
93
+
94
+
95
+ @dataclass
96
+ class AstInfixOp(Ast):
97
+ value: str
98
+
99
+
100
+ @dataclass()
101
+ class AstPass(Ast):
102
+ pass
103
+
104
+
105
+ @dataclass
106
+ class AstComparison(Ast):
107
+ lhs: "AstExpr"
108
+ op: AstInfixOp
109
+ rhs: "AstExpr"
110
+
111
+
112
+ @dataclass
113
+ class AstNot(Ast):
114
+ value: "AstExpr"
115
+
116
+
117
+ @dataclass
118
+ class AstAnd(Ast):
119
+ values: list["AstExpr"]
120
+
121
+
122
+ @dataclass
123
+ class AstOr(Ast):
124
+ values: list["AstExpr"]
125
+
126
+
127
+ AstTest = AstOr | AstAnd | AstNot | AstComparison
128
+
129
+
130
+ AstReference = AstGetAttr | AstGetItem | AstVar
131
+ AstExpr = Union[AstFuncCall, AstTest, AstLiteral, AstReference]
132
+
133
+
134
+ @dataclass
135
+ class AstAssign(Ast):
136
+ variable: AstVar
137
+ var_type: AstReference | None
138
+ value: AstExpr
139
+
140
+
141
+ @dataclass
142
+ class AstElif(Ast):
143
+ condition: AstExpr
144
+ body: "AstBody"
145
+
146
+
147
+ @dataclass
148
+ class AstElifs(Ast):
149
+ cases: list[AstElif]
150
+
151
+
152
+ @dataclass()
153
+ class AstIf(Ast):
154
+ condition: AstExpr
155
+ body: "AstBody"
156
+ elifs: AstElifs | None
157
+ els: Union["AstBody", None]
158
+
159
+
160
+ AstStmt = Union[AstExpr, AstAssign, AstPass, AstIf]
161
+
162
+
163
+ @dataclass
164
+ class AstBody(Ast):
165
+ stmts: list[AstStmt]
166
+
167
+
168
+ for cls in Ast.__subclasses__():
169
+ cls.__hash__ = Ast.__hash__
170
+ # cls.__repr__ = Ast.__repr__
171
+
172
+
173
+ @v_args(meta=False, inline=False)
174
+ def as_list(self, tree):
175
+ return list(tree)
176
+
177
+
178
+ def no_inline_or_meta(type):
179
+ @v_args(meta=False, inline=False)
180
+ def wrapper(self, tree):
181
+ return type(tree)
182
+
183
+ return wrapper
184
+
185
+
186
+ def no_inline(type):
187
+ @v_args(meta=True, inline=False)
188
+ def wrapper(self, meta, tree):
189
+ return type(meta, tree)
190
+
191
+ return wrapper
192
+
193
+
194
+ def no_meta(type):
195
+ @v_args(meta=False, inline=True)
196
+ def wrapper(self, tree):
197
+ return type(tree)
198
+
199
+ return wrapper
200
+
201
+ def handle_str(meta, s: str):
202
+ return s.strip("'").strip('"')
203
+
204
+
205
+ @v_args(meta=True, inline=True)
206
+ class FpyTransformer(Transformer):
207
+ input = no_inline(AstBody)
208
+ pass_stmt = AstPass
209
+
210
+ assign = AstAssign
211
+
212
+ if_stmt = AstIf
213
+ elifs = no_inline(AstElifs)
214
+ elif_ = AstElif
215
+ 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
221
+
222
+ func_call = AstFuncCall
223
+ arguments = no_inline_or_meta(list)
224
+
225
+ string = AstString
226
+ number = AstNumber
227
+ boolean = AstBoolean
228
+ name = no_meta(str)
229
+ get_attr = AstGetAttr
230
+ get_item = AstGetItem
231
+ var = AstVar
232
+
233
+ NAME = str
234
+ DEC_NUMBER = int
235
+ FLOAT_NUMBER = float
236
+ COMPARISON_OP = str
237
+ STRING = handle_str
238
+ CONST_TRUE = lambda a, b: True
239
+ CONST_FALSE = lambda a, b: False
@@ -13,7 +13,7 @@ import sys
13
13
  INITIALIZED = False
14
14
 
15
15
 
16
- def configure_py_log(directory=None, filename=sys.argv[0], mirror_to_stdout=False):
16
+ def configure_py_log(directory=None, filename=sys.argv[0], mirror_to_stdout=False, log_level="INFO"):
17
17
  """
18
18
  Configure the python logging. If logdir is supplied, our logs will go in that directory as a log file. Otherwise,
19
19
  logs will go to the CLI.
@@ -40,6 +40,6 @@ def configure_py_log(directory=None, filename=sys.argv[0], mirror_to_stdout=Fals
40
40
  for handler in handlers:
41
41
  handler.setFormatter(formatter)
42
42
  logging.getLogger().addHandler(handler)
43
- logging.getLogger().setLevel(logging.INFO)
43
+ logging.getLogger().setLevel(log_level)
44
44
  logging.info("Logging system initialized!")
45
45
  INITIALIZED = True
@@ -175,3 +175,11 @@ class CmdTemplate(data_template.DataTemplate):
175
175
 
176
176
  def getArgs(self):
177
177
  return self.get_args()
178
+
179
+ def __repr__(self):
180
+ arg_strs = []
181
+ for arg in self.arguments:
182
+ arg_strs.append(arg[0] + ": " + str(arg[2]))
183
+
184
+ args_str = ", ".join(arg_strs)
185
+ return f"CmdTemplate({self.comp_name}.{self.mnemonic}, args: ({args_str}))"
@@ -209,7 +209,9 @@ class ParserBase(ABC):
209
209
  arguments: arguments to process, None to use command line input
210
210
  Returns: namespace with all parsed arguments from all provided ParserBase subclasses
211
211
  """
212
- return cls._parse_args(parser_classes, description, arguments, use_parse_known=True, **kwargs)
212
+ return cls._parse_args(
213
+ parser_classes, description, arguments, use_parse_known=True, **kwargs
214
+ )
213
215
 
214
216
  @classmethod
215
217
  def parse_args(
@@ -234,7 +236,6 @@ class ParserBase(ABC):
234
236
  """
235
237
  return cls._parse_args(parser_classes, description, arguments, **kwargs)
236
238
 
237
-
238
239
  @staticmethod
239
240
  def _parse_args(
240
241
  parser_classes,
@@ -297,16 +298,17 @@ class ParserBase(ABC):
297
298
 
298
299
 
299
300
  class ConfigDrivenParser(ParserBase):
300
- """ Parser that allows options from configuration and command line
301
+ """Parser that allows options from configuration and command line
301
302
 
302
303
  This parser reads a configuration file (if supplied) and uses the values to drive the inputs to arguments. Command
303
304
  line arguments will still take precedence over the configured values.
304
305
  """
306
+
305
307
  DEFAULT_CONFIGURATION_PATH = Path("fprime-gds.yml")
306
308
 
307
309
  @classmethod
308
310
  def set_default_configuration(cls, path: Path):
309
- """ Set path for (global) default configuration file
311
+ """Set path for (global) default configuration file
310
312
 
311
313
  Set the path for default configuration file. If unset, will use 'fprime-gds.yml'. Set to None to disable default
312
314
  configuration.
@@ -321,7 +323,7 @@ class ConfigDrivenParser(ParserBase):
321
323
  arguments=None,
322
324
  **kwargs,
323
325
  ):
324
- """ Parse and post-process arguments using inputs and config
326
+ """Parse and post-process arguments using inputs and config
325
327
 
326
328
  Parse the arguments in two stages: first parse the configuration data, ignoring unknown inputs, then parse the
327
329
  full argument set with the supplied configuration to fill in additional options.
@@ -343,23 +345,29 @@ class ConfigDrivenParser(ParserBase):
343
345
 
344
346
  # Custom flow involving parsing the arguments of this parser first, then passing the configured values
345
347
  # as part of the argument source
346
- ns_config, _, remaining = ParserBase.parse_known_args([ConfigDrivenParser], description, arguments, **kwargs)
348
+ ns_config, _, remaining = ParserBase.parse_known_args(
349
+ [ConfigDrivenParser], description, arguments, **kwargs
350
+ )
347
351
  config_options = ns_config.config_values.get("command-line-options", {})
348
352
  config_args = cls.flatten_options(config_options)
349
353
  # Argparse allows repeated (overridden) arguments, thus the CLI override is accomplished by providing
350
354
  # remaining arguments after the configured ones
351
- ns_full, parser = ParserBase.parse_args(parser_classes, description, config_args + remaining, **kwargs)
352
- ns_final = argparse.Namespace(**vars(ns_config), **vars(ns_full))
355
+ ns_full, parser = ParserBase.parse_args(
356
+ parser_classes, description, config_args + remaining, **kwargs
357
+ )
358
+ ns_final = argparse.Namespace(**vars(ns_config), **vars(ns_full))
353
359
  return ns_final, parser
354
360
 
355
361
  @staticmethod
356
362
  def flatten_options(configured_options):
357
- """ Flatten options down to arguments """
363
+ """Flatten options down to arguments"""
358
364
  flattened = []
359
365
  for option, value in configured_options.items():
360
366
  flattened.append(f"--{option}")
361
367
  if value is not None:
362
- flattened.extend(value if isinstance(value, (list, tuple)) else [f"{value}"])
368
+ flattened.extend(
369
+ value if isinstance(value, (list, tuple)) else [f"{value}"]
370
+ )
363
371
  return flattened
364
372
 
365
373
  def get_arguments(self) -> Dict[Tuple[str, ...], Dict[str, Any]]:
@@ -375,24 +383,30 @@ class ConfigDrivenParser(ParserBase):
375
383
  }
376
384
 
377
385
  def handle_arguments(self, args, **kwargs):
378
- """ Handle the arguments
386
+ """Handle the arguments
379
387
 
380
388
  Loads the configuration file specified and fills in the `config_values` attribute of the namespace with the
381
389
  loaded configuration dictionary.
382
390
  """
383
391
  args.config_values = {}
384
392
  # Specified but non-existent config file is a hard error
385
- if ("-c" in sys.argv[1:] or "--config" in sys.argv[1:]) and not args.config.exists():
386
- raise ValueError(f"Specified configuration file '{args.config}' does not exist")
393
+ if (
394
+ "-c" in sys.argv[1:] or "--config" in sys.argv[1:]
395
+ ) and not args.config.exists():
396
+ raise ValueError(
397
+ f"Specified configuration file '{args.config}' does not exist"
398
+ )
387
399
  # Read configuration if the file was set and exists
388
- if args.config is not None and args.config.exists():
400
+ if args.config is not None and args.config.exists():
389
401
  print(f"[INFO] Reading command-line configuration from: {args.config}")
390
402
  with open(args.config, "r") as file_handle:
391
403
  try:
392
404
  loaded = yaml.safe_load(file_handle)
393
405
  args.config_values = loaded if loaded is not None else {}
394
406
  except Exception as exc:
395
- raise ValueError(f"Malformed configuration {args.config}: {exc}", exc)
407
+ raise ValueError(
408
+ f"Malformed configuration {args.config}: {exc}", exc
409
+ )
396
410
  return args
397
411
 
398
412
 
@@ -576,8 +590,9 @@ class PluginArgumentParser(ParserBase):
576
590
  """Parser for arguments coming from plugins"""
577
591
 
578
592
  DESCRIPTION = "Plugin options"
593
+ # Defaults:
579
594
  FPRIME_CHOICES = {
580
- "framing": "fprime",
595
+ "framing": "space-packet-space-data-link",
581
596
  "communication": "ip",
582
597
  }
583
598
 
@@ -829,6 +844,13 @@ class LogDeployParser(ParserBase):
829
844
  "default": False,
830
845
  "help": "Log to standard out along with log output files",
831
846
  },
847
+ ("--log-level-gds",): {
848
+ "action": "store",
849
+ "dest": "log_level_gds",
850
+ "choices": ["DEBUG", "INFO", "WARNING", "ERROR"],
851
+ "default": "INFO",
852
+ "help": "Set the logging level of GDS processes [default: %(default)s]",
853
+ },
832
854
  }
833
855
 
834
856
  def handle_arguments(self, args, **kwargs):
@@ -856,7 +878,7 @@ class LogDeployParser(ParserBase):
856
878
  raise
857
879
  # Setup the basic python logging
858
880
  fprime_gds.common.logger.configure_py_log(
859
- args.logs, mirror_to_stdout=args.log_to_stdout
881
+ args.logs, mirror_to_stdout=args.log_to_stdout, log_level=args.log_level_gds
860
882
  )
861
883
  return args
862
884
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fprime-gds
3
- Version: 4.0.0a7
3
+ Version: 4.0.0a9
4
4
  Summary: F Prime Flight Software Ground Data System layer
5
5
  Author-email: Michael Starch <Michael.D.Starch@jpl.nasa.gov>, Thomas Boyer-Chammard <Thomas.Boyer.Chammard@jpl.nasa.gov>
6
6
  License:
@@ -240,6 +240,7 @@ Requires-Dist: Jinja2>=2.11.3
240
240
  Requires-Dist: openpyxl>=3.0.10
241
241
  Requires-Dist: pyserial>=3.5
242
242
  Requires-Dist: pydantic>=2.6
243
+ Requires-Dist: lark>=1.2.2
243
244
  Requires-Dist: PyYAML>=6.0.2
244
245
  Requires-Dist: spacepackets>=0.30.0
245
246
  Requires-Dist: crc>=7.0.0
@@ -31,11 +31,11 @@ fprime_gds/common/data_types/sys_data.py,sha256=Xfk5xryFg7zWS3VcGUDx9lQYBTajjWXv
31
31
  fprime_gds/common/decoders/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
32
32
  fprime_gds/common/decoders/ch_decoder.py,sha256=mx0yfT-DQqQ8TrmRM3dr79eL9_E-c0gsKiKvvsjAu98,3849
33
33
  fprime_gds/common/decoders/decoder.py,sha256=9j7u05_nwXaEjR0etsoB--ATsHuILYCXlhk9m9yajKg,2655
34
- fprime_gds/common/decoders/event_decoder.py,sha256=BH1Q_489ZgBhqMutG-WwMGikpXsqiv-Jd2zZsHZBLnc,4280
34
+ fprime_gds/common/decoders/event_decoder.py,sha256=ib-O18V5Z7bcnUUSDE9R0fU--bAZsfxLwuHXm964rzE,4505
35
35
  fprime_gds/common/decoders/file_decoder.py,sha256=Ky2U8bli3YL6GbT9jSSvI73ySOtf0cdZLK4FXTuWjfA,2542
36
36
  fprime_gds/common/decoders/pkt_decoder.py,sha256=kW8k3OSbMy96w6MzsGWp656lAQvwxrIznWkD3Sbi8Ig,3329
37
37
  fprime_gds/common/distributor/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
38
- fprime_gds/common/distributor/distributor.py,sha256=KMQcr4fFncDewCMAUR64Yy5OIRdF2CCzmfGNE5J6wIY,7917
38
+ fprime_gds/common/distributor/distributor.py,sha256=ay2b-eMuBEGzQwNoSBLK341CXxGnrFHSIcRKErzIQIU,7999
39
39
  fprime_gds/common/encoders/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
40
40
  fprime_gds/common/encoders/ch_encoder.py,sha256=TBrTJ7TK4WwCh6KAspozh63WcPxrMImloB8tz7qeulw,2878
41
41
  fprime_gds/common/encoders/cmd_encoder.py,sha256=5wG5854ozmxctnYou3q9MdQNkTQEmpCiT4oBVgNRZdE,3499
@@ -49,9 +49,15 @@ fprime_gds/common/files/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG
49
49
  fprime_gds/common/files/downlinker.py,sha256=CZPfhH0J9-LNqW5Cv_ryicLTuoedLSWK8OPQmmQDZZY,7498
50
50
  fprime_gds/common/files/helpers.py,sha256=sGaxcczXmZ5_soawT7x_eJ_cC2PZ6KOGBfusAV4QC_g,7219
51
51
  fprime_gds/common/files/uplinker.py,sha256=lgqhlgeipBt3Arx-ohzK8vCdS54fKpv9Rg7SUTocUX8,13244
52
+ fprime_gds/common/fpy/README.md,sha256=AJE9KJDarTTW9nsTJBiZ6cKyPYQbWKbKJbFiNz6M8Z4,1414
53
+ fprime_gds/common/fpy/SPEC.md,sha256=XTMgr96BIVJheOtjAp6Qgu5l5RE16DxxIkPl0WwXfEs,2248
52
54
  fprime_gds/common/fpy/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
53
- fprime_gds/common/fpy/serialize_bytecode.py,sha256=RbBojtDGUjZyqGqKfqzJDLzU0Z9UBsNGaKMf8y2Qz7o,7283
54
- fprime_gds/common/fpy/types.py,sha256=XeDG6E_cm57lpG4wEdZuoGgtEJeSO8WmkCsIBbwWoQc,6143
55
+ fprime_gds/common/fpy/codegen.py,sha256=5VdV-f6CdU1LPJx4swB_GV5pvPe3Cqh9E3bkS0dBAo4,59828
56
+ fprime_gds/common/fpy/grammar.lark,sha256=QIQgmj58pW9ou2u7DzE39c0fz55eGNj3X7ridzAHRFk,2128
57
+ fprime_gds/common/fpy/main.py,sha256=U50sQCrwhZgxGzkjKgaJywoQM_cEH78hN9Vy3pDKKMA,1073
58
+ fprime_gds/common/fpy/parser.py,sha256=g-l67oZN_vB1JAdZ5S3u9m8APf6PdJ88GZyz0iX66qo,4418
59
+ fprime_gds/common/fpy/bytecode/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
60
+ fprime_gds/common/fpy/bytecode/directives.py,sha256=tBpPQ2ZnQXA7juB85HhacDdil1vEHUKW8m_AsMf1KdQ,13360
55
61
  fprime_gds/common/gds_cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
56
62
  fprime_gds/common/gds_cli/base_commands.py,sha256=nHnzHRMXs9haRjiUmq-Ciu1DSo1BXtcVscByk1Ypsxo,9432
57
63
  fprime_gds/common/gds_cli/channels.py,sha256=S8y0Mo2JbBFPvMzeW22HFVJ8p-UC-tzpYM7rXqIGWi4,2136
@@ -78,7 +84,7 @@ fprime_gds/common/loaders/pkt_json_loader.py,sha256=OuHYXE0FP33oAh0z6AScUdLgFg9V
78
84
  fprime_gds/common/loaders/pkt_xml_loader.py,sha256=ZS4qchqQnIBx0Tw69ehP8yqm1g_uYSQzmnijR3FxqJg,4795
79
85
  fprime_gds/common/loaders/prm_json_loader.py,sha256=YCSg3PhVsJTD1FgY_h0i8wV3TNikcZSrczHCzrTM6JM,2896
80
86
  fprime_gds/common/loaders/xml_loader.py,sha256=8AlTTHddJbJqUr6St-zJI8CTqoPuCNtNoRBmdwCorcg,14820
81
- fprime_gds/common/logger/__init__.py,sha256=YBrr9An0fZbp4kvphRl8nLfolkdBqFAsSGzEZXQiH6g,1448
87
+ fprime_gds/common/logger/__init__.py,sha256=TLUbrAnkCtckKGsLzh4hXgEshwQfZsWMDaOOt369BqU,1463
82
88
  fprime_gds/common/logger/data_logger.py,sha256=VjfhTGO1gGw954xNhSc0_zpw8JexCho5f8BlXDEYkL4,2505
83
89
  fprime_gds/common/logger/test_logger.py,sha256=wL8Lq49sVmxGRALgv-ei6AnXFh79qlHFehmKJ1A8X28,6475
84
90
  fprime_gds/common/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -97,7 +103,7 @@ fprime_gds/common/pipeline/router.py,sha256=-P1wI0KXEh_snOzDaq8CjEoWuM_zRm8vUMR1
97
103
  fprime_gds/common/pipeline/standard.py,sha256=fDSPfyhYPMNhev5IQG2j51sCtQxXZ5PrqmulKH8TNjE,9778
98
104
  fprime_gds/common/templates/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
99
105
  fprime_gds/common/templates/ch_template.py,sha256=1MoDZsia0dI_CvnIttwyKLhbQhum35OcJnFc50Xohuo,3893
100
- fprime_gds/common/templates/cmd_template.py,sha256=Bdkfgjb9Yqw7zaZyS8fR9ZUebrkFsRofF0g7xpKtkE4,5180
106
+ fprime_gds/common/templates/cmd_template.py,sha256=n91z4WhFgHwTu6_fQqy7JqpkEObAkllIeEy0AR0DvrQ,5455
101
107
  fprime_gds/common/templates/data_template.py,sha256=U87d8oC-BDTDuBRZbNnPkXy6rI_Pr-XnChHWZunw5jo,735
102
108
  fprime_gds/common/templates/event_template.py,sha256=L0hkWB_kEMhTNodPUqBAev76SMmWT9EWdcqxaaQX9ZE,4062
103
109
  fprime_gds/common/templates/pkt_template.py,sha256=5Wi6389m5j8w7JITBGfeUnw6CYE1-hjcVJ42NJmLDcE,1794
@@ -117,7 +123,7 @@ fprime_gds/common/utils/event_severity.py,sha256=7qPXHrDaM_REJ7sKBUEJTZIE0D4qVnV
117
123
  fprime_gds/common/utils/string_util.py,sha256=u_2iahRG3ROu3lAAt_KVcK226gEByElXqrA8mH8eDpI,3584
118
124
  fprime_gds/executables/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
119
125
  fprime_gds/executables/apps.py,sha256=u79T_PlgMmNmA4YwWjs7LvPMCJnrjnURr05NMthOYP0,13350
120
- fprime_gds/executables/cli.py,sha256=aNO8saIKuTDQMwWNFlrpIL5HuwIWWei94Wxf3G0lY3k,50382
126
+ fprime_gds/executables/cli.py,sha256=Qqq3JQOqTsfDRsbTALw25xnwN7fCEVlpcKDV4jvGopQ,50961
121
127
  fprime_gds/executables/comm.py,sha256=08rO0o0MJgTRngB7Ygu2IL_gEAWKF7WFvFyro1CqReE,5214
122
128
  fprime_gds/executables/data_product_writer.py,sha256=PGNju52vjfg7-AUURFojmMV8S83Tzy58Hyti5tmpffc,35821
123
129
  fprime_gds/executables/fprime_cli.py,sha256=CMoT7zWNwM8h2mSZW03AR96wl_XnZXoLNiOZN_sDi38,12431
@@ -238,10 +244,10 @@ fprime_gds/flask/static/third-party/webfonts/fa-solid-900.woff2,sha256=mDS4KtJuK
238
244
  fprime_gds/plugin/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
239
245
  fprime_gds/plugin/definitions.py,sha256=QlxW1gNvoiqGMslSJjh3dTFZuv0igFHawN__3XJ0Wns,5355
240
246
  fprime_gds/plugin/system.py,sha256=M9xb-8jBhCUUx3X1z2uAP8Wx_v6NkL8JeaFgGcMnQqY,13432
241
- fprime_gds-4.0.0a7.dist-info/licenses/LICENSE.txt,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
242
- fprime_gds-4.0.0a7.dist-info/licenses/NOTICE.txt,sha256=vXjA_xRcQhd83Vfk5D_vXg5kOjnnXvLuMi5vFKDEVmg,1612
243
- fprime_gds-4.0.0a7.dist-info/METADATA,sha256=rghvf1aW0D7_wd9TWo82U-XanfYlZK_eZXV7fglCMbs,24549
244
- fprime_gds-4.0.0a7.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
245
- fprime_gds-4.0.0a7.dist-info/entry_points.txt,sha256=qFBHIR7CZ5CEeSEdZ-ZVQN9ZfUOZfm0PvvDZAAheuLk,445
246
- fprime_gds-4.0.0a7.dist-info/top_level.txt,sha256=6vzFLIX6ANfavKaXFHDMSLFtS94a6FaAsIWhjgYuSNE,27
247
- fprime_gds-4.0.0a7.dist-info/RECORD,,
247
+ fprime_gds-4.0.0a9.dist-info/licenses/LICENSE.txt,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
248
+ fprime_gds-4.0.0a9.dist-info/licenses/NOTICE.txt,sha256=vXjA_xRcQhd83Vfk5D_vXg5kOjnnXvLuMi5vFKDEVmg,1612
249
+ fprime_gds-4.0.0a9.dist-info/METADATA,sha256=v5sVN1vOTmpwQbZTJxg2OsJnbUFPEasPQ_AJjQvLweg,24576
250
+ fprime_gds-4.0.0a9.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
251
+ fprime_gds-4.0.0a9.dist-info/entry_points.txt,sha256=V2XMHMUJUGTVx5s3_kK1jLmoxSKE1vvj2XWHH9y49WQ,423
252
+ fprime_gds-4.0.0a9.dist-info/top_level.txt,sha256=6vzFLIX6ANfavKaXFHDMSLFtS94a6FaAsIWhjgYuSNE,27
253
+ fprime_gds-4.0.0a9.dist-info/RECORD,,
@@ -1,7 +1,7 @@
1
1
  [console_scripts]
2
2
  fprime-cli = fprime_gds.executables.fprime_cli:main
3
3
  fprime-dp-write = fprime_gds.executables.data_product_writer:main
4
- fprime-fpy-bytecode = fprime_gds.common.fpy.serialize_bytecode:main
4
+ fprime-fpyc = fprime_gds.common.fpy.main:main
5
5
  fprime-gds = fprime_gds.executables.run_deployment:main
6
6
  fprime-prm-write = fprime_gds.common.tools.params:main
7
7
  fprime-seqgen = fprime_gds.common.tools.seqgen:main