robotransform 0.0.3__tar.gz → 0.0.4__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.4}/PKG-INFO +1 -1
- {robotransform-0.0.3 → robotransform-0.0.4}/pyproject.toml +1 -1
- robotransform-0.0.4/src/robotransform/concepts.py +598 -0
- robotransform-0.0.4/src/robotransform/filters.py +29 -0
- {robotransform-0.0.3 → robotransform-0.0.4}/src/robotransform/main.py +12 -9
- robotransform-0.0.4/src/robotransform/processors.py +59 -0
- {robotransform-0.0.3 → robotransform-0.0.4}/src/robotransform/robochart.tx +50 -46
- {robotransform-0.0.3 → robotransform-0.0.4}/src/robotransform/templates/logical.aadl +5 -5
- robotransform-0.0.4/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/messages.aadl +0 -27
- {robotransform-0.0.3 → robotransform-0.0.4}/LICENSE +0 -0
- {robotransform-0.0.3 → robotransform-0.0.4}/README.md +0 -0
- {robotransform-0.0.3 → robotransform-0.0.4}/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.4"
|
|
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"Seq({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
|
+
typename = str(type)
|
|
4
|
+
data_types = {"int", "integer", "real", "float", "double", "string"}
|
|
5
|
+
mixed_types = {"event_data", "event data"}
|
|
6
|
+
|
|
7
|
+
if typename in data_types:
|
|
8
|
+
return "data"
|
|
9
|
+
if typename in mixed_types:
|
|
10
|
+
return "event data"
|
|
11
|
+
return "data"
|
|
12
|
+
|
|
13
|
+
def type_to_aadl_type(type) -> str:
|
|
14
|
+
typename = str(type)
|
|
15
|
+
# Boolean,
|
|
16
|
+
# Character,
|
|
17
|
+
# Float, Float_32, Float_64,
|
|
18
|
+
# Integer, Integer_8, Integer_16, Integer_32, Integer_64,
|
|
19
|
+
# Natural,
|
|
20
|
+
# String,
|
|
21
|
+
# Unsigned_8, Unsigned_16, Unsigned_32, Unsigned_64
|
|
22
|
+
mapping = {
|
|
23
|
+
"boolean": "Base_Types::Boolean",
|
|
24
|
+
"nat": "Base_Types::Natural",
|
|
25
|
+
"real": "Base_Types::Float",
|
|
26
|
+
}
|
|
27
|
+
# TODO Seq -> Array[...]
|
|
28
|
+
# TODO Matrix to Array[Array[...]]
|
|
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
|
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
from robotransform.concepts import Variable, VectorDef, MatrixDef, TypeRef
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
def flatten_function_type(function_type):
|
|
5
|
+
current = function_type
|
|
6
|
+
linear = []
|
|
7
|
+
|
|
8
|
+
while current is not None:
|
|
9
|
+
linear.append(current.source)
|
|
10
|
+
current = current.target
|
|
11
|
+
|
|
12
|
+
function_type.source_chain = linear[:-1]
|
|
13
|
+
function_type.final_target = linear[-1]
|
|
14
|
+
return function_type
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def flatten_product_type(obj):
|
|
18
|
+
flat = [obj.types[0]] if obj.types else []
|
|
19
|
+
for t in obj.types[1:]:
|
|
20
|
+
flat.append(t)
|
|
21
|
+
obj.flat_types = flat
|
|
22
|
+
return obj
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def flatten_variable_list(var_list_obj):
|
|
26
|
+
flat_vars = []
|
|
27
|
+
for variable in var_list_obj.variables:
|
|
28
|
+
variable.modifier = var_list_obj.modifier
|
|
29
|
+
flat_vars.append(variable)
|
|
30
|
+
assert (len(flat_vars) == 1) # TODO Is this always the case?
|
|
31
|
+
return flat_vars[0]
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def flatten_vector_type(obj):
|
|
35
|
+
if isinstance(obj.source, VectorDef):
|
|
36
|
+
obj.flattened = [obj.source.base]
|
|
37
|
+
elif isinstance(obj.source, MatrixDef):
|
|
38
|
+
obj.flattened = [obj.source.base]
|
|
39
|
+
elif isinstance(obj.source, TypeRef):
|
|
40
|
+
obj.flattened = [obj.source.type]
|
|
41
|
+
return obj
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def convert_variable_no_init(variable_no_init):
|
|
45
|
+
return Variable(
|
|
46
|
+
name=variable_no_init.name,
|
|
47
|
+
type=variable_no_init.type,
|
|
48
|
+
initial=None,
|
|
49
|
+
parent=variable_no_init.parent
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
processors = {
|
|
54
|
+
"ProductType": flatten_product_type,
|
|
55
|
+
"FunctionType": flatten_function_type,
|
|
56
|
+
"VariableList": flatten_variable_list,
|
|
57
|
+
"VariableNoInit": convert_variable_no_init,
|
|
58
|
+
"VectorType": flatten_vector_type,
|
|
59
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
Package:
|
|
2
2
|
'package' name=QualifiedName? (
|
|
3
3
|
'diagram' ID
|
|
4
4
|
| imports+=Import
|
|
@@ -9,7 +9,7 @@ RCPackage:
|
|
|
9
9
|
| machines+=StateMachineDef
|
|
10
10
|
| operations+=OperationDef
|
|
11
11
|
| functions+=Function
|
|
12
|
-
| modules+=
|
|
12
|
+
| modules+=Module
|
|
13
13
|
)*
|
|
14
14
|
;
|
|
15
15
|
|
|
@@ -19,12 +19,12 @@ Import: 'import' name=QualifiedNameWithWildcard;
|
|
|
19
19
|
|
|
20
20
|
QualifiedNameWithWildcard: name=QualifiedName ('::*')?;
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
Module:
|
|
23
23
|
'module' name=ID '{' (connections+=Connection | nodes+=ConnectionNode)* '}'
|
|
24
24
|
;
|
|
25
25
|
|
|
26
26
|
Connection:
|
|
27
|
-
'connection'
|
|
27
|
+
'connection' source=QualifiedName 'on' event_source=QualifiedName 'to' target=QualifiedName 'on' event_target=QualifiedName ('(' asynchronous?='_async' ')')? ('[' bidirectional?='mult' ']')?
|
|
28
28
|
;
|
|
29
29
|
|
|
30
30
|
ConnectionNode: Controller | StateMachine | RoboticPlatform;
|
|
@@ -51,7 +51,7 @@ VariableList:
|
|
|
51
51
|
VariableModifier: 'var' | 'const';
|
|
52
52
|
|
|
53
53
|
Variable:
|
|
54
|
-
name=ID ':'
|
|
54
|
+
name=ID ':' type=Type ('=' initial=Expression)?
|
|
55
55
|
;
|
|
56
56
|
|
|
57
57
|
Type: source=FunctionType ('<->' target=Type)?;
|
|
@@ -70,7 +70,7 @@ VectorDef: 'vector' '(' base=Type ',' size=Atomic ')';
|
|
|
70
70
|
|
|
71
71
|
MatrixDef: 'matrix' '(' base=Type ',' rows=Atomic ',' columns=Atomic ')';
|
|
72
72
|
|
|
73
|
-
TypeRef:
|
|
73
|
+
TypeRef: type=SetType | type=SeqType | type=AnyType | '(' type=Type ')' | type=QualifiedName;
|
|
74
74
|
|
|
75
75
|
SetType: 'Set(' domain=Type ')';
|
|
76
76
|
|
|
@@ -101,7 +101,7 @@ Atomic:
|
|
|
101
101
|
| TupleExp
|
|
102
102
|
;
|
|
103
103
|
|
|
104
|
-
TypeLit:
|
|
104
|
+
TypeLit: type=QualifiedName '::' literal=QualifiedName;
|
|
105
105
|
EqualDelim: '<' (values+=PlusMinus[','])? '>';
|
|
106
106
|
|
|
107
107
|
RefExp:
|
|
@@ -117,14 +117,22 @@ FieldDefinition:
|
|
|
117
117
|
;
|
|
118
118
|
|
|
119
119
|
Expression:
|
|
120
|
+
expression=ForAll
|
|
121
|
+
| expression=Exists
|
|
122
|
+
| expression=LambdaExp
|
|
123
|
+
| expression=Iff
|
|
124
|
+
;
|
|
125
|
+
|
|
126
|
+
ForAll:
|
|
120
127
|
'forall' variables+=VariableNoInit[','] ('|' suchthat=Expression)? '@' predicate=Expression
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
128
|
+
;
|
|
129
|
+
|
|
130
|
+
Exists:
|
|
131
|
+
('exists' | unique?='exists1') variables+=VariableNoInit[','] ('|' suchthat=Expression)? '@' predicate=Expression
|
|
124
132
|
;
|
|
125
133
|
|
|
126
134
|
VariableNoInit:
|
|
127
|
-
name=ID ':'
|
|
135
|
+
name=ID ':' type=Type
|
|
128
136
|
;
|
|
129
137
|
|
|
130
138
|
LambdaExp:
|
|
@@ -151,7 +159,7 @@ Not:
|
|
|
151
159
|
'not' exp=Not | exp=Comp
|
|
152
160
|
;
|
|
153
161
|
|
|
154
|
-
Comp: left=DefiniteDescription (Comparison right=DefiniteDescription | 'in' set=DefiniteDescription)*;
|
|
162
|
+
Comp: left=DefiniteDescription (comp=Comparison right=DefiniteDescription | 'in' set=DefiniteDescription)*;
|
|
155
163
|
|
|
156
164
|
DefiniteDescription:
|
|
157
165
|
'the' variables+=VariableNoInit[','] ('|' suchthat=Expression)? '@' expression=DefiniteDescription
|
|
@@ -164,7 +172,7 @@ LetExpression:
|
|
|
164
172
|
;
|
|
165
173
|
|
|
166
174
|
Declaration:
|
|
167
|
-
name=ID '=='
|
|
175
|
+
name=ID '==' expression=Expression
|
|
168
176
|
;
|
|
169
177
|
|
|
170
178
|
IfExpression:
|
|
@@ -173,7 +181,7 @@ IfExpression:
|
|
|
173
181
|
;
|
|
174
182
|
|
|
175
183
|
TypedExpression:
|
|
176
|
-
expression=PlusMinus ('as'
|
|
184
|
+
expression=PlusMinus ('as' type=Type | 'is' type=Type)?
|
|
177
185
|
;
|
|
178
186
|
|
|
179
187
|
PlusMinus:
|
|
@@ -188,7 +196,7 @@ CatExp:
|
|
|
188
196
|
expression=Neg ('cat' right=Neg | '^' right=Neg)*
|
|
189
197
|
;
|
|
190
198
|
|
|
191
|
-
Neg: '-'
|
|
199
|
+
Neg: '-' expression=Neg | expression=Selection;
|
|
192
200
|
|
|
193
201
|
Selection:
|
|
194
202
|
expression=ArrayExp ('.' member=QualifiedName)*
|
|
@@ -227,18 +235,18 @@ TupleExp:
|
|
|
227
235
|
;
|
|
228
236
|
|
|
229
237
|
Comparison:
|
|
230
|
-
'==' right=DefiniteDescription
|
|
231
|
-
| '!=' right=DefiniteDescription
|
|
232
|
-
| '>' right=DefiniteDescription
|
|
233
|
-
| '>=' right=DefiniteDescription
|
|
234
|
-
| '<' right=DefiniteDescription
|
|
235
|
-
| '<=' right=DefiniteDescription
|
|
236
|
-
| 'in' set=DefiniteDescription
|
|
238
|
+
operator='==' right=DefiniteDescription
|
|
239
|
+
| operator='!=' right=DefiniteDescription
|
|
240
|
+
| operator='>' right=DefiniteDescription
|
|
241
|
+
| operator='>=' right=DefiniteDescription
|
|
242
|
+
| operator='<' right=DefiniteDescription
|
|
243
|
+
| operator='<=' right=DefiniteDescription
|
|
244
|
+
| operator='in' set=DefiniteDescription
|
|
237
245
|
;
|
|
238
246
|
|
|
239
|
-
Event: broadcast?='_broadcast'? 'event' name=ID (':'
|
|
247
|
+
Event: broadcast?='_broadcast'? 'event' name=ID (':' type=Type)?;
|
|
240
248
|
|
|
241
|
-
Operation: OperationRef | OperationDef;
|
|
249
|
+
Operation: operation=OperationRef | operation=OperationDef;
|
|
242
250
|
|
|
243
251
|
OperationDef:
|
|
244
252
|
'operation' name=ID '(' (parameters+=Parameter[','])? ')' '{' (
|
|
@@ -258,14 +266,14 @@ OperationDef:
|
|
|
258
266
|
;
|
|
259
267
|
|
|
260
268
|
Parameter:
|
|
261
|
-
name=ID ':'
|
|
269
|
+
name=ID ':' type=Type
|
|
262
270
|
;
|
|
263
271
|
|
|
264
272
|
Node: State | Initial | Junction | Final | ProbabilisticJunction;
|
|
265
273
|
|
|
266
274
|
State:
|
|
267
275
|
'state' name=ID '{'
|
|
268
|
-
body=
|
|
276
|
+
body=Body
|
|
269
277
|
//(
|
|
270
278
|
// nodes+=Node
|
|
271
279
|
// | transitions+=Transition
|
|
@@ -273,10 +281,6 @@ State:
|
|
|
273
281
|
//)*
|
|
274
282
|
'}'
|
|
275
283
|
;
|
|
276
|
-
StateBody: elements*=StateBodyContent;
|
|
277
|
-
StateBodyContent: /[^{}]+/ | NestedStateBlock;
|
|
278
|
-
NestedStateBlock: '{' body=StateBody '}';
|
|
279
|
-
|
|
280
284
|
|
|
281
285
|
Initial:
|
|
282
286
|
'initial' name=QualifiedName
|
|
@@ -312,23 +316,23 @@ Communication:
|
|
|
312
316
|
(
|
|
313
317
|
'[|'
|
|
314
318
|
(
|
|
315
|
-
|
|
316
|
-
( '|]' | '|'
|
|
317
|
-
|
|
|
319
|
+
source=QualifiedName '=' 'from'
|
|
320
|
+
( '|]' | '|' predicate=Expression '|]' )
|
|
321
|
+
| predicate=Expression? '|]'
|
|
318
322
|
)
|
|
319
323
|
)?
|
|
320
324
|
(
|
|
321
|
-
|
|
322
|
-
|
|
|
323
|
-
|
|
|
325
|
+
type=InputType
|
|
326
|
+
| type=OutputType
|
|
327
|
+
| type=SyncType
|
|
324
328
|
)?
|
|
325
329
|
;
|
|
326
330
|
|
|
327
|
-
InputType: '?';
|
|
331
|
+
InputType: '?' parameter=QualifiedName;
|
|
328
332
|
|
|
329
|
-
OutputType: '!';
|
|
333
|
+
OutputType: '!' value=CallExp;
|
|
330
334
|
|
|
331
|
-
SyncType: '.';
|
|
335
|
+
SyncType: '.' value=CallExp;
|
|
332
336
|
|
|
333
337
|
ClockReset: '#' clock=QualifiedName;
|
|
334
338
|
|
|
@@ -413,7 +417,7 @@ StateMachine: StateMachineDef | StateMachineRef;
|
|
|
413
417
|
StateMachineDef:
|
|
414
418
|
'stm' name=ID '{'
|
|
415
419
|
(
|
|
416
|
-
'uses'
|
|
420
|
+
'uses' uses+=QualifiedName[',']
|
|
417
421
|
| 'provides' provides+=QualifiedName[',']
|
|
418
422
|
| 'requires' requires+=QualifiedName[',']
|
|
419
423
|
| variables+=VariableList
|
|
@@ -474,7 +478,7 @@ RecordType:
|
|
|
474
478
|
;
|
|
475
479
|
|
|
476
480
|
Field:
|
|
477
|
-
name=ID ':'
|
|
481
|
+
name=ID ':' type=Type
|
|
478
482
|
;
|
|
479
483
|
|
|
480
484
|
Enumeration:
|
|
@@ -493,14 +497,14 @@ NamedExpression:
|
|
|
493
497
|
|
|
494
498
|
// TODO The FunctionBody is there to parse all contents of the function and replaces the pre and post condition parsing to simplify the translation to textx
|
|
495
499
|
Function:
|
|
496
|
-
'function' name=ID '(' (parameters+=Parameter[','])? ')' ':'
|
|
497
|
-
'{' body=
|
|
500
|
+
'function' name=ID '(' (parameters+=Parameter[','])? ')' ':' type=Type
|
|
501
|
+
'{' body=Body
|
|
498
502
|
//( 'precondition' preconditions+=Expression | 'postcondition' postconditions+=Expression)*
|
|
499
503
|
'}'
|
|
500
504
|
;
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
NestedBlock: '{' body=
|
|
505
|
+
Body: elements*=BodyContent;
|
|
506
|
+
BodyContent: /[^{}]+/ | NestedBlock;
|
|
507
|
+
NestedBlock: '{' body=Body '}';
|
|
504
508
|
|
|
505
509
|
Comment:
|
|
506
510
|
/\/\/.*$/
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
{%- macro render_port(name, direction,
|
|
2
|
-
{{ name }}: {{ direction }} {{
|
|
1
|
+
{%- macro render_port(name, direction, type) -%}
|
|
2
|
+
{{ name }}: {{ direction }} {{ type | type_to_port }} port {{ type | type_to_aadl_type}};
|
|
3
3
|
{%- endmacro -%}
|
|
4
4
|
|
|
5
5
|
{%- macro render_state_threads(machine) -%}
|
|
@@ -19,7 +19,7 @@ end {{ state.name }}.impl;
|
|
|
19
19
|
|
|
20
20
|
package LogicalArchitecture
|
|
21
21
|
public
|
|
22
|
-
with messages, Base_Types
|
|
22
|
+
with messages, Base_Types;
|
|
23
23
|
{%- for package in packages %}
|
|
24
24
|
process {{package.name}}
|
|
25
25
|
{%- set interface_vars = package.interfaces | map(attribute="variables") | sum(start=[]) -%}
|
|
@@ -28,12 +28,12 @@ public
|
|
|
28
28
|
features
|
|
29
29
|
{%- for interface in package.interfaces -%}
|
|
30
30
|
{%- for variable in interface.variables %}
|
|
31
|
-
{{ render_port(variable.name,
|
|
31
|
+
{{ render_port(variable.name, "in", variable.type) }}
|
|
32
32
|
{%- endfor %}
|
|
33
33
|
{%- endfor %}
|
|
34
34
|
{%- for machine in package.machines -%}
|
|
35
35
|
{%- for variable in machine.variables %}
|
|
36
|
-
{{ render_port(variable.name,
|
|
36
|
+
{{ render_port(variable.name, "in", variable.type) }}
|
|
37
37
|
{%- endfor %}
|
|
38
38
|
{%- endfor -%}
|
|
39
39
|
{%- endif %}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
package messages
|
|
2
|
+
public
|
|
3
|
+
with Base_Types, Data_Model;
|
|
4
|
+
{%- for package in packages %}
|
|
5
|
+
{%- for type in package.types %}
|
|
6
|
+
data {{ type.name }}
|
|
7
|
+
features
|
|
8
|
+
{%- for field in type.fields %}
|
|
9
|
+
{{ field.name }}: provides data access {{ field.type | type_to_aadl_type }};
|
|
10
|
+
{%- endfor %}
|
|
11
|
+
end {{type.name}};
|
|
12
|
+
{%- endfor %}
|
|
13
|
+
{%- endfor %}
|
|
14
|
+
end messages;
|
|
@@ -1,286 +0,0 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
from typing import Type as ClassType, Any, List, Optional, Union
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
# TODO Flatten this a little bit
|
|
6
|
-
|
|
7
|
-
class Node:
|
|
8
|
-
def __init__(self, parent: Optional[Any] = None):
|
|
9
|
-
self.parent = parent
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
class ControllerDef(Node):
|
|
13
|
-
def __init__(self, name, uses, provides, requires, connections, machines, events, operations, variables,
|
|
14
|
-
parent: Any):
|
|
15
|
-
super().__init__(parent)
|
|
16
|
-
self.name = name
|
|
17
|
-
self.uses = uses
|
|
18
|
-
self.provides = provides
|
|
19
|
-
self.requires = requires
|
|
20
|
-
self.connections = connections
|
|
21
|
-
self.machines = machines
|
|
22
|
-
self.events = events
|
|
23
|
-
self.operations = operations
|
|
24
|
-
self.variables = variables
|
|
25
|
-
|
|
26
|
-
def __repr__(self):
|
|
27
|
-
use_count = len(self.uses)
|
|
28
|
-
provide_count = len(self.provides)
|
|
29
|
-
require_count = len(self.requires)
|
|
30
|
-
connection_count = len(self.connections)
|
|
31
|
-
machine_count = len(self.machines)
|
|
32
|
-
event_count = len(self.events)
|
|
33
|
-
operation_count = len(self.operations)
|
|
34
|
-
variable_count = len(self.variables)
|
|
35
|
-
return f"{self.name}: ({use_count} uses), ({provide_count} provides), ({require_count} requires), ({connection_count} connections), ({machine_count} machines, ({event_count} events), ({operation_count} operations), ({variable_count} variables)"
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
class Variable(Node):
|
|
39
|
-
def __init__(self, name: str, kind, initial, parent: Any):
|
|
40
|
-
super().__init__(parent)
|
|
41
|
-
self.name = name
|
|
42
|
-
self.type = kind
|
|
43
|
-
self.initial = initial
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
class Type(Node):
|
|
47
|
-
def __init__(self, source: FunctionType, target: Optional[Type], parent: Any):
|
|
48
|
-
super().__init__(parent)
|
|
49
|
-
self.source = source
|
|
50
|
-
self.target = target
|
|
51
|
-
|
|
52
|
-
def __repr__(self):
|
|
53
|
-
if self.target:
|
|
54
|
-
return f"{self.source} <-> {self.target}"
|
|
55
|
-
return f"{self.source}"
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
class Field(Node):
|
|
59
|
-
def __init__(self, name: str, kind: Type, parent: Any):
|
|
60
|
-
super().__init__(parent)
|
|
61
|
-
self.name = name
|
|
62
|
-
self.type = kind
|
|
63
|
-
|
|
64
|
-
@property
|
|
65
|
-
def typename(self) -> str:
|
|
66
|
-
return str(self.type)
|
|
67
|
-
|
|
68
|
-
def __repr__(self):
|
|
69
|
-
return f"{self.name}[{self.type}]"
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
class RecordType(Node):
|
|
73
|
-
def __init__(self, name: str, fields: List[Field], parent: Any):
|
|
74
|
-
# Can be datatype or record
|
|
75
|
-
super().__init__(parent)
|
|
76
|
-
self.name = name
|
|
77
|
-
self.fields = fields
|
|
78
|
-
|
|
79
|
-
def __repr__(self):
|
|
80
|
-
return f"{self.name}({self.fields})"
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
class Function(Node):
|
|
84
|
-
def __init__(self, name: str, parameters, kind, body, parent: Any):
|
|
85
|
-
super().__init__(parent)
|
|
86
|
-
self.name = name
|
|
87
|
-
self.parameters = parameters
|
|
88
|
-
self.kind = kind
|
|
89
|
-
self.body = body
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
class RCModule(Node):
|
|
93
|
-
def __init__(self, name: str, connections, nodes, parent: Any):
|
|
94
|
-
super().__init__(parent)
|
|
95
|
-
self.name = name
|
|
96
|
-
self.connections = connections
|
|
97
|
-
self.nodes = nodes
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
class VariableList(Node):
|
|
101
|
-
def __init__(self, modifier, variables, parent: Any):
|
|
102
|
-
super().__init__(parent)
|
|
103
|
-
self.modifier = modifier
|
|
104
|
-
self.variables = variables
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
class Interface(Node):
|
|
108
|
-
def __init__(self, name: str, operations, events, variables: List[VariableList], clocks, parent: Any):
|
|
109
|
-
super().__init__(parent)
|
|
110
|
-
self.name = name
|
|
111
|
-
self.operations = operations
|
|
112
|
-
self.events = events
|
|
113
|
-
self._variables = variables
|
|
114
|
-
self.clocks = clocks
|
|
115
|
-
|
|
116
|
-
@property
|
|
117
|
-
def variables(self) -> List[Variable]:
|
|
118
|
-
return [var for v in self._variables for var in v.variables]
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
class RoboticPlatformDef(Node):
|
|
122
|
-
def __init__(self, name: str, uses, provides, requires, variables, operations, events, parent: Any):
|
|
123
|
-
super().__init__(parent)
|
|
124
|
-
self.name = name
|
|
125
|
-
self.uses = uses
|
|
126
|
-
self.provides = provides
|
|
127
|
-
self.requires = requires
|
|
128
|
-
self._variables = variables
|
|
129
|
-
self.operations = operations
|
|
130
|
-
self.events = events
|
|
131
|
-
|
|
132
|
-
@property
|
|
133
|
-
def variables(self) -> List[Variable]:
|
|
134
|
-
return [var for v in self._variables for var in v.variables]
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
class OperationDef(Node):
|
|
138
|
-
def __init__(self, name: str, parent: Any):
|
|
139
|
-
super().__init__(parent)
|
|
140
|
-
self.name = name
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
class RCPackage(Node):
|
|
144
|
-
def __init__(self, name: QualifiedName, imports: List[Import], controllers: List[ControllerDef],
|
|
145
|
-
modules: List[RCModule], functions: List[Function], types: List[RecordType],
|
|
146
|
-
machines: List[StateMachineDef], interfaces: List[Interface], robots: List[RoboticPlatformDef],
|
|
147
|
-
operations: List[OperationDef]):
|
|
148
|
-
super().__init__()
|
|
149
|
-
self.name = name
|
|
150
|
-
self.imports = imports
|
|
151
|
-
self.controllers = controllers
|
|
152
|
-
self.modules = modules
|
|
153
|
-
self.functions = functions
|
|
154
|
-
self.types = types
|
|
155
|
-
self.machines = machines
|
|
156
|
-
self.interfaces = interfaces
|
|
157
|
-
self.robots = robots
|
|
158
|
-
self.operations = operations
|
|
159
|
-
|
|
160
|
-
def __repr__(self):
|
|
161
|
-
return f"{self.name}"
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
class QualifiedName(Node):
|
|
165
|
-
def __init__(self, parts: List[str], parent: Any):
|
|
166
|
-
super().__init__(parent)
|
|
167
|
-
self.parts = parts
|
|
168
|
-
|
|
169
|
-
def __repr__(self):
|
|
170
|
-
return "".join(self.parts)
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
class StateMachineDef(Node):
|
|
174
|
-
def __init__(self, name, interfaces, provides, requires, variables, events, nodes, transitions, clocks,
|
|
175
|
-
parent: Any):
|
|
176
|
-
super().__init__(parent)
|
|
177
|
-
self.name = name
|
|
178
|
-
self.interfaces = interfaces
|
|
179
|
-
self.provides = provides
|
|
180
|
-
self.requires = requires
|
|
181
|
-
self._variables = variables
|
|
182
|
-
self.events = events
|
|
183
|
-
self.nodes = nodes
|
|
184
|
-
self.clocks = clocks
|
|
185
|
-
self.transitions = transitions
|
|
186
|
-
|
|
187
|
-
@property
|
|
188
|
-
def variables(self) -> List[Variable]:
|
|
189
|
-
return [var for v in self._variables for var in v.variables]
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
class Transition(Node):
|
|
193
|
-
def __init__(self, name, source, target, trigger, reset, deadline, condition, action, parent: Any):
|
|
194
|
-
super().__init__(parent)
|
|
195
|
-
self.name = name
|
|
196
|
-
self.source = source
|
|
197
|
-
self.target = target
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
class QualifiedNameWithWildcard(Node):
|
|
201
|
-
def __init__(self, name, parent: Any):
|
|
202
|
-
super().__init__(parent)
|
|
203
|
-
self.name = name
|
|
204
|
-
|
|
205
|
-
def __repr__(self):
|
|
206
|
-
return str(self.name) + "::*"
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
class Import(Node):
|
|
210
|
-
def __init__(self, name, parent: Any):
|
|
211
|
-
super().__init__(parent)
|
|
212
|
-
self.name = name
|
|
213
|
-
|
|
214
|
-
def __repr__(self):
|
|
215
|
-
return str(self.name)
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
class FunctionType(Node):
|
|
219
|
-
def __init__(self, source: ProductType, target: Optional[FunctionType], parent: Any):
|
|
220
|
-
super().__init__(parent)
|
|
221
|
-
self.source = source
|
|
222
|
-
self.target = target
|
|
223
|
-
|
|
224
|
-
def __repr__(self):
|
|
225
|
-
if self.target:
|
|
226
|
-
return f"{self.source} -> {self.target}"
|
|
227
|
-
return f"{self.source}"
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
class TypeRef(Node):
|
|
231
|
-
def __init__(self, kind, parent: Any):
|
|
232
|
-
super().__init__(parent)
|
|
233
|
-
self.type = kind
|
|
234
|
-
|
|
235
|
-
def __repr__(self):
|
|
236
|
-
return f"{self.type}"
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
class VectorType(Node):
|
|
240
|
-
# def __init__(self, source: Union[VectorDef, MatrixDef, TypeRef], parent: Any):
|
|
241
|
-
def __init__(self, source: Union[TypeRef], parent: Any):
|
|
242
|
-
super().__init__(parent)
|
|
243
|
-
self.source = source
|
|
244
|
-
|
|
245
|
-
def __repr__(self):
|
|
246
|
-
return f"{self.source}"
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
class ProductType(Node):
|
|
250
|
-
def __init__(self, types: List[Union[VectorType, TypeRef]], parent: Any):
|
|
251
|
-
super().__init__(parent)
|
|
252
|
-
self.types = types
|
|
253
|
-
|
|
254
|
-
def __repr__(self):
|
|
255
|
-
if len(self.types) > 1:
|
|
256
|
-
joined = "*".join(map(str, self.types))
|
|
257
|
-
return f"{joined}]"
|
|
258
|
-
return f"{self.types[0]}"
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
class SeqType(Node):
|
|
262
|
-
def __init__(self, domain, parent: Any):
|
|
263
|
-
super().__init__(parent)
|
|
264
|
-
self.domain = domain
|
|
265
|
-
|
|
266
|
-
def __repr__(self):
|
|
267
|
-
return f"Seq({self.domain})"
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
class Event(Node):
|
|
271
|
-
def __init__(self, name: str, broadcast: bool, kind: Type, parent: Any):
|
|
272
|
-
super().__init__(parent)
|
|
273
|
-
self.name = name
|
|
274
|
-
self.broadcast = broadcast
|
|
275
|
-
self.type = kind
|
|
276
|
-
|
|
277
|
-
def __repr__(self):
|
|
278
|
-
return f"Event: {self.name} {self.broadcast, self.type}"
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
def all_concepts() -> List[ClassType]:
|
|
282
|
-
import inspect
|
|
283
|
-
return [
|
|
284
|
-
obj for _, obj in globals().items()
|
|
285
|
-
if inspect.isclass(obj) and obj.__module__ == __name__
|
|
286
|
-
]
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
def typename_to_port(type_name: str) -> str:
|
|
2
|
-
event_types = {"event"}
|
|
3
|
-
data_types = {"int", "integer", "real", "float", "double", "string"}
|
|
4
|
-
mixed_types = {"event_data", "event data"}
|
|
5
|
-
|
|
6
|
-
if type_name in event_types:
|
|
7
|
-
return "event"
|
|
8
|
-
if type_name in data_types:
|
|
9
|
-
return "data"
|
|
10
|
-
if type_name in mixed_types:
|
|
11
|
-
return "event data"
|
|
12
|
-
return "data"
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
package messages
|
|
2
|
-
public
|
|
3
|
-
with Base_Types, Data_Model;
|
|
4
|
-
{%- for package in packages %}
|
|
5
|
-
{%- for type in package.types %}
|
|
6
|
-
data {{ type.name }}
|
|
7
|
-
features
|
|
8
|
-
{%- for field in type.fields %}
|
|
9
|
-
{%- if field.typename in ['real', 'float', 'double'] %}
|
|
10
|
-
{{ field.name }}: provides data access Base_Types::Float_64;
|
|
11
|
-
{%- elif field.typename in ['int', 'integer', 'long'] %}
|
|
12
|
-
{{ field.name }}: provides data access Base_Types::Integer_64;
|
|
13
|
-
{%- elif field.typename in ['bool', 'boolean'] %}
|
|
14
|
-
{{ field.name }}: provides data access Base_Types::Boolean;
|
|
15
|
-
{%- elif field.typename in ['string', 'text'] %}
|
|
16
|
-
{{ field.name }}: provides data access Data_Model::String;
|
|
17
|
-
{%- elif field.typename in ['byte', 'bytes'] %}
|
|
18
|
-
{{ field.name }}: provides data access Base_Types::Unsigned_8;
|
|
19
|
-
{%- else %}
|
|
20
|
-
-- Unknown type '{{ field.typename }}'; adjust mapping
|
|
21
|
-
{{ field.name }}: provides data access Data_Model::Generic_Type;
|
|
22
|
-
{%- endif %}
|
|
23
|
-
{%- endfor %}
|
|
24
|
-
end {{type.name}};
|
|
25
|
-
{%- endfor %}
|
|
26
|
-
{%- endfor %}
|
|
27
|
-
end messages;
|
|
File without changes
|
|
File without changes
|
|
File without changes
|