DSM & Definitions¶
DSM classes provide parsing and introspection of Digital Substrate Model files.
When to use: Use DSMBuilder to parse .dsm files and introspect
the resulting definitions (structures, enumerations, attachments, functions).
Quick Start¶
>>> from dsviper import *
>>> MODEL = """
... namespace MyApp {8f14e45f-ceea-467a-9575-1c14b48f0b7e} {
... concept User;
... struct Profile { string city; uint16 age; };
... attachment<User, Profile> profile;
... };
... """
>>> builder = DSMBuilder()
>>> builder.append("model.dsm", MODEL)
>>> report, dsm_defs, defs = builder.parse()
>>> report.has_error()
False
>>> defs.inject(globals()) # MY_APP_T_USER, MY_APP_A_USER_PROFILE, …
The declarations are reachable from dsm_defs:
>>> for struct in sorted(dsm_defs.structures(), key=str):
... print(struct.type_name())
... for field in struct.fields():
... print(" ", field.name(), ":", field.type())
MyApp::Profile
city : string
age : uint16
>>> for att in dsm_defs.attachments():
... print(att.type_name(), "-- key:", att.key_type(), "doc:", att.document_type())
MyApp::profile -- key: MyApp::User doc: MyApp::Profile
inject() fills the namespace with one constant per definition. The
prefix is derived from the DSM namespace, split on camel case — MyApp
gives MY_APP_, not MYAPP_:
>>> ns = {}
>>> defs.inject(ns)
>>> sorted(ns)
['MY_APP_A_USER_PROFILE', 'MY_APP_K_USER', 'MY_APP_P_PROFILE_AGE',
'MY_APP_P_PROFILE_CITY', 'MY_APP_S_PROFILE', 'MY_APP_T_USER']
A parse that failed reports why, and hands back None for both
definitions:
>>> bad = DSMBuilder()
>>> bad.append("broken.dsm", "namespace Oops { struct S { string };")
>>> bad_report, bad_dsm, bad_defs = bad.parse()
>>> bad_report.has_error()
True
>>> (bad_dsm, bad_defs)
(None, None)
>>> for err in bad_report.errors()[:1]:
... print(err.line(), err.message())
1 expected a UUID before `{`.
Parsing¶
Assembles a DSM model from several sources. |
|
One content appended to a DSMBuilder, and where it landed in the assembled text. |
|
A parsed model, whole. |
|
Retrieves parsed declarations by TypeName, and attachments by identifier. |
|
Collects the errors found while parsing the assembled sources. |
|
One parse failure. |
Model Elements¶
A concept as declared: its qualified name and the concept it specialises, if any. |
|
A club as declared: its qualified name and the concepts it gathers. |
|
A struct as declared: its qualified name and its fields, in order. |
|
One field of a struct, as declared: its name, its type, and the value it defaults to. |
|
An enum as declared: its qualified name and its cases, in order. |
|
One case of an enum, as declared: its name. |
|
An attachment as declared: its qualified name, the concept it keys on, and the type of the document it holds. |
DSM Types¶
A type as a parsed model declares it: the base of the declared type family. |
|
The key<element_type> as a parsed model declares it. |
|
The vector<element_type> as a parsed model declares it. |
|
The set<element_type> as a parsed model declares it. |
|
The map<key_type, element_type> as a parsed model declares it. |
|
The xarray<element_type> as a parsed model declares it. |
|
The optional<element_type> as a parsed model declares it. |
|
The tuple<T0, ...> as a parsed model declares it. |
|
The vec<numeric_type, size> as a parsed model declares it. |
|
The mat<numeric_type, columns, rows> as a parsed model declares it. |
|
The variant<T0, ...> as a parsed model declares it. |
|
A type a parsed model names rather than spells out. |
Functions¶
A function as declared: its prototype. |
|
A function pool as declared: the uuid it is declared under, its name, and its functions. |
|
A function signature as declared: its name, its parameters and their types, and what it returns. |
|
An attachment function as declared: its prototype, and whether it mutates the document or only reads it. |
|
An attachment function pool as declared: the uuid it is declared under, its name, and its functions. |
Literals¶
What a declaration writes as a literal: the base of DSMLiteralValue and DSMLiteralList. |
|
A single literal written in a declaration: which kind it is, and its text. |
|
A list literal written in a declaration: the literals it holds. |
Definitions¶
Definitions is the registry a DSM model is loaded into: the concepts, clubs,
attachments and types an application declares. Everything else on this page
describes the model; these classes hold it at runtime.
Registers concepts, clubs, enums, structs and attachments. |
|
Retrieves registered types and attachments by runtime id. |
|
Gathers the types a subset of definitions references, to hand to DefinitionsConst.extract. |
|
Retrieves registered types by TypeName, and attachments by identifier. |
|
The runtime ids an extension added: what Definitions.extend or a database's extend_definitions gained from the definitions it was given, and what a synchronization added (CommitSynchronizerInfo.extend_info). |
|
Rewrites a Type, a Value or an Attachment of source_definitions into the matching declaration of target_definitions, matched by name. |
Source Map¶
Pass a DSMSourceMap to DSMBuilder.parse(source_map=…) and the parser
records, as a by-product, the exact source span of every declaration, field,
case, namespace, type sub-expression and resolved type-reference. This is what
makes a span-precise codemod possible: patch a hand-authored .dsm in place
under a transformation — file split, comments and ordering preserved — instead
of regenerating it. Opt-in; a parse without a source map is unchanged.
from dsviper import DSMBuilder, DSMSourceMap
source_map = DSMSourceMap()
report, dsm_defs, defs = DSMBuilder.assemble("model.dsm").parse(source_map=source_map)
A source-map collected while parsing DSM: the exact source spans of every declaration, field, case, namespace, resolved type-reference and type sub-expression. |
|
A source span: a 1-based line, and the [start, stop] character offsets into the content the builder assembled. |
|
A declaration - struct, enum, concept, club or attachment - with its identifier and its source spans (name, block, documentation). |
|
A struct field and its source spans (name, type, whole declaration, doc). |
|
An enumeration case and its source spans (name, doc). |
|
A namespace declaration and its source spans (name, uuid). |
|
A resolved type-reference site: its source span and its referent TypeName. |
|
A type sub-expression occurrence: its source span and its fully-qualified DSM representation - the name-based identity of a type, such as 'vector<Shop::Order>'. |