robotransform 0.0.3__tar.gz → 0.0.5__tar.gz
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.
- {robotransform-0.0.3 → robotransform-0.0.5}/PKG-INFO +1 -1
- {robotransform-0.0.3 → robotransform-0.0.5}/pyproject.toml +1 -1
- robotransform-0.0.5/src/robotransform/concepts.py +598 -0
- robotransform-0.0.5/src/robotransform/filters.py +29 -0
- {robotransform-0.0.3 → robotransform-0.0.5}/src/robotransform/main.py +12 -9
- robotransform-0.0.5/src/robotransform/processors.py +59 -0
- {robotransform-0.0.3 → robotransform-0.0.5}/src/robotransform/robochart.tx +50 -46
- robotransform-0.0.5/src/robotransform/templates/logical.aadl +72 -0
- robotransform-0.0.5/src/robotransform/templates/messages.aadl +14 -0
- robotransform-0.0.3/src/robotransform/concepts.py +0 -286
- robotransform-0.0.3/src/robotransform/filters.py +0 -12
- robotransform-0.0.3/src/robotransform/templates/logical.aadl +0 -61
- robotransform-0.0.3/src/robotransform/templates/messages.aadl +0 -27
- {robotransform-0.0.3 → robotransform-0.0.5}/LICENSE +0 -0
- {robotransform-0.0.3 → robotransform-0.0.5}/README.md +0 -0
- {robotransform-0.0.3 → robotransform-0.0.5}/src/robotransform/__init__.py +0 -0
|
@@ -4,7 +4,7 @@ build-backend = "uv_build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "robotransform"
|
|
7
|
-
version = "0.0.
|
|
7
|
+
version = "0.0.5"
|
|
8
8
|
description="Perform model transformations for the RoboSapiens project."
|
|
9
9
|
authors = [
|
|
10
10
|
{name = "Arkadiusz Michał Ryś", email = "Arkadiusz.Michal.Rys@gmail.com"},
|
|
@@ -0,0 +1,598 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from dataclasses import dataclass, field
|
|
4
|
+
from typing import Type as ClassType, Any, List, Optional, Union
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
@dataclass
|
|
8
|
+
class ControllerDef:
|
|
9
|
+
name: str
|
|
10
|
+
uses: List[QualifiedName]
|
|
11
|
+
provides: List[QualifiedName]
|
|
12
|
+
requires: List[QualifiedName]
|
|
13
|
+
connections: List[Connection]
|
|
14
|
+
machines: List[Union[StateMachineDef, StateMachineRef]]
|
|
15
|
+
events: List[Event]
|
|
16
|
+
operations: List[Operation]
|
|
17
|
+
variables: List[Variable]
|
|
18
|
+
parent: Any
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
@dataclass
|
|
22
|
+
class Connection:
|
|
23
|
+
source: QualifiedName
|
|
24
|
+
event_source: QualifiedName
|
|
25
|
+
target: QualifiedName
|
|
26
|
+
event_target: QualifiedName
|
|
27
|
+
asynchronous: bool
|
|
28
|
+
bidirectional: bool
|
|
29
|
+
parent: Any
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
@dataclass
|
|
33
|
+
class StateMachineRef:
|
|
34
|
+
name: str
|
|
35
|
+
ref: QualifiedName
|
|
36
|
+
parent: Any
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
@dataclass
|
|
40
|
+
class Operation:
|
|
41
|
+
operation: Union[OperationRef, OperationDef]
|
|
42
|
+
parent: Any
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
@dataclass
|
|
46
|
+
class OperationRef:
|
|
47
|
+
name: str
|
|
48
|
+
ref: QualifiedName
|
|
49
|
+
parent: Any
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
@dataclass
|
|
53
|
+
class Variable:
|
|
54
|
+
name: str
|
|
55
|
+
type: Type
|
|
56
|
+
parent: Any
|
|
57
|
+
initial: Optional[Expression] = None
|
|
58
|
+
modifier: Optional[VariableModifier] = None
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
@dataclass
|
|
62
|
+
class Expression:
|
|
63
|
+
expression: Union[ForAll, Exists, LambdaExp, Iff]
|
|
64
|
+
parent: Any
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
@dataclass
|
|
68
|
+
class ForAll:
|
|
69
|
+
variables: List[Variable]
|
|
70
|
+
predicate: Expression
|
|
71
|
+
parent: Any
|
|
72
|
+
suchthat: Optional[Expression]
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
@dataclass
|
|
76
|
+
class Exists:
|
|
77
|
+
variables: List[Variable]
|
|
78
|
+
unique: bool
|
|
79
|
+
predicate: Expression
|
|
80
|
+
parent: Any
|
|
81
|
+
suchthat: Optional[Expression]
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
@dataclass
|
|
85
|
+
class LambdaExp:
|
|
86
|
+
variables: List[Variable]
|
|
87
|
+
predicate: Expression
|
|
88
|
+
parent: Any
|
|
89
|
+
suchthat: Optional[Expression]
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
@dataclass
|
|
93
|
+
class Iff:
|
|
94
|
+
left: Implies
|
|
95
|
+
right: List[Implies]
|
|
96
|
+
parent: Any
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
@dataclass
|
|
100
|
+
class Implies:
|
|
101
|
+
left: Or
|
|
102
|
+
right: List[Or]
|
|
103
|
+
parent: Any
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
@dataclass
|
|
107
|
+
class Or:
|
|
108
|
+
left: And
|
|
109
|
+
right: List[And]
|
|
110
|
+
parent: Any
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
@dataclass
|
|
114
|
+
class And:
|
|
115
|
+
left: Not
|
|
116
|
+
right: List[Not]
|
|
117
|
+
parent: Any
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
@dataclass
|
|
121
|
+
class Not:
|
|
122
|
+
exp: Union[Not, Comp]
|
|
123
|
+
parent: Any
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
@dataclass
|
|
127
|
+
class Comp:
|
|
128
|
+
left: DefiniteDescription
|
|
129
|
+
|
|
130
|
+
parent: Any
|
|
131
|
+
comp: Optional[Comparison] # TODO Unify these
|
|
132
|
+
right: Optional[DefiniteDescription] # TODO Unify these
|
|
133
|
+
set: Optional[DefiniteDescription] # TODO Unify these
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
@dataclass
|
|
137
|
+
class DefiniteDescription:
|
|
138
|
+
variables: List[Variable]
|
|
139
|
+
expression: Union[Expression, LetExpression]
|
|
140
|
+
parent: Any
|
|
141
|
+
suchthat: Optional[Expression]
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
@dataclass
|
|
145
|
+
class Comparison:
|
|
146
|
+
operator: str
|
|
147
|
+
right: DefiniteDescription
|
|
148
|
+
parent: Any
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
@dataclass
|
|
152
|
+
class LetExpression:
|
|
153
|
+
declarations: List[Declaration]
|
|
154
|
+
expression: Union[LetExpression, IfExpression]
|
|
155
|
+
parent: Any
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
@dataclass
|
|
159
|
+
class Declaration:
|
|
160
|
+
name: str
|
|
161
|
+
expression: Expression
|
|
162
|
+
parent: Any
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
@dataclass
|
|
166
|
+
class IfExpression:
|
|
167
|
+
condition: Expression
|
|
168
|
+
ifexp: Expression
|
|
169
|
+
elseexp: Expression
|
|
170
|
+
expression: TypedExpression
|
|
171
|
+
parent: Any
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
@dataclass
|
|
175
|
+
class TypedExpression:
|
|
176
|
+
expression: PlusMinus
|
|
177
|
+
|
|
178
|
+
parent: Any
|
|
179
|
+
type: Optional[Type]
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
@dataclass
|
|
183
|
+
class PlusMinus:
|
|
184
|
+
expression: MultDivMod
|
|
185
|
+
right: List[MultDivMod]
|
|
186
|
+
parent: Any
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
@dataclass
|
|
190
|
+
class MultDivMod:
|
|
191
|
+
expression: CatExp
|
|
192
|
+
right: List[CatExp]
|
|
193
|
+
parent: Any
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
@dataclass
|
|
197
|
+
class CatExp:
|
|
198
|
+
expression: Neg
|
|
199
|
+
right: List[Neg]
|
|
200
|
+
parent: Any
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
@dataclass
|
|
204
|
+
class Neg:
|
|
205
|
+
expression: Union[Neg, Selection]
|
|
206
|
+
parent: Any
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
@dataclass
|
|
210
|
+
class Selection:
|
|
211
|
+
expression: ArrayExp
|
|
212
|
+
member: List[QualifiedName]
|
|
213
|
+
parent: Any
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
@dataclass
|
|
217
|
+
class ArrayExp:
|
|
218
|
+
expression: CallExp
|
|
219
|
+
parameters: List[Expression]
|
|
220
|
+
parent: Any
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
@dataclass
|
|
224
|
+
class CallExp:
|
|
225
|
+
expression: Atomic
|
|
226
|
+
args: List[Expression]
|
|
227
|
+
parent: Any
|
|
228
|
+
|
|
229
|
+
|
|
230
|
+
@dataclass
|
|
231
|
+
class Atomic: # TODO Add subs
|
|
232
|
+
value: Union[str, int, float, bool]
|
|
233
|
+
parent: Any
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+
@dataclass
|
|
237
|
+
class Node: # TODO Add subs
|
|
238
|
+
parent: Any
|
|
239
|
+
|
|
240
|
+
|
|
241
|
+
@dataclass
|
|
242
|
+
class Type:
|
|
243
|
+
source: FunctionType
|
|
244
|
+
target: Optional[Type] = None
|
|
245
|
+
parent: Any = None
|
|
246
|
+
|
|
247
|
+
def __repr__(self):
|
|
248
|
+
if self.target:
|
|
249
|
+
return f"{self.source} <-> {self.target}"
|
|
250
|
+
return f"{self.source}"
|
|
251
|
+
|
|
252
|
+
@dataclass
|
|
253
|
+
class Field:
|
|
254
|
+
name: str
|
|
255
|
+
type: Type
|
|
256
|
+
parent: Any
|
|
257
|
+
|
|
258
|
+
|
|
259
|
+
@dataclass
|
|
260
|
+
class RecordType:
|
|
261
|
+
name: str
|
|
262
|
+
fields: List[Field]
|
|
263
|
+
parent: Any
|
|
264
|
+
|
|
265
|
+
@dataclass
|
|
266
|
+
class Parameter:
|
|
267
|
+
name: str
|
|
268
|
+
type: Type
|
|
269
|
+
parent: Any
|
|
270
|
+
|
|
271
|
+
@dataclass
|
|
272
|
+
class Function:
|
|
273
|
+
name: str
|
|
274
|
+
parameters: List[Parameter]
|
|
275
|
+
type: Type
|
|
276
|
+
body: Body
|
|
277
|
+
parent: Any
|
|
278
|
+
|
|
279
|
+
|
|
280
|
+
@dataclass
|
|
281
|
+
class Body:
|
|
282
|
+
elements: List[BodyContent]
|
|
283
|
+
parent: Any
|
|
284
|
+
|
|
285
|
+
|
|
286
|
+
@dataclass
|
|
287
|
+
class BodyContent:
|
|
288
|
+
parent: Any
|
|
289
|
+
|
|
290
|
+
|
|
291
|
+
@dataclass
|
|
292
|
+
class Module:
|
|
293
|
+
name: str
|
|
294
|
+
connections: List[Connection]
|
|
295
|
+
nodes: List[ConnectionNode]
|
|
296
|
+
parent: Any
|
|
297
|
+
|
|
298
|
+
|
|
299
|
+
@dataclass
|
|
300
|
+
class VariableModifier:
|
|
301
|
+
parent: Any
|
|
302
|
+
|
|
303
|
+
|
|
304
|
+
@dataclass
|
|
305
|
+
class Interface:
|
|
306
|
+
name: str
|
|
307
|
+
operations: List[OperationSig]
|
|
308
|
+
events: List[Event]
|
|
309
|
+
parent: Any
|
|
310
|
+
clocks: List[Clock]
|
|
311
|
+
variables: List[Variable]
|
|
312
|
+
|
|
313
|
+
|
|
314
|
+
@dataclass
|
|
315
|
+
class Clock:
|
|
316
|
+
name: str
|
|
317
|
+
|
|
318
|
+
|
|
319
|
+
@dataclass
|
|
320
|
+
class OperationSig:
|
|
321
|
+
name: str
|
|
322
|
+
parameters: List[Parameter]
|
|
323
|
+
terminates: bool
|
|
324
|
+
parent: Any
|
|
325
|
+
|
|
326
|
+
|
|
327
|
+
@dataclass
|
|
328
|
+
class RoboticPlatformDef:
|
|
329
|
+
name: str
|
|
330
|
+
uses: List[QualifiedName]
|
|
331
|
+
provides: List[QualifiedName]
|
|
332
|
+
requires: List[QualifiedName]
|
|
333
|
+
operations: List[OperationSig]
|
|
334
|
+
events: List[Event]
|
|
335
|
+
parent: Any
|
|
336
|
+
variables: List[Variable]
|
|
337
|
+
|
|
338
|
+
|
|
339
|
+
@dataclass
|
|
340
|
+
class OperationDef:
|
|
341
|
+
name: str
|
|
342
|
+
parameters: List[Parameter]
|
|
343
|
+
terminates: str
|
|
344
|
+
preconditions: List[Expression]
|
|
345
|
+
postconditions: List[Expression]
|
|
346
|
+
uses: List[QualifiedName]
|
|
347
|
+
provides: List[QualifiedName]
|
|
348
|
+
variables: List[Variable]
|
|
349
|
+
events: List[Event]
|
|
350
|
+
nodes: List[Node]
|
|
351
|
+
transitions: List[Transition]
|
|
352
|
+
clock: List[Transition]
|
|
353
|
+
parent: Any
|
|
354
|
+
|
|
355
|
+
|
|
356
|
+
@dataclass
|
|
357
|
+
class Package:
|
|
358
|
+
name: QualifiedName
|
|
359
|
+
imports: List[Import]
|
|
360
|
+
controllers: List[ControllerDef]
|
|
361
|
+
modules: List[Module]
|
|
362
|
+
functions: List[Function]
|
|
363
|
+
types: List[RecordType]
|
|
364
|
+
machines: List[StateMachineDef]
|
|
365
|
+
interfaces: List[Interface]
|
|
366
|
+
robots: List[RoboticPlatformDef]
|
|
367
|
+
operations: List[OperationDef]
|
|
368
|
+
|
|
369
|
+
|
|
370
|
+
@dataclass
|
|
371
|
+
class ConnectionNode: # TODO add subs
|
|
372
|
+
parent: Any
|
|
373
|
+
|
|
374
|
+
|
|
375
|
+
@dataclass
|
|
376
|
+
class QualifiedName:
|
|
377
|
+
parts: List[str]
|
|
378
|
+
parent: Any
|
|
379
|
+
|
|
380
|
+
def __hash__(self):
|
|
381
|
+
return hash(str(self.parts))
|
|
382
|
+
|
|
383
|
+
def __repr__(self):
|
|
384
|
+
return "::".join(self.parts)
|
|
385
|
+
|
|
386
|
+
|
|
387
|
+
@dataclass
|
|
388
|
+
class StateMachineDef:
|
|
389
|
+
name: str
|
|
390
|
+
uses: List[QualifiedName]
|
|
391
|
+
provides: List[QualifiedName]
|
|
392
|
+
requires: List[QualifiedName]
|
|
393
|
+
events: List[Event]
|
|
394
|
+
nodes: List[Node]
|
|
395
|
+
transitions: List[Transition]
|
|
396
|
+
clocks: List[Clock]
|
|
397
|
+
parent: Any
|
|
398
|
+
variables: List[Variable]
|
|
399
|
+
|
|
400
|
+
|
|
401
|
+
@dataclass
|
|
402
|
+
class Transition:
|
|
403
|
+
name: str
|
|
404
|
+
source: QualifiedName
|
|
405
|
+
target: QualifiedName
|
|
406
|
+
|
|
407
|
+
reset: List[ClockReset]
|
|
408
|
+
|
|
409
|
+
parent: Any
|
|
410
|
+
trigger: Optional[Trigger]
|
|
411
|
+
deadline: Optional[Expression]
|
|
412
|
+
condition: Optional[ConditionExpr]
|
|
413
|
+
action: Optional[Statement]
|
|
414
|
+
|
|
415
|
+
|
|
416
|
+
@dataclass
|
|
417
|
+
class ConditionExpr: # TODO
|
|
418
|
+
parent: Any
|
|
419
|
+
|
|
420
|
+
|
|
421
|
+
@dataclass
|
|
422
|
+
class Statement:
|
|
423
|
+
statements: List[EndStatement]
|
|
424
|
+
parent: Any
|
|
425
|
+
|
|
426
|
+
|
|
427
|
+
@dataclass
|
|
428
|
+
class EndStatement: # TODO
|
|
429
|
+
parent: Any
|
|
430
|
+
deadline: Optional[Expression]
|
|
431
|
+
|
|
432
|
+
|
|
433
|
+
@dataclass
|
|
434
|
+
class ClockReset:
|
|
435
|
+
clock: QualifiedName
|
|
436
|
+
parent: Any
|
|
437
|
+
|
|
438
|
+
|
|
439
|
+
@dataclass
|
|
440
|
+
class Trigger:
|
|
441
|
+
trigger: Communication
|
|
442
|
+
probability: Expression
|
|
443
|
+
parent: Any
|
|
444
|
+
|
|
445
|
+
|
|
446
|
+
@dataclass
|
|
447
|
+
class CommunicationStmt:
|
|
448
|
+
communication: Communication
|
|
449
|
+
parent: Any
|
|
450
|
+
|
|
451
|
+
|
|
452
|
+
@dataclass
|
|
453
|
+
class Communication:
|
|
454
|
+
event: QualifiedName
|
|
455
|
+
source: QualifiedName
|
|
456
|
+
predicate: List[Expression]
|
|
457
|
+
type: Union[InputType, OutputType, SyncType]
|
|
458
|
+
parent: Any
|
|
459
|
+
|
|
460
|
+
|
|
461
|
+
@dataclass
|
|
462
|
+
class InputType:
|
|
463
|
+
parameter: QualifiedName
|
|
464
|
+
parent: Any
|
|
465
|
+
|
|
466
|
+
|
|
467
|
+
@dataclass
|
|
468
|
+
class OutputType:
|
|
469
|
+
value: CallExp
|
|
470
|
+
parent: Any
|
|
471
|
+
|
|
472
|
+
|
|
473
|
+
@dataclass
|
|
474
|
+
class SyncType:
|
|
475
|
+
value: CallExp
|
|
476
|
+
parent: Any
|
|
477
|
+
|
|
478
|
+
|
|
479
|
+
@dataclass
|
|
480
|
+
class QualifiedNameWithWildcard:
|
|
481
|
+
name: QualifiedName
|
|
482
|
+
parent: Any
|
|
483
|
+
|
|
484
|
+
def __hash__(self):
|
|
485
|
+
return hash(str(self.name))
|
|
486
|
+
|
|
487
|
+
def __repr__(self):
|
|
488
|
+
return str(self.name) + "::*"
|
|
489
|
+
|
|
490
|
+
|
|
491
|
+
@dataclass
|
|
492
|
+
class Import:
|
|
493
|
+
name: QualifiedNameWithWildcard
|
|
494
|
+
parent: Any
|
|
495
|
+
|
|
496
|
+
def __repr__(self):
|
|
497
|
+
return str(self.name)
|
|
498
|
+
|
|
499
|
+
|
|
500
|
+
@dataclass
|
|
501
|
+
class FunctionType:
|
|
502
|
+
source: ProductType
|
|
503
|
+
parent: Any
|
|
504
|
+
target: Optional[FunctionType]
|
|
505
|
+
# added by processor
|
|
506
|
+
source_chain: list = field(default_factory=list)
|
|
507
|
+
final_target: Any = None
|
|
508
|
+
|
|
509
|
+
def __repr__(self):
|
|
510
|
+
if self.target:
|
|
511
|
+
return f"{self.source} -> {self.target}"
|
|
512
|
+
return f"{self.source}"
|
|
513
|
+
|
|
514
|
+
|
|
515
|
+
@dataclass
|
|
516
|
+
class SetType:
|
|
517
|
+
domain: Type
|
|
518
|
+
parent: Any
|
|
519
|
+
|
|
520
|
+
|
|
521
|
+
@dataclass
|
|
522
|
+
class AnyType:
|
|
523
|
+
identifier: str
|
|
524
|
+
parent: Any
|
|
525
|
+
|
|
526
|
+
|
|
527
|
+
@dataclass
|
|
528
|
+
class TypeRef:
|
|
529
|
+
type: Union[SetType, SeqType, AnyType, Type, QualifiedName]
|
|
530
|
+
parent: Any
|
|
531
|
+
|
|
532
|
+
def __repr__(self):
|
|
533
|
+
return f"{self.type}"
|
|
534
|
+
|
|
535
|
+
|
|
536
|
+
@dataclass
|
|
537
|
+
class VectorDef:
|
|
538
|
+
base: Type
|
|
539
|
+
size: int # TODO Add processor to set this to into from Atomic
|
|
540
|
+
parent: Any
|
|
541
|
+
|
|
542
|
+
|
|
543
|
+
@dataclass
|
|
544
|
+
class MatrixDef:
|
|
545
|
+
base: Type
|
|
546
|
+
rows: Atomic
|
|
547
|
+
columns: Atomic
|
|
548
|
+
parent: Any
|
|
549
|
+
|
|
550
|
+
|
|
551
|
+
@dataclass
|
|
552
|
+
class VectorType:
|
|
553
|
+
source: Union[VectorDef, MatrixDef, TypeRef]
|
|
554
|
+
parent: Any
|
|
555
|
+
|
|
556
|
+
def __repr__(self):
|
|
557
|
+
return f"{self.source}"
|
|
558
|
+
|
|
559
|
+
|
|
560
|
+
@dataclass
|
|
561
|
+
class ProductType:
|
|
562
|
+
types: List[Union[VectorType, TypeRef]]
|
|
563
|
+
flat_types: List[VectorType] = field(default_factory=list)
|
|
564
|
+
parent: Any = None
|
|
565
|
+
|
|
566
|
+
def __repr__(self):
|
|
567
|
+
if len(self.types) > 1:
|
|
568
|
+
joined = "*".join(map(str, self.types))
|
|
569
|
+
return f"{joined}"
|
|
570
|
+
return f"{self.types[0]}"
|
|
571
|
+
|
|
572
|
+
|
|
573
|
+
@dataclass
|
|
574
|
+
class SeqType:
|
|
575
|
+
domain: Type
|
|
576
|
+
parent: Any
|
|
577
|
+
|
|
578
|
+
def __repr__(self):
|
|
579
|
+
return f"[{self.domain}]"
|
|
580
|
+
|
|
581
|
+
|
|
582
|
+
@dataclass
|
|
583
|
+
class Event:
|
|
584
|
+
name: str
|
|
585
|
+
broadcast: bool
|
|
586
|
+
type: Type
|
|
587
|
+
parent: Any
|
|
588
|
+
|
|
589
|
+
def __repr__(self):
|
|
590
|
+
return f"Event: {self.name} {self.broadcast, self.type}"
|
|
591
|
+
|
|
592
|
+
|
|
593
|
+
def all_concepts() -> List[ClassType]:
|
|
594
|
+
import inspect
|
|
595
|
+
return [
|
|
596
|
+
obj for _, obj in globals().items()
|
|
597
|
+
if inspect.isclass(obj) and obj.__module__ == __name__
|
|
598
|
+
]
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
def type_to_port(_type) -> str:
|
|
2
|
+
# TODO this is wrong
|
|
3
|
+
if str(_type) in {"event", }:
|
|
4
|
+
return "event"
|
|
5
|
+
return "data"
|
|
6
|
+
|
|
7
|
+
def type_to_aadl_type(_type) -> str:
|
|
8
|
+
typename = str(_type)
|
|
9
|
+
# Boolean,
|
|
10
|
+
# Character,
|
|
11
|
+
# Float, Float_32, Float_64,
|
|
12
|
+
# Integer, Integer_8, Integer_16, Integer_32, Integer_64,
|
|
13
|
+
# Natural,
|
|
14
|
+
# String,
|
|
15
|
+
# Unsigned_8, Unsigned_16, Unsigned_32, Unsigned_64
|
|
16
|
+
mapping = {
|
|
17
|
+
"boolean": "Base_Types::Boolean",
|
|
18
|
+
"nat" : "Base_Types::Natural",
|
|
19
|
+
"real" : "Base_Types::Float",
|
|
20
|
+
}
|
|
21
|
+
# TODO Seq -> Array[...]
|
|
22
|
+
# TODO Matrix to Array[Array[...]]
|
|
23
|
+
# REASON: AADL does not support variable length arrays
|
|
24
|
+
# TODO Very hacky, not correct
|
|
25
|
+
if typename.startswith("[") and typename.endswith("]"):
|
|
26
|
+
typename = typename[1:-1]
|
|
27
|
+
elif "*" in typename:
|
|
28
|
+
typename = typename.split("*")[0]
|
|
29
|
+
return mapping.get(typename, f"messages::{typename}")
|
|
@@ -8,8 +8,9 @@ from jinja2 import Environment, FileSystemLoader, Template
|
|
|
8
8
|
import io
|
|
9
9
|
from typing import Union, Optional, Iterable, Iterator
|
|
10
10
|
|
|
11
|
-
from robotransform.concepts import all_concepts,
|
|
12
|
-
from robotransform.filters import
|
|
11
|
+
from robotransform.concepts import all_concepts, Package
|
|
12
|
+
from robotransform.filters import type_to_port, type_to_aadl_type
|
|
13
|
+
from robotransform.processors import processors
|
|
13
14
|
|
|
14
15
|
|
|
15
16
|
@dataclass
|
|
@@ -28,7 +29,7 @@ class Store:
|
|
|
28
29
|
yield item
|
|
29
30
|
continue
|
|
30
31
|
|
|
31
|
-
def parse_imports(self, package:
|
|
32
|
+
def parse_imports(self, package: Package, parent_path: Path, visited):
|
|
32
33
|
stack = [package]
|
|
33
34
|
while stack:
|
|
34
35
|
package = stack.pop()
|
|
@@ -45,7 +46,7 @@ class Store:
|
|
|
45
46
|
stack.append(sub_package)
|
|
46
47
|
return visited
|
|
47
48
|
|
|
48
|
-
def load(self, imports: bool = True) -> dict[Path,
|
|
49
|
+
def load(self, imports: bool = True) -> dict[Path, Package]:
|
|
49
50
|
visited = {}
|
|
50
51
|
for path in self:
|
|
51
52
|
package = parse_robochart(path)
|
|
@@ -85,11 +86,12 @@ def get_robochart_metamodel(name: str = "robochart.tx"):
|
|
|
85
86
|
arklog.debug(f"Loading ({name}) metamodel.")
|
|
86
87
|
metamodel_path = Path(__file__).resolve().parent / name
|
|
87
88
|
metamodel = metamodel_from_str(metamodel_path.read_text(), classes=all_concepts(), memoization=True)
|
|
89
|
+
metamodel.register_obj_processors(processors)
|
|
88
90
|
return metamodel
|
|
89
91
|
|
|
90
92
|
|
|
91
93
|
@lru_cache(maxsize=1)
|
|
92
|
-
def parse_robochart(source: Path | str) ->
|
|
94
|
+
def parse_robochart(source: Path | str) -> Package:
|
|
93
95
|
arklog.debug(f"Parsing ({source}).")
|
|
94
96
|
metamodel = get_robochart_metamodel()
|
|
95
97
|
data = source.read_text() if isinstance(source, Path) else source
|
|
@@ -99,8 +101,9 @@ def parse_robochart(source: Path | str) -> RCPackage:
|
|
|
99
101
|
@lru_cache(maxsize=2)
|
|
100
102
|
def get_template(name: str) -> Template:
|
|
101
103
|
environment = Environment(loader=FileSystemLoader(Path(__file__).resolve().parent / "templates"))
|
|
102
|
-
environment.filters["
|
|
103
|
-
|
|
104
|
+
environment.filters["type_to_port"] = type_to_port # For use with pipes
|
|
105
|
+
environment.filters["type_to_aadl_type"] = type_to_aadl_type # For use with pipes
|
|
106
|
+
# environment.globals["type_to_port"] = type_to_port # For use as a function
|
|
104
107
|
templates = {
|
|
105
108
|
"messages": "messages.aadl",
|
|
106
109
|
"logical": "logical.aadl",
|
|
@@ -108,7 +111,7 @@ def get_template(name: str) -> Template:
|
|
|
108
111
|
if found := templates.get(name):
|
|
109
112
|
return environment.get_template(found)
|
|
110
113
|
else:
|
|
111
|
-
raise ValueError(f"No template found for name
|
|
114
|
+
raise ValueError(f"No template found for name ({name}).")
|
|
112
115
|
|
|
113
116
|
|
|
114
117
|
def write_output(data: str, output: Optional[Union[io.TextIOBase, Path, str]] = None) -> str:
|
|
@@ -122,7 +125,7 @@ def write_output(data: str, output: Optional[Union[io.TextIOBase, Path, str]] =
|
|
|
122
125
|
output.write(data)
|
|
123
126
|
output.flush()
|
|
124
127
|
else:
|
|
125
|
-
raise TypeError(f"Unsupported output type
|
|
128
|
+
raise TypeError(f"Unsupported output type ({type(output)}).")
|
|
126
129
|
return data
|
|
127
130
|
|
|
128
131
|
|