The expression language for 

Presentation Dynamism in XML

The expression language we propose forms the basis for our dynamic attribute values and our event  predicates. In defining the expression language we have chosen names and definitions similar to those used in [ECMAScript]. We have, however, imposed a number of constraints for authoring simplicity and runtime safety. These assumptions particularly address types: there is no conversion between the numeric and Boolean types in our model, for instance. 

The expression language provides three types: numeric, string and Boolean types. The expression language is typed: if an operator is applied to an operand of an incorrect type, then the value undefined is returned. Moreover it is strongly typed: all types can be computed and verified prior to presentation. Furthermore, there are no coercions (automatic type conversions) between types in the model and in particular, therefore, there is no conversion between the numeric and Boolean types in our model. We believe that most authors will find such a type safe model more natural and less error prone. We contend that in the following fragment in which "-" has been mistyped as "<", the author would prefer to have the expression yield the value undefined (causing the animation to have no effect), rather than to have a Boolean quietly coerced to 0, causing the animation to behave in a subtly incorrect manner:
<animate from="calc(a+b)" to="calc(a-b)" …/>

1.1 The Expression Language

Our choice of data types is motivated to a very large degree by the application domain. Numeric types are needed as they are widely used when computing animation trajectories. Booleans are needed for use within events and predicates. Strings are used to convey information, and in a dynamic context it will be necessary to compute strings, (or at least to choose from among alternatives). For example, a different string might be generated according to the position of an object on a web page ('top' or 'bottom'). 

The numeric type consists of floating-point numbers and the Boolean type contains the two values true and false. More specifically, the Number type contains numbers, the special values NaN (not a number) and positive and negative Infinity. Integer and floating-point literals are given in the usual IEEE format: integer literals are (optionally signed) strings of digits, and floating point literals consist of a decimal number with fractional part and an optional integer exponent following the symbol E or e. Boolean literals are, as usual, defined by the keywords true and false. String literals are enclosed between single quotes (since double quotes are used to delimit XML attribute values).

In accordance with our rule that that expressions are well typed, if an operator is applied to an argument of the incorrect type, then the undefined result is returned from the evaluation. We also make the general assumption that if an evaluated argument to an operator has the value undefined, then the result of the operation is also undefined. In practice, when an expression evaluates to undefined, the effect is the same as if an author specified an illegal attribute value. The resulting behavior is defined by the integrating language – in SMIL Animation, for example, an undefined result for a from or to attribute will cause the animation to have no effect.

1.2 Numeric literals and constants

Integer literals are given by 0 and non-empty strings of digits that do not begin with zero, prefaced by an optional minus sign. Integers between -253 and 253 are represented exactly. Floating-point literals are given in the usual IEEE format: a decimal number with fractional part and an optional integer exponent, following the symbol E or e. The following numeric constants are defined:

NaN the not-a-number value
NEGATIVE_INFINITY negative infinity
POSITIVE_INFINITY positive infinity
MAX_VALUE maximum representable value
MIN_VALUE minimum representable value

1.3 Operators

We assume that expressions are well typed, so that if an operator is applied to an argument of the incorrect type, then the undefined result is returned from the evaluation. We also make the general assumption that if an evaluated argument to an operator has the value undefined then the result of the operation is also undefined. It may be that some arguments are not evaluated: see Section 2.4.3 for details.

1.3.1 Arithmetical operators over Number

- (unary)  Negate a number
+   -   *  Arithmetic operations
/ Floating-point division (IEEE 734 compliant)
% Remainder: applicable to floating point and integer arguments; analogous to C's fmod.

1.3.2 Relational operators over Number

<=  <   >=   >  Comparison operators over numbers.
==   !=  Equality and inequality. 

1.3.3 Boolean operators

! (unary) Logical negation of a Boolean
&&     | | Boolean conjunction and disjunction. 
... : ... ? ...  Conditional operator

The conjunction and disjunction operators are lazy: if their first argument evaluates to false (respectively true) then this is value returned without evaluating the second argument.

The first argument of :? is a Boolean; if this evaluates to true, then the result of the second argument is returned; otherwise, the result of the third argument is returned.

1.3.4 Operator precedences and associativity

Operators have precedences as given in the following table, highest precedence first; operators in the same line have the same precedence. The associativity (if any) is given in the right-hand column.

Operator precedence and associativity

Operator (highest precedence first) Associativity (if any)
 
/ % left
+ - left
> < >= <= == !=   
&& right
| |  right
?:   


1.4 Functions

We provide a fixed repertoire of numeric functions to supplement the basic arithmetic operators. The functions are of four types:

The choice of functions given here represents a core of general functionality likely to be required across all application areas. The choice is not intended to be definitive or closed; language designers who integrate this module may extend the language to include functions relevant to the particular domain. We expect that implementation techniques will extend to these domain specific elements in a straightforward way.

It should be noted that our model provides no facility for the author to define functions for herself. This important constraint greatly simplifies the authoring model, and also provides a measure of 'safety' for the implementation (ensuring, for example, that expressions used with animation can be quickly evaluated at each animation sample). Our goal was to provide flexible expressions, not a programming language.

Numerical functions 

abs(x)  absolute value of x
ceil(x) the ceiling of x
cos(x) cosine of x (in degrees)
exp(x) exponentiation (to base e)
floor(x) floor of x
isNaN(x) is x NaN?
isFinite(x) is x finite?
log(x) natural logarithm of x
max(x,y) maximum of the values x and y
min(x,y) minimum of the values x and y
pow(x,y) x to the power y
random(x,y) a random number in the range x to y chosen from a uniform distribution
round(x) x rounded to the nearest integer
sin(x) sine of x (in degrees)
sqrt(x) the (positive) square root of x
tan(x) tangent of x (in degrees)

1.5 Domain-specific values 

Each domain will have a set of properties that expose OM (Object Model) values in a manner convenient for use in expressions. For example in SMIL Timing integrations, properties such as the current simple time or a Boolean isActive would likely be provided. One set of properties we see as common to many applications exposes the mouse position in a simple manner. The mouseX and mouseY properties are exposed on all elements that can raise a mousemove event. The actual values follow the [DOM2Events] definition for mousemove events, returning the position of the mouse relative to the container (which in turn is language specific). Expressions can reference these mouseX/Y properties on the root layout element (e.g. "body.mouseY") to get "global" mouse positions, or on a particular target element to get "local" mouse positions.