ExpressDoc.tioga
Copyright © 1985 by Xerox Corporation. All rights reserved.
Created July 12, 1984 1:16:39 pm PDT
Last edited by Eric Nickell, July 31, 1984 11:20:35 pm PDT
Michael Plass, July 31, 1985 4:36:49 pm PDT
Abstract: Express provides the client a way to evaluate an arithmetic expression given in a rope (generally from the user), typically faster than Interpreter or JaM, especially if the same function is used repeatedly.
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.