<> <> <> <<>> Express: Rope to Procedure Converter 1. Introduction Express is a package that allows a client to evaluate a user-defined function. While it may be well-used in any application where a client would like an interpretive expression evaluator, it is particularly aimed at applications that are planning to evaluate the same user-defined function many times with different arguments. A typical application would be to generate an AIS file, mathematically based on pixel position. The client implements all the necessary structure for a tool capable of making an AIS file. Included in this tool is a viewer where the user can type in his function. The user types in any function of "x" and "y", the pixel coordinates, bugs the "Do it!" button, and away it goes. The client implements this by passing a ROPE containing the function's expression (and a few odds and ends) to the Express package, and receiving instead a directly-callable Cedar procedure. Neat, huh? The client then proceeds to call this procedure iteratively for each pixel location, thereby establishing the intensity everywhere in the image. This document does not contain the information needed by a client implementor  see Express.mesa for that. However, as the grammar used by the parser does not need to be specified in the interface, the grammar is documented here, in section 2. Performance evaluation is in section 3. Finally, section 4 contains a wish list. 2. Grammar Here is the grammar currently in use for Express. Italics show non-terminal syntactic units. Boldface show terminals. Underlined boldface means that the terminal is derived, while regular boldface means that the input must match the terminal exactly, except for case. Whitespace is ignored, except as a token delimiter. Plain typeface are just syntax constructors for describing the grammar. Braces {...} mean repeat contents zero or more times. Optional contents are denoted by ?( ... ). Selection of one choice from two or more is as ... | ... | ..., etc. expression ::= if disjunct then expression else expression | sum sum ::= product { addop product } product ::= factor { mulop factor } factor ::= ?( addop ) primary { ^ primary } primary ::= identifier | constant | ( expression ) | unaryfcn [ expression ] | binaryfcn [ expression , expression ] addop ::= + | - mulop ::= * | / | mod unaryfcn ::= sin | cos | tan | sqrt | atan | exp | ln | abs binaryfcn ::= atanxy | min | max | log disjunct ::= conjunct { or conjunct } conjunct ::= negation { ( and | xor ) negation } negation ::= ?( ~ ) relation relation ::= expression relop expression | ( disjunct ) relop ::= > | < | ~> | ~< | (# | ~=) | = 3. Performance Express seems to run roughly on the order of compiled Cedar code. Benchmarks, run in a stable environment show no perceptible difference in execution speeds, measured over about 3 minutes. 4. Shortcomings and Wish List Express has a limited number to procedures which it can modify and hand out. Further, it is at the mercy of the client to free these properly. Client-defined functions (i.e., those that the client can make available to the user) do not provide a REF ANY for the client to play with. The if-then-else construct always evaluates both the then-expression, and the else-expression, and then chooses a value to keep. Express does no optimization. In particular, expressions that are calculable at parse-time (like 2*3.14159) are not calculated, but are compiled in and reevaluated on each iteration. There is therefore some small penalty for the user not doing his own multiplies when possible.