viv-compiler 0.1.0__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/__init__.py +14 -0
- viv_compiler/__main__.py +3 -0
- viv_compiler/_samples/__init__.py +0 -0
- viv_compiler/_samples/smoke-test.viv +5 -0
- viv_compiler/api.py +58 -0
- viv_compiler/backports/__init__.py +1 -0
- viv_compiler/backports/backports.py +12 -0
- viv_compiler/cli.py +237 -0
- viv_compiler/config/__init__.py +1 -0
- viv_compiler/config/config.py +88 -0
- viv_compiler/core/__init__.py +5 -0
- viv_compiler/core/core.py +185 -0
- viv_compiler/core/importer.py +111 -0
- viv_compiler/core/postprocessor.py +749 -0
- viv_compiler/core/validator.py +915 -0
- viv_compiler/core/visitor.py +1188 -0
- viv_compiler/grammar/__init__.py +0 -0
- viv_compiler/grammar/viv.peg +228 -0
- viv_compiler/py.typed +1 -0
- viv_compiler/types/__init__.py +3 -0
- viv_compiler/types/content_public_schemas.py +420 -0
- viv_compiler/types/dsl_public_schemas.py +566 -0
- viv_compiler/types/internal_types.py +167 -0
- viv_compiler/utils/__init__.py +1 -0
- viv_compiler/utils/_version.py +2 -0
- viv_compiler/utils/utils.py +171 -0
- viv_compiler-0.1.0.dist-info/METADATA +284 -0
- viv_compiler-0.1.0.dist-info/RECORD +32 -0
- viv_compiler-0.1.0.dist-info/WHEEL +5 -0
- viv_compiler-0.1.0.dist-info/entry_points.txt +3 -0
- viv_compiler-0.1.0.dist-info/licenses/LICENSE +21 -0
- viv_compiler-0.1.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,566 @@
|
|
1
|
+
"""Types associated with the lower-level concerns represented in the Viv DSL's abstract syntax trees.
|
2
|
+
|
3
|
+
This module and `content_public_schemas.py` together define the public, stable schema for Viv compiled
|
4
|
+
content bundles. The schemas capture the compiler's emitted JSON shapes, which are mirrored in the
|
5
|
+
corresponding runtime type definitions, assuming the same version number for the compiler and runtime.
|
6
|
+
As such, the schemas constitute a reliable contract between the compiler and any Viv runtime.
|
7
|
+
"""
|
8
|
+
|
9
|
+
from __future__ import annotations
|
10
|
+
|
11
|
+
from typing import Union, Annotated, TypeAlias, Literal, TYPE_CHECKING
|
12
|
+
from typing_extensions import TypedDict
|
13
|
+
from pydantic import Field
|
14
|
+
from viv_compiler.backports import StrEnum
|
15
|
+
|
16
|
+
|
17
|
+
if TYPE_CHECKING:
|
18
|
+
# Imported for static checking only; referenced by string at runtime to avoid cycles
|
19
|
+
from .content_public_schemas import Reaction, RoleName, TropeName
|
20
|
+
|
21
|
+
# Union specifying all the Viv expression types
|
22
|
+
Expression: TypeAlias = Annotated[
|
23
|
+
Union[
|
24
|
+
"AdapterFunctionCall",
|
25
|
+
"ArithmeticExpression",
|
26
|
+
"Assignment",
|
27
|
+
"BoolField",
|
28
|
+
"ChanceExpression",
|
29
|
+
"Comparison",
|
30
|
+
"Conditional",
|
31
|
+
"Conjunction",
|
32
|
+
"Disjunction",
|
33
|
+
"EntityReference",
|
34
|
+
"Enum",
|
35
|
+
"EvalFailSafeField",
|
36
|
+
"FloatField",
|
37
|
+
"IntField",
|
38
|
+
"ListField",
|
39
|
+
"LocalVariableReference",
|
40
|
+
"Loop",
|
41
|
+
"MembershipTest",
|
42
|
+
"NullField",
|
43
|
+
"ObjectField",
|
44
|
+
"Reaction",
|
45
|
+
"RoleUnpacking",
|
46
|
+
"StringField",
|
47
|
+
"TemplateStringField",
|
48
|
+
"TropeFitExpression",
|
49
|
+
],
|
50
|
+
Field(discriminator="type"),
|
51
|
+
]
|
52
|
+
|
53
|
+
|
54
|
+
# Enum containing discriminators for each Viv expression type
|
55
|
+
class ExpressionDiscriminator(StrEnum):
|
56
|
+
ADAPTER_FUNCTION_CALL = "adapterFunctionCall"
|
57
|
+
ASSIGNMENT = "assignment"
|
58
|
+
ARITHMETIC_EXPRESSION = "arithmeticExpression"
|
59
|
+
BINDING = "binding"
|
60
|
+
BOOL = "bool"
|
61
|
+
CHANCE_EXPRESSION = "chanceExpression"
|
62
|
+
COMPARISON = "comparison"
|
63
|
+
CONDITIONAL = "conditional"
|
64
|
+
CONJUNCTION = "conjunction"
|
65
|
+
DISJUNCTION = "disjunction"
|
66
|
+
ENTITY_REFERENCE = "entityReference"
|
67
|
+
ENUM = "enum"
|
68
|
+
EVAL_FAIL_SAFE = "evalFailSafe"
|
69
|
+
FLOAT = "float"
|
70
|
+
INT = "int"
|
71
|
+
LIST = "list"
|
72
|
+
LOCAL_VARIABLE_REFERENCE = "localVariableReference"
|
73
|
+
LOOP = "loop"
|
74
|
+
MEMBERSHIP_TEST = "membershipTest"
|
75
|
+
NULL_TYPE = "nullType"
|
76
|
+
OBJECT = "object"
|
77
|
+
REACTION = "reaction"
|
78
|
+
ROLE_UNPACKING = "roleUnpacking"
|
79
|
+
STRING = "string"
|
80
|
+
TEMPLATE_STRING = "templateString"
|
81
|
+
TROPE_FIT_EXPRESSION = "tropeFitExpression"
|
82
|
+
|
83
|
+
|
84
|
+
# Mixin for expression types that may be negated
|
85
|
+
class NegatableExpression(TypedDict, total=False):
|
86
|
+
"""Mixin for expression types that may be negated."""
|
87
|
+
# Whether to negate the result of the expression. Only present when `True`.
|
88
|
+
negated: Literal[True]
|
89
|
+
|
90
|
+
|
91
|
+
class AdapterFunctionCall(NegatableExpression):
|
92
|
+
"""A Viv adapter function call, which parameterizes a call to some function that must be exposed in the target
|
93
|
+
application's Viv adapter.
|
94
|
+
|
95
|
+
For instance, a Viv author might specify a function call in an action such as
|
96
|
+
`~transport(@person.id, @destination.id)`, in which case there must be a function
|
97
|
+
`transport()` exposed in the adapter. The Viv runtime confirms the existence of all
|
98
|
+
referenced function names during adapter initialization.
|
99
|
+
"""
|
100
|
+
# Discriminant for a Viv adapter function call
|
101
|
+
type: Literal[ExpressionDiscriminator.ADAPTER_FUNCTION_CALL]
|
102
|
+
# The actual expression value
|
103
|
+
value: AdapterFunctionCallValue
|
104
|
+
|
105
|
+
|
106
|
+
class AdapterFunctionCallValue(TypedDict, total=False):
|
107
|
+
"""The actual expression value for a Viv function call."""
|
108
|
+
# The name of the target function. There must be a function stored in the target
|
109
|
+
# application's Viv adapter, via a key by this same name.
|
110
|
+
name: AdapterFunctionName
|
111
|
+
# An ordered list of Viv expressions whose evaluations will be passed as
|
112
|
+
# arguments to the function, in that same order.
|
113
|
+
args: list[Expression]
|
114
|
+
# Whether the function call should fail safely (i.e., evaluate to a falsy value) if the
|
115
|
+
# result of the function call is nullish. This field is only present when `True`.
|
116
|
+
resultFailSafe: Literal[True]
|
117
|
+
|
118
|
+
|
119
|
+
# The name for a function targeted by a Viv function call
|
120
|
+
AdapterFunctionName = str
|
121
|
+
|
122
|
+
|
123
|
+
class ArithmeticExpression(TypedDict):
|
124
|
+
"""A Viv arithmetic expression, which accepts two numeric operands and evaluates to a number."""
|
125
|
+
# Discriminant for a Viv arithmetic expression
|
126
|
+
type: Literal[ExpressionDiscriminator.ARITHMETIC_EXPRESSION]
|
127
|
+
# The actual expression value
|
128
|
+
value: ArithmeticExpressionValue
|
129
|
+
|
130
|
+
|
131
|
+
class ArithmeticExpressionValue(TypedDict):
|
132
|
+
"""The actual expression value for a Viv arithmetic expression."""
|
133
|
+
# An expression whose evaluation will be used as the left operand in the arithmetic expression
|
134
|
+
left: Expression
|
135
|
+
# The arithmetic operator
|
136
|
+
operator: ArithmeticOperator
|
137
|
+
# An expression whose evaluation will be used as the right operand in the arithmetic expression
|
138
|
+
right: Expression
|
139
|
+
|
140
|
+
|
141
|
+
# Enum of arithmetic operators supported by Viv
|
142
|
+
ArithmeticOperator = Literal["+", "-", "*", "/"]
|
143
|
+
|
144
|
+
|
145
|
+
class Assignment(TypedDict):
|
146
|
+
"""A Viv assignment (or update)."""
|
147
|
+
# Discriminant for a Viv assignment
|
148
|
+
type: Literal[ExpressionDiscriminator.ASSIGNMENT]
|
149
|
+
# The actual expression value
|
150
|
+
value: AssignmentValue
|
151
|
+
|
152
|
+
|
153
|
+
class AssignmentValue(TypedDict):
|
154
|
+
"""The actual expression value for a Viv assignment."""
|
155
|
+
# An expression whose evaluation will be used as the left operand in the assignment/update
|
156
|
+
left: Expression
|
157
|
+
# The assignment/update operator
|
158
|
+
operator: AssignmentOperator
|
159
|
+
# An expression whose evaluation will be used as the right operand in the assignment/update
|
160
|
+
right: Expression
|
161
|
+
|
162
|
+
|
163
|
+
# Enum containing the Viv assignment (and update) operators
|
164
|
+
AssignmentOperator = Literal["=", "+=", "-=", "*=", "/=", "append", "remove"]
|
165
|
+
|
166
|
+
|
167
|
+
class BoolField(TypedDict):
|
168
|
+
"""A Viv boolean."""
|
169
|
+
# Discriminant for a Viv boolean
|
170
|
+
type: Literal[ExpressionDiscriminator.BOOL]
|
171
|
+
# The boolean literal to which this expression will evaluate
|
172
|
+
value: bool
|
173
|
+
|
174
|
+
|
175
|
+
class ChanceExpression(TypedDict):
|
176
|
+
"""A Viv chance expression.
|
177
|
+
|
178
|
+
This is a kind of condition that evaluates to True if the specified probability value (a number
|
179
|
+
between 0.0 and 1.0) exceeds a pseudorandom number generated by the Viv interpreter.
|
180
|
+
"""
|
181
|
+
# Discriminant for a Viv chance expression
|
182
|
+
type: Literal[ExpressionDiscriminator.CHANCE_EXPRESSION]
|
183
|
+
# The specified probability, which the compiler guarantees to be a number in the range [0, 1]
|
184
|
+
value: float
|
185
|
+
|
186
|
+
|
187
|
+
class Comparison(NegatableExpression):
|
188
|
+
"""A Viv comparison, whereby two values are compared using a comparator."""
|
189
|
+
# Discriminant for a Viv comparison
|
190
|
+
type: Literal[ExpressionDiscriminator.COMPARISON]
|
191
|
+
# The actual expression value
|
192
|
+
value: ComparisonValue
|
193
|
+
|
194
|
+
|
195
|
+
class ComparisonValue(TypedDict):
|
196
|
+
"""The actual expression value for a Viv comparison."""
|
197
|
+
# An expression whose evaluation will serve as the left operand in the comparison
|
198
|
+
left: Expression
|
199
|
+
# The comparison operator
|
200
|
+
operator: Comparator
|
201
|
+
# An expression whose evaluation will serve as the right operand in the comparison
|
202
|
+
right: Expression
|
203
|
+
|
204
|
+
|
205
|
+
# Enum containing the Viv comparison operators
|
206
|
+
Comparator = Literal["==", ">", ">=", "<", "<=", "!="]
|
207
|
+
|
208
|
+
|
209
|
+
class Conditional(TypedDict):
|
210
|
+
"""A Viv conditional expression, allowing for branching based on the value of a test."""
|
211
|
+
# Discriminant for a Viv conditional
|
212
|
+
type: Literal[ExpressionDiscriminator.CONDITIONAL]
|
213
|
+
# The actual expression value
|
214
|
+
value: ConditionalValue
|
215
|
+
|
216
|
+
|
217
|
+
class ConditionalValue(TypedDict, total=False):
|
218
|
+
"""The actual expression value for a Viv conditional."""
|
219
|
+
# The condition that will be tested, which holds if its evaluation is truthy
|
220
|
+
condition: Expression
|
221
|
+
# A list of expressions that will be evaluated/executed should the condition hold
|
222
|
+
consequent: list[Expression]
|
223
|
+
# If an author has provided an alternative body (via an `else` clause), a list
|
224
|
+
# of expressions that will be evaluated/executed should the condition not hold.
|
225
|
+
alternative: list[Expression]
|
226
|
+
|
227
|
+
|
228
|
+
class Conjunction(NegatableExpression):
|
229
|
+
"""A Viv conjunction.
|
230
|
+
|
231
|
+
This kind of expression takes multiple expressions as operands and evaluates to
|
232
|
+
`True` if and only if all the respective expressions evaluate to truthy values.
|
233
|
+
"""
|
234
|
+
# Discriminant for a Viv conjunction
|
235
|
+
type: Literal[ExpressionDiscriminator.CONJUNCTION]
|
236
|
+
# The actual expression value
|
237
|
+
value: ConjunctionValue
|
238
|
+
|
239
|
+
|
240
|
+
class ConjunctionValue(TypedDict):
|
241
|
+
"""The actual expression value for a Viv conjunction."""
|
242
|
+
# A list of expressions that will be evaluated in turn to determine the result
|
243
|
+
# of the conjunction. Note that the interpreter stops evaluating as soon as a
|
244
|
+
# falsy evaluation is encountered.
|
245
|
+
operands: list[Expression]
|
246
|
+
|
247
|
+
|
248
|
+
class Disjunction(NegatableExpression):
|
249
|
+
"""A Viv disjunction.
|
250
|
+
|
251
|
+
This kind which takes multiple expressions and evaluates to `True` if and only
|
252
|
+
if at least one of the respective expressions evaluate to a truthy value.
|
253
|
+
"""
|
254
|
+
# Discriminant for a Viv disjunction
|
255
|
+
type: Literal[ExpressionDiscriminator.DISJUNCTION]
|
256
|
+
# The actual expression value
|
257
|
+
value: DisjunctionValue
|
258
|
+
|
259
|
+
|
260
|
+
class DisjunctionValue(TypedDict):
|
261
|
+
"""The actual expression value for a Viv disjunction."""
|
262
|
+
# A list of expressions that will be evaluated in turn to determine the result
|
263
|
+
# of the disjunction. Note that the interpreter stops evaluating as soon as a
|
264
|
+
# truthy evaluation is encountered.
|
265
|
+
operands: list[Expression]
|
266
|
+
|
267
|
+
|
268
|
+
class EntityReference(NegatableExpression):
|
269
|
+
"""A Viv entity reference, structured as an anchor role and a path to a specific property value.
|
270
|
+
|
271
|
+
Usually, the property is on the entity cast into the anchor role, but this is not the case if
|
272
|
+
the reference contains a pointer. For instance, `@person.boss->boss->traits.cruel` would return
|
273
|
+
the value stored at the path `traits.cruel` on the boss of the boss of the entity cast in the
|
274
|
+
anchor role `@person`.
|
275
|
+
|
276
|
+
Note that the compiler currently prevents an author from anchoring an entity reference in a
|
277
|
+
symbol role, which allows the interpreter to assume that the anchor role binds an entity.
|
278
|
+
|
279
|
+
Also note that references anchored in global variables, e.g. `$foo.bar.baz`, are compiled
|
280
|
+
to entities anchored in role references -- this is because `$` is really just syntactic
|
281
|
+
sugar for `@this.scratch.`.
|
282
|
+
"""
|
283
|
+
# Discriminant for a Viv reference
|
284
|
+
type: Literal[ExpressionDiscriminator.ENTITY_REFERENCE]
|
285
|
+
# The actual expression value
|
286
|
+
value: EntityReferenceValue
|
287
|
+
|
288
|
+
|
289
|
+
class EntityReferenceValue(TypedDict):
|
290
|
+
"""The actual expression value for a Viv entity reference."""
|
291
|
+
# The name of the role that anchors this reference
|
292
|
+
anchor: RoleName
|
293
|
+
# If applicable, the path to a specified property value. If the reference is just to
|
294
|
+
# the entity itself, this will be an empty list. Otherwise, it will specify a path
|
295
|
+
# to a specific property value, either on that entity or another one (via a pointer).
|
296
|
+
path: list[ReferencePathComponent]
|
297
|
+
|
298
|
+
|
299
|
+
class ReferencePathComponentPropertyName(TypedDict, total=False):
|
300
|
+
"""A component of a Viv reference path specifying a property to access."""
|
301
|
+
# Discriminant for a property-name reference path component
|
302
|
+
type: Literal[ReferencePathComponentDiscriminator.REFERENCE_PATH_COMPONENT_PROPERTY_NAME]
|
303
|
+
# The name of the property to access
|
304
|
+
name: str
|
305
|
+
# Whether this step should use the eval fail-safe. If the property is missing/null,
|
306
|
+
# the interpreter should return the eval fail-safe signal. Present only when `True`.
|
307
|
+
failSafe: Literal[True]
|
308
|
+
|
309
|
+
|
310
|
+
class ReferencePathComponentPointer(TypedDict, total=False):
|
311
|
+
"""A component of a Viv reference path specifying a pointer to dereference."""
|
312
|
+
# Discriminant for a pointer reference path component
|
313
|
+
type: Literal[ReferencePathComponentDiscriminator.REFERENCE_PATH_COMPONENT_POINTER]
|
314
|
+
# The name of the property to access in the entity data of the entity targeted by the pointer
|
315
|
+
propertyName: str
|
316
|
+
# Whether this pointer step should use the eval fail-safe. If the target isn't an entity or the
|
317
|
+
# pointed property is missing/null, the interpreter should return the eval fail-safe signal.
|
318
|
+
# Present only when `True`.
|
319
|
+
failSafe: Literal[True]
|
320
|
+
|
321
|
+
|
322
|
+
class ReferencePathComponentLookup(TypedDict, total=False):
|
323
|
+
"""A component of a Viv reference path specifying a property lookup or an array access.
|
324
|
+
|
325
|
+
The key/index can be specified by an arbitrary Viv expression.
|
326
|
+
"""
|
327
|
+
# Discriminant for a lookup reference path component
|
328
|
+
type: Literal[ReferencePathComponentDiscriminator.REFERENCE_PATH_COMPONENT_LOOKUP]
|
329
|
+
# An expression that should evaluate to a valid property key (string or integer)
|
330
|
+
key: Expression
|
331
|
+
# Whether this lookup should use the eval fail-safe. If the key/index yields a missing/null value,
|
332
|
+
# the interpreter should return the eval fail-safe signal. Present only when `True`.
|
333
|
+
failSafe: Literal[True]
|
334
|
+
|
335
|
+
|
336
|
+
class ReferencePathComponentDiscriminator(StrEnum):
|
337
|
+
"""Enum containing discriminators for the possible reference path components."""
|
338
|
+
# Discriminant for a property-name reference path component
|
339
|
+
REFERENCE_PATH_COMPONENT_PROPERTY_NAME = "referencePathComponentPropertyName"
|
340
|
+
# Discriminant for a pointer reference path component
|
341
|
+
REFERENCE_PATH_COMPONENT_POINTER = "referencePathComponentPointer"
|
342
|
+
# Discriminant for a lookup reference path component
|
343
|
+
REFERENCE_PATH_COMPONENT_LOOKUP = "referencePathComponentLookup"
|
344
|
+
|
345
|
+
|
346
|
+
# A component in a Viv reference path
|
347
|
+
ReferencePathComponent = Union[
|
348
|
+
ReferencePathComponentPropertyName,
|
349
|
+
ReferencePathComponentPointer,
|
350
|
+
ReferencePathComponentLookup,
|
351
|
+
]
|
352
|
+
|
353
|
+
|
354
|
+
class Enum(TypedDict):
|
355
|
+
"""A Viv enum.
|
356
|
+
|
357
|
+
Enums are resolved by the target application at runtime.
|
358
|
+
"""
|
359
|
+
# Discriminant for a Viv enum
|
360
|
+
type: Literal[ExpressionDiscriminator.ENUM]
|
361
|
+
# The actual expression value
|
362
|
+
value: EnumValue
|
363
|
+
|
364
|
+
|
365
|
+
class EnumValue(TypedDict):
|
366
|
+
"""The actual expression value for a Viv enum."""
|
367
|
+
# The name of the enum. This must be resolvable by the target application at runtime.
|
368
|
+
name: EnumName
|
369
|
+
# Whether the enum value should be scaled. In Viv, an enum value will by default be scaled according to the
|
370
|
+
# current size of the simulation timestep in the target application. (Technically, the target application
|
371
|
+
# could scale according to some other principle.) This is achieved by using the `#ENUM_NAME` syntax, as
|
372
|
+
# opposed to the unscaled `##ENUM_NAME` notation. This notation supports a pattern where effects will have
|
373
|
+
# proportionally more weight when the simulation fidelity is coarser, i.e., when fewer actions are being
|
374
|
+
# performed in general. That said, even in such cases, an author may not want their enum to scale -- e.g.,
|
375
|
+
# in an effect for a "love at first sight" action or a traumatic incident -- and thus the `##ENUM_NAME`
|
376
|
+
# notation remains available.
|
377
|
+
scaled: bool
|
378
|
+
# Whether to flip the sign of a numeric value associated with the enum.
|
379
|
+
minus: bool
|
380
|
+
|
381
|
+
|
382
|
+
# A unique label for an enum value
|
383
|
+
EnumName = str
|
384
|
+
|
385
|
+
|
386
|
+
class EvalFailSafeField(TypedDict):
|
387
|
+
"""The Viv eval fail-safe operator.
|
388
|
+
|
389
|
+
A Viv author may specify an attempt to access a property that may not exist, safely,
|
390
|
+
via the eval fail-safe operator `?`, as in this example: `@foo.bar?.baz`.
|
391
|
+
"""
|
392
|
+
# Discriminant for the Viv eval fail-safe operator
|
393
|
+
type: Literal[ExpressionDiscriminator.EVAL_FAIL_SAFE]
|
394
|
+
|
395
|
+
|
396
|
+
class FloatField(TypedDict):
|
397
|
+
"""A Viv floating-point number."""
|
398
|
+
# Discriminant for a Viv floating-point number
|
399
|
+
type: Literal[ExpressionDiscriminator.FLOAT]
|
400
|
+
# The float literal to which this expression will evaluate
|
401
|
+
value: float
|
402
|
+
|
403
|
+
|
404
|
+
class IntField(TypedDict):
|
405
|
+
"""A Viv integer."""
|
406
|
+
# Discriminant for a Viv integer
|
407
|
+
type: Literal[ExpressionDiscriminator.INT]
|
408
|
+
# The integer literal to which this expression will evaluate
|
409
|
+
value: int
|
410
|
+
|
411
|
+
|
412
|
+
class ListField(TypedDict):
|
413
|
+
"""A Viv list, defined as an ordered list of Viv expressions.
|
414
|
+
|
415
|
+
Once evaluated, the result will contain the respective evaluations of the expressions, in that same order.
|
416
|
+
"""
|
417
|
+
# Discriminant for a Viv list
|
418
|
+
type: Literal[ExpressionDiscriminator.LIST]
|
419
|
+
# The actual expression value
|
420
|
+
value: list[Expression]
|
421
|
+
|
422
|
+
|
423
|
+
class LocalVariableReference(NegatableExpression):
|
424
|
+
"""A Viv local-variable reference, meaning a reference anchored in a local variable.
|
425
|
+
|
426
|
+
This kind of expression is structured as an anchor (the local variable name) with a subsequent path
|
427
|
+
to a specific property value. If a local variable is bound to an entity, this works just like an
|
428
|
+
entity reference — common when looping over role unpackings. Local variables may, however, hold
|
429
|
+
arbitrary values to which authors can refer.
|
430
|
+
"""
|
431
|
+
# Discriminant for a Viv local-variable reference
|
432
|
+
type: Literal[ExpressionDiscriminator.LOCAL_VARIABLE_REFERENCE]
|
433
|
+
# The actual expression value
|
434
|
+
value: LocalVariableReferenceValue
|
435
|
+
|
436
|
+
|
437
|
+
class LocalVariableReferenceValue(TypedDict):
|
438
|
+
"""The actual expression value for a Viv local-variable reference."""
|
439
|
+
# The name of the local variable that anchors this reference
|
440
|
+
anchor: VariableName
|
441
|
+
# If applicable, the path to a specified property value. If the reference is just to the
|
442
|
+
# variable's value itself, this will be an empty list. Otherwise, it specifies the path.
|
443
|
+
path: list[ReferencePathComponent]
|
444
|
+
|
445
|
+
|
446
|
+
class Loop(TypedDict):
|
447
|
+
"""A Viv loop, allowing for iteration over some iterable value."""
|
448
|
+
# Discriminant for a Viv loop
|
449
|
+
type: Literal[ExpressionDiscriminator.LOOP]
|
450
|
+
# The actual expression value
|
451
|
+
value: LoopValue
|
452
|
+
|
453
|
+
|
454
|
+
class LoopValue(TypedDict):
|
455
|
+
"""The actual expression value for a Viv loop."""
|
456
|
+
# An expression that should evaluate to a value that is iterable in the runtime at hand.
|
457
|
+
iterable: Expression
|
458
|
+
# Name of the variable to which each member of the iterable is assigned
|
459
|
+
# on its respective iteration of the loop.
|
460
|
+
variable: VariableName
|
461
|
+
# The body of the loop, structured as a list of expressions that will each be interpreted,
|
462
|
+
# in order, on each iteration. These body expressions can reference the loop variable,
|
463
|
+
# allowing for Viv code that acts on each member of an iterable.
|
464
|
+
body: list[Expression]
|
465
|
+
|
466
|
+
|
467
|
+
# The name for a variable used in an assignment or a loop
|
468
|
+
VariableName = str
|
469
|
+
|
470
|
+
|
471
|
+
class MembershipTest(NegatableExpression):
|
472
|
+
"""A Viv membership test.
|
473
|
+
|
474
|
+
This kind of expression takes two expressions as operands and evaluates to `True` if the evaluation
|
475
|
+
of the first expression is a member of the (iterable) evaluation of the second expression.
|
476
|
+
"""
|
477
|
+
# Discriminant for a Viv membership test
|
478
|
+
type: Literal[ExpressionDiscriminator.MEMBERSHIP_TEST]
|
479
|
+
# The actual expression value
|
480
|
+
value: MembershipTestValue
|
481
|
+
|
482
|
+
|
483
|
+
class MembershipTestValue(TypedDict):
|
484
|
+
"""The actual expression value for a Viv membership test."""
|
485
|
+
# An expression whose evaluation will be used as the left operand in the membership test
|
486
|
+
left: Expression
|
487
|
+
# Always the membership-test operator `in`. This field isn't used by the interpreter, but it's
|
488
|
+
# included here as a convenience for the compiler, where it's easier to maintain parity in the
|
489
|
+
# shape of all relational expressions.
|
490
|
+
operator: Literal["in"]
|
491
|
+
# An expression whose evaluation will be used as the right operand in the membership test
|
492
|
+
right: Expression
|
493
|
+
|
494
|
+
|
495
|
+
class NullField(TypedDict):
|
496
|
+
"""A Viv null value."""
|
497
|
+
# Discriminant for a Viv null value
|
498
|
+
type: Literal[ExpressionDiscriminator.NULL_TYPE]
|
499
|
+
# Python's `None`, which serializes to JSON's `null`. In any Viv runtime, expressions of this
|
500
|
+
# type evaluate to the null-like value in the language at hand.
|
501
|
+
value: None
|
502
|
+
|
503
|
+
|
504
|
+
class ObjectField(TypedDict):
|
505
|
+
"""A Viv object literal.
|
506
|
+
|
507
|
+
Expressions of this type maps keys (string literals) to Viv expressions. Once evaluated,
|
508
|
+
the result will map those same keys to the respective evaluations of the Viv expressions.
|
509
|
+
"""
|
510
|
+
# Discriminant for a Viv object literal
|
511
|
+
type: Literal[ExpressionDiscriminator.OBJECT]
|
512
|
+
# The actual expression value
|
513
|
+
value: dict[str, "Expression"]
|
514
|
+
|
515
|
+
|
516
|
+
class RoleUnpacking(TypedDict):
|
517
|
+
"""A Viv "role unpacking" expression.
|
518
|
+
|
519
|
+
This kind of expression expands a role into an array containing all the entities cast into
|
520
|
+
that role. This allows for iterating over multiple entities cast into the same role, e.g.,
|
521
|
+
to carry out effects on each.
|
522
|
+
"""
|
523
|
+
# Discriminant for a Viv role-unpacking expression
|
524
|
+
type: Literal[ExpressionDiscriminator.ROLE_UNPACKING]
|
525
|
+
# The actual expression value
|
526
|
+
value: RoleName
|
527
|
+
|
528
|
+
|
529
|
+
class StringField(TypedDict):
|
530
|
+
"""A Viv string literal."""
|
531
|
+
# Discriminant for a Viv string literal
|
532
|
+
type: Literal[ExpressionDiscriminator.STRING]
|
533
|
+
# The string literal to which this expression will evaluate
|
534
|
+
value: str
|
535
|
+
|
536
|
+
|
537
|
+
class TemplateStringField(TypedDict):
|
538
|
+
"""A Viv templated string.
|
539
|
+
|
540
|
+
This kind of expression is structured as an ordered list of string literals and string-producing
|
541
|
+
references, the evaluations of which are concatenated to form the rendered string.
|
542
|
+
"""
|
543
|
+
# Discriminant for a Viv templated string
|
544
|
+
type: Literal[ExpressionDiscriminator.TEMPLATE_STRING]
|
545
|
+
# The actual expression value
|
546
|
+
value: list[Union[str, EntityReference, RoleUnpacking, LocalVariableReference]]
|
547
|
+
|
548
|
+
|
549
|
+
class TropeFitExpression(NegatableExpression):
|
550
|
+
"""A Viv "trope fit" expression.
|
551
|
+
|
552
|
+
This kind of expression evaluates to `True` if the trope holds with the given arguments.
|
553
|
+
"""
|
554
|
+
# Discriminant for a Viv trope-fit expression
|
555
|
+
type: Literal[ExpressionDiscriminator.TROPE_FIT_EXPRESSION]
|
556
|
+
# The actual expression value
|
557
|
+
value: TropeFitExpressionValue
|
558
|
+
|
559
|
+
|
560
|
+
class TropeFitExpressionValue(TypedDict):
|
561
|
+
"""The actual expression value for a Viv trope-fit expression."""
|
562
|
+
# The name of the trope that will be used for the test
|
563
|
+
tropeName: TropeName
|
564
|
+
# An ordered list of expressions whose evaluations will be passed as the
|
565
|
+
# arguments for the test. These must correspond to the trope's parameters.
|
566
|
+
args: list[Expression]
|