## Expression Reference |

## Lexical Conventions

The language parser operates on a C++ istream with the locale set to the standard "C" locale. Spaces, tabs, and line endings (composed of cr, lf, or (cr, lf) ) are considered white space and are ignored, except as they separate tokens.

### Lexical Grammar

simple_token = "+" | "-" | "*" | "/" | "%" | "?" | ":" | "=" | "!" | "{" | "}" | "<" | ">" | ";" | "@". compound_token = "&&" | "||" | "<=" | ">=" | "==" | "!=". string = quoted_string { quoted_string }. lead_comment = "/*" {character} "*/". trail_comment = "//" {character} eol. identifer = (letter | "_") {letter | "_" | digit}. keywords = "empty" | "true" | "false" | <extension>. number = digits ["e" ["+" | "-"]] digits. quoted_string = '"' {character} '"' | "'" {character} "'". digits = digit { digit }.

### Comments

Comments are lexical tokens to facilitate the editing and subsequent formatting of the language in alternate representations. The trail_comment is terminated by any form of line ending.

### Strings

Strings can be quoted either with single or double quotation marks. Adjacent strings are concatenated into a single string. There are no quote characters within a string. It is expected that the text within the string represents a higher-level representation (such as XML) which can provide additional mark-up.

### Keywords

The `empty`

, `true`

, and `false`

keywords represent the associated values (the `empty`

value corresponds to adobe::empty_t). The list of keywords can be extended by dependent grammars.

### Numbers:

Numbers are always 64 bit IEEE double precision values.

**Todo:**- (sparent) : Lexical conventions for hexadecimal constants may be added in the future.

## Expressions

The expression syntax and semantics are designed to closely resemble the C language. Expressions are dynamically typed and there is no implicit type coercion between types.

### Expression Grammar

expression = or_expression ["?" expression ":" expression]. or_expression = and_expression { "||" and_expression }. and_expression = equality_expression { "&&" equality_expression }. equality_expression = relational_expression { ("==" | "!=") relational_expression }. relational_expression = additive_expression { ("<" | ">" | "<=" | ">=") additive_expression }. additive_expression = multiplicative_expression { ("+" | "-") multiplicative_expression }. multiplicative_expression = unary_expression { ("*" | "/" | "%") unary_expression }. unary_expression = postfix_expression | (unary_operator unary_expression). unary_operator = "+" | "-" | "!". postfix_expression = primary_expression { ("[" expression "]") | ("." identifier) }. primary_expression = name | number | boolean | string | "empty" | array | dictionary | variable_or_fuction | ( "(" expression ")" ). variable_or_function = identifier ["(" [argument_expression_list] ")"]. array = "[" [argument_list] "]". dictionary = "{" named_argument_list "}". argument_expression_list = named_argument_list | argument_list. argument_list = expression { "," expression }. named_argument_list = named_argument { "," named_argument }. named_argument = identifier ":" expression. name = "@" identifier. boolean = "true" | "false".

### Types

#### boolean

Values of type `boolean`

are either `true`

or `false`

.

#### name

A name is a literal identifier. Names are used as keys for dictionaries [see dictionary_t] and can be used as enumerations would be used in C.

#### number

Numbers are always 64 bit IEEE double precision values.

#### string

A value of type `string`

can be any sequence of non '\0' characters.

#### empty

A value of type `empty`

has only the single value of `empty`

.

#### array

An `array`

is a heterogeneous (any type, including arrays and dictionaries may be placed in an array) ordered sequence. Arrays support random access through the index operator. See [indexing]

#### dictionary

A `dictionary`

is a heterogeneous SortedAssociativeContainer that associates objects of type `name`

(the key) with objects of any type. It is also a UniqueAssociativeContainer, no two elements have the same key.

### Operators

#### Index Operator

An `array`

or `dictionary`

may be indexed by an expression in square brackets. For an `array`

, the expression must evaluate to a `number`

, the floor of which will be used as a zero based integer index. For a `dictionary`

, the expression must evaluate to a `name`

. If the indexed item does not exist in the container a runtime exception is thrown.

A `dictionary`

may also be indexed using the dot operator where the following identifier is evaluated as a name. The following two expressions are equivalent:

dict[@my_name] dict.my_name

#### Unary Operators

The operand for unary `+`

and `-`

must be of type `number`

. The unary `-`

operator returns the negative of the operand. The unary `+`

operator is ignored, and provided for symmetry with unary `-`

.

The operand for `!`

must be of type `boolean`

. The result is `true`

if the operand is `false`

. The result is `false`

if the operand is `true`

.

#### Arithmetic Operators

The operands for `+`

, `-`

, `*`

, `/`

, and `%`

must be of type `number`

. The result of the binary operator `+`

is the sum of the operands. The result of the binary operator `-`

is the difference of the operands.

Operators `*`

and `/`

respectively denote floating point multiplication and division. The `%`

operator will truncate each operand to an integer and return the remainder. It is undefined if the remainder is negative if one of the operands is negative.

**Todo:**- (sparent) : The % operator is left over from Eve1 which supported only integer arithmetic. It will likely be redefined in the future to be a proper floating point modulus.

#### Logical Operators

The operands for `&&`

and `||`

must be of type `boolean`

. The result of the `&&`

and `||`

operator is of type `boolean`

denoting the logical-and or logical-or of the operands. The first operand is evaluated and if it is `false`

for && or `true`

for || then the second operand is not evaluated.

**Todo:**- (sparent) : [move this discussion down to a section on evaluating sheets.] The tracking of "considered" in Adam is currently handled at too course a granularity, an item is considered if is evaluated - there are some interesting issues with short circuit booleans - for example, for logical-or if the second operand evaluates to true - the value of the first operand doesn't matter. Was it considered? Similarly, does it contribute to the result. The answer today is yes for both of these but this may be revisited.

#### Relational Operators

The operands for `<`

(less than), `>`

(greater than), `<=`

(less than or equal to), and `>=`

(greater than or equal to) must be of type `number`

. The result is of type `boolean`

.

#### Equality Operators

The operands for `==`

(equal) and `!=`

(not equal) can be of any type. If the operands are not of the same type then they will compare as not equal.

#### Conditional Operator

The conditional operator takes three operands, separated by `? and `

`:. The first operand must be of type `

`boolean`

. If the first operand is `true`

, then the result is the second operand. If the first operand is `false`

then the result is the third operand. Only one of the second and third expressions is evaluated.

### Precedence and Order of Evaluation

**Todo:**- (sparent) : Allowing for operator overloading on external types is a possible future extension.

### Special Functions

*intentionally empty*

### Supplied Functions

*intentionally empty*