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.
@@ -1,2 +1,2 @@
1
1
  # This is programmatically updated by viv/scripts/bump_version.sh
2
- __version__ = "0.1.0"
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(f"\nviv_compiler {get_version()}\n")
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.default_priority),
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.default_priority),
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 Exception as e:
192
- print(f"Error encountered during compilation: {e}", file=sys.stderr)
193
- if args.debug:
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("\t== Result ==\n", file=sys.stderr)
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"\t== Actions ({len(action_names)}) ==\n", file=sys.stderr)
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
@@ -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
- # The path to which the global-variable sigil `$` expands. This sigil is really just syntactic sugar for
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 `$foo.bar = 99` is syntactic sugar for the expression `@this.scratch.foo.bar = 99`.
62
- GLOBAL_VARIABLE_REFERENCE_ANCHOR = "this"
63
- GLOBAL_VARIABLE_REFERENCE_PATH_PREFIX = [{
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",)
@@ -1,5 +1,5 @@
1
1
  from .core import *
2
- from .importer import *
3
- from .postprocessor import *
4
- from .validator import *
2
+ from .includes import *
3
+ from .postprocessing import *
4
+ from .validation import *
5
5
  from .visitor import *
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 .importer import integrate_imported_files
26
+ from .includes import integrate_included_files
27
27
  from .visitor import Visitor
28
- from .postprocessor import postprocess_combined_ast
29
- from .validator import validate_content_bundle
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 = False,
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 = integrate_imported_files(
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": viv_compiler.config.SALIENCES_VARIABLE_NAME,
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": viv_compiler.config.ASSOCIATIONS_VARIABLE_NAME,
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 `integrate_imported_files()`, and everything else is only meant to be
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__ = ["integrate_imported_files"]
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 integrate_imported_files(
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) and return a dictionary
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
- """Postprocessor for the Viv DSL.
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 .validator import validate_join_directives, validate_preliminary_action_definitions
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 = _create_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