v1.0.0
language syntax & features for v1.0.0
Last updated
language syntax & features for v1.0.0
Last updated
Describes and specifies the syntax structure, data type literals, language format, and features used within a file or literal string.
glyph | assignment type | description |
---|---|---|
Uppercase and Mixed case glyphs are also accepted, but not very clean looking. You may also set letters in the desired order in a file or string to load from and the result is the same (e.g. +hm= instead of +mh=). However, the default is what is described in the legend, and any dump mechanics will follow that default when output to a file or string.
There are also symbols that represent the letter-based glyphs, but those will be retired in the future and are not currently encouraged. The symbols were added as ported support from the older library for migration reasons.
Examples are demonstrating usage in a file to illustrate the language features. Language features may be used in files and strings to be parsed with maci's load functions (See functions).
Assigning names to values. Shows all supported data types accepted, and any maci specific extras
Example file "my.data"
The extras in this example are the date and time formats being parsed natively with maci returning datetime objects in python. It also accepts milliseconds in the time portions. (hint: date and times in example is an easter egg)
Locking a name to a value. This feature protects against an attribute name from being reassigned. Use the lock assignment glyph to set the lock.
During the code's runtime, if this attribute name is ever attempted to be reassigned, it will throw an exception and prevent reassignment. If the exception is caught, the value will remain unchanged.
Exception thrown (See errors)
If you need to reassign the name to a new value while it is locked, you may utilize the partner method "unlock_attr" to achieve this (See unlock_attr)
You may view all locked names using the "get_locked_list" method (See get_locked_list).
Hard locking a name to a value. This feature protects against an attribute name from being reassigned, deleted, and unlocked. Use the hard lock assignment glyph to set the hard lock. This feature effectively gives you a constant-like ability.
During the code's runtime, if this attribute name is ever attempted to be reassigned, deleted, or unlocked it will throw an exception to prevent those changes to the name. If an exception is caught, the name and value will remain unchanged. Once this is set, it is permanent during the code's runtime. The only way to change or remove the attribute name would be to delete the whole maci object.
Exceptions thrown (See errors)
This exception is thrown when attempting to reassign or delete name
This exception is thrown when attempting to unlock name. Unlock only searches for locked names, not hard-locked names.
You may view all hard-locked names using the "get_hard_locked_list" method (See get_hard_locked_list).
A Gotcha, but not really. Something to keep in mind is that any objects that are mutable (e.g. a list, dict, set) can still be updated in-place even if you lock/hard-lock an attribute name. Locking is a feature to protect the attribute name, not the value. Any immutable object must always be re-assigned to a name, hence why locking will protect against that.
Mapping a name to another name. This feature allows an attribute name to follow another attribute name's value. Use the map assignment glyph and set the value to be the name of the attribute name you want to follow. This feature effectively gives you a pointer-like ability, especially with python's native optimization features to reference the same object in memory for its immutable data types.
During the code's runtime, if the parent attribute name is ever reassigned or if the object it is assigned to changes, the child attribute name will always update its reference to match the parent. Take note, that the name must already exist to assign a name to follow it. If you wish to follow any other names that are not in a file, you may utilize the "map_attr" method in code to map to names (See map_attr). It is possible to create a chain-like structure of your references as well like so:
In this use case, if the parent name changes its value, all child names will update as well following one after another linked together like a chain.
It is also possible to create a key-ring-like structure of your references as well like so:
In this use case, if the parent name changes its value, all child names will update as well referencing the same parent. This is different from the chain concept where they are not following one after another, and just referencing the same parent, kind of like all keys on a single ring. You can have multiple mapped children to as many parents as you want. Once a name is assigned to another name, that other name will now become a parent. It is possible to have a name be a parent and a child simultaneously, and that is demonstrated in the chain concept.
If you need to release a reference to a name, you may utilize the partner method "unmap_attr" to achieve this (See unmap_attr). This will safely release the reference even if the name is locked. You can also reassign the child to another name or value and that will cause it to detach as well, but if it is locked, then a lock exception with be thrown.
You may view all map references and references in a chain-like view using the following methods:
get_all_maps = Shows all parent and child map references get_parent_maps = Shows all parent map references get_child_maps = Shows all child map references get_parent_map_chains = Shows all parent map references as a chain
Mapping and locking a name. You may combine certain glyphs to assign multiple features to a name. In this example you can map a child name to a parent name, then also lock that name from being changed. No matter the letter order you choose, maci will always first create the reference map, then lock the name to establish an assigned value before locking.
Example using map and lock
Example using map and hard lock
This combo may be desired if you want a name to initially reference another name's value, then to lock it so it is unchanged. Keep in mind though, if the parent name changes, the parent will change, but the child will not and throw an exception. You may unlock or unmap the child name temporarily in code to make any changes to the parent without receiving an exception from the child. If you wish to have the child mapped again, then it first must be unlocked if using a normal lock, then simply re-map with map_attr and then re-lock with lock_attr the child to the parent again. Another reason this combo may be desired is if you have a strict set of rules on names that cannot or should not be changed. This can promote architecting your code more carefully to maintain integrity of the names if certain aspects of your program heavily rely on those attribute names. For example, creating a dependency model using the chain concept where if a top or upper-level name changes via re-assignment, then the children that depend on that data will throw exceptions, which can be indicative to not change that data cause certain points of the program depend on it. Again, this can promote rethinking how the data should be updated more carefully depending on how you design it.
Certain data types may be represented over multiple lines in a file or string as well and will be read the same as if in a single line. Data types that support going over multiple lines will be represented in that format from maci's dump functions by default. The behavior can be changed by toggling some of the varying parameters (See functions).
Example list, dict, tuple, set
This format structure is typically desired for easier readability and that is why it is the default output behavior. This behavior will also automatically handle nested data structures as well, maintaining a clean human-readable format.
All multiline data must have their data enclosed properly by their respective delimiting partner character placing it as the first character on a newline trailing the data like in the example above. maci's dump functions auto-handles the formatting on this for any supported objects it accepts.
You may also represent multi-line string data to be loaded as well using triple-quoted strings. However, this is not the default format representation when using the dump functions for reasons of maintaining the integrity of the original string data. This is due to a multi-line string requiring 2 extra characters added to the string, being a leading and trailing newline character, to maintain maci's parsing format structure. If desired, that behavior can be turned on for the dump functions (See functions).
Example multiline string
If this dump behavior is turned on, it will generate your string data into a multi-line format only if it detects newline characters in your string. Upon each newline it detects, it will set the next line of data based on that newline detected. Note: maci will natively load multi-line strings in files.
If your string data contains a matching delimiting triple-quoted string at the start of a newline, it will terminate the read at that point just like python would. However, if it contains an opposite triple-quoted string like single triple-quotes inside of double triple-quotes, maci is smart enough to ignore that. You may also escape it if you need both, see example below.
maci ignores the single triple-quotes and vice versa if encapsulated by opposite quote type
Escaping the double triple-quotes
Commenting using the native python "#" syntax is fully supported. Multiline comments using single or double quotes are not currently supported but are targeted to feature and support in the future.
Example comment syntax variations in file
Describes the varying syntax structure and data type literals
maci follows and accepts a very similar and familiar name assignment structure as python, with the exception of adding special glyphs to perform special operations. You may assign names to values using any of the following methods:
Examples are represented using a file
Space before and after "=". Common pep8 style. Default structure from dump function format
Space before "="
Space after "="
No Spaces between "="
Many Random Spaces
Syntax also works for all assignment glyphs
Hard lock with no spaces
maci parses and supports a very similar experience and representation of primitive data types likened to python using a hybrid parsing concept where maci reads and parses the data to prepare for validation, to then be validated and transformed into a python object leveraging the ast library. The mechanics of how it is parsed are not the same of course, but the native data type representation found in python's basic data types can be written similarly.
maci attempts to keep it as familiar to python as possible to make the usage of data feel natural and not hard to learn if you're already comfortable with python's data types and structure. However, maci may add unique features that python does not have, or lack features that python has.
Literal values are expressed as if written in a file or string to be parsed
These are python-specific string literal prefixes that adhere to python's natural handling to produce the same results. maci does not do anything to handle these and is solely handled by the ast library.
Strings that contain any of the above prefixes can be parsed by maci leveraging the ast library.
f-strings are not currently supported but are targeted to feature and support in the future.
literal | type | description |
---|---|---|
literal | type | description |
---|---|---|