Adobe Systems Incorporated

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 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 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.


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 are always 64 bit IEEE double precision values.

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


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".



Values of type boolean are either true or false.


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.


Numbers are always 64 bit IEEE double precision values.


A value of type string can be any sequence of non '\0' characters.


A value of type empty has only the single value of empty.


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]


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.


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:


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.

(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.

(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

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

Special Functions

intentionally empty

Supplied Functions

intentionally empty

Copyright © 2006-2007 Adobe Systems Incorporated.

Use of this website signifies your agreement to the Terms of Use and Online Privacy Policy.

Search powered by Google