NAME
Muldis::D::Dialect::HDMD_Perl_Tiny - How to format Perl Hosted Data Muldis D
VERSION
This document is Muldis::D::Dialect::HDMD_Perl_Tiny version 0.24.0.
PREFACE
This document is part of the Muldis D language specification, whose root document is Muldis::D; you should read that root document before you read this one, which provides subservient details.
DESCRIPTION
This document outlines the grammar of the Hosted Data Muldis D dialect named HDMD_Perl_Tiny
. The fully-qualified name of this Muldis D dialect, in combination with the base language spec it is bundled with, is Muldis_D:'http://muldis.com':'N.N.N':'HDMD_Perl_Tiny'
(when the bundled base language version is substituted for the N.N.N
).
This dialect is designed to exactly match the Muldis D system catalog (the possible representation of Muldis D code that is visible to or updateable by Muldis D programs at runtime) as to what non-critical meta-data it explicitly stores; so code in the HDMD_Perl_Tiny
dialect should be round-trippable with the system catalog with the result maintaining all the details that were started with. Since it matches the system catalog, this dialect should be able to exactly represent all possible Muldis D base language code (and probably all extensions too), rather than a subset of it. This dialect similarly matches the PTMD_Tiny
dialect, which is documented at Muldis::D::Dialect::PTMD_Tiny; in fact, most of the details in common with that other dialect are described just in the current file, for both dialects.
This dialect is designed to be as small as possible while meeting the above criteria, and is designed such that a parser that handles all of this dialect can be tiny, hence the dialect's Tiny
name. Likewise, a code generator for this dialect from the system catalog can be tiny.
The HDMD_Perl_Tiny
dialect is defined to be hosted in either Perl 5 or Perl 6, and as composed of just|mainly core Perl types. Where Perl 5 and 6 differ, the terminology and examples in this documentation specifically uses Perl 6 terminology and examples by default, and adds analogous Perl 5 terminology as necessary.
Fundamentally, the various Muldis D scalar and collection types are represented by their equivalent Perl 5 or 6 native scalar and collection types. But since Muldis D is more strongly typed, or at least differently typed, than Perl, each Muldis D literal is represented by a Perl Array, whose elements include both the payload Perl literal plus explicit meta-data for how to interpret that Perl literal for mapping to Muldis D.
This document mainly just specifies a way to represent Muldis D values as Perl values. Since the fundamental way to do data definition in Muldis D is to update catalog (information schema) variables, aka the Muldis D meta-model, which are themselves just data, then this document only needs to tell you how to define values to put in the catalog variables. Defining data types or routines are done by defining catalog values describing them.
See instead Muldis::D::Core for how to actually define the tuples and relations that define your data types and routines and queries and so forth.
For the present, this document will use the term PHMD (Perl Hosted Muldis D) for brevity when referring to aspects of the Perl-Tiny dialect.
GENERAL STRUCTURE
A PHMD value is composed mainly of a tree of Perl Array, such that each Array is a tree node. The elements of each node/Array include typically a native Perl payload value, which may be a PHMD value itself, plus meta-data for that payload, that meta-data typically including the analogy of a class name, were PHMD nodes instead represented by a tree of PHMD-specific objects. As an exception, one kind of PHMD node is not a Perl Array, but just a Perl Str
; if you see a Str
where you expect a PHMD node, assume it is a Name
node; this exception is for huffmanizing.
It should be emphasized that no Perl undefined values are allowed anywhere in a PHMD value; you must use only defined values instead. This documentation also assumes that only defined values are used, and that supplying a Perl undef will result in an error. If you genuinely want to represent that a value is unknown or inapplicable, then the Nothing
node type is provided as one way you can explicitly say so. This policy may be reconsidered.
BOOTLOADER
A full or partial Muldis D bootloader
routine consists of a language name declaration plus a series of 0..N imperative routine calls. A bootloader
is formatted as a PHMD node having 1..N elements, where the first element is a PHMD node defining a Muldis D "language name", and each remaining element is a PHMD node defining a "bootloader imperative routine call".
Examples:
[
[
'boot_call'
,
'sys.std.Core.Cat.create_depot_procedure'
,
{}, { ... } ],
]
LANGUAGE NAME
As per the VERSIONING pod section of Muldis::D, code written in Muldis D must start by declaring the fully-qualified Muldis D language name it is written in. The HDMD_Perl_Tiny
dialect formats this name as a PHMD node having the following 5 elements:
Node type / language base name: the Perl
Str
valueMuldis_D
.Base authority: a Perl
Str
as per the payload of aText
node; typically the PerlStr
valuehttp://muldis.com
.Base version number: a Perl
Str
as per the payload of aText
node; typically a PerlStr
value like1.2.3
.Dialect: the Perl
Str
valueHDMD_Perl_Tiny
.Extensions: a Perl
Hash|Mapping
as per the payload of aTuple
node; see the "MULDIS D TINY DIALECT PRAGMAS" pod section for more details.
Examples:
'auto_complete'
=> [
'Bool'
,
'md_enum'
,
'true'
],
} ]
More specifically, a language name PHMD node like the above would generally be the input for a Perl Hosted Muldis D implementating virtual machine's configuration step, which provides a context for subsequent feeding of other PHMD trees to said virtual machine.
BOOTLOADER IMPERATIVE ROUTINE CALL
This PHMD node specifies one statement of a Muldis D bootloader
routine which invokes an imperative routine, such statements being what the entire body of a bootloader
is composed of. A bootloader imperative routine call is formatted as a PHMD node having the following 4 elements:
Node type: the Perl
Str
valueboot_call
.Imperative routine name: a Perl
Array|Seq|Str
as per the payload of aNameChain
PHMD node.Imperative routine subject-to-update args: a Perl
Hash|Mapping
as per the payload of aTuple
PHMD node except that everyHash|Mapping
value is just a PerlArray|Seq|Str
as per the payload of aNameChain
PHMD node (each value is the name of a global variable).Imperative routine read-only args: a Perl
Hash|Mapping
as per the payload of aTuple
PHMD node.
Examples
[
'boot_call'
,
'sys.std.Core.Cat.create_depot_procedure'
, {}, { ... } ]
CORE GENERIC SCALAR VALUES
sys.std.Core.Type.Scalar
This node type represents a scalar subtype value. It has 4 elements:
Node type: the Perl
Str
valueScalar
.Scalar type name: a Perl
Array|Seq|Str
as per the payload of aNameChain
PHMD node.Possrep name: a Perl
Str
as per aName
PHMD node.The payload: a Perl
Hash|Mapping
as per the payload of aTuple
PHMD node.
This node is interpreted as a Muldis D sys.std.Core.Type.Scalar
subtype value whose declared type is specified by the scalar type name (second node element) and whose attributes are defined by the payload. The Scalar
PHMD node type can only be used for scalar types that have at least 1 possrep, and the payload is interpreted specifically as attributes of the declared type's possrep which is specified by the possrep name (third node element). Each key+value pair of the payload defines a named possrep attribute of the new scalar; the pair's key and value are, respectively, a Perl Str
that specifies the possrep attribute name, and a PHMD node that specifies the possrep attribute value. (Note that most scalar types have at least 1 possrep; the only ones that don't are either union types of types having possreps, or they are core system-defined types, and those all have their own dedicated syntax for literals.)
Examples:
[
'Scalar'
,
'sys.std.Rational.Type.Rat'
,
'float'
, {
'mantissa'
=> [
'Int'
,
'perl_int'
, 45207196 ],
'radix'
=> [
'Int'
,
'perl_int'
, 10 ],
'exponent'
=> [
'Int'
,
'perl_int'
, 37 ],
} ]
[
'Scalar'
,
'fed.lib.the_db.WeekDay'
,
'name'
, {
''
=> [
'Text'
,
'monday'
],
} ]
[
'Scalar'
,
'fed.lib.the_db.WeekDay'
,
'number'
, {
''
=> [
'Int'
,
'perl_int'
, 5 ],
} ]
sys.std.Core.Type.Bool
This node type represents a logical boolean value. It has 3 elements:
Node type: the Perl
Str
valueBool
.Format; one of:
md_enum
,perl_bool
,any_perl
.The payload.
This node is interpreted as a Muldis D sys.std.Core.Type.Bool
value as follows:
If the format is
md_enum
, then the payload must be a PerlStr
having one of the valuesfalse
,true
. This format specifically is what the Plain Text Muldis D grammar uses, and is the result of parsing it.If the format is
perl_bool
, then: Under Perl 6, the payload must be a PerlBool
, and soBool::False
andBool::True
are mapped directly. Under Perl 5, the payload must be just the specific result of a Perl 5 logical expression, such as(1 == 0)
or(1 == 1)
, and nothing else; said values are probably the empty string and number 1, respectively.If the format is
any_perl
, then the payload may be any Perl value, and it is simply coerced into a boolean context as per Perl's own semantics; typically for built-in scalars, the empty string and number zero are considered false, and everything else true.
Examples:
[
'Bool'
,
'md_enum'
,
'true'
]
[
'Bool'
,
'perl_bool'
, Bool::False ]
# Perl 6 only
[
'Bool'
,
'perl_bool'
, (1 == 0) ]
[
'Bool'
,
'perl_any'
, 42 ]
sys.std.Core.Type.Int
This node type represents an integer value. It has 3-4 elements:
Node type: the Perl
Str
valueInt
.Format; one of:
md_int
,perl_int
,any_perl
.Only when format is
md_int
; the max-col-val.The payload.
This node is interpreted as a Muldis D sys.std.Core.Type.Int
value as follows:
If the format is
md_int
, then the max-col-val must be a PerlStr
composed of a single[1-9A-Z]
character, and the payload must be a PerlStr
of the format0
or\-?<[1-9A-Z]><[0-9A-Z]>*
. This format specifically is what the Plain Text Muldis D grammar uses, and is the result of parsing it. The payload is interpreted as a base-N integer where N might be between 2 and 36, and the given max-col-val says which possible value of N to use. Assuming all column values are between zero and N-minus-one, the max-col-val contains that N-minus-one. So to specify, eg, bases [2,8,10,16], use max-col-val of [1,7,9,F].If the format is
perl_int
, then: Under Perl 6, the payload must be a PerlInt
, which is mapped directly. Under Perl 5, the payload must be just a canonical integer value according to Perl.If the format is
any_perl
, then the payload may be any Perl value, and it is simply coerced into an integer context as per Perl's own semantics, meaning base-10 where applicable. If something doesn't look numeric, it becomes zero; if something looks like a fractional number, it is truncated.
Examples:
[
'Int'
,
'md_int'
,
'1'
,
'11001001'
]
# binary
[
'Int'
,
'md_int'
,
'7'
,
'0'
]
# octal
[
'Int'
,
'md_int'
,
'7'
,
'644'
]
# octal
[
'Int'
,
'md_int'
,
'9'
,
'-34'
]
# decimal
[
'Int'
,
'md_int'
,
'9'
,
'42'
]
# decimal
[
'Int'
,
'md_int'
,
'F'
,
'DEADBEEF'
]
# hexadecimal
[
'Int'
,
'md_int'
,
'Z'
,
'-HELLOWORLD'
]
# base-36
[
'Int'
,
'perl_int'
, 21 ]
[
'Int'
,
'any_perl'
,
' 171 '
]
[
'Int'
,
'md_int'
,
'3'
,
'301'
]
# base-4
[
'Int'
,
'perl_int'
, 0 ]
[
'Int'
,
'md_int'
,
'B'
,
'A09B'
]
# base-12
[
'Int'
,
'perl_int'
, 101 ]
sys.std.Core.Type.Blob
This node type represents a bit string. It has 3-4 elements:
Node type: the Perl
Str
valueBlob
.Format; one of:
md_blob
,perl_blob
.Only when format is
md_blob
; the max-col-val.The payload.
This node is interpreted as a Muldis D sys.std.Core.Type.Blob
value as follows:
If the format is
md_blob
, then the max-col-val must be a PerlStr
composed of a single[137F]
character, and the payload must be a PerlStr
of the format<[0-9A-F]>*
. This format specifically is what the Plain Text Muldis D grammar uses, and is the result of parsing it. Each column of the payload specifies a sequence of one of [1,2,3,4] bits, depending on whether max-col-val is [1,3,7,F].If the format is
perl_blob
, then: Under Perl 6, the payload must be a PerlBlob
, which is mapped directly. Under Perl 5, the payload must be just a canonical Perl bit string, which is a scalar whose utf-8 flag is false.
Examples:
[
'Blob'
,
'md_blob'
,
'1'
,
'00101110100010'
]
# binary
[
'Blob'
,
'md_blob'
,
'3'
,
''
]
[
'Blob'
,
'md_blob'
,
'F'
,
'A705E'
]
# hexadecimal
[
'Blob'
,
'perl_blob'
, (
pack
'H2'
,
'P'
) ]
[
'Blob'
,
'md_blob'
,
'7'
,
'523504376'
]
[
'Blob'
,
'perl_blob'
, (
pack
'H2'
,
'Z'
) ]
sys.std.Core.Type.Text
This node type represents a character string. It has 2 elements:
Node type: the Perl
Str
valueText
.The payload.
This node is interpreted as a Muldis D sys.std.Core.Type.Text
value by directly mapping the payload. Note that, while Plain Text Muldis D may contain a few escape sequences, those would be replaced with what they represent prior to making a PHMD node. Under Perl 6, the payload must be a Perl Str
, which is mapped directly. Under Perl 5, the payload must be just a canonical Perl character string, which is a scalar whose utf-8 flag is true, or that doesn't contain any octets with a 1
-valued highest bit.
Examples:
[
'Text'
,
'Ceres'
]
[
'Text'
,
'サンプル'
]
# note: Perl 5 needs "use utf8;" pragma to work
[
'Text'
,
''
]
[
'Text'
,
'Perl'
]
CORE GENERIC NONSCALAR VALUES
sys.std.Core.Type.Tuple
This node type represents a tuple value. It has 2 elements:
Node type: the Perl
Str
valueTuple
.The payload; a Perl
Hash|Mapping
value.
This node is interpreted as a Muldis D sys.std.Core.Type.Tuple
value whose attributes are defined by the payload. Each key+value pair of the payload defines a named attribute of the new tuple; the pair's key and value are, respectively, a Perl Str
that specifies the attribute name, and a PHMD node that specifies the attribute value.
Examples:
[
'Tuple'
, {} ]
[
'Tuple'
, {
'login_name'
=> [
'Text'
,
'hartmark'
],
'login_pass'
=> [
'Text'
,
'letmein'
],
'is_special'
=> [
'Bool'
,
'md_enum'
,
'true'
],
} ]
[
'Tuple'
, {
'name'
=> [
'Text'
,
'Michelle'
],
'age'
=> [
'Int'
,
'perl_int'
, 17 ],
} ]
sys.std.Core.Type.Relation
This node type represents a relation value. It has 2-3 elements:
Node type: the Perl
Str
valueRelation
.Only when the node has 3 elements; ordered attr names; a Perl
Array|Seq
value.The payload; only when the node has 2 elements, a Perl
Array|Seq|Set|KeySet
ofStr|Hash|Mapping
value; only when the node has 3 elements, a PerlArray|Seq
ofArray|Seq
value.
This node is interpreted as a Muldis D sys.std.Core.Type.Relation
value as follows:
If the node has 2 elements, then: The new relation value's tuples and attribute names are defined by the payload. Iff the payload has zero elements, then it defines the only relation value having zero attributes and zero tuples. If the payload has elements, then either the elements must all be
Str
, or they must all beHash|Mapping
, but not both kinds in the same payload. Iff a payload's elements are eachStr
, then the payload defines the attribute names of a relation having zero tuples; each element must be as per the payload of aName
-defining PHMD node. Iff a payload's elements are eachHash|Mapping
, then each element of the payload defines a tuple of the new relation; each element is as per the payload of a tuple-defining PHMD node; every tuple-defining element of the payload must be of the same degree and have the same attribute names as its sibling elements; these are the degree and attribute names of the relation as a whole, which is its heading for the current purposes.If the node has 3 elements, then: The new relation value's attribute names are defined by the ordered attr names (second element) and the relation body's tuples' attribute values are defined by the payload (third element). This format is meant to be the most compact of the generic relation node formats, as the attribute names only appear once for the relation rather than repeating for each tuple. As a trade-off, the attribute values per tuple from the third element must appear in the same order as their corresponding attribute names appear in the second element, as the names and values in the relation literal are matched up by ordinal position here.
Examples:
[
'Relation'
, [] ]
[
'Relation'
, [ {}, ] ]
[
'Relation'
, [
'x'
,
'y'
,
'z'
, ] ]
[
'Relation'
, [
{
'login_name'
=> [
'Text'
,
'hartmark'
],
'login_pass'
=> [
'Text'
,
'letmein'
],
'is_special'
=> [
'Bool'
,
'md_enum'
,
'true'
],
},
] ]
[
'Relation'
, [
'name'
,
'age'
, ], [
[ [
'Text'
,
'Michelle'
], [
'Int'
,
'perl_int'
, 17 ], ],
] ]
sys.std.Core.Type.Set
This node type represents a set value. It has 2 elements:
Node type: the Perl
Str
valueSet
.The payload; a Perl
Array|Seq|Set|KeySet
value.
This node is interpreted as a Muldis D sys.std.Core.Type.Set
value whose elements are defined by the payload. Each element of the payload defines a unary tuple of the new set; each element is a PHMD node that defines the value
attribute of the tuple.
Examples:
[
'Set'
, [
[
'Text'
,
'Canada'
],
[
'Text'
,
'Spain'
],
[
'Text'
,
'Jordan'
],
[
'Text'
,
'Thailand'
],
] ]
[
'Set'
, [
[
'Int'
,
'perl_int'
, 3 ],
[
'Int'
,
'perl_int'
, 16 ],
[
'Int'
,
'perl_int'
, 85 ],
] ]
sys.std.Core.Type.Nothing
This node type represents a 'nothing' value; it is interpreted as a Muldis D sys.std.Core.Type.Nothing
. It has 1 element, which is the Perl Str
value Nothing
.
Examples:
[
'Nothing'
]
sys.std.Core.Type.Single
This node type represents a 'single' value. It has 2 elements:
Node type: the Perl
Str
valueSingle
.The payload; a PHMD node that defines a single scalar or nonscalar value.
This node is interpreted as a Muldis D sys.std.Core.Type.Single
value whose element is defined by the payload. The payload is a PHMD node that defines the value
attribute of the single tuple of the new 'single'.
Examples:
[
'Single'
, [
'Text'
,
'2003.07.24'
] ]
sys.std.Core.Type.Array
This node type represents a sequence value. It has 2 elements:
Node type: the Perl
Str
valueArray
.The payload; a Perl
Array|Seq
value.
This node is interpreted as a Muldis D sys.std.Core.Type.Array
value whose elements are defined by the payload. Each element of the payload defines a binary tuple of the new sequence; the element value is a PHMD node that defines the value
attribute of the tuple, and the element index is used as the index
attribute of the tuple.
Examples:
[
'Array'
, [
[
'Text'
,
'Alphonse'
],
[
'Text'
,
'Edward'
],
[
'Text'
,
'Winry'
],
] ]
[
'Array'
, [
[
'Int'
,
'perl_int'
, 57 ],
[
'Int'
,
'perl_int'
, 45 ],
[
'Int'
,
'perl_int'
, 63 ],
[
'Int'
,
'perl_int'
, 61 ],
] ]
sys.std.Core.Type.Bag
This node type represents a bag value. It has 3 elements:
Node type: the Perl
Str
valueBag
.Format; one of:
aoa_counted
,array_repeated
,perl_bag
(p6).The payload; a Perl
Bag|KeyBag
value orArray|Seq
orArray|Seq
ofArray|Seq
.
This node is interpreted as a Muldis D sys.std.Core.Type.Bag
value whose elements are defined by the payload. The payload is interpreted as follows:
If the format is
aoa_counted
, then the payload must be a PerlArray|Seq
, and each element of the payload defines a binary tuple of the new bag; the element is a 2-elementArray|Seq
, and those 2 elements, by index order, are a PHMD node that defines thevalue
attribute of the tuple, and a 2-3-elementArray|Seq
(which is the same as an 'Int' PHMD node minus the first constant element) that defines thecount
attribute of the tuple; the count must be a positive integer.If the format is
array_repeated
, then the payload must be a PerlArray|Seq
, and each element of the payload contributes to a binary tuple of the new bag; the element value is a PHMD node that defines thevalue
attribute of the tuple. The bag has 1 tuple for every distinct (after format normalization) element value in the payload, and thecount
attribute of that tuple says how many instances of said element were in the payload.If the format is
perl_bag
, then the payload must be a Perl 6 (there is no Perl 5 analogy)Bag|KeyBag
value; the payload elements are PHMD nodes corresponding to thevalue
attribute of the new bag's tuples, and the mapping is as you should expect.
Examples:
[
'Bag'
,
'aoa_counted'
, [
[
[
'Text'
,
'Apple'
],
[
'md_int'
,
'9'
,
'500'
],
],
[
[
'Text'
,
'Orange'
],
[
'perl_int'
, 300 ],
],
[
[
'Text'
,
'Banana'
],
[
'perl_int'
, 400 ],
],
] ]
[
'Bag'
,
'array_repeated'
, [
[
'Text'
,
'Foo'
],
[
'Text'
,
'Quux'
],
[
'Text'
,
'Foo'
],
[
'Text'
,
'Bar'
],
[
'Text'
,
'Baz'
],
[
'Text'
,
'Baz'
],
] ]
QUASI- VALUES
Every PHMD node type for a generic scalar or nonscalar literal has a corresponding extra PHMD node type for a quasi- literal. The corresponding extra quasi- node types are exactly the same in format to the non-quasi types but that for each one of them, the value of its first element has the Perl Str
value Quasi
prepended. So PHMD nodes whose first elements each are [QuasiScalar
, QuasiTuple
, QuasiRelation
, QuasiSet
, QuasiNothing
, QuasiSingle
, QuasiArray
, QuasiBag
] are interpreted as Muldis D [sys.std.Core.Type.QuasiScalar
, sys.std.Core.Type.QuasiTuple
, sys.std.Core.Type.QuasiRelation
, sys.std.Core.Type.QuasiSet
, sys.std.Core.Type.QuasiNothing
, sys.std.Core.Type.QuasiSingle
, sys.std.Core.Type.QuasiArray
, sys.std.Core.Type.QuasiBag
] values, respectively.
CATALOG SCALAR VALUES
sys.std.Core.Type.Cat.Name
This node type represents a canonical short name for any kind of DBMS entity when declaring it; it is a character string type, that is disjoint from Text
.
Unlike every other PHMD node type, a canonical short name is simply a Perl Str
value, which is its payload; it is not encapsulated in a Perl Array; this difference is done for huffmanizing reasons, since a short name is probably the most often used node type, and moreover this change allows for simplifying other parts of the grammar.
This node is interpreted as a Muldis D sys.std.Core.Type.Cat.Name
value by directly mapping itself / the payload. Note that, while Plain Text Muldis D may contain a few escape sequences, those would be replaced with what they represent prior to making a PHMD node. The node / its payload must be as per the payload of a Text
PHMD node.
Examples:
'login_pass'
'First Name'
sys.std.Core.Type.Cat.NameChain
This node type represents a canonical long name for invoking a DBMS entity in some contexts; it is conceptually a sequence of entity short names. It has 2 elements:
Node type: the Perl
Str
valueNameChain
.The payload; a Perl
Array|Seq
value orStr
(char-mode scalar) value.
This node is interpreted as a Muldis D sys.std.Core.Type.Cat.NameChain
value as follows:
If the payload is an
Array|Seq
, then it must have at least 2 elements, and every element must be a valid payload for aName
PHMD node (that is, any Perl character string). Each element of the payload, in order, defines an element of thearray
possrep's attribute of aNameChain
.If the payload is a
Str
, then it must be formatted as a catenation (using period (.
) separators) of at least 2 parts, where each part is escaped such that backslashes, single-quotes, and periods are escaped as\b
,\q
and\p
respectively; it defines theflat
possrep's attribute of aNameChain
.
Examples:
[
'NameChain'
, [
'fed'
,
'data'
,
'the_db'
,
'gene'
,
'sorted_person_name'
] ]
[
'NameChain'
,
'fed.data.the_db.stats.samples_by_order'
]
sys.std.Core.Type.Cat.DeclNameChain
This node type represents a canonical long name for declaring a DBMS entity in N-depth contexts; it is conceptually a sequence of entity short names. It has 2 elements:
Node type: the Perl
Str
valueDeclNameChain
.The payload; a Perl
Array|Seq
value orStr
(char-mode scalar) value.
This node is interpreted as a Muldis D sys.std.Core.Type.Cat.DeclNameChain
value as follows:
If the payload is an
Array|Seq
, then every element must be a valid payload for aName
PHMD node (that is, any Perl character string). Each element of the payload, in order, defines an element of thearray
possrep's attribute of aDeclNameChain
.If the payload is a
Str
, then it must be formatted as a catenation of 0..N parts (starting with a period (.
) and each part ending with a period), where each part is escaped such that backslashes, single-quotes, and periods are escaped as\b
,\q
and\p
respectively; it defines theflat
possrep's attribute of aDeclNameChain
.
Examples:
[
'DeclNameChain'
, [
'gene'
,
'sorted_person_name'
] ]
[
'DeclNameChain'
,
'.stats.samples_by_order.'
]
sys.std.Core.Type.Cat.Comment
This node type represents the text of a Muldis D code comment; it is a character string type, that is disjoint from both Text
and Name
. It has 2 elements:
Node type: the Perl
Str
valueComment
.The payload.
This node is interpreted as a Muldis D sys.std.Core.Type.Cat.Comment
value by directly mapping the payload. Note that, while Plain Text Muldis D may contain a few escape sequences, those would be replaced with what they represent prior to making a PHMD node. The payload must be as per the payload of a Text
PHMD node.
Examples:
[
'Comment'
,
'This does something.'
]
sys.std.Core.Type.Cat.Order
This node type represents an order-determination. It has 3 elements:
Node type: the Perl
Str
valueOrder
.Format; one of:
md_enum
,perl_order
.The payload.
This node is interpreted as a Muldis D sys.std.Core.Type.Cat.Order
value as follows:
If the format is
md_enum
, then the payload must be a PerlStr
having one of the valuesincrease
,same
,decrease
,-1
,0
,1
(note that each of the 3Cat.Order
values has 2 possreps that are directly expressable here). This format specifically is what the Plain Text Muldis D grammar uses, and is the result of parsing it.If the format is
perl_order
, then: Under Perl 6, the payload must be a PerlOrder
, and soOrder::Increase
andOrder::Same
andOrder::Decrease
are mapped directly. Under Perl 5, the payload must be just the specific result of a Perl 5 order-determining expression, such as(1 <=> 2)
or(1 <=> 1)
or(2 <=> 1)
, and nothing else; said values are probably the numbers [-1
,0
,1
], respectively.
Examples:
[
'Order'
,
'md_enum'
,
'same'
]
[
'Order'
,
'perl_order'
, Order::Increase ]
# Perl 6 only
[
'Order'
,
'perl_order'
, (2 <=> 1) ]
RATIONAL EXTENSION SCALAR VALUES
sys.std.Rational.Type.Rat
This node type represents a rational value. It has 3-4 elements:
Node type: the Perl
Str
valueRat
.Format; one of:
md_radix
,md_ratio
,md_float
,perl_rat
,perl_float
,perl_int_ratio
,perl_int_float
,any_perl
,any_perl_ratio
,any_perl_float
.Only when format is
md_radix
|md_ratio
|md_float
; the max-col-val.The payload.
This node is interpreted as a Muldis D sys.std.Rational.Type.Rat
value as follows:
If the format is
md_radix
, then the max-col-val must be a PerlStr
composed of a single[1-9A-Z]
character, and the payload must be a PerlStr
of the format0\.?<[0-9A-Z]>*
or\-?<[1-9A-Z]><[0-9A-Z]>*\.?<[0-9A-Z]>*
. This format specifically is what the Plain Text Muldis D grammar uses ('radix' option), and is the result of parsing it. The payload is interpreted as a base-N rational where N might be between 2 and 36, and the given max-col-val says which possible value of N to use. Assuming all column values are between zero and N-minus-one, the max-col-val contains that N-minus-one. So to specify, eg, bases [2,8,10,16], use max-col-val of [1,7,9,F].If the format is
md_ratio
, then the max-col-val must be as permd_radix
, and the payload must be a 2-elementArray|Seq
where the first element is a PerlStr
of the format0
or\-?<[1-9A-Z]><[0-9A-Z]>*
(an integer) and the second element is a PerlStr
of the format<[1-9A-Z]><[0-9A-Z]>*
(a positive integer). The payload is interpreted as permd_radix
but that its value comes from the first element (a numerator) divided by the second (a denominator). Note that while themd_radix
format is limited to representing rationals whose denominator is a power of some N between 2 and 36, themd_ratio
format can represent those with any N that is greater than or equal to 2, such as 1/43.If the format is
md_float
, then the max-col-val must be as permd_radix
, and the payload must be a 3-elementArray|Seq
where the first element is a PerlStr
of the format0
or\-?<[1-9A-Z]><[0-9A-Z]>*
(an integer) and the second element is a PerlStr
of the format<[2-9A-Z]><[0-9A-Z]>*
(an integer greater than 1) and the third element is as per the first (an integer). The payload is interpreted as permd_radix
but that its value comes from the first element (a mantissa) multiplied by the result of the second element (a radix) taken to the power of the third (an exponent). Note that while themd_ratio
format can represent all rationals, the very large or very small ones would be quite verbose written in that format, and so themd_float
format allows writing those values in a more terse fashion, such as 1.56*10^37.If the format is
perl_rat
, then: Under Perl 6, the payload must be a PerlRat
(orNum
), which is mapped directly. Under Perl 5, the payload must be just a canonical rational or numeric value according to Perl.If the format is
perl_float
, then: Under Perl 6, the payload must be a PerlFloat
(orNum
), which is mapped directly. Under Perl 5, the payload must be just a canonical floating-point or numeric value according to Perl.If the format is
perl_int_ratio
, then the payload must a 2-elementArray|Seq
where each element must be a canonical integer (or positive integer, respectively) to Perl as per defining aperl_int
; the rational's value is interpreted as the first element divided by the second.If the format is
perl_int_float
, then the payload must a 3-elementArray|Seq
where each element must be a canonical integer (or integer greater than 2, or integer, respectively) to Perl as per defining aperl_int
; the rational's value is interpreted as the first element multiplied by the result of the second element taken to the power of the third.If the format is
any_perl
, then the payload may be any Perl value, and it is simply coerced into a numeric context as per Perl's own semantics, meaning base-10 where applicable. If something doesn't look numeric, it becomes zero.If the format is
any_perl_ratio
, then the payload is as perperl_int_ratio
but that each array element is simply coerced into an integer context. If Perl's coercion of the denominator produces an integer less than 1, it becomes a 1. This may be revised to fail instead.If the format is
any_perl_float
, then the payload is as perperl_int_float
but that each array element is simply coerced into an integer context. If Perl's coercion of the radix produces an integer less than 2, it becomes a 2. This may be revised to fail instead.
Examples:
[
'Rat'
,
'md_radix'
,
'1'
,
'-1.1'
]
[
'Rat'
,
'md_radix'
,
'9'
,
'-1.5'
]
# same val as prev
[
'Rat'
,
'md_radix'
,
'9'
,
'3.14159'
]
[
'Rat'
,
'md_radix'
,
'A'
,
'0.0'
]
[
'Rat'
,
'md_radix'
,
'F'
,
'DEADBEEF.FACE'
]
[
'Rat'
,
'md_radix'
,
'Z'
,
'0.000AZE'
]
[
'Rat'
,
'md_ratio'
,
'6'
, [
'500001'
,
'1000'
] ]
[
'Rat'
,
'md_ratio'
,
'B'
, [
'A09B'
,
'A'
] ]
[
'Rat'
,
'md_float'
,
'1'
, [
'1011101101'
,
'10'
,
'-11011'
] ]
[
'Rat'
,
'md_float'
,
'9'
, [
'45207196'
,
'10'
,
'37'
] ]
[
'Rat'
,
'perl_rat'
, 21.003 ]
[
'Rat'
,
'perl_float'
, 5.428**295 ]
[
'Rat'
,
'perl_int_ratio'
, [ 1, 43 ] ]
[
'Rat'
,
'perl_int_float'
, [ 314159, 10, -5 ] ]
[
'Rat'
,
'any_perl'
,
' 54.67 '
]
[
'Rat'
,
'any_perl_ratio'
, [
' 57 '
,
' 71 '
] ]
[
'Rat'
,
'any_perl_float'
, [
' 656573456 '
,
' 8 '
,
' 243323 '
] ]
sys.std.Rational.Type.RatRoundMeth
This node type represents a rounding method. It has 2 elements:
Node type: the Perl
Str
valueRatRoundMeth
.The payload.
This node is interpreted as a Muldis D sys.std.Rational.Type.RatRoundMeth
value by directly mapping the payload. The payload must be a Perl Str
having one of the 7 values half_down
, half_up
, half_even
, to_floor
, to_ceiling
, to_zero
, to_inf
.
Examples:
[
'RatRoundMeth'
,
'half_up'
]
TREAT AS TYPE
This PHMD node is a lexical-scoped pragma that may be used where any literal value representing PHMD node may be used. It has 3 elements:
Node type: the Perl
Str
valuetreat_as_type
.Type name: a Perl
Array|Seq|Str
as per the payload of aNameChain
PHMD node.The payload; a PHMD node that defines a single value.
This node is used just to provide meta-data for its sole child node, which typically is a tuple or relation literal. By default, when defining a nonscalar literal using a PHMD node tree, the resulting nonscalar value is "just a tuple|relation". If that literal is then a sub-literal used as either a scalar possrep attribute value or as an argument to a bootloader-invoked routine, the known declared type of that scalar possrep attribute or routine parameter would provide a context such that the expected specific type of the nonscalar value, such as what attributes it should have, can be gleaned, and then it would be known what type the nonscalar literal is supposed to belong to. But in some contexts, such as when the declared type of the routine parameter is simply Relation
, there isn't enough information in the normal context to know what attribute names and types the new nonscalar should have. So the treat_as_type
PHMD node type can then be used by the programmer to explicitly tell the Tiny dialect parser what the specific type of the nonscalar is. The literal being annotated is provided by the payload 3rd node element, and the type name it is being annotated with is given in the type name 2nd node element. Using treat_as_type
is useful to enable some kinds of compile-time type checking, and it also helps the auto_complete
pragma to work in many places where it otherwise lacks information needed to work.
Examples:
[
'treat_as_type'
,
'fed.lib.the_db.gene.Person'
,
[
'Relation'
, [
'name'
,
'age'
, ], [
[ [
'Text'
,
'Michelle'
], [
'Int'
,
'perl_int'
, 17 ], ],
] ]
]
MULDIS D TINY DIALECT PRAGMAS
auto_complete
All Muldis D values, besides scalars lacking any possreps, are defined in terms of a collection of attribute values, and there is no such thing as an attribute being undefined; normally when one selects a value of a particular attribute-based type, they must supply values for all of its attributes; this is true with values comprising the system catalog as with any other values. Code written in the Muldis D PTMD_Tiny
or HDMD_Perl_Tiny
dialect is comprised almost entirely of value literals, and by default all of the attribute values of said values must be explicitly given in the literals as sub-literals, even in the common case where some attributes just have the default values for their type.
While this fact allows for parsers to be very simple and for sub-literals to be compilable into values without knowing the context they're compiled into, it means that programmers would have to write maybe about twice as much code as they otherwise would if they could simply not write out the default-valued attributes.
If the 5th Extensions portion of the fully-qualified Muldis D language name contains a name+value pair of auto_complete
+ Bool:true
, then this activates the optional auto_complete
pragma, which provides one kind of automatic code completion. When auto_complete
is active, programmers may omit any literal attributes that they want, and those attributes will be automatically defined by the parser to have the default values for their type. Or more specifically, the wider literal whose attributes are missing will be extended to become the default value of the type of the wider literal but that those attributes of its that were explicitly given will override the default's values for those attributes. The actual behaviour is essentially what the sys.std.Tuple.substitution_in_default
function does.
But the auto_complete
pragma is not simply an automatically invoked pre-processing Muldis D function, because it also serves the common case where one is defining relation literals that have different attributes specified per tuple; such a thing by itself isn't even valid as a generic relation, so it certainly can't be given to a Muldis D function; so the pragma has at least that advantage unique to itself.
Note that the lexer is exactly the same regardless of whether the auto_complete
pragma is turned on or off, because the matters of missing attributes were never tested or enforced at the lexical level in the first place; rather the pragma only affects the parsing stage that follows the lexing. In other words, the actual syntax or grammar is identical regardless of the setting of this pragma.
Now one consequence of using the auto_complete
pragma is that in general the parser must be more complicated, and read type definitions from the DBMS information schema so that it knows what attributes each literal is supposed to have, and their declared types, and also sub-literals can no longer in general be fully converted to values in isolation; now the parent-most literal must be evaluated first, because its declared type generally determines the declared types of its attributes, and then their attributes recursively. For non-scalar types, the initial declared type being looked at is the declared type of the bootloader-invoked routine's parameter that the literal is being given to as an argument.
Now if the declared type of said parameter is just a generic type, such as Relation
or Array
, then often no information can be gleaned from this context for what attributes should exist, and so you will need to wrap the argument literal in a treat_as_type
literal that explicitly provides the specific type information needed; otherwise, auto_complete
won't help you and you must then fully define relation values with the same attributes per tuple. But fortunately for brevity, a lot of the places where auto_complete
would help you the most is when the bootloader is invoking system-defined data-defining procedures, and their parameters are all of attribute-specifying types, and it is in such data definition that you may be most likely to face a large number of default-valued attributes, such as comment
.
Note that the reason the auto_complete
behaviour is turned off by default is twofold. First, the parser can be a lot simpler / more tiny with it off. Second, requiring users to explicitly define even default-valued attributes can make the code more self-documenting and can help users avoid some kinds of bugs due to action from unseen values, or due to some default values "silently" changing between language versions. So then essentially, turning on auto_complete
means the programmer is telling the parser "I know what I'm doing" by explicitly asking for potentially less-safe behaviour. Of course, even with auto_complete
turned on, you can still explicitly define attribute values that are their type's default values, so it is possible to compromise such as you like.
Also note that it should be trivial for a Muldis D implementation to let users input code written with auto_complete
turned on, and then output the version of that code for their perusal with it turned off, so they can see what extra values were filled in without having to manually write said.
SEE ALSO
Go to Muldis::D for the majority of distribution-internal references, and Muldis::D::SeeAlso for the majority of distribution-external references.
AUTHOR
Darren Duncan (perl@DarrenDuncan.net
)
LICENSE AND COPYRIGHT
This file is part of the formal specification of the Muldis D language.
Muldis D is Copyright © 2002-2008, Darren Duncan.
See the LICENSE AND COPYRIGHT of Muldis::D for details.
TRADEMARK POLICY
The TRADEMARK POLICY in Muldis::D applies to this file too.
ACKNOWLEDGEMENTS
The ACKNOWLEDGEMENTS in Muldis::D apply to this file too.