diff --git a/gazprea/spec/types.rst b/gazprea/spec/types.rst index 80bd4a8..2e6525b 100644 --- a/gazprea/spec/types.rst +++ b/gazprea/spec/types.rst @@ -16,3 +16,40 @@ Types types/vector types/string types/matrix + +.. _ssec:storable_types: + +Storable Types, Nesting, and Recursion +-------------------------------------- + +A *storable type* is any type whose values may be stored in a variable, +passed as an argument, returned, or held as a member of an +:term:`aggregate `. Every type in *Gazprea* is storable +except :ref:`streams `, which name I/O endpoints rather than +values. + +Aggregates may be nested to any depth. An :ref:`array ` or +:ref:`matrix ` of any rank, a :ref:`vector `, a +:ref:`tuple `, and a :ref:`struct ` may each hold +any storable element or field type, including one another. For example a +``vector`` (for a struct type ``S``), a struct with a ``tuple`` field, +and a ``tuple(S, integer[3][3])`` are all well formed. + +Nesting must be **acyclic through value types**. A ``struct`` or ``tuple`` +whose fields, directly or transitively, contain a value of its own type +has no finite size and is ill formed; the compiler must emit a +``TypeError`` (see :ref:`sec:errors`). A type may, however, refer to +itself *through a* :ref:`vector `, because a vector is +dynamically sized and stored by indirection: + +:: + + struct Tree (integer value, vector children); // well formed + struct Bad (integer value, Bad next); // TypeError: infinite size + +.. note:: + + *Implementation.* Nested aggregates are laid out and accessed + structurally (a chain of ``getelementptr`` in the LLVM dialect); the + vector at a recursion boundary is the sole point of indirection. Flat, + non-nested sequences continue to lower through the tensor/linalg path. diff --git a/gazprea/spec/types/array.rst b/gazprea/spec/types/array.rst index d632ee8..899801d 100644 --- a/gazprea/spec/types/array.rst +++ b/gazprea/spec/types/array.rst @@ -4,9 +4,12 @@ Arrays ------ Arrays are fixed size collections, where each element of the array has -the same type. Arrays can contain any of *Gazprea*'s -:term:`primitive types ` (``boolean``, ``integer``, -``real``, and ``character``) or compound types (structs and tuples). +the same type. An array element may be of any +:ref:`storable type `: a +:term:`primitive type ` (``boolean``, ``integer``, +``real``, ``character``), or a compound type such as a ``struct``, +``tuple``, ``vector``, ``string``, or another array (which yields a +higher-rank array; see :ref:`ssec:matrix`). .. _sssec:array_decl: diff --git a/gazprea/spec/types/matrix.rst b/gazprea/spec/types/matrix.rst index fd5aae7..f14507e 100644 --- a/gazprea/spec/types/matrix.rst +++ b/gazprea/spec/types/matrix.rst @@ -3,9 +3,15 @@ Matrices -------- -*Gazprea* supports two dimensional matrices as arrays of arrays. -Although the syntax and concepts are easily generalizable to many dimensions, -we are restricting the language to two dimensions for now. +*Gazprea* arrays generalize to arbitrary rank: a type of the form +``T[n1][n2]...[nk]`` is a rank-``k`` array whose element type ``T`` may be +any :ref:`storable type `. A *matrix* is the rank-2 +case, and this section describes it in full; higher-rank arrays follow the +same construction, indexing, and element-wise operation rules, generalized +to ``k`` index positions. The rank-2 operators discussed below (matrix +multiplication, ``rows``, and ``columns``) are defined on matrices +specifically; their generalization to a rank-agnostic ``shape`` interface +is left to a future revision of this specification. .. _sssec:matrix_decl: diff --git a/gazprea/spec/types/struct.rst b/gazprea/spec/types/struct.rst index c760e39..072fb4b 100644 --- a/gazprea/spec/types/struct.rst +++ b/gazprea/spec/types/struct.rst @@ -7,8 +7,12 @@ Like ``tuples``, a ``struct`` is a way of grouping multiple values with different types into an :term:`aggregate ` data structure. The main differences between tuples and structs are that the fields of a struct are named, and the type signature of a struct is named as a user defined type. -Any type except ``tuple``, another ``struct`` and :ref:`streams` -may be stored within a struct. Also like tuples, structs must contain *at least two fields*. +Any :ref:`storable type ` may be stored within a +struct, including arrays and matrices of any rank, ``vector``, ``string``, +``tuple``, and other ``struct`` types, nested to any depth (subject to the +:ref:`acyclicity rule `). Only +:ref:`streams` may not be stored within a struct. Also like +tuples, structs must contain *at least two fields*. .. _sssec:struct_decl: diff --git a/gazprea/spec/types/tuple.rst b/gazprea/spec/types/tuple.rst index 24ac331..c7afb6f 100644 --- a/gazprea/spec/types/tuple.rst +++ b/gazprea/spec/types/tuple.rst @@ -3,7 +3,7 @@ Tuples ------ -A ``tuple`` is a way of grouping multiple values with potentially different types into an aggregate data structure. Tuples are similar to :ref:`structs`, except that a tuple's fields are indexed instead of named. Tuples are often used to return multiple values from a function or procedure. Any type may be stored within tuples except structs and tuples. Additionally streams can not be stored in tuples. +A ``tuple`` is a way of grouping multiple values with potentially different types into an aggregate data structure. Tuples are similar to :ref:`structs`, except that a tuple's fields are indexed instead of named. Tuples are often used to return multiple values from a function or procedure. Any :ref:`storable type ` may be stored within a tuple, including arrays and matrices of any rank, ``vector``, ``string``, ``struct``, and other ``tuple`` types, nested to any depth (subject to the :ref:`acyclicity rule `). Only streams may not be stored in a tuple. .. _sssec:tuple_decl: diff --git a/gazprea/spec/types/vector.rst b/gazprea/spec/types/vector.rst index 60de966..ab9cf0e 100644 --- a/gazprea/spec/types/vector.rst +++ b/gazprea/spec/types/vector.rst @@ -34,11 +34,12 @@ the literals ``<`` and ``>`` are used in the declaration) Unlike the array type, *Gazprea* vectors do not have an explicit size specifier, often called *capacity* in other languages. -The element type ``T`` of a ``vector`` may be any base type -(``boolean``, ``integer``, ``real``, ``character``) or a one-dimensional -array of a base type. Vectors of vectors, tuples, structs, strings, and -streams are not permitted. Below are some examples of -``vector`` declarations. +The element type ``T`` of a ``vector`` may be any +:ref:`storable type `: a base type (``boolean``, +``integer``, ``real``, ``character``), an array or matrix of any rank, a +``string``, a ``tuple``, a ``struct``, or another ``vector`` — nested to +any depth. Only a :ref:`stream ` may not be stored. Below +are some examples of ``vector`` declarations. ::