gltest.sl 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563
  1. % GLTEST.SL.2 18 February 1983
  2. % GLISP TEST FUNCTIONS, PSL VERSION.
  3. % Object descriptions for a Company database.
  4. (GLISPOBJECTS
  5. (EMPLOYEE % Name of the object type
  6. (LIST (NAME STRING) % Actual storage structure
  7. (DATE-HIRED (A DATE))
  8. (SALARY REAL)
  9. (JOBTITLE ATOM)
  10. (TRAINEE BOOLEAN))
  11. PROP ((SENIORITY ((THE YEAR OF (CURRENTDATE)) % Computed properties
  12. -
  13. (THE YEAR OF DATE-HIRED)))
  14. (MONTHLY-SALARY (SALARY * 174)))
  15. ADJ ((HIGH-PAID (MONTHLY-SALARY > 2000))) % Computed adjectives
  16. ISA ((TRAINEE (TRAINEE))
  17. (GREENHORN (TRAINEE AND SENIORITY < 2)))
  18. MSG ((YOURE-FIRED (SALARY _ 0))) ) % Message definitions
  19. (Date
  20. (List (MONTH INTEGER)
  21. (DAY INTEGER)
  22. (YEAR INTEGER))
  23. PROP ((MONTHNAME ((NTH '(JANUARY FEBRUARY MARCH APRIL MAY JUNE JULY
  24. AUGUST SEPTEMBER OCTOBER NOVEMBER DECEMBER)
  25. MONTH)))
  26. (PRETTYFORM ((LIST DAY MONTHNAME YEAR)))
  27. (SHORTYEAR (YEAR - 1900))) )
  28. (COMPANY
  29. (ATOM (PROPLIST (PRESIDENT (AN EMPLOYEE))
  30. (EMPLOYEES (LISTOF EMPLOYEE) )))
  31. PROP ((ELECTRICIANS ((THOSE EMPLOYEES WITH JOBTITLE='ELECTRICIAN)))) )
  32. )
  33. % Some test data for the above functions.
  34. (setq company1 (a company with
  35. President = (An Employee with Name = "Oscar the Grouch"
  36. Salary = 88.0
  37. Jobtitle = 'President
  38. Date-Hired = (A Date with Month = 3
  39. Day = 15 Year = 1907))
  40. Employees = (list
  41. (An Employee with Name = "Cookie Monster"
  42. Salary = 12.50
  43. Jobtitle = 'Electrician
  44. Date-Hired = (A Date with Month = 7
  45. Day = 21 Year = 1947))
  46. (An Employee with Name = "Betty Lou"
  47. Salary = 9.00
  48. Jobtitle = 'Electrician
  49. Date-Hired = (A Date with Month = 5
  50. Day = 15 Year = 1980))
  51. (An Employee with Name = "Grover"
  52. Salary = 3.00
  53. Jobtitle = 'Electrician
  54. Trainee = T
  55. Date-Hired = (A Date with Month = 6
  56. Day = 13 Year = 1978))
  57. )))
  58. % Program to give raises to the electricians.
  59. (DG GIVE-RAISE
  60. (:COMPANY)
  61. (FOR EACH ELECTRICIAN WHO IS NOT A TRAINEE
  62. DO (SALARY _+(IF SENIORITY > 1
  63. THEN 2.5
  64. ELSE 1.5))
  65. (PRINT (THE NAME OF THE ELECTRICIAN))
  66. (PRINT (THE PRETTYFORM OF DATE-HIRED))
  67. (PRINT MONTHLY-SALARY) ))
  68. (DG CURRENTDATE () (Result DATE)
  69. (A DATE WITH YEAR = 1981 MONTH = 11 DAY = 30))
  70. % The following object descriptions are used in a graphics object test
  71. % program (derived from one written by D.G. Bobrow as a LOOPS example).
  72. % The test program MGO-TEST runs on a Xerox D-machine, but won't run on
  73. % other machines.
  74. (GLISPOBJECTS
  75. % The actual stored structure for a Vector is simple, but it is overloaded
  76. % with many properties.
  77. (VECTOR
  78. (LIST (X INTEGER)
  79. (Y INTEGER))
  80. PROP ((MAGNITUDE ((SQRT X^2 + Y^2)))
  81. (DIRECTION ((IF X IS ZERO THEN (IF Y IS NEGATIVE THEN -90.0
  82. ELSE 90.0)
  83. ELSE (ATAN2D Y X))) RESULT DEGREES)
  84. )
  85. ADJ ((ZERO (X IS ZERO AND Y IS ZERO))
  86. (NORMALIZED (MAGNITUDE = 1.0)))
  87. MSG ((+ VECTORPLUS OPEN T) % Defining operators as messages
  88. % causes the compiler to automatically
  89. % overload the operators.
  90. (- VECTORDIFF OPEN T)
  91. (* VECTORTIMESSCALAR ARGTYPES (NUMBER) OPEN T)
  92. (* VECTORDOTPRODUCT ARGTYPES (VECTOR) OPEN T)
  93. (/ VECTORQUOTIENTSCALAR OPEN T)
  94. (_+ VECTORMOVE OPEN T)
  95. (PRIN1 ((PRIN1 "(")
  96. (PRIN1 X)
  97. (PRIN1 ",")
  98. (PRIN1 Y)
  99. (PRIN1 ")")))
  100. (PRINT ((SEND SELF PRIN1) % PRINT is defined in terms of the
  101. (TERPRI))) ) ) % PRIN1 message of this object.
  102. (DEGREES REAL % Stored value is just a real number.
  103. PROP ((RADIANS (self*(3.1415926 / 180.0)) RESULT RADIANS)))
  104. (RADIANS REAL
  105. PROP ((DEGREES (self*(180.0 / 3.1415926)) RESULT DEGREES)))
  106. % A FVECTOR is a very different kind of VECTOR: it has a different
  107. % storage structure and different element types. However, it can
  108. % still inherit some vector properties, e.g., addition.
  109. (FVECTOR (CONS (Y STRING) (X BOOLEAN))
  110. SUPERS (VECTOR))
  111. % The definition of GraphicsObject builds on that of Vector.
  112. (GRAPHICSOBJECT
  113. (LIST (SHAPE ATOM)
  114. (START VECTOR)
  115. (SIZE VECTOR))
  116. PROP ((LEFT (START:X)) % A property defined in terms of a
  117. % property of a substructure
  118. (BOTTOM (START:Y))
  119. (RIGHT (LEFT+WIDTH))
  120. (TOP (BOTTOM+HEIGHT))
  121. (WIDTH (SIZE:X))
  122. (HEIGHT (SIZE:Y))
  123. (CENTER (START+SIZE/2)) % Vector arithmetic
  124. (AREA (WIDTH*HEIGHT)))
  125. MSG ((DRAW ((APPLY (GET SHAPE 'DRAWFN) % A way to get runtime message
  126. (List SELF % behavior without using the
  127. (QUOTE PAINT))))) % message mechanism.
  128. (ERASE ((APPLY (GET SHAPE 'DRAWFN)
  129. (LIST SELF
  130. (QUOTE ERASE)))))
  131. (MOVE GRAPHICSOBJECTMOVE OPEN T)) )
  132. (MOVINGGRAPHICSOBJECT
  133. (LIST (TRANSPARENT GRAPHICSOBJECT) % Includes properties of a
  134. (VELOCITY VECTOR)) % GraphicsObject due to the
  135. % TRANSPARENT declaration.
  136. Msg ((ACCELERATE MGO-ACCELERATE OPEN T)
  137. (STEP ((SEND SELF MOVE VELOCITY)))) )
  138. )
  139. % The following functions define arithmetic operations on Vectors.
  140. % These functions are generally called OPEN (macro-expanded) rather
  141. % than being called directly.
  142. (DG VECTORPLUS
  143. (V1:vector V2:VECTOR)
  144. (A (TYPEOF V1) WITH X = V1:X + V2:X Y = V1:Y + V2:Y))
  145. (DG VECTORDIFF
  146. (V1:vector V2:VECTOR)
  147. (A (TYPEOF V1) WITH X = V1:X - V2:X Y = V1:Y - V2:Y))
  148. (DG VECTORTIMESSCALAR
  149. (V:VECTOR N:NUMBER)
  150. (A (TYPEOF V) WITH X = X*N Y = Y*N))
  151. (DG VECTORDOTPRODUCT
  152. (V1:vector V2:VECTOR)
  153. (A (TYPEOF V1) WITH X = V1:X * V2:X Y = V1:Y * V2:Y))
  154. (DG VECTORQUOTIENTSCALAR
  155. (V:VECTOR N:NUMBER)
  156. (A (TYPEOF V) WITH X = X/N Y = Y/N))
  157. % VectorMove, which defines the _+ operator for vectors, does a destructive
  158. % addition to the vector which is its first argument. Thus, the expression
  159. % U_+V will destructively change U, while U_U+V will make a new vector with
  160. % the value U+V and assign its value to U.
  161. (DG VECTORMOVE
  162. (V:vector DELTA:VECTOR)
  163. (V:X _+ DELTA:X)
  164. (V:Y _+ DELTA:Y)
  165. V)
  166. % An object is moved by erasing it, changing its starting point, and
  167. % then redrawing it.
  168. (DG GRAPHICSOBJECTMOVE
  169. (SELF:GRAPHICSOBJECT DELTA:VECTOR)
  170. (SEND SELF ERASE) % Erase the object
  171. (START _+ DELTA) % Destructively move start point by delta
  172. (SEND SELF DRAW)) % Redraw the object in new location
  173. (DG MGO-ACCELERATE
  174. (SELF: MOVINGGRAPHICSOBJECT ACCELERATION: VECTOR)
  175. VELOCITY _+ ACCELERATION)
  176. % Now we define some test functions which use the above definitions.
  177. % First there are some simple functions which test vector operations.
  178. (DG TVPLUS (U:VECTOR V:VECTOR) U+V)
  179. (DG TVMOVE (U:VECTOR V:VECTOR) U_+V)
  180. (DG TVTIMESV (U:VECTOR V:VECTOR) U*V)
  181. (DG TVTIMESN (U:VECTOR V:NUMBER) U*V)
  182. (DG TFVPLUS (U:FVECTOR V:FVECTOR) U+V)
  183. % This test function creates a MovingGraphicsObject and then moves it
  184. % across the screen by sending it MOVE messages. Everything in this
  185. % example is compiled open; the STEP message involves a great deal of
  186. % message inheritance.
  187. (DG MGO-TEST ()
  188. (PROG (MGO N)
  189. (MGO _(A MOVINGGRAPHICSOBJECT WITH
  190. SHAPE = (QUOTE RECTANGLE)
  191. SIZE = (A VECTOR WITH X = 4 Y = 3)
  192. VELOCITY = (A VECTOR WITH X = 3 Y = 4)))
  193. (N _ 0)
  194. (WHILE (N_+1)<100 (SEND MGO STEP))
  195. (SEND (THE START OF MGO) PRINT)))
  196. % This function tests the properties of a GraphicsObject.
  197. (DG TESTFN2 (:GRAPHICSOBJECT)
  198. (LIST SHAPE START SIZE LEFT BOTTOM RIGHT TOP
  199. WIDTH HEIGHT CENTER AREA))
  200. % Function to draw a rectangle. Computed properties of the rectangle are
  201. % used within calls to the graphics functions, making the code easy to
  202. % write and understand.
  203. (DG DRAWRECT (SELF:GRAPHICSOBJECT DSPOP:ATOM)
  204. (PROG (OLDDS)
  205. (OLDDS _(CURRENTDISPLAYSTREAM DSPS))
  206. (DSPOPERATION DSPOP)
  207. (MOVETO LEFT BOTTOM)
  208. (DRAWTO LEFT TOP)
  209. (DRAWTO RIGHT TOP)
  210. (DRAWTO RIGHT BOTTOM)
  211. (DRAWTO LEFT BOTTOM)
  212. (CURRENTDISPLAYSTREAM OLDDS) ))
  213. % The LispTree and PreorderSearchRecord objects illustrate how generators
  214. % can be written.
  215. (GLISPOBJECTS
  216. % In defining a LispTree, which can actually be of multiple types (atom or
  217. % dotted pair), we define it as the more complex dotted-pair type and take
  218. % care of the simpler case in the PROPerty definitions.
  219. (LISPTREE
  220. (CONS (CAR LISPTREE) % Defines a LispTree structure as the CONS
  221. (CDR LISPTREE)) % of two fields named CAR and CDR.
  222. PROP ((LEFTSON ((IF SELF IS ATOMIC THEN NIL ELSE CAR)))
  223. (RIGHTSON ((IF SELF IS ATOMIC THEN NIL ELSE CDR))))
  224. ADJ ((EMPTY (~SELF))) )
  225. % PreorderSearchRecord is defined to be a generator. Its data structure holds
  226. % the current node and a stack of previous nodes, and its NEXT message is
  227. % defined as code to step through the preorder search.
  228. (PREORDERSEARCHRECORD
  229. (CONS (NODE LISPTREE)
  230. (PREVIOUSNODES (LISTOF LISPTREE)))
  231. MSG ((NEXT ((PROG (TMP)
  232. (IF TMP_NODE:LEFTSON
  233. THEN (IF NODE:RIGHTSON THEN PREVIOUSNODES+_NODE)
  234. NODE_TMP
  235. ELSE TMP-_PREVIOUSNODES
  236. NODE_TMP:RIGHTSON))))) )
  237. )
  238. % PRINTLEAVES prints the leaves of the tree, using a PreorderSearchRecord
  239. % as the generator for searching the tree.
  240. (DG PRINTLEAVES (:LISPTREE)
  241. (PROG (PSR)
  242. (PSR _(A PREORDERSEARCHRECORD WITH NODE =(THE LISPTREE)))
  243. (WHILE NODE (IF NODE IS ATOMIC (PRINT NODE))
  244. (SEND PSR NEXT))))
  245. % The Circle objects illustrate the definition of a number of mathematical
  246. % properties of an object in terms of stored data and other properties.
  247. (Glispobjects
  248. (CIRCLE (LIST (START VECTOR) (RADIUS REAL))
  249. PROP ((PI (3.1415926)) % A PROPerty can be a constant.
  250. (DIAMETER (RADIUS*2))
  251. (CIRCUMFERENCE (PI*DIAMETER)) % Defined in terms of other prop.
  252. (AREA (PI*RADIUS^2)) )
  253. ADJ ((BIG (AREA>120)) % BIG defined in terms of AREA
  254. (MEDIUM (AREA >= 60 AND AREA <= 120))
  255. (SMALL (AREA<60)))
  256. MSG ((STANDARD (AREA_100)) % "Storing into" computed property
  257. (GROW (AREA_+100))
  258. (SHRINK (AREA_AREA/2)) )
  259. )
  260. % A DCIRCLE is implemented differently from a circle.
  261. % The data structure is different, and DIAMETER is stored instead of RADIUS.
  262. % By defining RADIUS as a PROPerty, all of the CIRCLE properties defined
  263. % in terms of radius can be inherited.
  264. (DCIRCLE (LISTOBJECT (START VECTOR) (DIAMETER REAL))
  265. PROP ((RADIUS (DIAMETER/2)))
  266. SUPERS (CIRCLE) )
  267. )
  268. % Make a DCIRCLE for testing
  269. (setq dc (a dcircle with diameter = 10.0))
  270. % Since DCIRCLE is an Object type, it can be used with interpreted messages,
  271. % e.g., (send dc area) to get the area property,
  272. % (send dc standard) to set the area to the standard value,
  273. % (send dc diameter) to get the stored diameter value.
  274. % EXAMPLE OF ASSIGNMENT TO COMPUTED PROPERTY
  275. (DG GROWCIRCLE (C:CIRCLE)
  276. (C:AREA_+100)
  277. C )
  278. (SETQ MYCIRCLE (A CIRCLE))
  279. % Since SQRT is not defined in the bare-PSL system, we redefine it here.
  280. (DG SQRT (X)
  281. (PROG (S)
  282. (S_X)
  283. (IF X < 0 THEN (ERROR)
  284. ELSE (WHILE (ABS S*S - X) > 0.000001 DO (S _ (S+X/S) * 0.5)))
  285. (RETURN S)))
  286. % Function SQUASH illustrates elimination of compile-time constants.
  287. % Of course, nobody would write such a function directly. However, such forms
  288. % can arise when inherited properties are compiled. Conditional compilation
  289. % occurs automatically when appropriate variables are defined to the GLISP
  290. % compiler as compile-time constants because the post-optimization phase of
  291. % the compiler makes the unwanted code disappear.
  292. (DG SQUASH ()
  293. (IF 1>3 THEN 'AMAZING
  294. ELSEIF (SQRT 7.2) < 2 THEN 'INCREDIBLE
  295. ELSEIF 2 + 2 = 4 THEN 'OKAY
  296. ELSE 'JEEZ))
  297. % The following object definitions describe a student records database.
  298. (glispobjects
  299. (student (atom (proplist (name string)
  300. (sex atom)
  301. (major atom)
  302. (grades (listof integer))))
  303. prop ((average student-average)
  304. (grade-average student-grade-average))
  305. adj ((male (sex='male))
  306. (female (sex='female))
  307. (winning (average>=95))
  308. (losing (average<60)))
  309. isa ((winner (self is winning))))
  310. (student-group (listof student)
  311. prop ((n-students length) % This property is implemented by
  312. % the Lisp function LENGTH.
  313. (Average Student-group-average)))
  314. (class (atom (proplist (department atom)
  315. (number integer)
  316. (instructor string)
  317. (students student-group)))
  318. prop ((n-students (students:n-students))
  319. (men ((those students who are male)))
  320. (women ((those students who are female)))
  321. (winners ((those students who are winning)))
  322. (losers ((those students who are losing)))
  323. (class-average (students:average))))
  324. )
  325. (dg student-average (s:student)
  326. (prog ((sum 0.0)(n 0.0))
  327. (for g in grades do n _+ 1.0 sum_+g)
  328. (return sum/n) ))
  329. (dg student-grade-average (s:student)
  330. (prog ((av s:average))
  331. (return (if av >= 90.0 then 'a
  332. elseif av >= 80.0 then 'b
  333. elseif av >= 70.0 then 'c
  334. elseif av >= 60.0 then 'd
  335. else 'f))))
  336. (dg student-group-average (sg:student-group)
  337. (prog ((sum 0.0))
  338. (for s in sg do sum_+s:average)
  339. (return sum/sg:n-students) ))
  340. % Print name and grade average for each student
  341. (dg test1 (c:class)
  342. (for s in c:students (prin1 s:name)
  343. (prin2 '! )
  344. (print s:grade-average)))
  345. % Another version of the above function
  346. (dg test1b (:class)
  347. (for each student (prin1 name)
  348. (prin2 '! )
  349. (print grade-average)))
  350. % Print name and average of the winners in the class
  351. (dg test2 (c:class)
  352. (for s in c:winners (prin1 s:name)
  353. (prin2 '! )
  354. (print s:average)))
  355. % The average of all the male students' grades
  356. (dg test3 (c:class)
  357. c:men:average)
  358. % The name and average of the winning women
  359. (dg test4 (c:class)
  360. (for s in c:women when s is winning
  361. (prin1 s:name)
  362. (prin2 '! )
  363. (print s:average)))
  364. % Another version of the above function. The * operator in this case
  365. % denotes the intersection of the sets of women and winners. The
  366. % GLISP compiler optimizes the code so that these intermediate sets are
  367. % not actually constructed.
  368. (dg test4b (c:class)
  369. (for s in c:women*c:winners
  370. (prin1 s:name)
  371. (prin2 '! )
  372. (print s:average)))
  373. % Make a list of the easy professors.
  374. (dg easy-profs (classes:(listof class))
  375. (for each class with class-average > 90.0 collect (the instructor)))
  376. % A more Pascal-like version of easy-profs:
  377. (dg easy-profs-b (classes:(listof class))
  378. (for c in classes when c:class-average > 90.0 collect c:instructor))
  379. % Some test data for testing the above functions.
  380. (setq class1 (a class with instructor = "A. Prof" department = 'cs
  381. number = 102 students =
  382. (list
  383. (a student with name = "John Doe" sex = 'male major = 'cs
  384. grades = '(99 98 97 93))
  385. (a student with name = "Fred Failure" sex = 'male major = 'cs
  386. grades = '(52 54 43 27))
  387. (a student with name = "Mary Star" sex = 'female major = 'cs
  388. grades = '(100 100 99 98))
  389. (a student with name = "Doris Dummy" sex = 'female major = 'cs
  390. grades = '(73 52 46 28))
  391. (a student with name = "Jane Average" sex = 'female major = 'cs
  392. grades = '(75 82 87 78))
  393. (a student with name = "Lois Lane" sex = 'female major = 'cs
  394. grades = '(98 95 97 96)) )))
  395. % The following object definitions illustrate inheritance of properties
  396. % from multiple parent classes. The three "bottom" classes Planet, Brick,
  397. % and Bowling-Ball all inherit the same definition of the property Density,
  398. % although they are represented in very different ways.
  399. (glispobjects
  400. (physical-object anything
  401. prop ((density (mass/volume))))
  402. (ordinary-object anything
  403. prop ((mass (weight / 9.88))) % Compute mass as weight/gravity
  404. supers (physical-object))
  405. (sphere anything
  406. prop ((volume ((4.0 / 3.0) * 3.1415926 * radius ^ 3))))
  407. (parallelepiped anything
  408. prop ((volume (length*width*height))))
  409. (planet (listobject (mass real)(radius real))
  410. supers (physical-object sphere)) % A planet is a physical-object
  411. % and a sphere.
  412. (brick (object (length real)(width real)(height real)(weight real))
  413. supers (ordinary-object parallelepiped))
  414. (bowling-ball (atomobject (type atom)(weight real))
  415. prop ((radius ((if type='adult then 0.1 else 0.07))))
  416. supers (ordinary-object sphere))
  417. )
  418. % Three test functions to demonstrate inheritance of the Density property.
  419. (dg dplanet (p:planet) density)
  420. (dg dbrick (b:brick) density)
  421. (dg dbb (b:bowling-ball) density)
  422. % Some objects to test the functions on.
  423. (setq earth (a planet with mass = 5.98e24 radius = 6.37e6))
  424. (setq brick1 (a brick with weight = 20.0 width = 0.10 height = 0.05
  425. length = 0.20))
  426. (setq bb1 (a bowling-ball with type = 'adult weight = 60.0))
  427. % Since the object types Planet, Brick, and Bowling-Ball are defined as
  428. % Object types (i.e., they contain the Class name as part of their stored
  429. % data), messages can be sent to them directly from the keyboard for
  430. % interactive examination of the objects. For example, the following
  431. % messages could be used:
  432. % (send earth density)
  433. % (send brick1 weight: 25.0)
  434. % (send brick1 mass: 2.0)
  435. % (send bb1 radius)
  436. % (send bb1 type: 'child)