diff --git a/docs/fpp-spec.html b/docs/fpp-spec.html index a181fe582..a1558e9e6 100644 --- a/docs/fpp-spec.html +++ b/docs/fpp-spec.html @@ -465,84 +465,91 @@

The F Prime Prime (FPP) Language Specification, Unreleased, after v2.2.1

5.1.3. Examples -
  • 5.2. Array Definitions +
  • 5.2. Alias Type Definitions
  • -
  • 5.3. Component Definitions +
  • 5.3. Array Definitions
  • -
  • 5.4. Component Instance Definitions +
  • 5.4. Component Definitions
  • -
  • 5.5. Constant Definitions +
  • 5.5. Component Instance Definitions
  • -
  • 5.6. Enum Definitions +
  • 5.6. Constant Definitions
  • -
  • 5.7. Enumerated Constant Definitions +
  • 5.7. Enum Definitions
  • -
  • 5.8. Module Definitions +
  • 5.8. Enumerated Constant Definitions
  • -
  • 5.9. Port Definitions +
  • 5.9. Module Definitions
  • -
  • 5.10. State Machine Definitions +
  • 5.10. Port Definitions
  • -
  • 5.11. Struct Definitions +
  • 5.11. State Machine Definitions
  • -
  • 5.12. Topology Definitions +
  • 5.12. Struct Definitions +
  • +
  • 5.13. Topology Definitions +
  • @@ -903,18 +910,21 @@

    The F Prime Prime (FPP) Language Specification, Unreleased, after v2.2.1

    17.8. Enum Types
  • 17.9. Struct Types
  • 17.10. Abstract Types
  • -
  • 17.11. Internal Types +
  • 17.11. Alias Types
  • +
  • 17.12. Internal Types
  • -
  • 17.12. Displayable Types
  • -
  • 17.13. Types with Numeric Members
  • -
  • 17.14. Default Values
  • +
  • 17.13. Canonical Types
  • +
  • 17.14. Underlying Types
  • +
  • 17.15. Displayable Types
  • +
  • 17.16. Types with Numeric Members
  • +
  • 17.17. Default Values
  • 18. Type Checking @@ -1652,13 +1662,51 @@

    5.1.3. Examples

    -

    5.2. Array Definitions

    +

    5.2. Alias Type Definitions

    +
    +

    An alias type definition associates a name with a type +that is defined elsewhere.

    +
    +
    +

    5.2.1. Syntax

    + +
    +
    +

    5.2.2. Semantics

    +
    +

    The identifier is the name N of the type. +The definition associates the name N with +the type T specified after the = symbol. +Elsewhere in the model, the name N may be used as alias of (i.e., an +alternate name for) the type T.

    +
    +
    +
    +

    5.2.3. Examples

    +
    +
    +
    # Defines a type A that is an alias of U32
    +type A = U32
    +
    +# Defines a struct type B whose member x has type A
    +struct B {
    +  x: A
    +  y: F32
    +} default { y = 1 }
    +
    +
    +
    +
    +
    +

    5.3. Array Definitions

    An array definition defines a new array type and associates a name with it.

    -

    5.2.1. Syntax

    +

    5.3.1. Syntax

    array identifier = [ expression ] type-name @@ -1671,7 +1719,7 @@

    5.2.1. Syntax

    -

    5.2.2. Semantics

    +

    5.3.2. Semantics

    The identifier is the name N of the new type. The first expression must evaluate to a compile-time constant numeric value n @@ -1696,7 +1744,7 @@

    5.2.2. Semantics

    -

    5.2.3. Examples

    +

    5.3.3. Examples

    # Defines an array type A of 3 U8 elements with default value [ 0, 0, 0 ]
    @@ -1721,7 +1769,7 @@ 

    5.2.3. Examples

    -

    5.3. Component Definitions

    +

    5.4. Component Definitions

    A component definition defines an F Prime component. A component is a unit of function in the F Prime framework. @@ -1729,7 +1777,7 @@

    5.3. Component Definitions

    ports.

    -

    5.3.1. Syntax

    +

    5.4.1. Syntax

    component-kind component identifier @@ -1830,7 +1878,7 @@

    5.3.1. Syntax

    -

    5.3.2. Semantics

    +

    5.4.2. Semantics

    The identifier is the name of the component. The definitions inside the body of the component are @@ -1941,7 +1989,7 @@

    5.3.2. Semantics

    -

    5.3.3. Examples

    +

    5.4.3. Examples

    @ Receives commands from the ground or from a sequencer
    @@ -2196,7 +2244,7 @@ 

    5.3.3. Examples

    -

    5.4. Component Instance Definitions

    +

    5.5. Component Instance Definitions

    A component instance definition defines an instance of a @@ -2205,7 +2253,7 @@

    5.4. Component Instance Defi topology definition.

    -

    5.4.1. Syntax

    +

    5.5.1. Syntax

    instance identifier @@ -2243,7 +2291,7 @@

    5.4.1. Syntax

    -

    5.4.2. Semantics

    +

    5.5.2. Semantics

    1. @@ -2373,7 +2421,7 @@

      5.4.2. Semantics

    -

    5.4.3. Examples

    +

    5.5.3. Examples

    instance commandDispatcher: Svc.CommandDispatcher \
    @@ -2405,14 +2453,14 @@ 

    5.4.3. Examples

    -

    5.5. Constant Definitions

    +

    5.6. Constant Definitions

    A constant definition associates a name with a compile-time constant value. You can use the name in place of the value elsewhere in the model.

    -

    5.5.1. Syntax

    +

    5.6.1. Syntax

    constant identifier @@ -2421,7 +2469,7 @@

    5.5.1. Syntax

    -

    5.5.2. Semantics

    +

    5.6.2. Semantics

    expression must evaluate @@ -2433,7 +2481,7 @@

    5.5.2. Semantics

    -

    5.5.3. Examples

    +

    5.6.3. Examples

    constant a = 0 # a has value 0
    @@ -2444,7 +2492,7 @@ 

    5.5.3. Examples

    -

    5.6. Enum Definitions

    +

    5.7. Enum Definitions

    An enum definition does two things:

    @@ -2467,7 +2515,7 @@

    5.6. Enum Definitions

    -

    5.6.1. Syntax

    +

    5.7.1. Syntax

    enum identifier [ : type-name ] @@ -2484,7 +2532,7 @@

    5.6.1. Syntax

    -

    5.6.2. Semantics

    +

    5.7.2. Semantics

    The enumerated constants have the enum type defined in the enum definition. During @@ -2509,14 +2557,14 @@

    5.6.2. Semantics

    -

    5.6.3. Inferred Representation Type

    +

    5.7.3. Inferred Representation Type

    If type-name does not appear after the identifier, then the implied representation type is I32.

    -

    5.6.4. Explicit Representation Type

    +

    5.7.4. Explicit Representation Type

    If type-name appears after the identifier, then the semantic analyzer does the following:

    @@ -2535,7 +2583,7 @@

    5.6.4. Explic

    -

    5.6.5. Examples

    +

    5.7.5. Examples

    The following example shows two definitions. In the first one, the implied representation type is I32. @@ -2572,7 +2620,7 @@

    5.6.5. Examples

    -

    5.7. Enumerated Constant Definitions

    +

    5.8. Enumerated Constant Definitions

    An enumerated constant definition is an element of an enum @@ -2583,7 +2631,7 @@

    5.7. Enumerated Constant De in the enum definition.

    -

    5.7.1. Syntax

    +

    5.8.1. Syntax

    identifier [ @@ -2592,7 +2640,7 @@

    5.7.1. Syntax

    -

    5.7.2. Semantics

    +

    5.8.2. Semantics

    If present, expression must evaluate @@ -2625,7 +2673,7 @@

    5.7.2. Semantics<

    -

    5.7.3. Example

    +

    5.8.3. Example

    -

    5.8. Module Definitions

    +

    5.9. Module Definitions

    A module definition provides a named scope that encloses and qualifies other definitions, including other module definitions. It is similar to a namespace in C++ or a package in Java or Scala.

    -

    5.8.1. Syntax

    +

    5.9.1. Syntax

    module identifier @@ -2699,7 +2747,7 @@

    5.8.1. Syntax

    -

    5.8.2. Semantics

    +

    5.9.2. Semantics

    A module definition D qualifies the names of all the definitions inside it with its own name. Inside D, you can refer to definitions in @@ -2715,7 +2763,7 @@

    5.8.2. Semantics

    -

    5.8.3. Example

    +

    5.9.3. Example

    module M {
    @@ -2730,13 +2778,13 @@ 

    5.8.3. Example

    -

    5.9. Port Definitions

    +

    5.10. Port Definitions

    An port definition defines an F Prime port. A port is the endpoint of a connection between F Prime components.

    -

    5.9.1. Syntax

    +

    5.10.1. Syntax

    port identifier @@ -2752,7 +2800,7 @@

    5.9.1. Syntax

    -

    5.9.2. Semantics

    +

    5.10.2. Semantics

    • @@ -2780,7 +2828,7 @@

      5.9.2. Semantics

    -

    5.9.3. Examples

    +

    5.10.3. Examples

    @ Port 1
    @@ -2803,7 +2851,7 @@ 

    5.9.3. Examples

    -

    5.10. State Machine Definitions

    +

    5.11. State Machine Definitions

    A state machine definition defines a state machine.

    @@ -2830,7 +2878,7 @@

    5.10. State Machine Definitions

    -

    5.10.1. Syntax

    +

    5.11.1. Syntax

    state machine identifier [ { state-machine-member-sequence } ]

    @@ -2871,7 +2919,7 @@

    5.10.1. Syntax

    -

    5.10.2. Static Semantics

    +

    5.11.2. Static Semantics

    1. @@ -3139,7 +3187,7 @@
    -

    5.10.3. Dynamic Semantics

    +

    5.11.3. Dynamic Semantics

    An internal state machine M has the following runtime behavior:

    @@ -3174,7 +3222,7 @@

    5.10.3. Dynamic

    -

    5.10.4. Examples

    +

    5.11.4. Examples

    state machine MonitorSm {
    @@ -3227,13 +3275,13 @@ 

    5.10.4. Examples

    -

    5.11. Struct Definitions

    +

    5.12. Struct Definitions

    A struct definition defines a new structure type and associates a name with it.

    -

    5.11.1. Syntax

    +

    5.12.1. Syntax

    struct identifier { struct-type-member-sequence } @@ -3257,10 +3305,10 @@

    5.11.1. Syntax

    -

    5.11.2. Semantics

    +

    5.12.2. Semantics

    -

    The identifier is the name N of the type. The definition associates the name -N with a +

    The identifier is the name N of the type. +The definition associates the name N with a struct type T representing a structure with named members, each of the specified type. Each identifier appearing in the struct type member sequence must be distinct.

    @@ -3295,7 +3343,7 @@

    5.11.2. Semantics

    -

    5.11.3. Examples

    +

    5.12.3. Examples

    # Defines a struct type A with members x and y
    @@ -3330,7 +3378,7 @@ 

    5.11.3. Examples

    -

    5.12. Topology Definitions

    +

    5.13. Topology Definitions

    A topology definition defines an F Prime topology, that is, a set of component instances and the connections @@ -3344,7 +3392,7 @@

    5.12. Topology Definitions

    The connections are merged graph by graph.

    -

    5.12.1. Syntax

    +

    5.13.1. Syntax

    topology identifier @@ -3379,7 +3427,7 @@

    5.12.1. Syntax

    -

    5.12.2. Semantics

    +

    5.13.2. Semantics

    A topology definition D must be resolvable to a topology T, according to the following algorithm:

    @@ -3755,7 +3803,7 @@
    Orde
    -

    5.12.3. Examples

    +

    5.13.3. Examples

    Example 1.

    @@ -7755,6 +7803,7 @@

    9.5. Qualified Identifier Ty qualified identifier that refers to an abstract type definition, +alias type definition, array definition, enum definition, or struct definition @@ -9473,20 +9522,31 @@

    17.10. Abstract Types

    -

    17.11. Internal Types

    +

    17.11. Alias Types

    +
    +

    An alias type is a type associated with an +alias type definition. +There is one alias type per alias type definition. +An alias type is written using its +unique qualified +name.

    +
    +
    +
    +

    17.12. Internal Types

    Internal types do not have syntactic names in FPP source models. The compiler assigns these types to expressions during type checking.

    -

    17.11.1. Integer

    +

    17.12.1. Integer

    The type Integer represents all integer values, without regard to bit width.

    -

    17.11.2. Integer Types

    +

    17.12.2. Integer Types

    Integer together with the primitive integer types are called @@ -9494,7 +9554,7 @@

    17.11.2. Integer Types

    -

    17.11.3. Numeric Types

    +

    17.12.3. Numeric Types

    Integer together with the primitive numeric types are called @@ -9502,7 +9562,7 @@

    17.11.3. Numeric Types

    -

    17.11.4. Anonymous Array Types

    +

    17.12.4. Anonymous Array Types

    The type [ n ] T, where n is an integer and T is a type, represents an array of n elements, @@ -9510,7 +9570,7 @@

    17.11.4. Anonymous Array Typ

    -

    17.11.5. Anonymous Struct Types

    +

    17.12.5. Anonymous Struct Types

    The type { \$m_1\$ : \$T_1, ...,\$ \$m_n\$ : \$T_n\$ }, where each \$m_i\$ is an identifier and each \$T_i\$ is a type, @@ -9524,9 +9584,35 @@

    17.11.5. Anonymous Struct T

    -

    17.12. Displayable Types

    +

    17.13. Canonical Types

    -

    A type is a displayable type if it is one of the following:

    +

    A type is a canonical type if it is not an alias type.

    +
    +
    +
    +

    17.14. Underlying Types

    +
    +

    The underlying type of a type T is the canonical type +associated with T.

    +
    +
    +
      +
    • +

      If T is a canonical type, then the underlying type of T is T.

      +
    • +
    • +

      Otherwise T is an alias type. +In this case, the underlying type of T is the underlying type of the type +associated with T in the definition of T.

      +
    • +
    +
    +
    +
    +

    17.15. Displayable Types

    +
    +

    A displayable type is a type that the F Prime ground data system can display. +It is one of the following:

    -

    17.13. Types with Numeric Members

    +

    17.16. Types with Numeric Members

    -

    A type has numeric members if it is one of the following:

    +

    A type has numeric members if its underlying type +is one of the following:

      @@ -9578,7 +9669,7 @@

      17.13. Types with Numeric Members

    -

    17.14. Default Values

    +

    17.17. Default Values

    Every type T with a syntactic name in FPP has an associated default value. @@ -9634,6 +9725,12 @@

    17.14. Default Values

    This value is left abstract in the FPP model; the implementation of T must provide a concrete value.

  • +
  • +

    The default value associated with an +alias type T is the +default value of its +underlying type.

    +
  • @@ -9975,6 +10072,8 @@

    18.12. Identical Types

  • Each of \$T_1\$ and \$T_2\$ is an +abstract type, +alias type, array type, enum type, or struct type, @@ -10000,6 +10099,13 @@

    18.13. Type Conversion

    are identical types.

  • +

    If either \$T_1\$ or \$T_2\$ or both is an +alias type, then \$T_1\$ +may be converted to \$T_2\$ if the underlying +type of \$T_1\$ may be converted to +the underlying type of \$T_2\$.

    +
  • +
  • Any string type may be converted to any other string type.

  • @@ -10097,6 +10203,12 @@

    18.14.1. Pairs of \$T\$ be \$T_1\$.

  • +

    Otherwise if \$T_1\$ or \$T_2\$ or both are alias +types, then replace +each alias type with its underlying type +and reapply these rules.

    +
  • +
  • Otherwise if \$T_1\$ and \$T_2\$ are both numeric types, then do the following:

    @@ -10245,6 +10357,14 @@

    19.1. Conversion of Type Option

    \$T_1\$ and \$T_2\$ are identical types.

  • +

    Either or both of \$T_1\$ and \$T_2\$ is an alias +type, +and Some \$T'_1\$ may be converted to Some \$T'_2\$, where +\$T'_1\$ is the underlying type of \$T_1\$, +and +\$T'_2\$ is the underlying type of \$T_2\$.

    +
  • +
  • \$T_1\$ and \$T_2\$ are both signed primitive integer types, and \$T_2\$ is at least as wide as \$T_1\$.

    @@ -10294,6 +10414,11 @@

    19.2. then let \$T\$ be \$T_1\$.

  • +

    Otherwise if either \$T_1\$ or \$T_2\$ is an alias type, +then replace each alias type with its underlying type +and reapply these rules.

    +
  • +
  • Otherwise if \$T_1\$ and \$T_2\$ are both signed primitive integer types, then let \$T\$ be the wider of the two types.

    @@ -10395,13 +10520,35 @@

    20. Values

    -

    Every value belongs to exactly one type.

    +

    Every value v belongs to exactly one canonical type +T, except as follows:

    +
    +
    +
      +
    • +

      Every string value belongs to the type string and to +all types string n, for any n.

      +
    • +
    • +

      Every value that belongs to type T also belongs to every +alias type whose +underlying type is T.

      +
    • +
    +
    +
    +

    When a value v belongs to a type T, we say that v is a value +of type T.

    +
    +
    +

    In the following subsections, we describe each kind of value and +its associated canonical types.

    20.1. Primitive Integer Values

    A primitive integer value is an ordinary (mathematical) integer value -together with a +together with its canonical type, which is a primitive integer type. Formally, the set of primitive integer values is the disjoint union over the integer types of the values @@ -10422,7 +10569,8 @@

    20.1. Primitive Integer Values

    -

    We represent a primitive integer value as an expression followed by a colon and a type. +

    We represent a primitive integer value as an expression followed by a colon and +a primitive integer type. For example, we write the value 1 at type U32 as 1: U32. The value 1: U32 is distinct from the value 1: U8.

    @@ -10431,7 +10579,7 @@

    20.1. Primitive Integer Values

    20.2. Integer Values

    An integer value is an ordinary (mathematical) integer value. -It has type Integer. +Its canonical type is Integer. We represent an integer value as an integer number, with no explicit type. For example, 1 is an integer value.

    @@ -10455,14 +10603,15 @@

    20.3. Floating-Point Values

    We write a floating-point values analogously to primitive integer values. For -example, we write the value 1.0 at type F32 as 1.0: F32.

    +example, we write the value 1.0 at type F32 as 1.0: F32. +The canonical type of a floating-point value is F32 or F64.

    20.4. Boolean Values

    A Boolean value is one of the values true and false. -Its type is bool.

    +Its canonical type is bool.

    @@ -10472,7 +10621,17 @@

    20.5. String Values

    represented as a string literal expression. It is written in the same way as a string literal expression, e.g., "abc". -Its type is string.

    +A string value belongs to the following canonical types:

    +
    +
    +
      +
    • +

      string

      +
    • +
    • +

      string n for any n

      +
    • +
    @@ -10480,7 +10639,11 @@

    20.6. Abstract Type Values

    An abstract type value is a value associated with an abstract type. -There is one value associated with each abstract type \$T\$. +For each abstract type \$T\$, there is one +value with canonical type \$T\$. +This value is not represented explicitly in the model, but it +may be represented in the generated code, e.g., as an object +with default initialization. We write the value value of type \$T\$.

    @@ -10491,10 +10654,18 @@

    20.7. Anonymous Array Values

    array type. We write an anonymous array value similarly to an array expression: -an anonymous array value has the form [ \$v_1\$ , \$...\$ , +an anonymous array value \$v\$ has the form [ \$v_1\$ , \$...\$ +, \$v_n\$ ], where for each \$i in [1,n\$], \$v_i\$ is a value of type -\$T\$ for some \$T\$. -The type of the value is [ \$n\$ ] \$T\$.

    +\$T\$ for some canonical type \$T\$. +The canonical type of \$v\$ is [ \$n\$ ] \$T\$.

    + +
    +

    Note that for an anonymous array value \$v\$ to be well-formed, the member +values must have identical types. +If an array expression appearing in the source syntax has +member values with non-identical types, then one or more members must be +converted to a different type before forming \$v\$.

    @@ -10520,12 +10691,16 @@

    20.8. Array Values

    with member type \$T\$.

  • -

    For each \$i in [1,n\$], \$v_i\$ is a value of type \$T\$.

    +

    For each \$i in [1,n\$], \$v_i\$ is a value of type \$T\$. +Note that \$T\$ need not be a canonical type. +For example, it is permissible for \$T\$ to be T, for +T to be an alias of U32, and for \$v\$ to be the value [ 1: U32, 2: U32 ]. +In this case 1: U32 and 2: U32 are values of type T, as required.

  • -

    The type of the value is \$Q\$.

    +

    The canonical type of the value is \$Q\$.

    @@ -10535,7 +10710,7 @@

    20.9. Enumeration Values

    enumerated constant definition. It is a pair consisting of the name and the integer value specified in the enumerated constant definition. -Its type is the type associated with the +Its canonical type is the type associated with the enum definition in which the enumerated constant definition appears.

    @@ -10551,8 +10726,9 @@

    20.10. Anonymous Struct Values

    a struct value has the form { \$m_1\$ = \$v_1\$ , \$...\$ , \$m_n\$ = \$v_n\$ }, where for each \$i in [1,n\$], \$v_i\$ is a value of type \$T_i\$. -The type of \$v\$ is { \$m_1\$ : \$T_1\$ , \$...\$ , -\$m_n\$ : \$T_n\$ }.

    +Each type \$T_i\$ must be a canonical type. +The canonical type of the value is { \$m_1\$ : \$T_1\$ , \$...\$ +, \$m_n\$ : \$T_n\$ }.

    @@ -10579,12 +10755,17 @@

    20.11. Struct Values

    The members of \$Q\$ are \$m_i\$ : \$T_i\$ for \$i in [1,n]\$.

  • -

    For each \$i in [1,n\$], \$v_i\$ is a value of type \$T_i\$.

    +

    For each \$i in [1,n\$], \$v_i\$ is a value of type \$T_i\$. +Note that \$T_i\$ need not be a canonical type. +For example, it is permissible for \$T_1\$ to be T, for +T to be an alias of U32, and for \$v_1\$ to be the value 1: U32. +In this case 1: U32 is a value of type T, as required.

  • -

    All the members must be explicitly assigned values.

    +

    Each member of the struct value must have an explicit value. +The canonical type of the struct value is \$Q\$.

    @@ -10634,6 +10815,11 @@

    20.12. Serialized Sizes

    abstract type, then s is not specified in FPP. It is up to the implementer of T to provide the serialized size.

    +
  • +

    If T is a +alias type, then apply these rules to its +underlying type.

    +
  • diff --git a/docs/spec/Definitions/Alias-Type-Definitions.adoc b/docs/spec/Definitions/Alias-Type-Definitions.adoc new file mode 100644 index 000000000..54086328a --- /dev/null +++ b/docs/spec/Definitions/Alias-Type-Definitions.adoc @@ -0,0 +1,30 @@ +=== Alias Type Definitions + +An *alias type definition* associates a name with a type +that is defined elsewhere. + +==== Syntax + +`type` <> = <> + +==== Semantics + +The identifier is the name _N_ of the type. +The definition associates the name _N_ with +the type _T_ specified after the `=` symbol. +Elsewhere in the model, the name _N_ may be used as alias of (i.e., an +alternate name for) the type _T_. + +==== Examples + +[source,fpp] +---- +# Defines a type A that is an alias of U32 +type A = U32 + +# Defines a struct type B whose member x has type A +struct B { + x: A + y: F32 +} default { y = 1 } +---- diff --git a/docs/spec/Definitions/Struct-Definitions.adoc b/docs/spec/Definitions/Struct-Definitions.adoc index 2ad9e3248..fba6401e1 100644 --- a/docs/spec/Definitions/Struct-Definitions.adoc +++ b/docs/spec/Definitions/Struct-Definitions.adoc @@ -25,8 +25,8 @@ _]_ ==== Semantics -The identifier is the name _N_ of the type. The definition associates the name -_N_ with a +The identifier is the name _N_ of the type. +The definition associates the name _N_ with a <> _T_ representing a structure with named members, each of the specified type. Each identifier appearing in the struct type member sequence must be distinct. diff --git a/docs/spec/Definitions/defs.sh b/docs/spec/Definitions/defs.sh index 98f53c403..575d47c26 100644 --- a/docs/spec/Definitions/defs.sh +++ b/docs/spec/Definitions/defs.sh @@ -9,6 +9,7 @@ redo-ifchange defs.sh export FILES=" Introduction.adoc Abstract-Type-Definitions.adoc +Alias-Type-Definitions.adoc Array-Definitions.adoc Component-Definitions.adoc Component-Instance-Definitions.adoc diff --git a/docs/spec/Type-Checking.adoc b/docs/spec/Type-Checking.adoc index 9f402338e..bd5309e79 100644 --- a/docs/spec/Type-Checking.adoc +++ b/docs/spec/Type-Checking.adoc @@ -241,6 +241,8 @@ are both the same . Each of stem:[T_1] and stem:[T_2] is an +<>, +<>, <>, <>, or <>, @@ -257,6 +259,12 @@ Here are the rules for type conversion: . stem:[T_1] may be converted to stem:[T_2] if stem:[T_1] and stem:[T_2] are <>. +. If either stem:[T_1] or stem:[T_2] or both is an +<>, then stem:[T_1] +may be converted to stem:[T_2] if the <> of stem:[T_1] may be converted to +the <> of stem:[T_2]. + . Any <> may be converted to any other string type. @@ -331,6 +339,11 @@ the whole expression): <>, then let stem:[T] be stem:[T_1]. +. Otherwise if stem:[T_1] or stem:[T_2] or both are <>, then replace +each alias type with its <> +and reapply these rules. + . Otherwise if stem:[T_1] and stem:[T_2] are both <>, then do the following: diff --git a/docs/spec/Type-Names.adoc b/docs/spec/Type-Names.adoc index 788a2fc93..c37803c74 100644 --- a/docs/spec/Type-Names.adoc +++ b/docs/spec/Type-Names.adoc @@ -62,6 +62,7 @@ A *qualified identifier type name* is a <> that refers to an <>, +<>, <>, <>, or <> diff --git a/docs/spec/Type-Options.adoc b/docs/spec/Type-Options.adoc index 51b69950c..2dfa73e60 100644 --- a/docs/spec/Type-Options.adoc +++ b/docs/spec/Type-Options.adoc @@ -21,6 +21,13 @@ stem:[O_2] in the following cases. .. stem:[T_1] and stem:[T_2] are <>. +.. Either or both of stem:[T_1] and stem:[T_2] is an <>, +and _Some_ stem:[T'_1] may be converted to _Some_ stem:[T'_2], where +stem:[T'_1] is the <> of stem:[T_1], +and +stem:[T'_2] is the <> of stem:[T_2]. + .. stem:[T_1] and stem:[T_2] are both <>, and stem:[T_2] is at least as wide as stem:[T_1]. @@ -53,6 +60,10 @@ is computed as follows: .. If stem:[T_1] and stem:[T_2] are <>, then let stem:[T] be stem:[T_1]. +.. Otherwise if either stem:[T_1] or stem:[T_2] is an <>, +then replace each alias type with its <> +and reapply these rules. + .. Otherwise if stem:[T_1] and stem:[T_2] are both <>, then let stem:[T] be the wider of the two types. diff --git a/docs/spec/Types.adoc b/docs/spec/Types.adoc index 695d4ada8..6f8bdb7f1 100644 --- a/docs/spec/Types.adoc +++ b/docs/spec/Types.adoc @@ -80,6 +80,15 @@ An abstract type is written using its <>. +=== Alias Types + +An *alias type* is a type associated with an +<>. +There is one alias type per alias type definition. +An alias type is written using its +<>. + === Internal Types *Internal types* do not have syntactic names in FPP source models. @@ -118,9 +127,25 @@ The order of the members is not significant. For example, `{ a: U32, b: F32 }` represents the same type as `{ b : F32, a: U32 }`. +=== Canonical Types + +A type is a *canonical type* if it is not an <>. + +=== Underlying Types + +The *underlying type* of a type _T_ is the <> +associated with _T_. + +* If _T_ is a canonical type, then the underlying type of _T_ is _T_. + +* Otherwise _T_ is an <>. +In this case, the underlying type of _T_ is the underlying type of the type +associated with _T_ in the definition of _T_. + === Displayable Types -A type is a **displayable type** if it is one of the following: +A *displayable type* is a type that the F Prime ground data system can display. +It is one of the following: * A <>. * A <>. @@ -129,10 +154,13 @@ A type is a **displayable type** if it is one of the following: * An <>. * An <> whose member type is a displayable type. * A <> whose member types are all displayable types. +* An <> whose <> is a displayable type. === Types with Numeric Members -A type *has numeric members* if it is one of the following: +A type *has numeric members* if its <> +is one of the following: * A <>. @@ -192,3 +220,8 @@ struct definitions>> for examples. <>. This value is left abstract in the FPP model; the implementation of _T_ must provide a concrete value. + +* The default value associated with an +<> _T_ is the +<> of its +<>. diff --git a/docs/spec/Values.adoc b/docs/spec/Values.adoc index fefb79ebe..884a0eb77 100644 --- a/docs/spec/Values.adoc +++ b/docs/spec/Values.adoc @@ -24,12 +24,26 @@ A *value* is one of the following: * A struct value -Every value belongs to exactly one type. +Every value _v_ belongs to exactly one <> +_T_, except as follows: + +* Every string value belongs to the type `string` and to +all types `string` _n_, for any _n_. + +* Every value that belongs to type _T_ also belongs to every +<> whose +<> is _T_. + +When a value _v_ belongs to a type _T_, we say that _v_ is a value +*of type _T_*. + +In the following subsections, we describe each kind of value and +its associated canonical types. === Primitive Integer Values A *primitive integer value* is an ordinary (mathematical) integer value -together with a +together with its canonical type, which is a <>. Formally, the set of primitive integer values is the disjoint union over the integer types of the values @@ -43,14 +57,15 @@ stem:[[0, 255\]]. stem:[[-2^(w-1), 2^(w-1)-1\]]. For example, `I8` represents the integers stem:[[-128, 127\]]. -We represent a primitive integer value as an expression followed by a colon and a type. +We represent a primitive integer value as an expression followed by a colon and +a primitive integer type. For example, we write the value 1 at type `U32` as `1: U32`. The value `1: U32` is distinct from the value `1: U8`. === Integer Values An *integer value* is an ordinary (mathematical) integer value. -It has type _Integer_. +Its canonical type is _Integer_. We represent an integer value as an integer number, with no explicit type. For example, `1` is an integer value. @@ -66,11 +81,12 @@ over the types `F32` and `F64` of the values represented by each type: We write a floating-point values analogously to primitive integer values. For example, we write the value 1.0 at type `F32` as `1.0: F32`. +The canonical type of a floating-point value is `F32` or `F64`. === Boolean Values A *Boolean value* is one of the values `true` and `false`. -Its type is `bool`. +Its canonical type is `bool`. === String Values @@ -78,13 +94,21 @@ A *string value* is a sequence of characters that can be represented as a <>. It is written in the same way as a string literal expression, e.g., `"abc"`. -Its type is `string`. +A string value belongs to the following canonical types: + +* `string` + +* `string` _n_ for any _n_ === Abstract Type Values An *abstract type value* is a value associated with an abstract type. -There is one value associated with each abstract type stem:[T]. +For each abstract type stem:[T], there is one +value with canonical type stem:[T]. +This value is not represented explicitly in the model, but it +may be represented in the generated code, e.g., as an object +with default initialization. We write the value `value of type` stem:[T]. === Anonymous Array Values @@ -93,10 +117,17 @@ An *anonymous array value* is a value associated with an anonymous array type. We write an anonymous array value similarly to an <>: -an anonymous array value has the form `[` stem:[v_1] `,` stem:[...] `,` +an anonymous array value stem:[v] has the form `[` stem:[v_1] `,` stem:[...] +`,` stem:[v_n] `]`, where for each stem:[i in [1,n]], stem:[v_i] is a value of type -stem:[T] for some stem:[T]. -The type of the value is _[_ stem:[n] _]_ stem:[T]. +stem:[T] for some <> stem:[T]. +The canonical type of stem:[v] is _[_ stem:[n] _]_ stem:[T]. + +Note that for an anonymous array value stem:[v] to be well-formed, the member +values must have identical types. +If an array expression appearing in the source syntax has +member values with non-identical types, then one or more members must be +converted to a different type before forming stem:[v]. === Array Values @@ -116,8 +147,12 @@ that refers to a with member type stem:[T]. . For each stem:[i in [1,n]], stem:[v_i] is a value of type stem:[T]. +Note that stem:[T] need not be a canonical type. +For example, it is permissible for stem:[T] to be `T`, for +`T` to be an alias of `U32`, and for stem:[v] to be the value `[ 1: U32, 2: U32 ]`. +In this case `1: U32` and `2: U32` are values of type `T`, as required. -The type of the value is stem:[Q]. +The canonical type of the value is stem:[Q]. === Enumeration Values @@ -125,7 +160,7 @@ An *enumeration value* is a value associated with an <>. It is a pair consisting of the name and the integer value specified in the enumerated constant definition. -Its type is the type associated with the +Its canonical type is the type associated with the <> in which the enumerated constant definition appears. @@ -139,8 +174,9 @@ We write an anonymous struct value stem:[v] similarly to a a struct value has the form `{` stem:[m_1] `=` stem:[v_1] `,` stem:[...] `,` stem:[m_n] `=` stem:[v_n] `}`, where for each stem:[i in [1,n]], stem:[v_i] is a value of type stem:[T_i]. -The type of stem:[v] is _{_ stem:[m_1] _:_ stem:[T_1] _,_ stem:[...] _,_ -stem:[m_n] _:_ stem:[T_n] _}_. +Each type stem:[T_i] must be a <>. +The canonical type of the value is _{_ stem:[m_1] _:_ stem:[T_1] _,_ stem:[...] +_,_ stem:[m_n] _:_ stem:[T_n] _}_. === Struct Values @@ -161,8 +197,13 @@ that refers to a . The members of stem:[Q] are stem:[m_i] `:` stem:[T_i] for stem:[i in [1,n\]]. . For each stem:[i in [1,n]], stem:[v_i] is a value of type stem:[T_i]. +Note that stem:[T_i] need not be a canonical type. +For example, it is permissible for stem:[T_1] to be `T`, for +`T` to be an alias of `U32`, and for stem:[v_1] to be the value `1: U32`. +In this case `1: U32` is a value of type `T`, as required. -All the members must be explicitly assigned values. +Each member of the struct value must have an explicit value. +The canonical type of the struct value is stem:[Q]. === Serialized Sizes @@ -200,3 +241,7 @@ the sum of the serialized sizes of the members of _v_ * If _T_ is an <>, then _s_ is not specified in FPP. It is up to the implementer of _T_ to provide the serialized size. + +* If _T_ is a +<>, then apply these rules to its +<>.