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
@@ -1,2 +1,2 @@
|
|
1
1
|
# This is programmatically updated by viv/scripts/bump_version.sh
|
2
|
-
__version__ = "0.1.
|
2
|
+
__version__ = "0.1.2"
|
viv_compiler/cli.py
CHANGED
@@ -10,6 +10,8 @@ import traceback
|
|
10
10
|
import viv_compiler.config
|
11
11
|
from pathlib import Path
|
12
12
|
from importlib import resources
|
13
|
+
|
14
|
+
from viv_compiler import VivCompileError
|
13
15
|
from .api import compile_from_path, get_version
|
14
16
|
from viv_compiler.types import CompiledContentBundle
|
15
17
|
|
@@ -22,16 +24,17 @@ def main() -> None:
|
|
22
24
|
args = parser.parse_args()
|
23
25
|
# If the user has requested the compiler version, print it and exit
|
24
26
|
if args.version:
|
25
|
-
print(
|
27
|
+
print(get_version())
|
26
28
|
sys.exit(0)
|
29
|
+
# If test mode is not engaged and no source file was provided, error and exit
|
30
|
+
if not args.test and not args.input:
|
31
|
+
parser.error("Unless the 'test' flag is engaged, an action file must be provided")
|
27
32
|
# If test mode is engaged, invoke the compiler on a test file and exit
|
33
|
+
print("\nCompiling...\n", file=sys.stderr)
|
28
34
|
if args.test:
|
29
35
|
_run_smoke_test(args=args)
|
30
36
|
sys.exit(0)
|
31
|
-
elif not args.input:
|
32
|
-
parser.error("Unless the 'test' flag is engaged, an action file must be provided")
|
33
37
|
# Otherwise, it's showtime, so let's invoke the compiler
|
34
|
-
print("\nCompiling...\n", file=sys.stderr)
|
35
38
|
if args.output:
|
36
39
|
path_to_output_file = Path(args.output).expanduser().resolve()
|
37
40
|
if not path_to_output_file.parent.exists():
|
@@ -152,7 +155,7 @@ def _run_smoke_test(args: argparse.Namespace) -> None:
|
|
152
155
|
source_file_path=sample_path,
|
153
156
|
default_salience=float(args.default_salience),
|
154
157
|
default_associations=args.default_associations,
|
155
|
-
default_reaction_priority=float(args.
|
158
|
+
default_reaction_priority=float(args.default_reaction_priority),
|
156
159
|
debug=False,
|
157
160
|
use_memoization=True,
|
158
161
|
)
|
@@ -174,7 +177,7 @@ def _invoke_compiler(args: argparse.Namespace) -> CompiledContentBundle:
|
|
174
177
|
source_file_path=source_file_path,
|
175
178
|
default_salience=float(args.default_salience),
|
176
179
|
default_associations=args.default_associations,
|
177
|
-
default_reaction_priority=float(args.
|
180
|
+
default_reaction_priority=float(args.default_reaction_priority),
|
178
181
|
debug=args.debug,
|
179
182
|
use_memoization=args.memoization,
|
180
183
|
)
|
@@ -188,10 +191,9 @@ def _invoke_compiler(args: argparse.Namespace) -> CompiledContentBundle:
|
|
188
191
|
except Exception:
|
189
192
|
pass
|
190
193
|
sys.exit(1)
|
191
|
-
except
|
192
|
-
|
193
|
-
|
194
|
-
traceback.print_exc()
|
194
|
+
except VivCompileError as e:
|
195
|
+
cause = e.__cause__ or e
|
196
|
+
print(f"Error encountered during compilation:\n\n{cause}\n", file=sys.stderr)
|
195
197
|
sys.exit(1)
|
196
198
|
|
197
199
|
|
@@ -211,7 +213,7 @@ def _emit_results(
|
|
211
213
|
"""
|
212
214
|
# If we're to print out the result, let's do so now, via `stdout` (with headers piped to `stderr`)
|
213
215
|
if args.print:
|
214
|
-
print("
|
216
|
+
print(" == Result ==\n", file=sys.stderr)
|
215
217
|
sys.stdout.write(json.dumps(compiled_content_bundle, indent=2, sort_keys=True))
|
216
218
|
sys.stdout.write("\n\n")
|
217
219
|
# If we're to list out the compiled actions, let's do so now (again via
|
@@ -223,7 +225,7 @@ def _emit_results(
|
|
223
225
|
lines.append(action_name)
|
224
226
|
if not action_names:
|
225
227
|
lines.append("N/A")
|
226
|
-
print(f"
|
228
|
+
print(f" == Actions ({len(action_names)}) ==\n", file=sys.stderr)
|
227
229
|
print("\n".join(f"- {line}" for line in lines), file=sys.stderr)
|
228
230
|
print("", file=sys.stderr)
|
229
231
|
# If an output file path has been provided, write the output file to the specified path
|
viv_compiler/config/config.py
CHANGED
@@ -25,9 +25,9 @@ NEGATABLE_EXPRESSION_TYPES = {
|
|
25
25
|
ExpressionDiscriminator.CONJUNCTION,
|
26
26
|
ExpressionDiscriminator.DISJUNCTION,
|
27
27
|
ExpressionDiscriminator.ENTITY_REFERENCE,
|
28
|
-
ExpressionDiscriminator.LOCAL_VARIABLE_REFERENCE,
|
29
28
|
ExpressionDiscriminator.LOOP,
|
30
29
|
ExpressionDiscriminator.MEMBERSHIP_TEST,
|
30
|
+
ExpressionDiscriminator.SYMBOL_REFERENCE,
|
31
31
|
ExpressionDiscriminator.TROPE_FIT_EXPRESSION,
|
32
32
|
}
|
33
33
|
|
@@ -56,28 +56,21 @@ REACTION_FIELD_DEFAULT_OPTIONS = {
|
|
56
56
|
"abandonmentConditions": [],
|
57
57
|
}
|
58
58
|
|
59
|
-
#
|
59
|
+
# Name for the special action self-reference role, which is always bound to the action itself
|
60
|
+
ACTION_SELF_REFERENCE_ROLE_NAME = 'this'
|
61
|
+
|
62
|
+
# A set containing the special role names that are automatically created by Viv at various points
|
63
|
+
SPECIAL_ROLE_NAMES = {'hearer', ACTION_SELF_REFERENCE_ROLE_NAME}
|
64
|
+
|
65
|
+
# The path to which the scratch-variable sigil `$` expands. This sigil is really just syntactic sugar for
|
60
66
|
# the path `@this.scratch`, which stores a blackboard local to a performed action. For instance, the scratch
|
61
|
-
# operation
|
62
|
-
|
63
|
-
|
67
|
+
# operation `$@foo.bar = 99` is syntactic sugar for the expression `@this.scratch.foo.bar = 99`.
|
68
|
+
SCRATCH_VARIABLE_REFERENCE_ANCHOR = ACTION_SELF_REFERENCE_ROLE_NAME
|
69
|
+
SCRATCH_VARIABLE_REFERENCE_PATH_PREFIX = [{
|
64
70
|
"type": ReferencePathComponentDiscriminator.REFERENCE_PATH_COMPONENT_PROPERTY_NAME,
|
65
71
|
"name": "scratch",
|
66
72
|
}]
|
67
73
|
|
68
|
-
# The path to which the local-variable sigil `$$` expands. This sigil is really just a property lookup in
|
69
|
-
# the special `__locals__` field of an evaluation context, which is a temporary store for scoped local
|
70
|
-
# variables. For instance, the local-variable reference `$$c` defines an attempt to access `__locals__.c`
|
71
|
-
# in an evaluation context. Unlike the `$` sigil, this is not syntactic sugar, since the Viv author has
|
72
|
-
# no other way to reference local variables.
|
73
|
-
LOCAL_VARIABLE_REFERENCE_PATH = ["__locals__"]
|
74
|
-
|
75
|
-
# Name for the variable to which each character is set when computing their salience for an action
|
76
|
-
SALIENCES_VARIABLE_NAME = "c"
|
77
|
-
|
78
|
-
# Name for the variable to which each character is set when computing their associations for an action
|
79
|
-
ASSOCIATIONS_VARIABLE_NAME = "c"
|
80
|
-
|
81
74
|
# A default salience value, to be used when the API caller does not provide one
|
82
75
|
DEFAULT_SALIENCE_VALUE = 1.0
|
83
76
|
|
@@ -86,3 +79,9 @@ DEFAULT_ASSOCIATIONS_VALUE = []
|
|
86
79
|
|
87
80
|
# A default reaction priority value, to be used when the API caller does not provide one
|
88
81
|
DEFAULT_REACTION_PRIORITY_VALUE = 1.0
|
82
|
+
|
83
|
+
# A list containing the names of action fields in which assignments are permitted
|
84
|
+
ACTION_FIELDS_PERMITTING_ASSIGNMENTS = ("scratch", "effects",)
|
85
|
+
|
86
|
+
# A list containing the names of action fields in which reactions are permitted
|
87
|
+
ACTION_FIELDS_PERMITTING_REACTIONS = ("reactions",)
|
viv_compiler/core/__init__.py
CHANGED
viv_compiler/core/core.py
CHANGED
@@ -23,10 +23,10 @@ import viv_compiler.types
|
|
23
23
|
from typing import Any
|
24
24
|
from pathlib import Path
|
25
25
|
from importlib.resources import files
|
26
|
-
from .
|
26
|
+
from .includes import integrate_included_files
|
27
27
|
from .visitor import Visitor
|
28
|
-
from .
|
29
|
-
from .
|
28
|
+
from .postprocessing import postprocess_combined_ast
|
29
|
+
from .validation import validate_content_bundle
|
30
30
|
# noinspection PyUnresolvedReferences
|
31
31
|
from arpeggio.cleanpeg import ParserPEG
|
32
32
|
|
@@ -37,7 +37,7 @@ def compile_viv_source_code(
|
|
37
37
|
default_associations: list[str],
|
38
38
|
default_reaction_priority: float,
|
39
39
|
use_memoization: bool,
|
40
|
-
debug
|
40
|
+
debug=False,
|
41
41
|
) -> viv_compiler.types.CompiledContentBundle:
|
42
42
|
"""Compile the given Viv source file to produce a JSON-serializable compiled content bundle.
|
43
43
|
|
@@ -71,7 +71,7 @@ def compile_viv_source_code(
|
|
71
71
|
# construct an abstract syntax tree (AST).
|
72
72
|
ast: viv_compiler.types.AST = _sanitize_ast(ast=arpeggio.visit_parse_tree(tree, Visitor()))
|
73
73
|
# If there are any include declarations (i.e., import statements), honor those now
|
74
|
-
combined_ast: viv_compiler.types.CombinedAST =
|
74
|
+
combined_ast: viv_compiler.types.CombinedAST = integrate_included_files(
|
75
75
|
viv_parser=viv_parser,
|
76
76
|
ast=ast,
|
77
77
|
entry_point_file_path=source_file_path
|
@@ -106,7 +106,7 @@ def _honor_user_supplied_config_parameters(
|
|
106
106
|
"""
|
107
107
|
viv_compiler.config.ACTION_DEFINITION_OPTIONAL_FIELD_DEFAULT_VALUES["saliences"] = {
|
108
108
|
"default": {'type': 'float', 'value': default_salience},
|
109
|
-
"variable":
|
109
|
+
"variable": None,
|
110
110
|
"body": [],
|
111
111
|
}
|
112
112
|
default_associations_expression = {
|
@@ -115,7 +115,7 @@ def _honor_user_supplied_config_parameters(
|
|
115
115
|
}
|
116
116
|
viv_compiler.config.ACTION_DEFINITION_OPTIONAL_FIELD_DEFAULT_VALUES["associations"] = {
|
117
117
|
"default": default_associations_expression,
|
118
|
-
"variable":
|
118
|
+
"variable": None,
|
119
119
|
"body": [],
|
120
120
|
}
|
121
121
|
viv_compiler.config.REACTION_FIELD_DEFAULT_OPTIONS["priority"] = {
|
@@ -1,10 +1,10 @@
|
|
1
1
|
"""Module that handles importing between Viv files.
|
2
2
|
|
3
|
-
The entrypoint function is `
|
3
|
+
The entrypoint function is `integrate_included_files()`, and everything else is only meant to be
|
4
4
|
invoked internally, i.e., within this module.
|
5
5
|
"""
|
6
6
|
|
7
|
-
__all__ = ["
|
7
|
+
__all__ = ["integrate_included_files"]
|
8
8
|
|
9
9
|
import arpeggio
|
10
10
|
import viv_compiler.types
|
@@ -14,13 +14,13 @@ from .visitor import Visitor
|
|
14
14
|
from arpeggio.cleanpeg import ParserPEG
|
15
15
|
|
16
16
|
|
17
|
-
def
|
17
|
+
def integrate_included_files(
|
18
18
|
viv_parser: ParserPEG,
|
19
19
|
ast: viv_compiler.types.AST,
|
20
20
|
entry_point_file_path: Path,
|
21
21
|
) -> viv_compiler.types.CombinedAST:
|
22
|
-
"""Handle any include declarations in the given AST (including any recursive ones)
|
23
|
-
containing trope definitions and action definitions.
|
22
|
+
"""Handle any `include` declarations in the given AST (including any recursive ones)
|
23
|
+
and return a dictionary containing trope definitions and action definitions.
|
24
24
|
|
25
25
|
Args:
|
26
26
|
viv_parser: A prepared Viv parser.
|
@@ -0,0 +1,71 @@
|
|
1
|
+
"""Module that handles the creation of metadata to attach to a compiled content bundle.
|
2
|
+
|
3
|
+
The entrypoint function is `create_metadata()`.
|
4
|
+
"""
|
5
|
+
|
6
|
+
__all__ = ["create_metadata"]
|
7
|
+
|
8
|
+
import viv_compiler.types
|
9
|
+
import viv_compiler.utils
|
10
|
+
from viv_compiler import __version__
|
11
|
+
from viv_compiler.types import ExpressionDiscriminator
|
12
|
+
from viv_compiler.utils import get_all_expressions_of_type
|
13
|
+
|
14
|
+
|
15
|
+
def create_metadata(
|
16
|
+
action_definitions: list[viv_compiler.types.ActionDefinition],
|
17
|
+
trope_definitions: list[viv_compiler.types.TropeDefinition],
|
18
|
+
) -> viv_compiler.types.CompiledContentBundleMetadata:
|
19
|
+
"""Return a package containing metadata for the given compiled content bundle.
|
20
|
+
|
21
|
+
Args:
|
22
|
+
action_definitions: List containing all actions in the content bundle.
|
23
|
+
trope_definitions: List containing all tropes in the content bundle.
|
24
|
+
|
25
|
+
Returns:
|
26
|
+
A metadata package for the given content bundle.
|
27
|
+
"""
|
28
|
+
metadata = {
|
29
|
+
"vivVersion": __version__,
|
30
|
+
"referencedEnums": [],
|
31
|
+
"referencedFunctionNames": [],
|
32
|
+
"itemRoles": [],
|
33
|
+
"buildRoles": [],
|
34
|
+
"timeOfDayConstrainedReactions": []
|
35
|
+
}
|
36
|
+
all_referenced_enum_names = []
|
37
|
+
all_referenced_function_names = []
|
38
|
+
for ast_chunk in action_definitions + trope_definitions:
|
39
|
+
# Compile all referenced enums
|
40
|
+
all_referenced_enum_names.extend(viv_compiler.utils.get_all_referenced_enum_names(ast_chunk=ast_chunk))
|
41
|
+
# Compile all referenced adapter functions
|
42
|
+
all_referenced_function_names.extend(viv_compiler.utils.get_all_referenced_adapter_function_names(
|
43
|
+
ast_chunk=ast_chunk
|
44
|
+
))
|
45
|
+
metadata["referencedEnums"].extend(sorted(set(all_referenced_enum_names)))
|
46
|
+
metadata["referencedFunctionNames"].extend(sorted(set(all_referenced_function_names)))
|
47
|
+
for action_definition in action_definitions:
|
48
|
+
# Compile all roles carrying 'item' and 'build' labels
|
49
|
+
for role_definition in action_definition["roles"].values():
|
50
|
+
if role_definition["item"]:
|
51
|
+
metadata["itemRoles"].append({
|
52
|
+
"action": action_definition["name"],
|
53
|
+
"role": role_definition["name"]
|
54
|
+
})
|
55
|
+
if role_definition["build"]:
|
56
|
+
metadata["buildRoles"].append({
|
57
|
+
"action": action_definition["name"],
|
58
|
+
"role": role_definition["name"]
|
59
|
+
})
|
60
|
+
# Compile all reactions referencing time of day
|
61
|
+
all_nested_reactions = get_all_expressions_of_type(
|
62
|
+
expression_type=ExpressionDiscriminator.REACTION,
|
63
|
+
ast_chunk=action_definition
|
64
|
+
)
|
65
|
+
for reaction in all_nested_reactions:
|
66
|
+
if reaction["options"]["when"] and reaction["options"]["when"]["timeOfDay"]:
|
67
|
+
metadata["timeOfDayConstrainedReactions"].append({
|
68
|
+
"action": action_definition["name"],
|
69
|
+
"reaction": reaction["actionName"]
|
70
|
+
})
|
71
|
+
return metadata
|
@@ -1,4 +1,4 @@
|
|
1
|
-
"""
|
1
|
+
"""Module that handles postprocessing of compiled ASTs for the Viv DSL.
|
2
2
|
|
3
3
|
This module takes in ASTs produced by the Viv parser (with imports honored) and
|
4
4
|
postprocesses them to produce compiled content bundles that are ready for validation.
|
@@ -13,9 +13,9 @@ import copy
|
|
13
13
|
import viv_compiler.config
|
14
14
|
import viv_compiler.types
|
15
15
|
import viv_compiler.utils
|
16
|
-
from viv_compiler import __version__
|
17
16
|
from typing import Any, cast
|
18
|
-
from .
|
17
|
+
from .validation import validate_join_directives, validate_preliminary_action_definitions
|
18
|
+
from .metadata import create_metadata
|
19
19
|
|
20
20
|
|
21
21
|
def postprocess_combined_ast(combined_ast: viv_compiler.types.CombinedAST) -> viv_compiler.types.CompiledContentBundle:
|
@@ -62,15 +62,15 @@ def postprocess_combined_ast(combined_ast: viv_compiler.types.CombinedAST) -> vi
|
|
62
62
|
# Isolate the trope definitions
|
63
63
|
finalized_trope_definitions = combined_ast["tropes"]
|
64
64
|
# Create metadata to be attached to the compiled content bundle
|
65
|
-
content_bundle_metadata =
|
65
|
+
content_bundle_metadata = create_metadata(
|
66
66
|
action_definitions=finalized_action_definitions,
|
67
67
|
trope_definitions=finalized_trope_definitions
|
68
68
|
)
|
69
69
|
# Package up and return the compiled content bundle
|
70
70
|
compiled_content_bundle: viv_compiler.types.CompiledContentBundle = {
|
71
|
+
"meta": content_bundle_metadata,
|
71
72
|
"tropes": {trope["name"]: trope for trope in finalized_trope_definitions},
|
72
|
-
"actions": {action["name"]: action for action in finalized_action_definitions}
|
73
|
-
"meta": content_bundle_metadata
|
73
|
+
"actions": {action["name"]: action for action in finalized_action_definitions}
|
74
74
|
}
|
75
75
|
return compiled_content_bundle
|
76
76
|
|
@@ -721,29 +721,3 @@ def _attribute_preconditions(
|
|
721
721
|
)
|
722
722
|
final_action_definitions.append(final_action_definition)
|
723
723
|
return final_action_definitions
|
724
|
-
|
725
|
-
|
726
|
-
def _create_metadata(
|
727
|
-
action_definitions: list[viv_compiler.types.ActionDefinition],
|
728
|
-
trope_definitions: list[viv_compiler.types.TropeDefinition],
|
729
|
-
) -> viv_compiler.types.CompiledContentBundleMetadata:
|
730
|
-
"""Return a package containing metadata for the given compiled content bundle.
|
731
|
-
|
732
|
-
Args:
|
733
|
-
action_definitions: List containing all actions in the content bundle.
|
734
|
-
trope_definitions: List containing all tropes in the content bundle.
|
735
|
-
|
736
|
-
Returns:
|
737
|
-
A metadata package for the given content bundle.
|
738
|
-
"""
|
739
|
-
metadata = {
|
740
|
-
"vivVersion": __version__,
|
741
|
-
"referencedEnums": [],
|
742
|
-
"referencedFunctionNames": []
|
743
|
-
}
|
744
|
-
for ast_chunk in action_definitions + trope_definitions:
|
745
|
-
all_referenced_enum_names = set(viv_compiler.utils.get_all_referenced_enum_names(ast_chunk=ast_chunk))
|
746
|
-
metadata["referencedEnums"].extend(all_referenced_enum_names)
|
747
|
-
all_referenced_function_names = set(viv_compiler.utils.get_all_referenced_enum_names(ast_chunk=ast_chunk))
|
748
|
-
metadata["referencedFunctionNames"].extend(all_referenced_function_names)
|
749
|
-
return metadata
|