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.
@@ -0,0 +1,167 @@
1
+ """Internal types that are used by the compiler only.
2
+
3
+ The types defined here describe shapes whose life cycles begin and expire during
4
+ compilation. As such, they are not part of the public API for the compiler.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ from typing import Literal
10
+ from typing_extensions import TypedDict, NotRequired
11
+ from .dsl_public_schemas import (
12
+ Expression,
13
+ TemplateStringField,
14
+ ListField,
15
+ )
16
+ from .content_public_schemas import (
17
+ ActionName,
18
+ Associations,
19
+ EmbargoDeclaration,
20
+ Reaction,
21
+ RoleDefinition,
22
+ RoleName,
23
+ Saliences,
24
+ TropeDefinition,
25
+ WrappedExpression
26
+ )
27
+
28
+
29
+ class AST(TypedDict):
30
+ """Visitor output for a single source file."""
31
+ # A list of relative import paths, exactly as authored in the source file (using the
32
+ # `include` operator). This transient field is deleted once inheritance has been handled.
33
+ _includes: list[str]
34
+ # All raw trope definitions in the source file
35
+ tropes: list[TropeDefinition]
36
+ # All raw action definitions in the source file
37
+ actions: list["RawActionDefinition"]
38
+
39
+
40
+ class CombinedAST(TypedDict):
41
+ """The merged AST after import resolution.
42
+
43
+ Notes:
44
+ * The `includes` field has been handled and is no longer present here.
45
+ """
46
+ # All trope definitions across the entry file and its resolved imports
47
+ tropes: list[TropeDefinition]
48
+ # All raw actions across the entry file and its resolved imports
49
+ actions: list["RawActionDefinition"]
50
+
51
+
52
+ class RawActionDefinition(TypedDict, total=False):
53
+ """An action definition as emitted directly by the visitor.
54
+
55
+ Notes:
56
+ * Default values are not yet filled in.
57
+ * No expressions have been converted into wrapped expressions.
58
+ * The `initiator` field is not present.
59
+ # The transient "join" flags are still present.
60
+ * The `roles` and `preconditions` fields are still lists (converted into dictionaries later on).
61
+ * Role-renaming declarations may be included in the `roles` field.
62
+ """
63
+ # Unique action name (public-schema shape)
64
+ name: ActionName
65
+ # Whether this action can only be targeted via a reaction (public-schema shape)
66
+ special: bool
67
+ # Optional parent action from which this action inherits fields
68
+ parent: ActionName | None
69
+ # Author-specified tags as a literal list of strings (public-schema shape)
70
+ tags: ListField
71
+ # All roles defined for this action, including role-renaming declarations (later converted into a dictionary)
72
+ roles: list[RoleDefinition | RoleRenaming]
73
+ # If present, a definition for a simple templated string describing this action
74
+ # in a sentence or so (public-schema shape).
75
+ gloss: TemplateStringField | None
76
+ # If present, a definition for a more detailed templated string describing this
77
+ # action in a paragraph or so (public-schema shape).
78
+ report: TemplateStringField | None
79
+ # A list of preconditions on this action (pre-wrapping)
80
+ preconditions: list[Expression]
81
+ # Scratch expressions for preparing an arbitrary action blackboard state (public-schema shape)
82
+ scratch: list[Expression]
83
+ # A list of effects on this action (pre-wrapping)
84
+ effects: list[Expression]
85
+ # A list of reactions on this action (pre-wrapping)
86
+ reactions: list[Reaction]
87
+ # Salience-computation block (public-schema shape)
88
+ saliences: "Saliences"
89
+ # Association-computation block (public-schema shape)
90
+ associations: "Associations"
91
+ # Embargo declarations constraining future performance of the action (public-schema shape)
92
+ embargoes: list["EmbargoDeclaration"]
93
+ # Whether to combine the `tags` field here with those of a parent (`True` if present)
94
+ _join_tags: NotRequired[Literal[True]]
95
+ # Whether to combine the `roles` field here with those of a parent (`True` if present)
96
+ _join_roles: NotRequired[Literal[True]]
97
+ # Whether to combine the `preconditions` field here with those of a parent (`True` if present)
98
+ _join_preconditions: NotRequired[Literal[True]]
99
+ # Whether to combine the `scratch` field here with those of a parent (`True` if present)
100
+ _join_scratch: NotRequired[Literal[True]]
101
+ # Whether to combine the `effects` field here with those of a parent (`True` if present)
102
+ _join_effects: NotRequired[Literal[True]]
103
+ # Whether to combine the `reactions` field here with those of a parent (`True` if present)
104
+ _join_reactions: NotRequired[Literal[True]]
105
+ # Whether to combine the `saliences` field here with those of a parent (`True` if present)
106
+ _join_saliences: NotRequired[Literal[True]]
107
+ # Whether to combine the `associations` field here with those of a parent (`True` if present)
108
+ _join_associations: NotRequired[Literal[True]]
109
+ # Whether to combine the `embargoes` field here with those of a parent (`True` if present)
110
+ _join_embargoes: NotRequired[Literal[True]]
111
+
112
+
113
+ class RoleRenaming(TypedDict):
114
+ """A declaration to rename a role inherited from a parent definition."""
115
+ # Flag indicating that a `roles` entry is a role-renaming declaration
116
+ _role_renaming: Literal[True]
117
+ # The name of source role, from the parent action, that is to be renamed
118
+ _source_name: RoleName
119
+ # The new name to be used for the source role, from the parent action, whose definition will be retained
120
+ _target_name: RoleName
121
+
122
+
123
+ class IntermediateActionDefinition(TypedDict, total=False):
124
+ """An intermediate action definition.
125
+
126
+ Notes:
127
+ * Default values are now filled in.
128
+ * Expressions have been converted into wrapped expressions, as applicable.
129
+ * The `initiator` field is now present.
130
+ * All "join" flags have been honored and deleted.
131
+ * The `roles` field may either be a list or a dictionary. We collapse both variants
132
+ of the intermediate action-definition shape here for convenience.
133
+ * The `preconditions` fields is still a list (converted into dictionary later on).
134
+ * Role-renaming declarations have been handled and are no longer present in the `roles` field.
135
+ """
136
+ # Unique action name (public-schema shape)
137
+ name: ActionName
138
+ # Whether this action can only be targeted via a reaction (public-schema shape)
139
+ special: bool
140
+ # Optional parent action from which this action inherits fields
141
+ parent: ActionName | None
142
+ # Author-specified tags as a literal list of strings (public-schema shape)
143
+ tags: ListField
144
+ # All roles defined for this action (may already be converted into a dictionary)
145
+ roles: list[RoleDefinition] | dict[RoleName, RoleDefinition]
146
+ # The initiator role definition duplicated for convenience during post-processing
147
+ initiator: RoleDefinition
148
+ # If present, a definition for a simple templated string describing this action
149
+ # in a sentence or so (public-schema shape).
150
+ gloss: TemplateStringField | None
151
+ # If present, a definition for a more detailed templated string describing this
152
+ # action in a paragraph or so (public-schema shape).
153
+ report: TemplateStringField | None
154
+ # A list of preconditions on this action (post-wrapping, but not yet a dictionary)
155
+ preconditions: list[WrappedExpression]
156
+ # Scratch expressions for preparing an arbitrary action blackboard state (public-schema shape)
157
+ scratch: list[Expression]
158
+ # A list of effects on this action (public-schema shape)
159
+ effects: list[WrappedExpression]
160
+ # A list of reactions on this action (public-schema shape)
161
+ reactions: list[WrappedExpression]
162
+ # Salience computation block (public-schema shape)
163
+ saliences: "Saliences"
164
+ # Association computation block (public-schema shape)
165
+ associations: "Associations"
166
+ # Embargo declarations constraining future performance of the action (public-schema shape)
167
+ embargoes: list["EmbargoDeclaration"]
@@ -0,0 +1 @@
1
+ from .utils import *
@@ -0,0 +1,2 @@
1
+ # This is programmatically updated by viv/scripts/bump_version.sh
2
+ __version__ = "0.1.0"
@@ -0,0 +1,171 @@
1
+ """Utility functions used by various components of the Viv DSL compiler."""
2
+
3
+ import viv_compiler.types
4
+ from viv_compiler.types import ExpressionDiscriminator
5
+ from typing import Any
6
+
7
+
8
+ def get_all_role_names(action_definition: viv_compiler.types.ActionDefinition) -> set[viv_compiler.types.RoleName]:
9
+ """Return a set containing the names of all roles associated with the given action definition.
10
+
11
+ Args:
12
+ action_definition:
13
+
14
+ Returns:
15
+ A set containing the names of all roles associated with the given action definition.
16
+ """
17
+ return {'hearer', 'this', 'default'} | set(action_definition['roles'])
18
+
19
+
20
+ def get_all_referenced_roles(
21
+ ast_chunk: Any,
22
+ ignore_role_unpackings: bool = False,
23
+ ignore: Any = None
24
+ ) -> list[viv_compiler.types.RoleName]:
25
+ """Return a list of all roles referenced in the given AST chunk.
26
+
27
+ Args:
28
+ ast_chunk: The full or partial AST to search for role references.
29
+ ignore_role_unpackings: Whether to search for role references inside role unpackings.
30
+ ignore: Only used internally, via recursive calls to this function.
31
+
32
+ Returns:
33
+ A list containing the names of all roles referenced in the given AST chunk.
34
+ """
35
+ ignore = ignore or ["this"]
36
+ roles_referenced_so_far = []
37
+ if isinstance(ast_chunk, list):
38
+ for element in ast_chunk:
39
+ roles_referenced_so_far.extend(get_all_referenced_roles(
40
+ ast_chunk=element,
41
+ ignore_role_unpackings=ignore_role_unpackings,
42
+ ignore=ignore
43
+ ))
44
+ elif isinstance(ast_chunk, dict):
45
+ if ast_chunk.get('type') == ExpressionDiscriminator.ENTITY_REFERENCE:
46
+ referenced_role = ast_chunk['value']['anchor']
47
+ roles_referenced_so_far.append(referenced_role)
48
+ elif not ignore_role_unpackings and ast_chunk.get('type') == ExpressionDiscriminator.ROLE_UNPACKING:
49
+ referenced_role = ast_chunk['value']
50
+ roles_referenced_so_far.append(referenced_role)
51
+ else:
52
+ scoped_ignore = ignore
53
+ if ast_chunk.get('type') == ExpressionDiscriminator.LOOP:
54
+ scoped_ignore = [*ignore, ast_chunk['value']['variable']]
55
+ iterable = ast_chunk['value']['iterable']
56
+ if iterable.get('type') == ExpressionDiscriminator.ROLE_UNPACKING:
57
+ if not ignore_role_unpackings:
58
+ roles_referenced_so_far.append(iterable['value'])
59
+ for key, value in ast_chunk.items():
60
+ roles_referenced_so_far.extend(get_all_referenced_roles(
61
+ ast_chunk=value,
62
+ ignore_role_unpackings=ignore_role_unpackings,
63
+ ignore=scoped_ignore
64
+ ))
65
+ return list(set(filter(lambda role: role not in ignore, roles_referenced_so_far)))
66
+
67
+
68
+ def get_all_referenced_enum_names(ast_chunk: Any) -> list[viv_compiler.types.EnumName]:
69
+ """Return a list of the names of all enums referenced in the given AST chunk.
70
+
71
+ This list will be stored in the compiled content bundle, where it's used for
72
+ validation purposes upon the initialization of a Viv runtime.
73
+
74
+ Args:
75
+ ast_chunk: The full or partial AST to search for enum references.
76
+
77
+ Returns:
78
+ A list containing the names of all the enums referenced in the given AST chunk.
79
+ """
80
+ all_enum_expressions = get_all_expressions_of_type(expression_type="enum", ast_chunk=ast_chunk)
81
+ all_referenced_enum_names = [expression['name'] for expression in all_enum_expressions]
82
+ return all_referenced_enum_names
83
+
84
+
85
+ def get_all_referenced_adapter_function_names(ast_chunk: Any) -> list[viv_compiler.types.AdapterFunctionName]:
86
+ """Return a list of the names of all adapter functions referenced in the given AST chunk.
87
+
88
+ This list will be stored in the compiled content bundle, where it's used for
89
+ validation purposes upon the initialization of a Viv runtime.
90
+
91
+ Args:
92
+ ast_chunk: The full or partial AST to search for adapter-function references.
93
+
94
+ Returns:
95
+ A list containing the names of all the adapter functions referenced in the given AST chunk.
96
+ """
97
+ all_adapter_function_references = get_all_expressions_of_type(
98
+ expression_type="adapterFunctionCall",
99
+ ast_chunk=ast_chunk
100
+ )
101
+ all_referenced_adapter_function_names = [expression['name'] for expression in all_adapter_function_references]
102
+ return all_referenced_adapter_function_names
103
+
104
+
105
+ def get_all_expressions_of_type(expression_type: str, ast_chunk: Any) -> list[Any]:
106
+ """Return a list containing values for all expressions of the given type that are nested in the given AST chunk.
107
+
108
+ Args:
109
+ expression_type: String indicating the type of Viv expression to search for.
110
+ ast_chunk: The AST chunk to search for expressions of the given type.
111
+
112
+ Returns:
113
+ A list containing all the Viv expressions of the given type in the given AST chunk.
114
+ """
115
+ expressions = []
116
+ if isinstance(ast_chunk, list):
117
+ for element in ast_chunk:
118
+ expressions.extend(get_all_expressions_of_type(expression_type=expression_type, ast_chunk=element))
119
+ elif isinstance(ast_chunk, dict):
120
+ if 'type' in ast_chunk and ast_chunk['type'] == expression_type:
121
+ expression_of_type = ast_chunk['value']
122
+ expressions.append(expression_of_type)
123
+ else:
124
+ for key, value in ast_chunk.items():
125
+ expressions.extend(get_all_expressions_of_type(expression_type=expression_type, ast_chunk=value))
126
+ return expressions
127
+
128
+
129
+ def get_all_negated_expressions(ast_chunk: Any) -> list[viv_compiler.types.Expression]:
130
+ """
131
+ Return every negated expression in the given AST chunk.
132
+
133
+ Args:
134
+ ast_chunk: The full or partial AST to search for negated expressions.
135
+
136
+ Returns:
137
+ A list containing all the negated Viv expressions in the given AST chunk.
138
+ """
139
+ negated_expressions = []
140
+ if isinstance(ast_chunk, list):
141
+ for element in ast_chunk:
142
+ negated_expressions.extend(get_all_negated_expressions(ast_chunk=element))
143
+ elif isinstance(ast_chunk, dict):
144
+ if ast_chunk.get("negated"):
145
+ negated_expressions.append(ast_chunk)
146
+ for value in ast_chunk.values():
147
+ negated_expressions.extend(get_all_negated_expressions(ast_chunk=value))
148
+ return negated_expressions
149
+
150
+
151
+ def contains_eval_fail_safe_operator(ast_chunk: Any) -> bool:
152
+ """Return whether the given AST chunk contains an eval fail-safe operator.
153
+
154
+ Args:
155
+ ast_chunk: The full or partial AST to search for expressions of the given type.
156
+
157
+ Returns:
158
+ True if the given AST chunk contains an eval fail-safe operator, else False.
159
+ """
160
+ if isinstance(ast_chunk, list):
161
+ for element in ast_chunk:
162
+ if contains_eval_fail_safe_operator(ast_chunk=element):
163
+ return True
164
+ elif isinstance(ast_chunk, dict):
165
+ if 'type' in ast_chunk and ast_chunk['type'] == ExpressionDiscriminator.EVAL_FAIL_SAFE:
166
+ return True
167
+ else:
168
+ for key, value in ast_chunk.items():
169
+ if contains_eval_fail_safe_operator(ast_chunk=value):
170
+ return True
171
+ return False
@@ -0,0 +1,284 @@
1
+ Metadata-Version: 2.4
2
+ Name: viv-compiler
3
+ Version: 0.1.0
4
+ Summary: Compiler for the DSL of Viv, an action system for emergent narrative.
5
+ Author-email: James Ryan <mail@jamesryan.ai>
6
+ License: MIT License
7
+
8
+ Copyright (c) 2025 James Ryan
9
+
10
+ Permission is hereby granted, free of charge, to any person obtaining a copy
11
+ of this software and associated documentation files (the "Software"), to deal
12
+ in the Software without restriction, including without limitation the rights
13
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14
+ copies of the Software, and to permit persons to whom the Software is
15
+ furnished to do so, subject to the following conditions:
16
+
17
+ The above copyright notice and this permission notice shall be included in all
18
+ copies or substantial portions of the Software.
19
+
20
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26
+ SOFTWARE.
27
+ Project-URL: Homepage, https://github.com/james-owen-ryan/viv
28
+ Project-URL: Repository, https://github.com/james-owen-ryan/viv/tree/main/compiler
29
+ Project-URL: Issues, https://github.com/james-owen-ryan/viv/issues
30
+ Classifier: License :: OSI Approved :: MIT License
31
+ Classifier: Programming Language :: Python :: 3 :: Only
32
+ Classifier: Programming Language :: Python :: 3.10
33
+ Classifier: Programming Language :: Python :: 3.11
34
+ Classifier: Programming Language :: Python :: 3.12
35
+ Classifier: Topic :: Software Development :: Compilers
36
+ Requires-Python: >=3.10
37
+ Description-Content-Type: text/markdown
38
+ License-File: LICENSE
39
+ Requires-Dist: arpeggio<3.0,>=2.0
40
+ Requires-Dist: pydantic<2.12,>=2.11
41
+ Requires-Dist: typing_extensions<5.0,>=4.6
42
+ Dynamic: license-file
43
+
44
+ # Viv Compiler
45
+
46
+ This package contains the reference compiler for the domain-specific language (DSL) at the heart of [Viv](https://github.com/james-owen-ryan/viv), an action system for emergent narrative.
47
+
48
+ The Viv compiler accepts a *Viv source file* (`.viv`) and produces a *Viv content bundle* in a JSON-serializable format conforming to the `CompiledContentBundle` schema defined [here](https://github.com/james-owen-ryan/viv/blob/main/compiler/src/viv_compiler/types/dsl_public_schemas.py), making it ready for usage in any Viv runtime.
49
+
50
+ Once you've installed this package, you'll have access to the two compiler interfaces that are documented below:
51
+
52
+ * A **command-line interface** (`vivc`) for invoking the compiler from the command line.
53
+
54
+ * A **Python API** for invoking the compiler programmatically.
55
+
56
+
57
+ ## Table of Contents
58
+
59
+ - [Installation](#installation)
60
+ - [Command-Line Interface](#command-line-interface-cli)
61
+ - [Python API](#python-api)
62
+ - [Running from Source](#running-from-source)
63
+ - [License](#license)
64
+
65
+
66
+ ## Installation
67
+
68
+ Install from PyPI:
69
+
70
+ ```
71
+ pip install viv-compiler
72
+ ```
73
+
74
+ This installs both the `viv_compiler` Python package and the `vivc` command-line interface.
75
+
76
+ Smoke test to confirm your installation looks good:
77
+
78
+ ```
79
+ vivc --test
80
+ ```
81
+
82
+
83
+ ## Command-Line Interface (CLI)
84
+
85
+ Once you've installed `viv-compiler`, the Viv compiler CLI will be exposed via the command `vivc` (and its alias `viv-compiler`).
86
+
87
+
88
+ ### Usage
89
+
90
+ ```
91
+ vivc --input path/to/source.viv [options]
92
+ ```
93
+
94
+
95
+ ### Arguments
96
+
97
+ * `-i, --input <path_to_source_file>`
98
+
99
+ * Required unless `--version` or `--test` is specified.
100
+ * Relative or absolute path to the Viv source file (`.viv`) to compile.
101
+ * If you are using `include` statements to import between files, this should be the main entrypoint file.
102
+
103
+ * `-o, --output <path_to_output_file>`
104
+
105
+ * Optional.
106
+ * Path to write the compiled JSON bundle.
107
+
108
+
109
+ ### Flags and Options (Optional)
110
+
111
+ * `-h, --help`
112
+
113
+ * Show help message and exit.
114
+
115
+ * `-s, --default_salience <float>`
116
+
117
+ * Sets the default salience (floating-point number) for actions when unspecified.
118
+ * Default: value from `viv_compiler.config.DEFAULT_SALIENCE_VALUE`.
119
+
120
+ * `-a, --default_associations <string ...>`
121
+
122
+ * Sets the default associations (zero or more strings) for actions when unspecified.
123
+ * Default: value from `viv_compiler.config.DEFAULT_ASSOCIATIONS_VALUE`.
124
+
125
+ * `-r, --default_reaction_priority <float>`
126
+
127
+ * Sets the default reaction priority (floating-point number) for actions when unspecified.
128
+ * Default: value from `viv_compiler.config.DEFAULT_REACTION_PRIORITY_VALUE`.
129
+
130
+ * `-m, --memoization, --no-memoization`
131
+
132
+ * Enable/disable memoization in the underlying PEG parser (slower but uses less memory).
133
+ * Default: enabled.
134
+
135
+ * `-p, --print`
136
+
137
+ * After compilation, pretty-print the compiled bundle JSON.
138
+
139
+ * `-l, --list`
140
+
141
+ * After compilation, print out a list of compiled action names.
142
+
143
+ * `-d, --debug`
144
+
145
+ * Enable verbose debugging for the underlying PEG parser.
146
+
147
+ * `-t, --test`
148
+
149
+ * Run a smoke test using a sample Viv file to confirm the installation works.
150
+ * Ignores `--input`.
151
+
152
+ * `-v, --version`
153
+
154
+ * Print the current compiler version and exit.
155
+
156
+
157
+ ### Examples
158
+
159
+ Compile a source file and write the resulting content bundle to file:
160
+
161
+ ```
162
+ vivc --input /path/to/my-actions.viv --output /path/to/myContentBundle.json
163
+ ```
164
+
165
+ Compile a source file and log the output in the console:
166
+
167
+ ```
168
+ vivc --input /path/to/my-actions.viv --print
169
+ ```
170
+
171
+ Log the version number for the installed Viv compiler:
172
+
173
+ ```
174
+ vivc -v
175
+ ```
176
+
177
+
178
+ ## Python API
179
+
180
+ The API is intended for programmatic invocation of the compiler.
181
+
182
+
183
+ ### `compile_from_path()`
184
+
185
+ This function invokes the compiler for a specified Viv source file.
186
+
187
+ **Arguments**
188
+
189
+ * `source_file_path` (`Path`)
190
+
191
+ * Absolute path to a `.viv` source file.
192
+
193
+ * `default_salience` (`float`)
194
+
195
+ * Default salience for actions (if unspecified).
196
+
197
+ * `default_associations` `(list[str])`
198
+
199
+ * Default associations for actions (if unspecified).
200
+
201
+ * `default_reaction_priority` (`float`)
202
+
203
+ * Default reaction priority for actions (if unspecified).
204
+
205
+ * `use_memoization` (`bool`)
206
+
207
+ * Whether to enable memoization in the underlying PEG parser (faster but uses more memory).
208
+
209
+ * `debug` (`bool`)
210
+
211
+ * Whether to enable verbose debugging for the underlying PEG parser.
212
+
213
+ **Returns**
214
+
215
+ * The compiled Viv bundle, in a JSON-serializable format conforming to the `CompiledContentBundle` schema defined in the project code.
216
+
217
+ **Raises**
218
+
219
+ * `VivCompileError`
220
+
221
+ * Raised when compilation fails.
222
+
223
+
224
+ ### `get_version()`
225
+
226
+ Returns the version string for the currently installed compiler.
227
+
228
+
229
+ ### `VivCompileError`
230
+
231
+ Custom exception type raised by the API when compilation fails. Inherits from `Exception`.
232
+
233
+
234
+ ### Examples
235
+
236
+ Compile a source file:
237
+
238
+ ```python
239
+ from pathlib import Path
240
+ from viv_compiler import compile_from_path, VivCompileError
241
+
242
+ try:
243
+ content_bundle = compile_from_path(source_file_path=Path("my-actions.viv"))
244
+ print("Compilation succeeded:", content_bundle)
245
+ except VivCompileError as e:
246
+ print("Compilation failed:", e)
247
+ ```
248
+
249
+ Print the version number for the installed Viv compiler:
250
+
251
+ ```python
252
+ from viv_compiler import get_version
253
+ print(get_version())
254
+ ```
255
+
256
+
257
+ ## Running from Source
258
+
259
+ For contributors or developers working directly from a repo checkout:
260
+
261
+ ```
262
+ # Clone the Viv monorepo
263
+ git clone https://github.com/james-owen-ryan/viv
264
+ cd viv/compiler
265
+
266
+ # Create a virtual environment
267
+ python -m venv .venv-viv-compiler
268
+ source .venv-viv-compiler/bin/activate # macOS/Linux
269
+ # Windows PowerShell: .\.venv-viv-compiler\Scripts\Activate.ps1
270
+
271
+ # Install the compiler package from source (editable)
272
+ python -m pip install -e .
273
+
274
+ # Invoke the CLI directly
275
+ python -m viv_compiler --test
276
+
277
+ # Or use the installed console script
278
+ vivc --test
279
+ ```
280
+
281
+
282
+ ## License
283
+
284
+ MIT License © 2025 James Ryan
@@ -0,0 +1,32 @@
1
+ viv_compiler/__init__.py,sha256=qYCGYC46CCguVk7LybHbWlV1b4dPY7K0UOfrEF8k0E8,592
2
+ viv_compiler/__main__.py,sha256=dyCH7r86O9Nw516E38Gm0gQjcSYDd57dhLGRBPoCi7s,60
3
+ viv_compiler/api.py,sha256=8vr_WoLEzPSOMRNmovewE2f4b8_-r5xp5PdYc7S2rgc,2164
4
+ viv_compiler/cli.py,sha256=6ZMj0TnDNXS99NpOV2Y3CiOVAh-cpknmOACrR_bBmh0,8350
5
+ viv_compiler/py.typed,sha256=qrkHrYJvGoZpU2BpVLNxJB44LlhqVSKyYOwD_L_1m3s,10
6
+ viv_compiler/_samples/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
+ viv_compiler/_samples/smoke-test.viv,sha256=hBgnuOvO7A78iDZPTM6Z6xlkaLAA9zgmkuxPVwCLUGQ,152
8
+ viv_compiler/backports/__init__.py,sha256=OozGI7C0wkn6Xjn19DPE_SSdSKX-gRiOQu8yooJ382E,25
9
+ viv_compiler/backports/backports.py,sha256=NkZcknH0-iuZczNfGSlL-3yy9FpL9-Y9j_H65TQs_FA,243
10
+ viv_compiler/config/__init__.py,sha256=A00lpnUKg-q3y_b-cN3jKF9urkGTGjb2Yz_gGc9WCLs,22
11
+ viv_compiler/config/config.py,sha256=y8R2W2mctP6lbyB_aqIAmJINDIqAAXtzPJrA6lYv-bk,3981
12
+ viv_compiler/core/__init__.py,sha256=QHyfqFCifNLT5ZTmLFUMWCURN4BuN2_uY4Z-7wTAeQo,121
13
+ viv_compiler/core/core.py,sha256=1ViI19Qa6F_mQbiqbEC7sYyJGH3VbuABI4mqF9xwFik,7828
14
+ viv_compiler/core/importer.py,sha256=XRv9wum_V4ll_vHU0pyerwmJW1Nr1IVlA_-ALtmzGxo,4877
15
+ viv_compiler/core/postprocessor.py,sha256=EBW8GAJa7Pikln5FzHQEpJ2QfPC66-HOmfAjGIA_HEY,40160
16
+ viv_compiler/core/validator.py,sha256=punxJ-2iPBFhyyR0ZePcyQAjMTma3ENr4gIiRKckWzU,42314
17
+ viv_compiler/core/visitor.py,sha256=t70j4e6CK363h7ey3W-v2_FbGeu80r4fOTK7npgxRmk,46864
18
+ viv_compiler/grammar/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
19
+ viv_compiler/grammar/viv.peg,sha256=otsDwXAAE14XmdzgjL4oPYgY651RgVVHVFQmmyde4TE,10538
20
+ viv_compiler/types/__init__.py,sha256=FLwJ0wV_vdR95waeHfZ4YnUIvkK7v8RqR139lpnP1RE,102
21
+ viv_compiler/types/content_public_schemas.py,sha256=4yPq3rEUzvKp6WOBoCERZuifUVtl-bXsSen_eQjithw,22019
22
+ viv_compiler/types/dsl_public_schemas.py,sha256=UMRoL197O0U-UAnpGHE_XXGzdg1I8S2jyXtV71ekoGI,22318
23
+ viv_compiler/types/internal_types.py,sha256=LOU4kT_tjxjU0CXqnqfluV-EBgX2KkhmUOa07B0i1xo,7816
24
+ viv_compiler/utils/__init__.py,sha256=alIDGBnxWH4JvP-UW-7N99seBBi0r1GV1h8f1ERFBec,21
25
+ viv_compiler/utils/_version.py,sha256=B40VyT6r1P2PNwgWWItzAYhh25_deCqUcl4EaXq0Beg,88
26
+ viv_compiler/utils/utils.py,sha256=TwT9VKV1fXVFLToSXO-Cu046Gu2siA_Y7xGog_Zx9pA,7257
27
+ viv_compiler-0.1.0.dist-info/licenses/LICENSE,sha256=_N1SL7eyeeqRS4HHgl_n85kuwUSw22qWP6IpQZ9F_M4,1066
28
+ viv_compiler-0.1.0.dist-info/METADATA,sha256=GH9QH_XkSBoMYrmmqyTz-hP4EXIdejMDgWzimmgmVFI,7955
29
+ viv_compiler-0.1.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
30
+ viv_compiler-0.1.0.dist-info/entry_points.txt,sha256=YluMB1bLcPmnfaeAaMAtxXsKCkIEvyhb2dVgkVp55Ko,84
31
+ viv_compiler-0.1.0.dist-info/top_level.txt,sha256=fd_4ocrOmLnp5oEnwxv2_Yt_JkluHdKD-Jr5eN__iaE,13
32
+ viv_compiler-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (80.9.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,3 @@
1
+ [console_scripts]
2
+ viv-compiler = viv_compiler.cli:main
3
+ vivc = viv_compiler.cli:main