(o\llLw1:l~ (:RAIIII(:~ .ATIl Ihl-\(:E IKocESSIN(: (1972) 1, (317-3401
EX.GRAF: An Extensible Language Including
This paper describes a high-level extensible language. The language allows the user to define new data types and new operations to suit his needs and to simplify sul~sr- quent programming. This work began as an effort to produce a graphic language, but soon led to the design of a general purpose extensible language in which graphical data types and operations could easily be embedded.
A prime aim in the definition of the language was to provide powerful features at a level that is easily understood and yet is straightforward to implement. Examples fol computer graphics are given to illustrate the most important features of the language.
High-level language facilities are needed to simplify many different pro- gramming problems. This is certainly the case with applications involving computer graphics in which many data representations, including numerical parameters, topological data, relational data and graphical information, may exist in complex data structures. Therefore it is necessary to consider the problems of specifying the representation and internal processing of all forms of data, with graphical data as one special case, when discussing gen- eral purpose languages.
The prime requirement of a general purpose language is to have a sufficient set of data types and operations on these data types to permit efficient and elegant programming for the given application. However, it is not known or agreed upon, as to which data types and operations form a sufficient set even for one class of applications, e.g., graphical. Some data types, like PTR (pointer or reference) seem to be fairly obvious, but the operations one would like to perform on variables with type PTR are not so clear. Operations on graphical display structures are even less clear. Therefore the language that is being developed is an extensible language. In this language new data
* This work waj supported in part hy the Air Force Office of Scientific Research, Air Force Systems Command, USAF, under grant AF-AFOSR-70-1854, Professor H. Freeman, Principal Investigator, and in part by a National Science Foundation Institutional Grant to New York Cniversity.
f T. J. Watson Research Center, IBM, Yorktown Heights, New York; formerly at New York University.
t Research Institute for Automation, Hungarian Academy of Science, Budapest, Hungary-. Visiting scholar at New York University, July 72-September 72.
318 WILLIAMS ANI) KHAMMEH
types and operations that are considered to be use&l for a given application can be added easily by anyone at any time. The important point is to JXO- vide the means for the user to create new data types and operations. This i$; different from the work of Smith . Smith extended PL/I to GPL/ 1 by I I). eluding two new data types and several new operations. The new data tcpf~4 are tjector and image, where vector is a point having two or three coordinate values, and image is a variable having values that are combinations of ~jic- torial data, pictorial function values and other images, and imagc~ data consists of points (vectors), text or values returned from image t;mctiruls 1131. He also defined vector addition, subtraction, scalar and cross prodrxct operations for vectors, and transformations (i.e., position, scale, and rotation), inclusion and connection operations for images. Also, the Phil interrupt facility is extended to allow interrupts from graphical accessories at~tl tht~m~ is a special ANIMATE statement for animation purposes. This approach appears to be a step in the right direction hut it provides a fixed set ofcluta types and operations. In the language described in this paper, the user i> encouraged to develop his own data types and operations as he discovcyr\ ,i need for them.
We acknowledge immediately that such languages exist already. The mosi important of these, in our opinion, are ALGOL 68 [4,17] and ELI i&w Wctg- breit) [15,16]. ALGOL 68 is somewhat difficult to lmderstand and list3 ;mrf has not been implemented very widely. ELI is more easily understood ancl our work has been considerably influenced lay it. ELI is more ambitious thall our efforts, but our aims are different. Our aims are to define an extensibls, language that is simply understood by the user and that is not overly difficult to implement, and which is also specifically useful for graphical applicatiotrh. It would be interesting and helpful to experiment with different graphical data types and structures and attempt to find the most useful data types ant1 operations for a wide range of graphical applications.
2. THE LANGUAGE
A program in the language is a sequence of statements. These statemetrtx may define new types of objects, new elements of a given type or may per- form calculations with the previously defined elements. The nlost impor-. tant feature of the language is the possibility to define new types and opera-~ tions between elements of new types. This then allows expressions to I)(> built in other high level languages.
In this section we describe the main features of the language. The RNI; syntax for the statements that follow is given in the Appendix.
2.1 The Definition of New Types
The language has a few built-in basic types which are widely used in eom- puting: REAL, INT, (integer) BIT, and CHAR (character). Variables having these data types can be used in expressions and assignment skatcmcxrlts ,;:s,. in other languages.
In most applications there are some &sic> a)l,iec:ts ~haracterlmc~ /I> ,i ,I< 1
of structured data blocks and it is necessary to perform some well-defined operations on these blocks. The statement STYPE (read S TYPE, which stands for Structured TYPE) is used in the language to specify names of a new type and also to define the structure of the elements of this type in terms of previously defined element types. The built-in types behave like any other previously defined type in this respect.
A new type is defined by assigning a name to the type and specifying its constituent subparts. Each subpart has a name, possibly dimensioned, and a type specification, which must be an existing type, i.e., either a built-in type or a previously-defined STYPE.
EXAMPLES. STYPE RINGC: (NEXT: PTR, LAST: PTR, DATA: INT);
STYPE ABLK: (HEAD: INT=8192, BODY(40): INT, NEXT: PTR,
DATA: PTR, TAIL: INT=l);
In the first example a block structure is defined to consist of a pointer, a sec- ond pointer and an integer, and the type of this structure is named RINGC. Subsequently, an element or object of type RINGC can be created with a DECL statement. The second example shows how initial data values (con- stants) may be assigned to a structure. Assigning values in STYPE statements is a very convenient method of placing values in every object of a given type and saves the user from the tedious task of specifying the values in every DECL statement that creates an object of this type.
The information given in an STYPE statement is stored in an STYPE record. The record contains the name of the new STYPE, its memory re- quirements for an element declared to have this STYPE, and a reference to the record which describes the structure of the first subpart. The subpart information is correspondingly similar and is stored in an SFORD record.
However the information about a subpart of an STYPE can only be ac- cessed via the STYPE information, Therefore type names used in subsequent declaration statements can only be STYPE names and not names of subparts. Similarly for reference purposes, as is explained in Section 2.3, a subpart name has no meaning by itself.
As it is possible to create new elements of any type at run-time the STYPE specifications are retained through compilation and become part of the run- time object program.
Some people have suggested different forms for this statement and for some of the following statements; APL, PL/l and others have been sug- gested. We happen to like the syntax we have chosen but we remain quite open to other suggestions. Some modifications have already been made as a result of such suggestions.
2.2 Declaration of Variables The DECL statement is used to define names as variables or arrays of a
given type and also to assign initial values if necessary.
EXAMPLES. DECL INDEX: INT; DECL VECTOR (10): REAL, MATRIX (40,401: TNT. DECL Bl: HLOK = (BLOK: 1526, (40:kO). 0):
The first example declares the variable INDEX as one of tllra t>rpi: 1W (integer). The : second csxample has two declarations in it: the first ctefiltc~~ .: vector with ten elements of type REAL, while the other defines a 40 b! 4l1 array of integers. The third example defines the name RI 34: a t,nriai)lc ati type BLOK which must have 1)ee11 defined previousl>. as tlrts Ilarrit o? !II STYPE. The variable 131 is given tllcb values of the constatlt follah! limit is given for thca nlmibcr of elc~ments in the arm\. At an! time ilrcstt, 11 a given number h of elements in this array and the supporting rlxn-time, .>$. b/. tern will provide the appropriate access to these elements when DFILE ?(l properly indexed. A new element can be added to the array by the statcmt:tlt*,
INCR(DFILE, 1 j DFILE -t II;
where rz is the name of a new element of type INST. The stateme~lt INC:!-i indicates to the system that the dimension of DFILE is to he increasc,tl ill one. For convenience this statement could be included in the definition o! the operation + with DFILE, then it is only necessary to write it OIIW. A complete example is given in Section 4.2.
2.3 Rclferencing Objects by Name
Names in the language are used as symbolic, referenc
The category of a given name can be decided always from the context in which a name is used; names used after a colon in DECL statements specify a type, names used before a colon in STYPE statements also specify a type.
Variable names are defined when used in basic-decls in DECL state- ments (see Appendix), and once defined they can be used in expressions for calculation purposes. The name of an object is used to reference the whole object, while subparts of structured objects can be referenced via name strings. Name strings are formed by concatenating with period delim- iters (.) the name of the whole object with the formal names of the subparts of that object. Any name in a string may be subscripted.
As an example, suppose that type CBL is defined as:
STYPE CBL: (HEAD; INT, BODY(40): INT, TAIL: INT);
and that 100 blocks of type CBL are created by the declaration
DECL TAB(lOO): CBL;
The tenth element of the BODY in the twenty-third TAB can be referenced by TAB(23).BODY(lO).
The references HEAD or BODY(lO) by themselves have no meaning, unless these names have been declared separately in a DECL statement to have a separate, quite different meaning. The reference TAB(23).BODY which can be used to reference the whole BODY within TAB(23), and TAB are also meaningful references. The exact meaning of an incomplete ref- erence like TAB is actually defined by the user, for, once a new type and elements of this type have been declared they can be used in expressions like any other variables.
An important point to note here is that whenever a name reference in an expression is evaluated both the object itself and its type are available so as to make it possible to decide which operation is to be performed. The defi- nition of an operation using new type elements is specified by a routine, as discussed in the next section.
2.4 Definition of Routines and New Operations
Operations can be defined for any types of operands. The operators can be unary operators or binary operators, they can involve lists of operands and they can occur in prefix notation or in infix notation. An EXPR statement followed by a block of code is used to define a new operation or a new rou- tine. An EXPR statement contains two operands and an operator. The oper- ator may be any convenient string of characters such as +, ADD, .3AD., etc. The triple operand type, operator, operand type uniquely identifies an operation. Thus the same operator symbol may be used unambiguously with different operand types to specify similar but different operations. An oper- ator priority code may also be specified.
EXAMPLES. (i) EXPR A+ B, 2;
BEGIN DECL A( ), B( ): REAL, N: INT;
N = SIZE(A); DECL C(N): REAL; For J- 1, N: C(J)=A(Jj?-B(J), RETURN C;
END: (ii) EXPR A = B, 0;
BEGIN DECL A, B: ABLK; A.HEAD = B.HEAD;
FOR J = 1,40: A.BODY( J) = B.BODY( J); A.NEXT = B.NEXT; A.DATA = B.DATA; A.TAIL = B.TAIL; RETURN A,
END; (iii) EXPR SPUR(A,iNI;
BEGIN DECL A(N,N), S: REAL N: IN?: s =o.o; FOR J-1, N : S=S-+mA(J,J!: RETURN S;
The first example above defines the addition for vectors as an operatior~ with priority 2. A and B are declared to be arrays without specified tlimkari sions. There is a run-time system routim SIZE, which can be used to fetcrh the current size of an element referenced by name. A statement OJ :I 191ot:i. of statements has always a value which is the value last evaluated, or Im;. plicitly referenced in a RETURN statement. The result of the opcaratlr,ri the address and type of C, are returned.
The second example defines the operator == for elements ot tlrpe ABLL. Note that = is an infix operator with two operands and has the lowest pr>>, sible priority. In this language, assignment statements are expressions. Al\cl any operator, including =, may effect one of its operands and change its v;li~~~~
The third example is a traditional subroutine definition which ~:al~*~~- lates the sum of the diagonal elements in ali array-.
The use of routines defined in the above way ih simply a means lor defirr ing the operator with given types of operands. In some cases this is similat to the use of procedures in ALGOL 60, or functions in FORTRAIK. If thaw operator is used in connection with basic types the operation is performrd in a normal way, i.e., with in-line compiled code, but if the operands types are user-defined STYPES, the corresponding routine that defines tile operation with the given operand types is invoked to execute the operation In both cases an address and a type for each operand must be determinrd from the name strings of the operands before the operation can be performed.
The basic statement form used in programming is the expresslon ;tnti III EX.GRAF expressions includes value assignment statements. Operators CXI!
ture of T and the display format. A conversion routine to convert real or in- teger three-dimensional data into display format would have to be supplied as a run-time routine with the basic EX.GRAF system because of the hard- ware dependency. Once the mechanism for creating SCL is understood, it is a straightforward matter to create translation and rotation operations.
Now all the transformation parameters to be ap...