aboutsummaryrefslogtreecommitdiff
path: root/language/type-definition.rst
diff options
context:
space:
mode:
Diffstat (limited to 'language/type-definition.rst')
-rw-r--r--language/type-definition.rst52
1 files changed, 50 insertions, 2 deletions
diff --git a/language/type-definition.rst b/language/type-definition.rst
index 02616b8..88c4a04 100644
--- a/language/type-definition.rst
+++ b/language/type-definition.rst
@@ -5,7 +5,7 @@ Defining Types
Crowbar has three different kinds of user-defined types.
-.. crowbar:element:: StructDefinition <- 'struct' identifier '{' VariableDeclaration+ '}' ';'
+.. crowbar:element:: StructDefinition <- 'struct' identifier '{' VariableDeclaration+ '}'
A ``struct`` defines a composite type with several members.
@@ -13,7 +13,7 @@ Defining Types
define struct layout in memory
-.. crowbar:element:: EnumDefinition <- 'enum' identifier '{' EnumMember (',' EnumMember)* ','? '}' ';'
+.. crowbar:element:: EnumDefinition <- 'enum' identifier '{' EnumMember (',' EnumMember)* ','? '}'
EnumMember <- identifier ('=' Expression)?
An ``enum`` defines a type which can take one of several specified values.
@@ -21,3 +21,51 @@ Defining Types
.. todo::
define enum value assignment, type-related behavior
+
+.. crowbar:element:: UnionDefinition <- RobustUnionDefinition / FragileUnionDefinition
+
+ Unions as implemented in C are not robust by default, and care must be taken to ensure that they are only used robustly.
+ However, for the purpose of interoperability with C, Crowbar unions may be defined as robust or as fragile.
+
+.. crowbar:element:: RobustUnionDefinition <- 'union' identifier '{' VariableDeclaration UnionBody '}'
+ UnionBody <- 'switch' '(' identifier ')' '{' UnionBodySet+ '}'
+ UnionBodySet <- CaseSpecifier+ (VariableDeclaration / ';')
+
+ A robust union, or simply union, in Crowbar is what is known more broadly as a tagged union.
+ The top-level variable declaration must have a type which is some ``enum``, and its name must be the same as the identifier in the ``switch``.
+
+ For example::
+
+ enum TokenType {
+ Identifier,
+ Constant,
+ Operator,
+ Whitespace,
+ }
+
+ union Token {
+ enum TokenType type;
+
+ switch (type) {
+ case Identifier: (const char) * name;
+ case Constant: int value;
+ case Operator: char op;
+ case Whitespace: ;
+ }
+ }
+
+ defines a ``union Token`` type, where the ``type`` field controls which of the other fields in the union is valid.
+
+ .. todo::
+
+ go into more depth about how tagged unions work
+
+.. crowbar:element:: FragileUnionDefinition <- 'fragile' 'union' identifier '{' VariableDeclaration+ '}'
+
+ A fragile union, like a struct, is a simple bag of fields.
+ However, unlike a struct, only the most recently assigned field is valid at any given time.
+ As such, in non-trivial cases no compiler can predict which field is or is not valid, and any statement which reads a field of a fragile union must itself be a :crowbar:ref:`FragileStatement`.
+
+ .. todo::
+
+ explain memory layout of fragile unions