viv-compiler 0.1.0__py3-none-any.whl → 0.1.2__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.
- viv_compiler/{utils/_version.py → _version.py} +1 -1
- viv_compiler/cli.py +14 -12
- viv_compiler/config/config.py +17 -18
- viv_compiler/core/__init__.py +3 -3
- viv_compiler/core/core.py +7 -7
- viv_compiler/core/{importer.py → includes.py} +5 -5
- viv_compiler/core/metadata.py +71 -0
- viv_compiler/core/{postprocessor.py → postprocessing.py} +6 -32
- viv_compiler/core/{validator.py → validation.py} +203 -88
- viv_compiler/core/visitor.py +184 -139
- viv_compiler/grammar/viv.peg +450 -218
- viv_compiler/types/content_public_schemas.py +59 -31
- viv_compiler/types/dsl_public_schemas.py +84 -82
- viv_compiler/utils/utils.py +93 -33
- {viv_compiler-0.1.0.dist-info → viv_compiler-0.1.2.dist-info}/METADATA +120 -82
- viv_compiler-0.1.2.dist-info/RECORD +33 -0
- viv_compiler-0.1.0.dist-info/RECORD +0 -32
- {viv_compiler-0.1.0.dist-info → viv_compiler-0.1.2.dist-info}/WHEEL +0 -0
- {viv_compiler-0.1.0.dist-info → viv_compiler-0.1.2.dist-info}/entry_points.txt +0 -0
- {viv_compiler-0.1.0.dist-info → viv_compiler-0.1.2.dist-info}/licenses/LICENSE +0 -0
- {viv_compiler-0.1.0.dist-info → viv_compiler-0.1.2.dist-info}/top_level.txt +0 -0
viv_compiler/core/visitor.py
CHANGED
@@ -9,8 +9,8 @@ import copy
|
|
9
9
|
import arpeggio
|
10
10
|
import viv_compiler.config
|
11
11
|
import viv_compiler.types
|
12
|
-
from viv_compiler.types import ExpressionDiscriminator, ReferencePathComponentDiscriminator
|
13
|
-
from typing import Any, Optional
|
12
|
+
from viv_compiler.types import ExpressionDiscriminator, ReferencePathComponentDiscriminator, LocalVariable
|
13
|
+
from typing import Any, Optional
|
14
14
|
|
15
15
|
|
16
16
|
class Visitor(arpeggio.PTNodeVisitor):
|
@@ -21,24 +21,47 @@ class Visitor(arpeggio.PTNodeVisitor):
|
|
21
21
|
"""Visit the <file> node, i.e., the root of the parse tree."""
|
22
22
|
ast = {"_includes": [], "tropes": [], "actions": []}
|
23
23
|
for child in children:
|
24
|
-
if child["
|
24
|
+
if child["_type"] == 'include':
|
25
25
|
ast['_includes'].append(child['value'])
|
26
|
-
elif child["
|
26
|
+
elif child["_type"] == 'action':
|
27
27
|
ast['actions'].append(child['value'])
|
28
|
-
elif child["
|
28
|
+
elif child["_type"] == 'trope':
|
29
29
|
ast['tropes'].append(child['value'])
|
30
30
|
return ast
|
31
31
|
|
32
32
|
@staticmethod
|
33
33
|
def visit_include(_, children: Any) -> dict[str, Any]:
|
34
34
|
"""Visit an <include> node."""
|
35
|
-
return {"
|
35
|
+
return {"_type": "include", "value": children[0]}
|
36
36
|
|
37
37
|
@staticmethod
|
38
38
|
def visit_filename(_, children: Any) -> str:
|
39
39
|
"""Visit a <filename> node."""
|
40
40
|
return ''.join(children)
|
41
41
|
|
42
|
+
@staticmethod
|
43
|
+
def visit_trope(_, children: Any) -> dict[str, Any]:
|
44
|
+
"""Visit a <trope> node."""
|
45
|
+
if len(children) == 3:
|
46
|
+
name, params, conditions = children
|
47
|
+
else:
|
48
|
+
name, conditions = children
|
49
|
+
params = []
|
50
|
+
trope_definition = {"name": name, "params": params, "conditions": conditions}
|
51
|
+
return {"_type": "trope", "value": trope_definition}
|
52
|
+
|
53
|
+
@staticmethod
|
54
|
+
def visit_trope_params(_, children: Any) -> list[str]:
|
55
|
+
"""Visit a <trope_params> node."""
|
56
|
+
return children
|
57
|
+
|
58
|
+
@staticmethod
|
59
|
+
def visit_trope_param(_, children: Any) -> viv_compiler.types.TropeParam:
|
60
|
+
"""Visit a <trope_param> node."""
|
61
|
+
role_type, name = children
|
62
|
+
component = {"name": name, "isEntityParam": role_type["_is_entity"]}
|
63
|
+
return component
|
64
|
+
|
42
65
|
@staticmethod
|
43
66
|
def visit_action(_, children: Any) -> dict[str, Any]:
|
44
67
|
"""Visit an <action> node."""
|
@@ -46,7 +69,7 @@ class Visitor(arpeggio.PTNodeVisitor):
|
|
46
69
|
header, body = children
|
47
70
|
action_definition.update(header)
|
48
71
|
action_definition.update(body)
|
49
|
-
return {"
|
72
|
+
return {"_type": "action", "value": action_definition}
|
50
73
|
|
51
74
|
@staticmethod
|
52
75
|
def visit_action_header(_, children: Any) -> dict[str, Any]:
|
@@ -134,6 +157,12 @@ class Visitor(arpeggio.PTNodeVisitor):
|
|
134
157
|
component = {"type": ExpressionDiscriminator.LIST, "value": children}
|
135
158
|
return component
|
136
159
|
|
160
|
+
@staticmethod
|
161
|
+
def visit_tag(_, children: Any) -> viv_compiler.types.StringField:
|
162
|
+
"""Visit a <tag> node."""
|
163
|
+
component = {"type": ExpressionDiscriminator.STRING, "value": children[0]}
|
164
|
+
return component
|
165
|
+
|
137
166
|
@staticmethod
|
138
167
|
def visit_roles(_, children: Any) -> dict[str, Any]:
|
139
168
|
"""Visit a <roles> node."""
|
@@ -166,17 +195,23 @@ class Visitor(arpeggio.PTNodeVisitor):
|
|
166
195
|
"partner": False,
|
167
196
|
"recipient": False,
|
168
197
|
"bystander": False,
|
169
|
-
"subject": False,
|
170
198
|
"absent": False,
|
171
199
|
"precast": False,
|
172
200
|
"build": False,
|
173
201
|
}
|
202
|
+
marked_entity_role = False
|
174
203
|
for child in children:
|
175
|
-
if
|
204
|
+
if "_is_entity" in child:
|
205
|
+
marked_entity_role = child["_is_entity"]
|
206
|
+
elif "min" in child:
|
176
207
|
component['min'] = child['min']['value']
|
177
208
|
component['max'] = child['max']['value']
|
178
209
|
else:
|
179
210
|
component.update(child)
|
211
|
+
if marked_entity_role and component['symbol']:
|
212
|
+
raise ValueError(f"Role '@{component['name']}' has entity prefix but is marked symbol")
|
213
|
+
if not marked_entity_role and not component['symbol']:
|
214
|
+
raise ValueError(f"Role '&{component['name']}' has symbol prefix but is not marked symbol")
|
180
215
|
if not (component['item'] or component['action'] or component['location'] or component['symbol']):
|
181
216
|
component['character'] = True
|
182
217
|
if component['mean'] is not None:
|
@@ -206,6 +241,11 @@ class Visitor(arpeggio.PTNodeVisitor):
|
|
206
241
|
return {"min": children[0], "max": children[0]}
|
207
242
|
return {"min": children[0], "max": children[1]}
|
208
243
|
|
244
|
+
@staticmethod
|
245
|
+
def visit_binding_type(_, children: Any) -> dict[str, bool]:
|
246
|
+
"""Visit a <binding_type> node."""
|
247
|
+
return {"_is_entity": children[0] == "@"}
|
248
|
+
|
209
249
|
@staticmethod
|
210
250
|
def visit_role_name(_, children: Any) -> dict[str, str]:
|
211
251
|
"""Visit a <role_name> node."""
|
@@ -348,31 +388,6 @@ class Visitor(arpeggio.PTNodeVisitor):
|
|
348
388
|
# Move the 'bindings' field from the options component to the top level of the reaction value
|
349
389
|
reaction_object['bindings'] = reaction_object['options']['bindings']
|
350
390
|
del reaction_object['options']['bindings']
|
351
|
-
# Validate the shape of the reaction value
|
352
|
-
def _is_reaction_value(obj) -> "TypeGuard[viv_compiler.types.ReactionValue]":
|
353
|
-
if not isinstance(obj, dict):
|
354
|
-
return False
|
355
|
-
if not {"actionName", "bindings", "options"} <= set(obj):
|
356
|
-
return False
|
357
|
-
if not isinstance(obj.get("actionName"), str):
|
358
|
-
return False
|
359
|
-
bindings = obj.get("bindings")
|
360
|
-
if not isinstance(bindings, list):
|
361
|
-
return False
|
362
|
-
for b in bindings:
|
363
|
-
if not (isinstance(b, dict) and b.get("type") == "binding" and isinstance(b.get("value"), dict)):
|
364
|
-
return False
|
365
|
-
v = b["value"]
|
366
|
-
if not (isinstance(v.get("role"), str) and "entity" in v):
|
367
|
-
return False
|
368
|
-
options = obj.get("options")
|
369
|
-
if not isinstance(options, dict):
|
370
|
-
return False
|
371
|
-
if "bindings" in options:
|
372
|
-
return False
|
373
|
-
return True
|
374
|
-
if not _is_reaction_value(reaction_object):
|
375
|
-
raise ValueError(f"Malformed reaction generated by Visitor: {reaction_object!r}")
|
376
391
|
# Package up the component and return it
|
377
392
|
reaction_value: viv_compiler.types.ReactionValue = reaction_object # type: ignore[assignment]
|
378
393
|
component: viv_compiler.types.Reaction = {"type": ExpressionDiscriminator.REACTION, "value": reaction_value}
|
@@ -389,14 +404,14 @@ class Visitor(arpeggio.PTNodeVisitor):
|
|
389
404
|
return {"bindings": children}
|
390
405
|
|
391
406
|
@staticmethod
|
392
|
-
def visit_binding(_, children: Any) -> viv_compiler.types.
|
407
|
+
def visit_binding(_, children: Any) -> viv_compiler.types.ReactionRoleBindings:
|
393
408
|
"""Visit a <binding> node."""
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
409
|
+
role_type, role_name, candidate_expression = children
|
410
|
+
component = {
|
411
|
+
"role": role_name,
|
412
|
+
"isEntityRole": role_type["_is_entity"],
|
413
|
+
"candidates": candidate_expression,
|
414
|
+
}
|
400
415
|
return component
|
401
416
|
|
402
417
|
@staticmethod
|
@@ -525,21 +540,20 @@ class Visitor(arpeggio.PTNodeVisitor):
|
|
525
540
|
@staticmethod
|
526
541
|
def visit_time(_, children: Any) -> dict[str, Any]:
|
527
542
|
"""Visit a <time> node."""
|
528
|
-
period = children[-1] # AM or PM
|
529
543
|
raw_hour = int(children[0])
|
530
|
-
|
531
|
-
if
|
532
|
-
|
533
|
-
|
534
|
-
"hour
|
535
|
-
|
536
|
-
|
537
|
-
|
538
|
-
|
539
|
-
|
540
|
-
|
541
|
-
|
542
|
-
|
544
|
+
minute = int(children[1]) if len(children) > 1 and children[1].isdigit() else 0
|
545
|
+
if children[-1].upper() in ("AM", "PM"): # 12-hour form
|
546
|
+
period = children[-1].upper()
|
547
|
+
if not 1 <= raw_hour <= 12:
|
548
|
+
raise ValueError(f"Invalid hour in 12-hour time: {raw_hour}")
|
549
|
+
hour = (raw_hour % 12) + (12 if period == "PM" else 0)
|
550
|
+
else: # 24-hour form
|
551
|
+
if not 0 <= raw_hour <= 23:
|
552
|
+
raise ValueError(f"Invalid hour in 24-hour time: {raw_hour}")
|
553
|
+
hour = raw_hour
|
554
|
+
if not 0 <= minute <= 59:
|
555
|
+
raise ValueError(f"Invalid minute in time: {minute}")
|
556
|
+
component = {"type": "time", "hour": hour, "minute": minute}
|
543
557
|
return component
|
544
558
|
|
545
559
|
@staticmethod
|
@@ -560,12 +574,15 @@ class Visitor(arpeggio.PTNodeVisitor):
|
|
560
574
|
if children[0] == "join":
|
561
575
|
join_saliences = True
|
562
576
|
children = children[1:]
|
563
|
-
|
564
|
-
|
577
|
+
local_variable, body = None, []
|
578
|
+
if len(children) == 1: # Default only
|
579
|
+
default_value_expression = children[0]
|
580
|
+
else:
|
581
|
+
local_variable, default_value_expression, body = children
|
565
582
|
component = {
|
566
583
|
"saliences": {
|
567
584
|
"default": default_value_expression,
|
568
|
-
"variable":
|
585
|
+
"variable": local_variable,
|
569
586
|
"body": body,
|
570
587
|
}
|
571
588
|
}
|
@@ -590,12 +607,15 @@ class Visitor(arpeggio.PTNodeVisitor):
|
|
590
607
|
if children[0] == "join":
|
591
608
|
join_associations = True
|
592
609
|
children = children[1:]
|
593
|
-
|
594
|
-
|
610
|
+
local_variable, body = None, []
|
611
|
+
if len(children) == 1: # Default only
|
612
|
+
default_value_expression = children[0]
|
613
|
+
else:
|
614
|
+
local_variable, default_value_expression, body = children
|
595
615
|
component = {
|
596
616
|
"associations": {
|
597
617
|
"default": default_value_expression,
|
598
|
-
"variable":
|
618
|
+
"variable": local_variable,
|
599
619
|
"body": body,
|
600
620
|
}
|
601
621
|
}
|
@@ -641,6 +661,19 @@ class Visitor(arpeggio.PTNodeVisitor):
|
|
641
661
|
conditional_object['value'].update(child)
|
642
662
|
return conditional_object
|
643
663
|
|
664
|
+
@staticmethod
|
665
|
+
def visit_associations_conditional_branches(_, children: Any) -> dict[str, viv_compiler.types.Expression]:
|
666
|
+
"""Visit a <associations_conditional_branches> node."""
|
667
|
+
return {"branches": children}
|
668
|
+
|
669
|
+
@staticmethod
|
670
|
+
def visit_associations_conditional_branch(_, children: Any) -> dict[str, viv_compiler.types.Expression]:
|
671
|
+
"""Visit a <associations_conditional_branch> node."""
|
672
|
+
component = {}
|
673
|
+
for child in children:
|
674
|
+
component.update(child)
|
675
|
+
return component
|
676
|
+
|
644
677
|
@staticmethod
|
645
678
|
def visit_associations_conditional_consequent(_, children: Any) -> dict[str, list[viv_compiler.types.Expression]]:
|
646
679
|
"""Visit a <associations_conditional_consequent> node."""
|
@@ -709,10 +742,23 @@ class Visitor(arpeggio.PTNodeVisitor):
|
|
709
742
|
@staticmethod
|
710
743
|
def visit_conditional(_, children: Any) -> viv_compiler.types.Conditional:
|
711
744
|
"""Visit a <conditional> node."""
|
712
|
-
|
745
|
+
component = {"type": ExpressionDiscriminator.CONDITIONAL, "value": {}}
|
713
746
|
for child in children:
|
714
|
-
|
715
|
-
return
|
747
|
+
component['value'].update(child)
|
748
|
+
return component
|
749
|
+
|
750
|
+
@staticmethod
|
751
|
+
def visit_conditional_branches(_, children: Any) -> dict[str, viv_compiler.types.Expression]:
|
752
|
+
"""Visit a <conditional_branches> node."""
|
753
|
+
return {"branches": children}
|
754
|
+
|
755
|
+
@staticmethod
|
756
|
+
def visit_conditional_branch(_, children: Any) -> dict[str, viv_compiler.types.Expression]:
|
757
|
+
"""Visit a <conditional_branch> node."""
|
758
|
+
component = {}
|
759
|
+
for child in children:
|
760
|
+
component.update(child)
|
761
|
+
return component
|
716
762
|
|
717
763
|
@staticmethod
|
718
764
|
def visit_condition(_, children: Any) -> dict[str, viv_compiler.types.Expression]:
|
@@ -732,10 +778,20 @@ class Visitor(arpeggio.PTNodeVisitor):
|
|
732
778
|
@staticmethod
|
733
779
|
def visit_loop(_, children: Any) -> viv_compiler.types.Loop:
|
734
780
|
"""Visit a <loop> node."""
|
735
|
-
iterable_reference,
|
781
|
+
iterable_reference, loop_variable, loop_body = children
|
736
782
|
component = {
|
737
783
|
"type": ExpressionDiscriminator.LOOP,
|
738
|
-
"value": {"iterable": iterable_reference, "variable":
|
784
|
+
"value": {"iterable": iterable_reference, "variable": loop_variable, "body": loop_body}
|
785
|
+
}
|
786
|
+
return component
|
787
|
+
|
788
|
+
@staticmethod
|
789
|
+
def visit_local_variable(_, children: Any) -> LocalVariable:
|
790
|
+
"""Visit a <local_variable> node."""
|
791
|
+
_, binding_type, name = children
|
792
|
+
component = {
|
793
|
+
"name": name,
|
794
|
+
"isEntityVariable": binding_type["_is_entity"]
|
739
795
|
}
|
740
796
|
return component
|
741
797
|
|
@@ -912,68 +968,76 @@ class Visitor(arpeggio.PTNodeVisitor):
|
|
912
968
|
return children
|
913
969
|
|
914
970
|
@staticmethod
|
915
|
-
def visit_reference(
|
916
|
-
|
917
|
-
|
918
|
-
|
919
|
-
|
920
|
-
|
921
|
-
|
922
|
-
"""Visit a <role_anchored_reference> node."""
|
923
|
-
# Determine the anchor role name
|
924
|
-
if "globalVariable" in children[0]:
|
925
|
-
# If the reference is anchored in a global variable, expand the `$` anchor. `$` is really
|
926
|
-
# just syntactic sugar for `@this.scratch.`, which means any reference anchored in a global
|
971
|
+
def visit_reference(_, children: Any) -> viv_compiler.types.EntityReference | viv_compiler.types.SymbolReference:
|
972
|
+
"""Visit a <reference> node."""
|
973
|
+
is_symbol_reference = False
|
974
|
+
anchor_is_local_variable = False
|
975
|
+
if children[0] == "$":
|
976
|
+
# If the reference is anchored in a scratch variable, expand the `$` anchor. `$` is really
|
977
|
+
# just syntactic sugar for `@this.scratch.`, which means any reference anchored in a scratch
|
927
978
|
# variable is in fact an entity reference anchored in a role name.
|
928
|
-
|
929
|
-
|
930
|
-
|
931
|
-
|
932
|
-
|
933
|
-
|
934
|
-
|
979
|
+
children = children[1:]
|
980
|
+
if children[0] == "&":
|
981
|
+
# We will ignore the symbol sigil here, because ultimately that refers to the type of
|
982
|
+
# the scratch variable, not the anchor, which is always entity data.
|
983
|
+
pass
|
984
|
+
children = children[1:]
|
985
|
+
anchor = viv_compiler.config.SCRATCH_VARIABLE_REFERENCE_ANCHOR
|
986
|
+
path = [
|
987
|
+
*viv_compiler.config.SCRATCH_VARIABLE_REFERENCE_PATH_PREFIX,
|
988
|
+
{
|
989
|
+
"type": ReferencePathComponentDiscriminator.REFERENCE_PATH_COMPONENT_PROPERTY_NAME,
|
990
|
+
"name": children[0],
|
991
|
+
}
|
992
|
+
]
|
935
993
|
path += children[1] if len(children) > 1 else []
|
936
|
-
|
937
|
-
|
994
|
+
elif children[0] == "_":
|
995
|
+
anchor_is_local_variable = True
|
996
|
+
children = children[1:]
|
997
|
+
if children[0] == "&":
|
998
|
+
is_symbol_reference = True
|
999
|
+
children = children[1:]
|
1000
|
+
anchor = children[0]
|
1001
|
+
path = children[1] if len(children) > 1 else []
|
1002
|
+
else: # Bare reference to a role, e.g., `@foo` or `&bar`
|
1003
|
+
if children[0] == "&":
|
1004
|
+
is_symbol_reference = True
|
1005
|
+
children = children[1:]
|
1006
|
+
anchor = children[0]
|
938
1007
|
path = children[1] if len(children) > 1 else []
|
1008
|
+
if is_symbol_reference:
|
1009
|
+
component_type = ExpressionDiscriminator.SYMBOL_REFERENCE
|
1010
|
+
else:
|
1011
|
+
component_type = ExpressionDiscriminator.ENTITY_REFERENCE
|
939
1012
|
component = {
|
940
|
-
"type":
|
1013
|
+
"type": component_type,
|
941
1014
|
"value": {
|
942
|
-
"
|
943
|
-
"
|
1015
|
+
"local": anchor_is_local_variable,
|
1016
|
+
"anchor": anchor,
|
1017
|
+
"path": path,
|
944
1018
|
}
|
945
1019
|
}
|
946
1020
|
return component
|
947
1021
|
|
948
1022
|
@staticmethod
|
949
|
-
def
|
950
|
-
"""Visit
|
951
|
-
|
952
|
-
path = children[1] if len(children) > 1 else []
|
953
|
-
component = {
|
954
|
-
"type": ExpressionDiscriminator.LOCAL_VARIABLE_REFERENCE,
|
955
|
-
"value": {
|
956
|
-
"anchor": anchor, # The name of the local variable anchoring this reference
|
957
|
-
"path": path, # Sequence of components constituting a property path
|
958
|
-
}
|
959
|
-
}
|
960
|
-
return component
|
1023
|
+
def visit_entity_sigil(node: Any, _) -> Any:
|
1024
|
+
"""Visit an <entity_sigil> node."""
|
1025
|
+
return node
|
961
1026
|
|
962
1027
|
@staticmethod
|
963
|
-
def
|
964
|
-
"""Visit a <
|
965
|
-
|
966
|
-
return {"name": name}
|
1028
|
+
def visit_symbol_sigil(node: Any, _) -> Any:
|
1029
|
+
"""Visit a <symbol_sigil> node."""
|
1030
|
+
return node
|
967
1031
|
|
968
1032
|
@staticmethod
|
969
|
-
def
|
970
|
-
"""Visit a <
|
971
|
-
return
|
1033
|
+
def visit_scratch_variable_sigil(node: Any, _) -> Any:
|
1034
|
+
"""Visit a <scratch_variable_sigil> node."""
|
1035
|
+
return node
|
972
1036
|
|
973
1037
|
@staticmethod
|
974
|
-
def
|
975
|
-
"""Visit a <
|
976
|
-
return
|
1038
|
+
def visit_local_variable_sigil(node: Any, _) -> Any:
|
1039
|
+
"""Visit a <local_variable_sigil> node."""
|
1040
|
+
return node
|
977
1041
|
|
978
1042
|
@staticmethod
|
979
1043
|
def visit_reference_path(_, children: Any) -> list[viv_compiler.types.ReferencePathComponent]:
|
@@ -1063,13 +1127,17 @@ class Visitor(arpeggio.PTNodeVisitor):
|
|
1063
1127
|
@staticmethod
|
1064
1128
|
def visit_enum(_, children: Any) -> viv_compiler.types.Enum:
|
1065
1129
|
"""Visit an <enum> node."""
|
1066
|
-
|
1067
|
-
|
1130
|
+
additive_inverse_present = False
|
1131
|
+
if len(children) > 1:
|
1132
|
+
additive_inverse_present = children[0] == "-"
|
1133
|
+
token = children[-1]
|
1134
|
+
unscaled = token[:2] == "##" # As opposed to '#', which yields a scaled enum
|
1135
|
+
name = token.lstrip('#')
|
1068
1136
|
component = {
|
1069
1137
|
"type": ExpressionDiscriminator.ENUM,
|
1070
1138
|
"value": {
|
1071
|
-
"name":
|
1072
|
-
"scaled":
|
1139
|
+
"name": name,
|
1140
|
+
"scaled": not unscaled,
|
1073
1141
|
"minus": additive_inverse_present
|
1074
1142
|
}
|
1075
1143
|
}
|
@@ -1140,35 +1208,12 @@ class Visitor(arpeggio.PTNodeVisitor):
|
|
1140
1208
|
component = {"type": ExpressionDiscriminator.NULL_TYPE, "value": None}
|
1141
1209
|
return component
|
1142
1210
|
|
1143
|
-
@staticmethod
|
1144
|
-
def visit_tag(_, children: Any) -> viv_compiler.types.StringField:
|
1145
|
-
"""Visit a <tag> node."""
|
1146
|
-
component = {"type": ExpressionDiscriminator.STRING, "value": children[0]}
|
1147
|
-
return component
|
1148
|
-
|
1149
1211
|
@staticmethod
|
1150
1212
|
def visit_eval_fail_safe_marker(_, __: Any) -> viv_compiler.types.EvalFailSafeField:
|
1151
1213
|
"""Visit an <eval_fail_safe_marker> node."""
|
1152
1214
|
component = {"type": ExpressionDiscriminator.EVAL_FAIL_SAFE}
|
1153
1215
|
return component
|
1154
1216
|
|
1155
|
-
@staticmethod
|
1156
|
-
def visit_trope(_, children: Any) -> dict[str, Any]:
|
1157
|
-
"""Visit a <trope> node."""
|
1158
|
-
if len(children) == 3:
|
1159
|
-
name, role_names, conditions = children
|
1160
|
-
else:
|
1161
|
-
name, conditions = children
|
1162
|
-
role_names = []
|
1163
|
-
component_value = {"name": name, "params": role_names, "conditions": conditions}
|
1164
|
-
component = {"type": "trope", "value": component_value}
|
1165
|
-
return component
|
1166
|
-
|
1167
|
-
@staticmethod
|
1168
|
-
def visit_trope_role_names(_, children: Any) -> list[str]:
|
1169
|
-
"""Visit a <trope_role_names> node."""
|
1170
|
-
return children
|
1171
|
-
|
1172
1217
|
@staticmethod
|
1173
1218
|
def visit_trope_fit_expression(_, children: Any) -> viv_compiler.types.TropeFitExpression:
|
1174
1219
|
"""Visit a <trope_fit_expression> node."""
|