Introduction to Flex
Flex is a specification language that allows you to define message data types and transform functions for component software interfaces. From Flex specifications, Tangram Pro generates consistent interface libraries in C++ and other languages, even as your system design changes. To facilitate broad compatibility we are limiting C++ usage to the C++11 standard.
Tangram Pro provides a Flex Editor and Package Manager that allows you to write code in your web browser with an interactive development experience, along with versioning and package management.
- Follow this tutorial to create your own Flex package and use it within a component software interface: Author a Message Set with Flex.
- For general information about managing Flex packages in Tangram Pro see Flex Package Management.
Example Flex File
To introduce the Flex language, we will use an example similar to the one found in Author a Transform with Flex. The Flex code below should be found in the file MyExamplePackage_v1/MyExampleModule.flex
.
module Tangram::MyExamplePackage.MyExampleModule
import Tangram::MyHelpfulConstants.ConversionFactors (feet2meters)
import Tangram::MyHelpfulConstants.Approximations as Approx
const pi: float64 = Approx.PI_8PLACES;
// A position using imperial units
message struct PositionUS {
latitudeDegrees: float64;
longitudeDegrees: float64;
altitudeFeet: float32;
}
// A position using metric units
message struct PositionMetric {
latitudeRadians: float64;
longitudeRadians: float64;
altitudeMeters: float32;
}
/* Convert a position that uses imperial units into a position
* that uses metric units.
*/
transform US_to_Metric(i : PositionUS) -> PositionMetric {
let degrees2radians = pi / 180.0;
PositionMetric {
latitudeRadians = i.latitudeDegrees * degrees2radians;
longitudeRadians = i.longitudeDegrees * degrees2radians;
altitudeMeters = i.altitudeFeet * feet2meters;
};
}
The standard unit of Flex code is called a package (e.g., MyExamplePackage::v1
). Flex packages can be published in Tangram ProTM and depend on other packages. A single package corresponds to a folder in the file system. Within a package are zero or more modules (e.g., MyExampleModule
), each contained in its own separate file with the .flex
extension. A module file should begin with a module
header followed by zero or more import
statements followed by a list of declarations.
- Flex supports single line
//
and multi-line/* */
comments. - Identifiers may contain alphanumeric characters and underscores. They must begin with a letter or underscore.
- Identifiers are case-sensitive.
Import Statements
An import
statement brings other modules and declarations therein into this module's scope. There are two forms of import statement:
import PACKAGE_NAME.MODULE_NAME (DECL1, DECL2, ...);
import PACKAGE_NAME.MODULE_NAME as ALIAS;
The first form directly imports the declarations listed in the parentheses. In other words, DECL1
and DECL2
can now be referenced elsewhere in this module. The second form imports another module and establishes an alias to refer to it. A declaration named MYDECL
in PACKAGE_NAME.MODULE_NAME
is now accessible as ALIAS.MYDECL
.
Flex does not include a "wildcard" import that directly imports all declarations in a module. This is so that the definitions of all identifiers can be easily found.
Declarations
The rest of a Flex module, after the imports, is a list of declarations. A declaration can define a data type, transform, function, or constant. In the example above, pi
, PositionUS
, PositionMetric
, and US_to_Metric
are declarations.
The order in which the declarations appear is unimportant. Although it is generally good practice to place a declaration before its uses. For this reason, US_to_Metric
appears last in the example since its definition refers to the other three declarations.
Data Type Declarations
See section Data Types.
Flex's user-defined data types include structs, enums, variants, newtypes and type aliases.
Transforms and Functions
See section Transforms
Transforms describe conversions between data types of a message standard. The message
keyword indicates that a data type is part of a message standard, and thus is a valid input or output type of a transform. While the syntax of transforms is intended to be familiar to C++ and Java programmers, the semantics are designed to be amenable to formal verification and program transformation.
Constants
A const
definition binds an expression to an identifier. In the example above, Approx.PI_8PLACES
is bound to the identifier pi
. Note that Flex does not have mutable state, so a const
definition says that the identifier "is precisely equal to" or "can be replaced with" its definition. It is not a variable or place in memory that contains a value, and its value cannot be changed.
const NAME: TYPE = EXPRESSION;
- See the Flex Standard Library for more details on everything included in Flex
- See section Syntax Overview for a complete description of what is included in flex