home *** CD-ROM | disk | FTP | other *** search
/ ftp.cs.arizona.edu / ftp.cs.arizona.edu.tar / ftp.cs.arizona.edu / icon / newsgrp / group91b.txt < prev    next >
Internet Message Format  |  1991-06-13  |  436KB

  1. From icon-group-request@arizona.edu  Mon Apr  1 15:58:46 1991
  2. Received: from megaron.cs.arizona.edu by cheltenham.cs.arizona.edu; Mon, 1 Apr 91 15:58:46 MST
  3. Resent-From: icon-group-request@arizona.edu
  4. Received: from Arizona.edu (Merlin.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
  5.     id AA27326; Mon, 1 Apr 91 15:58:43 -0700
  6. Received: from ucbvax.Berkeley.EDU by Arizona.edu with PMDF#10282; Mon, 1 Apr
  7.  1991 15:58 MST
  8. Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA10724; Mon, 1 Apr 91 05:45:50
  9.  -0800
  10. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  11.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  12.  usenet@ucbvax.Berkeley.EDU if you have questions)
  13. Resent-Date: Mon, 1 Apr 1991 15:58 MST
  14. Date: 1 Apr 91 08:09:44 GMT
  15. From: haven!ni.umd.edu!uc780.umd.edu!cs450a03@ames.arc.nasa.gov
  16. Subject: RE: Survey Results : Perl vs Icon vs .... (> 500 line
  17. Sender: icon-group-request@arizona.edu
  18. Resent-To: icon-group@cs.arizona.edu
  19. To: icon-group@arizona.edu
  20. Resent-Message-Id: <C2D5FA28FC605A14@Arizona.edu>
  21. Message-Id: <1APR91.08094454@uc780.umd.edu>
  22. X-Envelope-To: icon-group@CS.Arizona.EDU
  23. X-Vms-To: icon-group@Arizona.edu
  24. Organization: The University of Maryland University College
  25. References: <BEVAN.91Mar29162211@panda.cs.man.ac.uk>,
  26.  <1991Apr1.043321.11251@midway.uchicago.edu>
  27.  
  28. Richard Goerwitz writes:
  29. >I'm curious why it is that you would see any advantage in run-time
  30. >loading other than decreased in-core mem. reqs.  If you were to use the
  31. >Icon compiler (i.e. Icon->C translator), you wouldn't even have to
  32. >worry about adding any code to any run-time system.
  33.  
  34. Well, I don't Icon, but I'm willing to put my foot in my mouth
  35. anyways...
  36.  
  37. (1)  If you compile an entire application, you lose the
  38. maintainability that the {Icon} environment provides.
  39.  
  40. (2) If you have some method of adding new primitives (accessible as
  41. proper objects of your system) you suddenly make it possible to use
  42. {Icon} for commercial applications (e.g. where speed is important).
  43.  
  44. Also note that it should be considered in good taste to provide, along
  45. with any object code, the {Icon} work-alike "source" so that a year or
  46. two down the road when somebody else wants to know what this thing is
  47. doing they can figure it out.  If you GPL, you'd want to keep around
  48. the intermidiate language source as well.
  49.  
  50. Raul Rockwell
  51.  
  52. From icon-group-request@arizona.edu  Mon Apr  1 16:03:25 1991
  53. Received: from megaron.cs.arizona.edu by cheltenham.cs.arizona.edu; Mon, 1 Apr 91 16:03:25 MST
  54. Resent-From: icon-group-request@arizona.edu
  55. Received: from Arizona.edu (Merlin.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
  56.     id AA27431; Mon, 1 Apr 91 16:03:22 -0700
  57. Received: from ucbvax.Berkeley.EDU by Arizona.edu with PMDF#10282; Mon, 1 Apr
  58.  1991 16:02 MST
  59. Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA02529; Sun, 31 Mar 91
  60.  22:06:28 -0800
  61. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  62.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  63.  usenet@ucbvax.Berkeley.EDU if you have questions)
  64. Resent-Date: Mon, 1 Apr 1991 16:03 MST
  65. Date: 1 Apr 91 04:33:21 GMT
  66. From: midway!ellis.uchicago.edu!goer@mimsy.umd.edu (Richard L. Goerwitz)
  67. Subject: RE: Survey Results : Perl vs Icon vs .... (> 500 lines)
  68. Sender: icon-group-request@arizona.edu
  69. Resent-To: icon-group@cs.arizona.edu
  70. To: icon-group@arizona.edu
  71. Resent-Message-Id: <C380C6385C60481C@Arizona.edu>
  72. Message-Id: <1991Apr1.043321.11251@midway.uchicago.edu>
  73. X-Envelope-To: icon-group@CS.Arizona.EDU
  74. X-Vms-To: icon-group@Arizona.edu
  75. Organization: University of Chicago
  76. References: <BEVAN.91Mar29162211@panda.cs.man.ac.uk>
  77.  
  78. We've seen an excellent summary of Icon's benefits and deficits, and I
  79. think it is a good one (especially considering that the person in
  80. question was only doing an initial survey).  Let me comment on some of
  81. the conclusions reached in efforts to refine them, and ask some
  82. question of my own.
  83.  
  84. In <BEVAN.91Mar29162211@panda.cs.man.ac.uk> Stephen J Bevan writes (re-
  85. garding Icon), that it has
  86.  
  87. > -  no packages.  Everything is in one namespace.  However ...
  88.  
  89. The "however" is for Idol, I gather.  For people who don't want to add
  90. yet another level of indirection to their Icon programs, though, naming
  91. conflicts remain a problem.
  92.  
  93. >-  no exceptions.
  94.  
  95. Have you looked at the Icon "error conversion" capability?  Normally,
  96. run-time errors will result in program termination.  You can, however,
  97. turn off this feature, and catch the errors yourself, either passing
  98. them through an exception handler, or else passing them back to the
  99. normal termination routine via runerr().  It's not an elegant system,
  100. since every expression that might normally cause error termination has
  101. to be checked individually.  I wonder if there are plans to expand
  102. this feature.
  103.  
  104. > +  Object oriented features.
  105. >    An extension to the language called Idol is included.
  106. >    This converts Idol into standard Icon.
  107. >    Idol itself looks (to me) like Smalltalk.
  108. > +  has records.  Other types include :- sets, lists, strings, tables
  109. > +  unlimited line length when reading
  110. >    (Note. the newline is discarded)
  111. > !  The only language that has enough facilities to be able to re-write
  112. >    some of my Lex/Yacc code.
  113. > +  stack trace on error.
  114. > +  C interface is good.  Can extend the language by building `personal
  115. >    interpreter'.  No dynamic linking.
  116. > +  extensive documentation
  117. >    9 technical reports in all (PostScript and ASCII)
  118.  
  119. > -  Unix interface is quite primitive.
  120. >    If you just want to use a command, you can use `callout', anything
  121. >    more complicated requires building a personal interpreter (not as
  122. >    difficult as it may sound)
  123.  
  124. It is quite true that Icon does not provide a good low-level interface
  125. with the operating system.  Moreover this is unlikely to change, since
  126. one of the great aims of Icon has been to keep it portable.  Luckily,
  127. customization (as you note) is not as difficult as it might seem.
  128.  
  129. > +  extensive test suite
  130. > +  Usenet group exists specifically for it - comp.lang.icon
  131. > -  Unless you use Idol, all procedures are at the same level
  132. >    i.e. one scope.
  133. > -  regular expressions not supported.
  134. >   However, in many cases, you can use an Icon functions `find',
  135. >   `match', `many' and `upto' instead.
  136.  
  137. "In many cases" ain't so.  ANY pattern representable by regular
  138. expressions can also be represented via Icon's builtin string
  139. processing control structures and functions.
  140.  
  141. I note, though, that many still want regular expressions.  The
  142. reason usually given for NOT including them is that they lack
  143. sufficient power.  In point of fact, they represent a miniscule subset
  144. of the range of patterns that can be specified using Icon's native
  145. facilities.  The advantage they would bring is that they would allow
  146. far greater recognition speed for those patterns which can be
  147. recognized via regular expressions, and that they would allow much
  148. more compact expression of these patterns than can be achieved with
  149. Icon's intrinsic functions.
  150.  
  151. Until someone does it *right*, I've written a prototype findre()
  152. function, which is in one of the more recent IPL updates.  It
  153. essentially combines Icon's find() function with an egrep-style
  154. FSTN-description language.  Ideally, someone should write this in C.
  155. Let's fool with the prototype for a while until we know exactly what
  156. we want, and then let's try to talk some poor soul into coding it up
  157. as part of the Icon run-time system.  A matchre() function should also
  158. be added as well.
  159.  
  160. > +  Can trace execution.
  161. > *  Pascal/C-like syntax
  162. >    i.e. uses {} but has a few more keywords than C.
  163. > +  lots of example programs included.
  164. > +  can define your own iterators
  165. >    i.e. your own procedures for iterating through arbitrary structures.
  166. > +  co-expressions.  Powerful tool, hard to explain briefly.  See
  167. >    chapter 13 of the Icon Programming Language.
  168.  
  169. > -  co-expressions haven't been implemented on Sun 4s (the type of
  170. >    machine I use)
  171.  
  172. Please correct me if I'm wrong, but I believe I saw the coexpression
  173. code for the Sun4 posted almost a year ago.
  174.  
  175. > +  has an `initial' section in procedures that is only ever executed
  176. >    once and allows you to initialise C like static variables with the
  177. >    result of other functions (unlike C).
  178. > +  arbitrary precision integers.
  179.  
  180. Wish list:
  181.  
  182. > E.2.4 Add a regular expression data type.  Modify the functions find
  183. >       and match to perate appropriately when their first argument is a
  184. >       regular expression.
  185.  
  186. I'd modify this to say, add findre() and matchre() to the list of
  187. builtin functions.  Most C libraries have regexp routines that can be
  188. drafted to serve in these capacities.  I know that regular expression
  189. don't fit into the traditional image of what Icon string processing
  190. has always been.  Practical advantages of speed and compactness,
  191. though, far outweigh this supposed disadvantage, and would make Icon
  192. much more useful for many real-world tasks.
  193.  
  194. > E.2.5 \  All of these suggest extending
  195. > E.5.4  | the string scanning facilities to
  196. > E.5.5 /  cope with files and strings in a uniform way.
  197.  
  198. Not sure what you mean.
  199.  
  200. > E.12.1 Provide a way to load functions (written in C) at runtime
  201.  
  202. My impression is that inclusion of this feature would be
  203. hopelessly implementation dependent, and would dramatically increase
  204. the complexity of maintaining the many implementations that exist.
  205. I'm curious why it is that you would see any advantage in run-time
  206. loading other than decreased in-core mem. reqs.  If you were to use the
  207. Icon compiler (i.e. Icon->C translator), you wouldn't even have to
  208. worry about adding any code to any run-time system.
  209. -- 
  210.  
  211.    -Richard L. Goerwitz              goer%sophist@uchicago.bitnet
  212.    goer@sophist.uchicago.edu         rutgers!oddjob!gide!sophist!goer
  213.  
  214. From icon-group-request@arizona.edu  Mon Apr  1 22:27:16 1991
  215. Received: from megaron.cs.arizona.edu by cheltenham.cs.arizona.edu; Mon, 1 Apr 91 22:27:16 MST
  216. Resent-From: icon-group-request@arizona.edu
  217. Received: from Arizona.edu (Merlin.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
  218.     id AA01885; Mon, 1 Apr 91 22:27:14 -0700
  219. Received: from ucbvax.Berkeley.EDU by Arizona.edu with PMDF#10282; Mon, 1 Apr
  220.  1991 22:26 MST
  221. Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA09229; Mon, 1 Apr 91 21:22:58
  222.  -0800
  223. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  224.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  225.  usenet@ucbvax.Berkeley.EDU if you have questions)
  226. Resent-Date: Mon, 1 Apr 1991 22:26 MST
  227. Date: 1 Apr 91 11:50:48 GMT
  228. From: mcsun!ukc!mucs!m1!bevan@uunet.uu.net (Stephen J Bevan)
  229. Subject: Icon (was Re: Survey Results : Perl vs Icon vs ... ))
  230. Sender: icon-group-request@arizona.edu
  231. Resent-To: icon-group@cs.arizona.edu
  232. To: icon-group@arizona.edu
  233. Resent-Message-Id: <F91C0DDB8C6046B1@Arizona.edu>
  234. Message-Id: <BEVAN.91Apr1125048@panda.cs.man.ac.uk>
  235. X-Envelope-To: icon-group@CS.Arizona.EDU
  236. X-Vms-To: icon-group@Arizona.edu
  237. Organization: Department of Computer Science, University of Manchester
  238. References: <BEVAN.91Mar29162211@panda.cs.man.ac.uk>
  239.  
  240. In <1991Apr1.043321.11251@midway.uchicago.edu> Richard L. Goerwitz
  241. writes :-
  242.  
  243. >> -  no packages.  Everything is in one namespace.  However ...
  244. >
  245. >The "however" is for Idol, I gather.  For people who don't want to add
  246. >yet another level of indirection to their Icon programs, though, naming
  247. >conflicts remain a problem.
  248.  
  249. I was thinking about the indirection stuff myself, however I received
  250. a message from Clinton Jeffery <cjeffery@cs.arizona.edu> about Idol
  251. and in it he says :-
  252.  
  253. ``... its method lookup is a constant time operation unlike Smalltalk's''
  254.  
  255. I'm not exactly sure how this is achieved, but maybe it removes some
  256. of the worries about slow execution.
  257.  
  258. >>-  no exceptions.
  259. >
  260. >Have you looked at the Icon "error conversion" capability?
  261.  
  262. No this one slipped me by.
  263.  
  264. >> -  regular expressions not supported.
  265. >>   However, in many cases, you can use an Icon functions `find',
  266. >>   `match', `many' and `upto' instead.
  267. >
  268. >"In many cases" ain't so.  ANY pattern representable by regular
  269. >expressions can also be represented via Icon's builtin string
  270. >processing control structures and functions.
  271.  
  272. Excuse the poor phrasing on my part.  I didn't mean to imply that Icon
  273. couldn't handle the expressions.  What I meant was that in a lot of
  274. cases, you can replace a regexp with one of the above functions, and
  275. in all cases, you can replace it with a combination of the above.
  276.  
  277. >> -  co-expressions haven't been implemented on Sun 4s (the type of
  278. >>    machine I use)
  279. >Please correct me if I'm wrong, but I believe I saw the coexpression
  280. >code for the Sun4 posted almost a year ago.
  281.  
  282. You are right, I've only been reading comp.lang.icon for about month
  283. and so wasn't aware of it.  All I can say is that the copy of Icon v8
  284. I retrieved, explicitly mentioned the fact that co-expressions didn't
  285. work on Sun4s.  I assume the code will be in the next release.
  286.  
  287. >> E.2.4 Add a regular expression data type.  Modify the functions find
  288. >>       and match to perate appropriately when their first argument is a
  289. >>       regular expression.
  290. >
  291. >I'd modify this to say, add findre() and matchre() to the list of
  292. >builtin functions.  Most C libraries have regexp routines that can be
  293. >drafted to serve in these capacities.
  294.  
  295. Well after spending a day adding regular expressions to ELK, I
  296. wouldn't be so sure about the regexp facilies of C libraries.  For
  297. example the regexp library with SunOS 4.1 only has ed/grep style
  298. regular expression, not egrep ones.  I therefore used the GNU regexp
  299. code which implements Emacs like regexps i.e. egrep standard, but with
  300. different quoting conventions.  This works well for me as I've written
  301. more Emacs Lisp code than egrep/awk code.  If you prefer the standard
  302. egrep style, I'd recommend Henry Spencer's regexp code. (This is used
  303. by both Python and TCL, in slightly modified forms)
  304.  
  305. >> E.2.5 \  All of these suggest extending
  306. >> E.5.4  | the string scanning facilities to
  307. >> E.5.5 /  cope with files and strings in a uniform way.
  308. >
  309. >Not sure what you mean.
  310.  
  311. Well to quote ``The Implementation of the Icon Programming Language''
  312. by Ralph E. Griswold and Madge T. Griswold :-
  313.  
  314. E.2.5
  315. ``Unify string and file data types so that string operations can be
  316. performed on files.''
  317.  
  318. E.4.1 (this is E.5.4 refered to above.  There is a typo in the book
  319. which refers to E.4 as 5.4.  This was somehow further mangled by me to
  320. produce E.5.4!)
  321. ``Many problems that should be easy to deal with using string scanning
  322. are complicated by the fact that the data to be processed is contained
  323. in a file that consists of a sequence of lines that logically
  324. constitute a single string. ...''
  325.  
  326. E.4.2 (this was E.5.5, reason as above)
  327. ``Extend string scanning to apply to files''
  328.  
  329. This topic is also mentioned in a recent post by David Gudeman in
  330. alt.lang.cfutures
  331.  
  332. >> E.12.1 Provide a way to load functions (written in C) at runtime
  333. >I'm curious why it is that you would see any advantage in run-time
  334. >loading other than decreased in-core mem. reqs.
  335.  
  336. Maybe you should ask Madge or Ralph Griswold, it's in their book!
  337. Personally, I thought it would be useful for the reason you mention
  338. i.e.  you only load what you need.  However given the following I
  339. don't think it is necessary :-
  340.  
  341. >If you were to use the Icon compiler (i.e. Icon->C translator), you
  342. >wouldn't even have to worry about adding any code to any run-time
  343. >system.
  344.  
  345. I knew that an Icon compiler was been developed, but I didn't actually
  346. know that it was available until after I posted.  Personally I
  347. wouldn't be looking for an increase in speed (although its alway
  348. welcome, even on a SPARCstation!), I'd be more interested in the C
  349. interface i.e. how easy would it be to add extensions like, for
  350. example, dbm support?  (note. that was a rhetorical question)
  351.  
  352. Stephen J. Bevan            bevan@cs.man.ac.uk
  353.  
  354. From icon-group-request@arizona.edu  Wed Apr  3 06:12:10 1991
  355. Received: from megaron.cs.arizona.edu by cheltenham.cs.arizona.edu; Wed, 3 Apr 91 06:12:10 MST
  356. Resent-From: icon-group-request@arizona.edu
  357. Received: from Arizona.edu (Osprey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
  358.     id AA19634; Wed, 3 Apr 91 06:12:08 -0700
  359. Received: from ucbvax.Berkeley.EDU by Arizona.edu with PMDF#10282; Wed, 3 Apr
  360.  1991 06:11 MST
  361. Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA29165; Wed, 3 Apr 91 04:55:54
  362.  -0800
  363. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  364.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  365.  usenet@ucbvax.Berkeley.EDU if you have questions)
  366. Resent-Date: Wed, 3 Apr 1991 06:11 MST
  367. Date: 3 Apr 91 09:27:21 GMT
  368. From: eru!hagbard!sunic!mcsun!hp4nl!charon!guido@bloom-beacon.mit.edu (Guido
  369.  van Rossum)
  370. Subject: RE: Survey Results : Perl vs Icon vs .... (> 500 lines)
  371. Sender: icon-group-request@arizona.edu
  372. Resent-To: icon-group@cs.arizona.edu
  373. To: icon-group@arizona.edu
  374. Resent-Message-Id: <033A8C3E54400F82@Arizona.edu>
  375. Message-Id: <3252@charon.cwi.nl>
  376. X-Envelope-To: icon-group@CS.Arizona.EDU
  377. X-Vms-To: icon-group@Arizona.edu
  378. References: <BEVAN.91Mar29162211@panda.cs.man.ac.uk>,
  379.  <1991Apr1.043321.11251@midway.uchicago.edu>
  380.  
  381. Richard L. Goerwitz replies to Stephen Bevan, regarding Icon:
  382.  
  383. Bevan:
  384. >> -  Unix interface is quite primitive.
  385. >>    If you just want to use a command, you can use `callout', anything
  386. >>    more complicated requires building a personal interpreter (not as
  387. >>    difficult as it may sound)
  388.  
  389. Goerwitz:
  390. >It is quite true that Icon does not provide a good low-level interface
  391. >with the operating system.  Moreover this is unlikely to change, since
  392. >one of the great aims of Icon has been to keep it portable.  Luckily,
  393. >customization (as you note) is not as difficult as it might seem.
  394.  
  395. I don't buy the argument that you can't provide a good Unix interface
  396. because of portability.
  397.  
  398. Python is designed to be just as portable as Icon (runs on the Mac,
  399. for starters) but its Unix interface is quite good (and will improve).
  400. The trick is that all the Unix dependencies are encapsulated in a
  401. separate module.  Unix dependent applications won't run on non-Unix
  402. systems, but then they are probably not needed there either.  Many
  403. applications and library modules can be (and are!) written without the
  404. use of explicit Unix features.  Of course, the standard I/O interface
  405. exists on all systems.
  406.  
  407. There is no excuse for not providing a decent Unix interface for a
  408. language that runs under Unix.  Leaving it up to local initiative
  409. ("customization") is fatal for portability.
  410.  
  411. --Guido van Rossum, CWI, Amsterdam <guido@cwi.nl>
  412. "Life's gotta be more than meeting pretty faces and sitting on them"
  413.  
  414. From icon-group-request@arizona.edu  Wed Apr  3 11:44:25 1991
  415. Received: from megaron.cs.arizona.edu by cheltenham.cs.arizona.edu; Wed, 3 Apr 91 11:44:25 MST
  416. Resent-From: icon-group-request@arizona.edu
  417. Received: from Arizona.edu (Osprey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
  418.     id AA00221; Wed, 3 Apr 91 11:44:22 -0700
  419. Received: from ucbvax.Berkeley.EDU by Arizona.edu with PMDF#10282; Wed, 3 Apr
  420.  1991 11:43 MST
  421. Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA07914; Wed, 3 Apr 91 10:35:38
  422.  -0800
  423. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  424.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  425.  usenet@ucbvax.Berkeley.EDU if you have questions)
  426. Resent-Date: Wed, 3 Apr 1991 11:43 MST
  427. Date: 3 Apr 91 15:11:53 GMT
  428. From: midway!ellis.uchicago.edu!goer@mimsy.umd.edu (Richard L. Goerwitz)
  429. Subject: RE: Survey Results : Perl vs Icon vs .... (> 500 lines)
  430. Sender: icon-group-request@arizona.edu
  431. Resent-To: icon-group@cs.arizona.edu
  432. To: icon-group@arizona.edu
  433. Resent-Message-Id: <319D8DEC04401141@Arizona.edu>
  434. Message-Id: <1991Apr3.151153.3447@midway.uchicago.edu>
  435. X-Envelope-To: icon-group@CS.Arizona.EDU
  436. X-Vms-To: icon-group@Arizona.edu
  437. Organization: University of Chicago
  438. References: <BEVAN.91Mar29162211@panda.cs.man.ac.uk>,
  439.  <1991Apr1.043321.11251@midway.uchicago.edu>, <3252@charon.cwi.nl>
  440.  
  441. In article <3252@charon.cwi.nl> guido@cwi.nl (Guido van Rossum) writes:
  442. >
  443. >>> -  [the Icon-]Unix interface is quite primitive.
  444. >>>    If you just want to use a command, you can use `callout', anything
  445. >>>    more complicated requires building a personal interpreter (not as
  446. >>>    difficult as it may sound)
  447. >
  448. >Goerwitz:
  449. >>It is quite true that Icon does not provide a good low-level interface
  450. >>with the operating system.  Moreover this is unlikely to change, since
  451. >>one of the great aims of Icon has been to keep it portable....
  452. >
  453. >I don't buy the argument that you can't provide a good Unix interface
  454. >because of portability.
  455. >
  456. >Python is designed to be just as portable as Icon (runs on the Mac,
  457. >for starters) but its Unix interface is quite good (and will improve).
  458. >The trick is that all the Unix dependencies are encapsulated in a
  459. >separate module.  Unix dependent applications won't run on non-Unix
  460. >systems, but then they are probably not needed there either.
  461.  
  462. What is portability?  Portability doesn't just involve the compiler or
  463. interpreter itself.  It's a property of code written for it as well.
  464. Why?  Because the code is as important as the language tools themselves.
  465. What good is it, say, to be make it easy to reimplement a compiler for
  466. more than one system when code written for that compiler will present
  467. a horrendous problem?
  468.  
  469. Portability is also not just a theoretical thing.  The proof is in the
  470. pudding.  How many platforms is Python actively used on?  Here's a list
  471. for Icon.  Note that most programs will run practically unaltered on
  472. each of the listed platforms.  Do you know of any language for which a
  473. similar claim could be made for so many machines and operating systems?
  474.  
  475.     MS-DOS
  476.     OS/2
  477.     Mac (MPW and standalone)
  478.     Atari
  479.     Apollo (AEGIS)
  480.     IBM 370 (MVS/XA and VM/CMS)
  481.     Amiga
  482.     DEC VAX (8650, running VMS)
  483.  
  484. And for Unix-oids:
  485.  
  486.     BSD 4.3
  487.     SunOS 4.0
  488.     Ultrix
  489.     AIX
  490.     Xenix
  491.     Mach (on the NeXT)
  492.     SYSVR3 (4 also?)
  493.  
  494. This is just what I can think of offhand.  There are probably others as
  495. well.
  496.  
  497. >There is no excuse for not providing a decent Unix interface for a
  498. >language that runs under Unix.  Leaving it up to local initiative
  499. >("customization") is fatal for portability.
  500.  
  501. I'm not sure, but I think you've got this backwards.  Customization
  502. *creates* nonportability.  Still, I think you are right that languages
  503. need a good OS interface in order to be useful for certain types of
  504. tasks.  The question is, "What features would you regard as vital for
  505. work in a Unix environment?"  I'll be curious to see your answer.
  506. Mine would be:
  507.  
  508.     ability to call C functions
  509.     ability to store C pointers for calls to C functions
  510.     built-in support for conversion from Icon to C types
  511.     intrinsic fork()/exec()/wait() ability
  512.     intrinsic ability to work with pipes
  513.     intrinsic system() function
  514.  
  515. These would be the basic things I'd want.  Icon has three of them.  It
  516. lacks the other two.  Yet another it partially implements, but the inter-
  517. face is nontrivial for complex objects (I'm talking about Icon->C type
  518. conversions).
  519.  
  520. -Richard (goer@sophist.uchicago.edu)
  521. -- 
  522.  
  523.    -Richard L. Goerwitz              goer%sophist@uchicago.bitnet
  524.    goer@sophist.uchicago.edu         rutgers!oddjob!gide!sophist!goer
  525.  
  526. From @um.cc.umich.edu:Paul_Abrahams@MTS.cc.Wayne.edu  Wed Apr  3 19:02:53 1991
  527. Received: from megaron.cs.arizona.edu by cheltenham.cs.arizona.edu; Wed, 3 Apr 91 19:02:53 MST
  528. Received: from umich.edu by megaron.cs.arizona.edu (5.61/15) via SMTP
  529.     id AA00116; Wed, 3 Apr 91 19:02:49 -0700
  530. Received: from um.cc.umich.edu by umich.edu (5.61/1123-1.0)
  531.     id AA22765; Wed, 3 Apr 91 18:26:36 -0500
  532. Received: from MTS.cc.Wayne.edu by um.cc.umich.edu via MTS-Net; Wed, 3 Apr 91 18:20:17 EST
  533. Date: Wed, 3 Apr 91 18:20:20 EST
  534. From: Paul_Abrahams@MTS.cc.Wayne.edu
  535. To: icon-group@cs.arizona.edu
  536. Message-Id: <315814@MTS.cc.Wayne.edu>
  537. Subject: Using the ``map'' function
  538.  
  539.  
  540. In doing the index for my latest book, I need to sort the entries using a
  541. nonstandard collating sequence.  I therefore need a ``keytrans'' function
  542. that transforms a sorting key to a key that uses the correct collating
  543. sequence.  Here's the obvious way to do it in Icon:
  544.  
  545. procedure keytrans(key)
  546.    static collator
  547.    initial {collator := ...} # printable chars in collating sequence order
  548.    return map(key, collator, &ascii[33:128])
  549. end
  550.  
  551. This is simple but slow since the map must be regenerated for each key.
  552. Here's the other way:
  553.  
  554. procedure keytrans(key)
  555.    static collator, lookup
  556.    initial {
  557.       collator := ...
  558.       lookup = map(&ascii[33:128], collator, &ascii[33:128])
  559.       }
  560.    local c, retval
  561.    retval := ""
  562.    every c := !key do
  563.       retval ||:= lookup[ord(c) - 31]
  564.    return retval
  565. end
  566.  
  567. This is inelegant but fast.
  568.  
  569. Is there any way I can have my cake and eat it too?  I wouldn't mind a small
  570. loss in speed, but the difference here seems pretty big.
  571.  
  572. Paul Abrahams
  573. Abrahams@mts.cc.wayne.edu 
  574.  
  575. From alex@laguna.Metaphor.COM  Wed Apr  3 19:52:34 1991
  576. Received: from megaron.cs.arizona.edu by cheltenham.cs.arizona.edu; Wed, 3 Apr 91 19:52:34 MST
  577. Received: from relay.metaphor.com by megaron.cs.arizona.edu (5.61/15) via SMTP
  578.     id AA01041; Wed, 3 Apr 91 19:52:27 -0700
  579. Received: from laguna.Metaphor.COM by relay.metaphor.com (4.1/SMI-4.1)
  580.     id AA00313; Wed, 3 Apr 91 18:47:42 PST
  581. Received: by laguna.Metaphor.COM (4.0/SMI-4.0)
  582.     id AA09079; Wed, 3 Apr 91 18:51:32 PST
  583. Date: Wed, 3 Apr 91 18:51:32 PST
  584. From: alex@laguna.Metaphor.COM (Bob Alexander)
  585. Message-Id: <9104040251.AA09079@laguna.Metaphor.COM>
  586. To: Paul_Abrahams@MTS.cc.Wayne.edu
  587. Subject: Re:  Using the ``map'' function
  588. Cc: icon-group@cs.arizona.edu
  589.  
  590. Hi Paul --
  591.  
  592. In your initial procedure (the slow one) it's likely that much of the
  593. time used in repeatedly executing
  594.  
  595.        return map(key, collator, &ascii[33:128])
  596.  
  597. is due to the fact that every call converts the cset, &ascii, to a
  598. string.
  599.  
  600. Also, there is an optimization in the iconx code for map() such that
  601. the internal translation table is not rebuilt if the second and third
  602. arguments are the same (i.e. identical descriptors) as for the previous
  603. map() call.  That optimization cannot be used in your proc.
  604.  
  605. Given all that, I'll bet this will execute a lot faster (the proof is
  606. left to the reader :)
  607.  
  608.     procedure keytrans(key)
  609.        static collator, ascii
  610.        initial {
  611.           collator := ...
  612.           ascii := &ascii[33:128]
  613.        }
  614.        return map(key, collator, ascii)
  615.     end
  616.  
  617. -- Bob Alexander
  618.  
  619. Metaphor Computer Systems   (415) 961-3600 x751   alex@metaphor.com
  620. ====^=== Mountain View, CA  ...{uunet}!{decwrl,apple}!metaphor!alex
  621.  
  622. From icon-group-request@arizona.edu  Wed Apr  3 21:57:43 1991
  623. Received: from megaron.cs.arizona.edu by cheltenham.cs.arizona.edu; Wed, 3 Apr 91 21:57:43 MST
  624. Resent-From: icon-group-request@arizona.edu
  625. Received: from Arizona.edu (Osprey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
  626.     id AA02486; Wed, 3 Apr 91 21:57:41 -0700
  627. Received: from ucbvax.Berkeley.EDU by Arizona.edu with PMDF#10282; Wed, 3 Apr
  628.  1991 21:57 MST
  629. Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA25670; Wed, 3 Apr 91 20:50:57
  630.  -0800
  631. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  632.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  633.  usenet@ucbvax.Berkeley.EDU if you have questions)
  634. Resent-Date: Wed, 3 Apr 1991 21:57 MST
  635. Date: 4 Apr 91 03:40:38 GMT
  636. From: att!linac!midway!ellis.uchicago.edu!goer@ucbvax.Berkeley.EDU (Richard L.
  637.  Goerwitz)
  638. Subject: bits -> bytes
  639. Sender: icon-group-request@arizona.edu
  640. Resent-To: icon-group@cs.arizona.edu
  641. To: icon-group@arizona.edu
  642. Resent-Message-Id: <875233CCB4401C20@Arizona.edu>
  643. Message-Id: <1991Apr4.034038.271@midway.uchicago.edu>
  644. X-Envelope-To: icon-group@CS.Arizona.EDU
  645. X-Vms-To: icon-group@Arizona.edu
  646. Organization: University of Chicago
  647.  
  648. Perhaps I'm opening a can of worms, like I did with the last such
  649. posting ("terrible code").  Anyway, I just wrote a section of code
  650. for some compression work I'm doing, and I just don't like the
  651. looks of it.  Is there a clearer and/or more efficient way of do-
  652. ing this sort of thing in Icon??
  653.  
  654. -Richard
  655.  
  656. (what sort of thing I'm talking about will shortly become clear;
  657. behold the code -)
  658.  
  659. #
  660. #  outbits() & inbits()
  661. #
  662. #  Pass to outbits(i, len) an integer i, and a length parameter (len),
  663. #  and outbits will suspend byte-sized chunks of i converted to
  664. #  characters (most significant bits first) until there is not enough
  665. #  left of i to fill up an 8-bit character.  The remaining portion is
  666. #  stored in a buffer until outbits() is called again, at which point
  667. #  the buffer is combined with the new i and then output in the same
  668. #  manner as before.  The buffer is flushed by calling outbits() with
  669. #  no i argument.
  670. #
  671. #  A trivial example of how outbits() might be used:
  672. #
  673. #      outtext := open("some.file.name","w")
  674. #      l := [1,2,3,4]
  675. #      every writes(outtext, outbits(!l,3))
  676. #      writes(outtext, outbits(&null,3))           # flush buffer
  677. #
  678. #  List l may be reconstructed with inbits() (see inbits.icn):
  679. #
  680. #      intext := open("some.file.name")
  681. #      l := []
  682. #      while put(l, inbits(intext, 3))
  683. #
  684. #  Note that outbits() is a generator, while inbits() is not.
  685. #
  686.  
  687. procedure outbits(i, len)
  688.  
  689.     local old_part, new_part, window, old_byte_mask
  690.     static old_i, old_len, byte_length, byte_mask
  691.     initial {
  692.     old_i := old_len := 0
  693.     byte_length := 8
  694.     byte_mask := (2^byte_length)-1
  695.     }
  696.  
  697.     old_byte_mask := (0 < 2^old_len - 1) | 0
  698.     window := byte_length - old_len
  699.     old_part := ishift(iand(old_i, old_byte_mask), window)
  700.  
  701.     # If we have a no-arg invocation, then flush buffer (old_i).
  702.     if /i then {
  703.     old_i := old_len := 0
  704.     return char(old_part)
  705.     } else {
  706.     new_part := ishift(i, window-len)
  707.     len -:= (len >= window) | {
  708.         old_len +:= len
  709.         old_i := ior(ishift(old_part, len-window), i)
  710.         fail
  711.     }
  712.     suspend char(ior(old_part, new_part))
  713.     }
  714.  
  715.     until len < byte_length do {
  716.     suspend char(iand(ishift(i, byte_length-len), byte_mask))
  717.     len -:= byte_length
  718.     }
  719.  
  720.     old_len := len
  721.     old_i := i
  722.     fail
  723.  
  724. end
  725.  
  726.  
  727. procedure inbits(f, len)
  728.  
  729.     local i, byte, old_byte_mask
  730.     static old_byte, old_len, byte_length
  731.     initial {
  732.     old_byte := old_len := 0
  733.     byte_length := 8
  734.     }
  735.  
  736.     old_byte_mask := (0 < 2^old_len - 1) | 0
  737.     old_byte := iand(old_byte, old_byte_mask)
  738.     i := ishift(old_byte, len-old_len)
  739.  
  740.     len -:= (len > old_len) | {
  741.     old_len -:= len
  742.     return i
  743.     }
  744.     
  745.     while byte := ord(reads(f)) do {
  746.     i := ior(i, ishift(byte, len-byte_length))
  747.     len -:= (len > byte_length) | {
  748.         old_len := byte_length-len
  749.         old_byte := byte
  750.         return i
  751.     }
  752.     }
  753.  
  754. end
  755. -- 
  756.  
  757.    -Richard L. Goerwitz              goer%sophist@uchicago.bitnet
  758.    goer@sophist.uchicago.edu         rutgers!oddjob!gide!sophist!goer
  759.  
  760. From alex@laguna.Metaphor.COM  Fri Apr  5 16:04:36 1991
  761. Received: from megaron.cs.arizona.edu by cheltenham.cs.arizona.edu; Fri, 5 Apr 91 16:04:36 MST
  762. Received: from relay.metaphor.com by megaron.cs.arizona.edu (5.61/15) via SMTP
  763.     id AA09355; Fri, 5 Apr 91 16:04:34 -0700
  764. Received: from laguna.Metaphor.COM by relay.metaphor.com (4.1/SMI-4.1)
  765.     id AA00534; Fri, 5 Apr 91 14:59:48 PST
  766. Received: by laguna.Metaphor.COM (4.0/SMI-4.0)
  767.     id AA10400; Fri, 5 Apr 91 10:53:52 PST
  768. Date: Fri, 5 Apr 91 10:53:52 PST
  769. From: alex@laguna.Metaphor.COM (Bob Alexander)
  770. Message-Id: <9104051853.AA10400@laguna.Metaphor.COM>
  771. To: eru!kth.se!sunic!mcsun!ukc!mucs!m1!bevan@bloom-beacon.mit.edu
  772. Subject: Re: Survey Results
  773. Cc: icon-group@cs.arizona.edu
  774.  
  775. I read your language survey with great interest, since (1) I'm also
  776. currently in the process of surveying languages for a particular use,
  777. and (2) I'm an Icon fan, user, and implementor.
  778.  
  779. Regarding (1), you've done a really nice job of researching the
  780. languages and sharing your findings -- my interest is piqued to further
  781. investigate a couple of new languages.  Thanks.
  782.  
  783. Regarding (2), I watched the icon-group traffic stimulated by your
  784. posting, and noticed a couple of area that might not have been
  785. covered.  So here are my additions:
  786.  
  787. > -  Unix interface is quite primitive.
  788. >    If you just want to use a command, you can use `callout', anything
  789. >    more complicated requires building a personal interpreter (not as
  790. >    difficult as it may sound)
  791.  
  792. I'm not sure just what constitutes a good UNIX interface, but Icon has
  793. great access to "commands" via subshells.  It has a system() function
  794. just like C, and has popen() access for both reading and writing via
  795. the "p" option of the Icon open() function.  "callout" was really
  796. intended for adding C functions to Icon, not for access to UNIX
  797. "commands".  (However, if what you intended by the term "commands" is
  798. UNIX system calls, I agree the built-in interface is weak, although
  799. some of that sort of work can be done through subshell commands).
  800.  
  801. > +  can define your own iterators
  802. >    i.e. your own procedures for iterating through arbitrary structures.
  803.  
  804. Merely the tip of the generator/goal-directed iceberg :-)!
  805.  
  806. >     The Icon Programmming Language
  807. >     Ralph E. Griswold and Madge T. Griswold
  808. >     Prentice Hall 1983
  809.  
  810. There's a second edition of the excellent "Icon Book" that is even
  811. bigger and better than the original:
  812.  
  813. Griswold, Ralph E. and Madge T. Griswold.  "The Icon Programming
  814. Language, Second Edition", Prentice-Hall, Inc., Englewood Cliffs, New
  815. Jersey.  1990.
  816.  
  817. -- Bob Alexander
  818.  
  819. Metaphor Computer Systems   (415) 961-3600 x751   alex@metaphor.com
  820. ====^=== Mountain View, CA  ...{uunet}!{decwrl,apple}!metaphor!alex
  821.  
  822. From icon-group-request@arizona.edu  Sat Apr  6 04:19:06 1991
  823. Received: from megaron.cs.arizona.edu by cheltenham.cs.arizona.edu; Sat, 6 Apr 91 04:19:06 MST
  824. Resent-From: icon-group-request@arizona.edu
  825. Received: from Arizona.edu (Osprey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
  826.     id AA21193; Sat, 6 Apr 91 04:19:04 -0700
  827. Received: from ucbvax.Berkeley.EDU by Arizona.edu with PMDF#10282; Sat, 6 Apr
  828.  1991 04:18 MST
  829. Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA16343; Sat, 6 Apr 91 03:12:14
  830.  -0800
  831. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  832.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  833.  usenet@ucbvax.Berkeley.EDU if you have questions)
  834. Resent-Date: Sat, 6 Apr 1991 04:18 MST
  835. Date: 5 Apr 91 14:22:37 GMT
  836. From: eru!hagbard!sunic!mcsun!ukc!mucs!m1!bevan@bloom-beacon.mit.edu (Stephen J
  837.  Bevan)
  838. Subject: Portability (was Re: Survey Results : Perl vs Icon vs ...)
  839. Sender: icon-group-request@arizona.edu
  840. Resent-To: icon-group@cs.arizona.edu
  841. To: icon-group@arizona.edu
  842. Resent-Message-Id: <4EEF664444402C3C@Arizona.edu>
  843. Message-Id: <BEVAN.91Apr5152237@panda.cs.man.ac.uk>
  844. X-Envelope-To: icon-group@CS.Arizona.EDU
  845. X-Vms-To: icon-group@Arizona.edu
  846. Organization: Department of Computer Science, University of Manchester
  847. References: <BEVAN.91Mar29162211@panda.cs.man.ac.uk>
  848.  
  849. > What is portability?  Portability doesn't just involve the compiler or
  850. > interpreter itself.  It's a property of code written for it as well.
  851.  
  852. If we are talking about the base language, then I'd agree with this.
  853. However, if you have a decent module system (like Python) you can put
  854. system specific features in separate modules.  i.e if you are running
  855. under Amoeba, you can use the Amoeba module, if you are running on a
  856. Mac, you can use the Mac module.  BTW I'm not saying the modules have to
  857. impement the same thing, rather they take advantage of the facilties
  858. of the machine.
  859.  
  860. Where's the portability problem?
  861.  
  862. Stephen J. Bevan            bevan@cs.man.ac.uk
  863.  
  864. From ksr!ksr.com!tim@uunet.UU.NET  Sun Apr  7 11:20:37 1991
  865. Received: from megaron.cs.arizona.edu by cheltenham.cs.arizona.edu; Sun, 7 Apr 91 11:20:37 MST
  866. Received: from relay1.UU.NET by megaron.cs.arizona.edu (5.61/15) via SMTP
  867.     id AA06775; Sun, 7 Apr 91 11:20:35 -0700
  868. Received: from ksr.UUCP by relay1.UU.NET with UUCP 
  869.     (5.61/UUNET-shadow-mx) id AA06792; Sun, 7 Apr 91 14:20:31 -0400
  870. Received: from kaos.ksr.com by ksr.com (4.0/SMI-3.2)
  871.     id AA24983; Sat, 6 Apr 91 18:23:38 EST
  872. Received: by kaos.ksr.com (4.0/SMI-3.2)
  873.     id AA19070; Sat, 6 Apr 91 18:23:37 EST
  874. Message-Id: <9104062323.AA19070@kaos.ksr.com>
  875. To: icon-group@cs.arizona.edu
  876. Subject: Bignum bug in Icon Version 8
  877. Date: Sat, 06 Apr 91 18:23:36 EST
  878. From: Tim Peters <tim@ksr.com>
  879.  
  880. Attempting to add the most negative native integer to a bignum causes an
  881. "Illegal instruction" trap on our SPARC (Solbourne, pretty much
  882. equivalent to a Sun-4) installation of Icon V8.
  883.  
  884. Following is a terminal session showing the problem:
  885.  
  886. kaos 338= cat bug.icn
  887. procedure main()
  888.    local i, j
  889.    write( "host: ", &host )
  890.    write( "version: ", &version )
  891.    write( "features:" )
  892.    every write( "   ", &features )
  893.  
  894.    i := -2147483647
  895.    i -:= 1
  896.    j := 6103515625
  897.    write(i," ",j)
  898.    i +:= j
  899. end
  900. kaos 339= /usr/local/lib/icon/v8/bin/icont -u bug -x
  901. Translating:
  902. bug.icn:
  903.   main (521/15000)
  904. No errors
  905. Linking:
  906. Executing:
  907. host: kaos
  908. version: Icon Version 8.0.  May 7, 1990
  909. features:
  910.    UNIX
  911.    ASCII
  912.    co-expressions
  913.    direct execution
  914.    environment variables
  915.    error trace back
  916.    executable images
  917.    expandable regions
  918.    external functions
  919.    large integers
  920.    math functions
  921.    memory monitoring
  922.    pipes
  923.    string invocation
  924.    system function
  925. -2147483648 6103515625
  926. Illegal instruction
  927. kaos 340= echo $?
  928. 132
  929. kaos 341= 
  930.  
  931. There's a longish (perhaps a second) pause between the output of i & j
  932. and the "Illegal instruction" trap, leading me to believe that Icon has
  933. gotten horribly confused.
  934.  
  935. Note that i is -2^31, the most negative native integer on this "long
  936. ints are 4 bytes" machine.  The problem does not occur for other values
  937. of i (well, I didn't try *all* possible values ... <grin>), and goes
  938. away if i is intialized via
  939.  
  940.   i := -2147483648
  941.  
  942. instead.  Indeed, *most* plausible ways of setting i to -2^31 make the
  943. problem go away:  I assume the code sequence in the test case is special
  944. only in that it causes i to "look like" a native integer internally,
  945. while most other ways cause i to look like a bignum internally.
  946.  
  947. Finally, I doubt this is a local installation problem, because I've used
  948. Icon's bignums extensively over several months, and this is the first
  949. major error I've stumbled into.
  950.  
  951. If I can be of any further assistance in tracking this down, please let
  952. me know.
  953.  
  954. one-of-icon's-admirers-ly y'rs  - tim
  955.  
  956. Tim Peters   Kendall Square Research Corp
  957. tim@ksr.com,  ksr!tim@harvard.harvard.edu
  958.  
  959. From @um.cc.umich.edu:Paul_Abrahams@MTS.cc.Wayne.edu  Sun Apr  7 20:17:10 1991
  960. Received: from megaron.cs.arizona.edu by cheltenham.cs.arizona.edu; Sun, 7 Apr 91 20:17:10 MST
  961. Received: from umich.edu by megaron.cs.arizona.edu (5.61/15) via SMTP
  962.     id AA03010; Sun, 7 Apr 91 20:17:07 -0700
  963. Received: from um.cc.umich.edu by umich.edu (5.61/1123-1.0)
  964.     id AA28022; Sun, 7 Apr 91 23:17:01 -0400
  965. Received: from MTS.cc.Wayne.edu by um.cc.umich.edu via MTS-Net; Sun, 7 Apr 91 23:11:32 EDT
  966. Date: Sun, 7 Apr 91 23:11:42 EDT
  967. From: Paul_Abrahams@MTS.cc.Wayne.edu
  968. To: icon-group@cs.arizona.edu
  969. Message-Id: <317214@MTS.cc.Wayne.edu>
  970. Subject: Efficiency of the `map' function
  971.  
  972.  
  973. Thanks to all for your informative comments about the efficiency
  974. of the map function.  I had guessed that it might do some caching
  975. of its arguments.  I'm glad to hear that it really does and in
  976. particular that its cache can hold more than one item.
  977.  
  978. I'm still wondering, though, how the map cache works and what its
  979. capacity is.  Is the cache associated with each call or is it
  980. global over the program?  It seems pretty difficult to get a
  981. decent implementation of map without a cache, since each call
  982. requires processing every character in the second argument and
  983. possibly in the third as well.  There does seem to be a hazard
  984. here: writing calls on map that aren't cached and therefore take
  985. a long time to execute.  Not knowing the caching policy, it would
  986. be easy for someone (like me) to inadvertently write a noncached
  987. map call.
  988.  
  989. There's a deeper issue buried here, what some have called
  990. `performance transparency'.  It's the property of a programming
  991. language that enables a programmer to gauge the relative costs of
  992. different constructs.  Certainly someone familiar with the
  993. innards of the Icon implementation can gauge these costs, but as
  994. someone who isn't familiar with the innards, I've always found
  995. that difficult. 
  996.  
  997. Paul Abrahams
  998. abrahams@mts.cc.wayne.edu 
  999.  
  1000. From @um.cc.umich.edu:Paul_Abrahams@MTS.cc.Wayne.edu  Sun Apr  7 20:17:30 1991
  1001. Received: from megaron.cs.arizona.edu by cheltenham.cs.arizona.edu; Sun, 7 Apr 91 20:17:30 MST
  1002. Received: from umich.edu by megaron.cs.arizona.edu (5.61/15) via SMTP
  1003.     id AA03020; Sun, 7 Apr 91 20:17:28 -0700
  1004. Received: from um.cc.umich.edu by umich.edu (5.61/1123-1.0)
  1005.     id AA28042; Sun, 7 Apr 91 23:17:22 -0400
  1006. Received: from MTS.cc.Wayne.edu by um.cc.umich.edu via MTS-Net; Sun, 7 Apr 91 23:13:00 EDT
  1007. Date: Sun, 7 Apr 91 23:13:06 EDT
  1008. From: Paul_Abrahams@MTS.cc.Wayne.edu
  1009. To: icon-group@cs.arizona.edu
  1010. Message-Id: <317216@MTS.cc.Wayne.edu>
  1011. Subject: Plusses and minuses of Icon
  1012.  
  1013.  
  1014. I've been following with interest the discussion about the
  1015. plusses and minuses of Icon.  My own view is that we shouldn't
  1016. expect a single programming language to be the best one around
  1017. for absolutely everything, any more than we expect that of other
  1018. fine tools.  Icon is superb for prototyping medium-size programs,
  1019. for quick and dirty solutions, and for symbol manipulation tasks,
  1020. especially those where goal-directed evaluation helps.  Examples
  1021. of tasks where I've found it beyond compare are an index
  1022. generation program for a book, a bootstrap version of a compiler,
  1023. and a printer-specific simulator of the IBM Script document
  1024. formatter.  Moreover, its internal structure and its superb
  1025. engineering make it a pleasure to use.
  1026.  
  1027. At the same time I cannot imagine that Icon would *ever* be the
  1028. language of choice for, say, writing a disk caching program in a
  1029. competitive commercial environment where the name of the game is
  1030. coming out first in the PC Magazine speed comparisons.  Nor can I
  1031. imagine it being used for writing a million-line spaceship
  1032. control program.  Two of its limitations are the inherent
  1033. efficiency of its code and the weakness of its global packaging
  1034. mechanisms. 
  1035.  
  1036. The proponents of nearly every language I know seem to feel that
  1037. criticism of the language for a particular application implies
  1038. criticism of the language in general.  I think that feeling is
  1039. misplaced.  With respect to Icon in particular, a very useful
  1040. activity would be to try to spell out the scope of tasks at which
  1041. Icon excels without attempting to make that scope universal. 
  1042. There are few language around that are as good at *anything* as
  1043. Icon is at the tasks for which it is suited.
  1044.  
  1045. Several people have argued that Idol solves the global packaging
  1046. problem.  That argument is in a sense irrelevant, for reasons
  1047. that have nothing to do with the intrinsic merits of Idol.  Idol
  1048. is not Icon; if we're talking about Icon, then let's leave Idol
  1049. out of it.  Perhaps Idol is the natural direction in which Icon
  1050. should evolve, and perhaps Idol will turn out to be Icon 9.0 (or
  1051. n.0).  But Idol does not as yet have the wide distribution, the
  1052. supporting structure, or the backlog of experience that Icon
  1053. does.  This is in no way a criticism of it or even a statement
  1054. about the limitations of its future.  If we're discussing the
  1055. merits of languages, let's keep our languages straight. 
  1056.  
  1057.  
  1058. Paul Abrahams
  1059. abrahams@mts.cc.wayne.edu 
  1060.  
  1061. From icon-group-request@arizona.edu  Mon Apr  8 15:34:51 1991
  1062. Received: from megaron.cs.arizona.edu by cheltenham.cs.arizona.edu; Mon, 8 Apr 91 15:34:51 MST
  1063. Resent-From: icon-group-request@arizona.edu
  1064. Received: from Arizona.edu (Merlin.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
  1065.     id AA28894; Mon, 8 Apr 91 15:34:49 -0700
  1066. Received: from ucbvax.Berkeley.EDU by Arizona.edu with PMDF#10282; Mon, 8 Apr
  1067.  1991 15:34 MST
  1068. Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA15549; Mon, 8 Apr 91 12:49:54
  1069.  -0700
  1070. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  1071.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  1072.  usenet@ucbvax.Berkeley.EDU if you have questions)
  1073. Resent-Date: Mon, 8 Apr 1991 15:34 MST
  1074. Date: 8 Apr 91 09:45:22 GMT
  1075. From: mcsun!hp4nl!charon!guido@uunet.uu.net (Guido van Rossum)
  1076. Subject: RE: Survey Results : Perl vs Icon vs .... (> 500 lines)
  1077. Sender: icon-group-request@arizona.edu
  1078. Resent-To: icon-group@cs.arizona.edu
  1079. To: icon-group@arizona.edu
  1080. Resent-Message-Id: <3FA3956016C005C3@Arizona.edu>
  1081. Message-Id: <3282@charon.cwi.nl>
  1082. X-Envelope-To: icon-group@CS.Arizona.EDU
  1083. X-Vms-To: icon-group@Arizona.edu
  1084. References: <1991Apr1.043321.11251@midway.uchicago.edu>, <3252@charon.cwi.nl>,
  1085.  <1991Apr3.151153.3447@midway.uchicago.edu>
  1086.  
  1087. goer@ellis.uchicago.edu (Richard L. Goerwitz) writes:
  1088.  
  1089. >What is portability?  Portability doesn't just involve the compiler or
  1090. >interpreter itself.  It's a property of code written for it as well.
  1091. >Why?  Because the code is as important as the language tools themselves.
  1092. >What good is it, say, to be make it easy to reimplement a compiler for
  1093. >more than one system when code written for that compiler will present
  1094. >a horrendous problem?
  1095. >
  1096. >Portability is also not just a theoretical thing.  The proof is in the
  1097. >pudding.  How many platforms is Python actively used on?  Here's a list
  1098. >for Icon.  Note that most programs will run practically unaltered on
  1099. >each of the listed platforms.  Do you know of any language for which a
  1100. >similar claim could be made for so many machines and operating systems?
  1101.  
  1102. If I understand you well, you can make this claim for Icon because
  1103. Icon forbids things that are inherently system-dependent.  This means
  1104. that probably a host of programs that would benefit from Icon's
  1105. high-level problem-solving abilities won't be written in Icon because
  1106. it lacks the low-level interfaces needed to gather the data or
  1107. whatever.
  1108.  
  1109. True, if a program opens a pipe and forks off a process that calls
  1110. sendmail it won't be portable to the Mac.  But forbidding such things
  1111. even when the OS provides the functionality forces the author to use a
  1112. non-portable solution anyway (such as writing a shell script wrapper
  1113. around an Icon program).  I argue that if the language at least allows
  1114. you to make non-portable OS calls, users are better off -- of course
  1115. assuming standard modularization techniques are available to isolate
  1116. non-portable portions of programs, and encouraging portable solutions
  1117. where they exist.
  1118.  
  1119. >[list of platforms on which Ican is used deleted]
  1120.  
  1121. I don't really want to engage in "mine is longer than yours" contests,
  1122. but just for the record: Python is out only two months now and has
  1123. already been ported to all of the Unix platforms you mention (plus
  1124. hpux) and some of the micro ones (Mac, MS-DOS, Atari ST).  I don't
  1125. claim that all Python programs run on all platforms, because some
  1126. platforms don't provide some built-in modules, but Python programs
  1127. that don't use system-dependent modules will run everywhere
  1128. without change.  The crux is that a non-portable Python program is
  1129. immediately recognizable because it imports a system-dependent module.
  1130. Also note that Python provides uniform interfaces for OS-dependent
  1131. features that are available on many systems but not all -- if you have
  1132. a symbolic link system call, it will be called posix.symlink().
  1133. Programs can dynamically test for the presence of such features (which
  1134. is unly useful if they have a way of handling their absence).
  1135.  
  1136. >[...]  Still, I think you are right that languages
  1137. >need a good OS interface in order to be useful for certain types of
  1138. >tasks.  The question is, "What features would you regard as vital for
  1139. >work in a Unix environment?"  I'll be curious to see your answer.
  1140. >Mine would be:
  1141. >
  1142. >    ability to call C functions
  1143. >    ability to store C pointers for calls to C functions
  1144. >    built-in support for conversion from Icon to C types
  1145. >    intrinsic fork()/exec()/wait() ability
  1146. >    intrinsic ability to work with pipes
  1147. >    intrinsic system() function
  1148.  
  1149. >These would be the basic things I'd want.  Icon has three of them.  It
  1150. >lacks the other two.  Yet another it partially implements, but the inter-
  1151. >face is nontrivial for complex objects (I'm talking about Icon->C type
  1152. >conversions).
  1153.  
  1154. You don't say which three Icon has and I don't know enough about Icon
  1155. to guess.  Python has all that you mention except fork/exec/wait and
  1156. pipes, which are easy enough to add, but since this is a one-person
  1157. project, for now I am content with system() and temporary files.
  1158.  
  1159. Disclaimer: maybe I seem stubborn on this point, but I have worked on
  1160. a language project where OS independence was considered so important
  1161. that the language didn't even have a primitive to open a file and read
  1162. data from it within a program.  The language didn't become a terrible
  1163. success, even though it had other properties that made it a big leap
  1164. forward from other languages...
  1165.  
  1166. --Guido van Rossum, CWI, Amsterdam <guido@cwi.nl>
  1167. "Twenty years ago, Dan Bernstein would be defending Assembler against HLL's"
  1168.  
  1169. From icon-group-request@arizona.edu  Tue Apr  9 05:16:51 1991
  1170. Received: from megaron.cs.arizona.edu by cheltenham.cs.arizona.edu; Tue, 9 Apr 91 05:16:51 MST
  1171. Resent-From: icon-group-request@arizona.edu
  1172. Received: from Arizona.edu (Merlin.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
  1173.     id AA00431; Tue, 9 Apr 91 05:16:49 -0700
  1174. Received: from ucbvax.Berkeley.EDU by Arizona.edu with PMDF#10282; Tue, 9 Apr
  1175.  1991 05:16 MST
  1176. Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA15630; Tue, 9 Apr 91 05:00:44
  1177.  -0700
  1178. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  1179.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  1180.  usenet@ucbvax.Berkeley.EDU if you have questions)
  1181. Resent-Date: Tue, 9 Apr 1991 05:16 MST
  1182. Date: 9 Apr 91 08:23:13 GMT
  1183. From: olivea!samsung!transfer!lectroid!jjmhome!smds!rh@apple.com (Richard
  1184.  Harter)
  1185. Subject: RE: Survey Results : Perl vs Icon vs .... (> 500 lines)
  1186. Sender: icon-group-request@arizona.edu
  1187. Resent-To: icon-group@cs.arizona.edu
  1188. To: icon-group@arizona.edu
  1189. Resent-Message-Id: <B27FB80626C00C35@Arizona.edu>
  1190. Message-Id: <388@smds.UUCP>
  1191. X-Envelope-To: icon-group@CS.Arizona.EDU
  1192. X-Vms-To: icon-group@Arizona.edu
  1193. Organization: SMDS Inc., Concord, MA
  1194. References: <BEVAN.91Mar29162211@panda.cs.man.ac.uk>,
  1195.  <1991Apr3.151153.3447@midway.uchicago.edu>
  1196.  
  1197. In article <1991Apr3.151153.3447@midway.uchicago.edu>, goer@ellis.uchicago.edu (Richard L. Goerwitz) writes:
  1198.  
  1199. > What is portability?  Portability doesn't just involve the compiler or
  1200. > interpreter itself.  It's a property of code written for it as well.
  1201. > Why?  Because the code is as important as the language tools themselves.
  1202. > What good is it, say, to be make it easy to reimplement a compiler for
  1203. > more than one system when code written for that compiler will present
  1204. > a horrendous problem?
  1205.  
  1206. There are some issues that weren't addressed in this discussion.  In
  1207. languages which have OS command capability one has to come to terms with
  1208. the fact that different OS's have differing command syntax and differing
  1209. file system syntax.  Portability of command code across OS's really implies
  1210. that the language must supply that portability.  Consider, for example,
  1211. path names.  UNIX and VMS both have a path naming system that amounts to
  1212. device - directory tree list - file name.  If the code refers to files by
  1213. path name then the language should provide a standard function to return
  1214. a correct path name from the components [or equivalent functionality].  I
  1215. am supposing here that the language is strong enough so that path name
  1216. elements are symbolic and switchable in a config file.
  1217.  
  1218. One can list a number of such requirements, depending on the objectives
  1219. of the language in question.  In general, however, portability of code
  1220. in the language requires that all host OS interface capability be portable
  1221. across the OS's being supported.
  1222. -- 
  1223. Richard Harter, Software Maintenance and Development Systems, Inc.
  1224. Net address: jjmhome!smds!rh Phone: 508-369-7398 
  1225. US Mail: SMDS Inc., PO Box 555, Concord MA 01742
  1226. This sentence no verb.  This sentence short.  This signature done.
  1227.  
  1228. From TENAGLIA@mis.mcw.edu  Tue Apr  9 06:04:05 1991
  1229. Received: from megaron.cs.arizona.edu by cheltenham.cs.arizona.edu; Tue, 9 Apr 91 06:04:05 MST
  1230. Received: from mis.mcw.edu (mis3.mis.mcw.edu) by megaron.cs.arizona.edu (5.61/15) via SMTP
  1231.     id AA00505; Tue, 9 Apr 91 06:03:54 -0700
  1232. Date: Tue, 9 Apr 1991 08:01 CST
  1233. From: Chris Tenaglia - 257-8765 <TENAGLIA@mis.mcw.edu>
  1234. Subject: Comparative Languages (icon vs perl etal)
  1235. To: icon-group@cs.arizona.edu
  1236. Message-Id: <C9931A3740801DA5@mis.mcw.edu>
  1237. X-Organization: Medical College of Wisconsin MIS Department (Milwaukee, WI)
  1238. X-Vms-To: IN%"icon-group@cs.arizona.edu"
  1239.  
  1240.  
  1241. I run icon under VMS. I use it usually as a file filter. Typical languages
  1242. such as BASIC, FORTRAN, PASCAL, and C may generate faster running code, but
  1243. I usually find myself spending all my time fighting typed variables. VMS
  1244. has a shell language called DCL which is easy to program, but it's
  1245. interpreted and runs 10 times slower than icon in regards to file I/O.
  1246. I often find myself making DCL/icon hybrid applications. DCL offers much
  1247. faster screen I/O, so I use it to front end icon filters which are much
  1248. faster with file I/O.
  1249.  
  1250. As far as structured languages go, Icon has one thing to it's advantage that
  1251. all the other 'structured' languages lack. No GOTO. The other languages
  1252. preach against GOTO, yet implement it anyway. Icon doesn't even acknowledge
  1253. its existence and thus, no GOTO. In my years of Icon programming, I've never
  1254. needed a GOTO in it. Apparently it was well thought out and implemented.
  1255.  
  1256. There is another string handling language in the genre of icon and perl.
  1257. It's ABC. I've seen it for PC and MAC. I've heard it exists for unix, and
  1258. a VMS implementation is in the works. It's a nifty interactive environment
  1259. set up to handle strings. It doesn't have a lot of features, but it looks
  1260. like it my be a nice first programming to teach.
  1261.  
  1262. Chris Tenaglia (System Manager) | Medical College of Wisconsin
  1263. 8701 W. Watertown Plank Rd.     | Milwaukee, WI 53226
  1264. (414)257-8765                   | tenaglia@mis.mcw.edu, mcwmis!tenaglia
  1265.  
  1266. From icon-group-request@arizona.edu  Tue Apr  9 09:34:26 1991
  1267. Received: from megaron.cs.arizona.edu by cheltenham.cs.arizona.edu; Tue, 9 Apr 91 09:34:26 MST
  1268. Resent-From: icon-group-request@arizona.edu
  1269. Received: from Arizona.edu (Merlin.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP
  1270.     id AA01411; Tue, 9 Apr 91 09:34:23 -0700
  1271. Received: from ucbvax.Berkeley.EDU by Arizona.edu with PMDF#10282; Tue, 9 Apr
  1272.  1991 09:33 MST
  1273. Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA20832; Tue, 9 Apr 91 08:50:52
  1274.  -0700
  1275. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  1276.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  1277.  usenet@ucbvax.Berkeley.EDU if you have questions)
  1278. Resent-Date: Tue, 9 Apr 1991 09:34 MST
  1279. Date: 9 Apr 91 15:14:51 GMT
  1280. From: usc!zaphod.mps.ohio-state.edu!pacific.mps.ohio-state.edu!linac!midway!ellis.uchicago.edu!goer@apple.com (Richard L.
  1281.  Goerwitz)
  1282. Subject: RE: Comparative Languages
  1283. Sender: icon-group-request@arizona.edu
  1284. Resent-To: icon-group@cs.arizona.edu
  1285. To: icon-group@arizona.edu
  1286. Resent-Message-Id: <D67A83BD16C00EA4@Arizona.edu>
  1287. Message-Id: <1991Apr9.151451.6713@midway.uchicago.edu>
  1288. X-Envelope-To: icon-group@CS.Arizona.EDU
  1289. X-Vms-To: icon-group@Arizona.edu
  1290. Organization: University of Chicago
  1291. References: <C9931A3740801DA5@mis.mcw.edu>
  1292.  
  1293.  
  1294. There seems to be some misunderstanding about where Icon "fits in" in
  1295. the great scheme of programming languages.  Having worked with Icon
  1296. very intensely for several years now, I feel I can report effectively
  1297. on it, and would like to do so here.  I would only offer my standard
  1298. word of warning:  I'm trained as a philologist, and have never taken a
  1299. CS or programming course from any CS department in any university I've
  1300. attended.
  1301.  
  1302. First, let's speak diachronically.  How did Icon evolve?  A simple
  1303. illustration will suffice here, I think:
  1304.  
  1305.  
  1306. SNOBOL  ---->  SL5  -----\
  1307.                            \----> Icon
  1308.                            /
  1309. ALGOL  --->  Pascal  ----/
  1310.  
  1311.  
  1312. Along about '76 or so, the people at the U of Arizona working on SL5
  1313. suddenly realized that the evaluation mechanisms originally confined
  1314. to string scanning in SNOBOL could actually be generalized to the
  1315. entire language.  You might say, "Whaddya think Prolog is?"  Prolog,
  1316. though, is a somewhat constrained implementation of first order
  1317. predicate logic :-), and is foreign to most programmers (and even many
  1318. theorists).  Instead of going off on some "tangent," the people at the
  1319. U of Arizona designed a language that utilized backtracking and
  1320. goal-directed evaluation within the context of a more standard,
  1321. Algol-derived, structures.
  1322.  
  1323. Icon was first implemented in FORTRAN (save the barfing, please), and
  1324. then later in C (1979 or so?).  It's now one of the most widely
  1325. implemented of the "unknown" programming languages.
  1326.  
  1327. Okay, that's my mangled version of Icon's evolution.  Now let's talk
  1328. synchronically (i.e. typologically).
  1329.  
  1330. One thing I find amusing is that people often put perl and Icon in the
  1331. same category.  About all they have in common is that they are both
  1332. optimized for string handling of one kind or another.  If there is any
  1333. real relation, it's via awk, which took on a few SNOBOL-ish features
  1334. (e.g. the ~ "contains" operator).  Awk, perl, and Icon all have
  1335. associative arrays and what not, and free the user from having to
  1336. worry about storage.  Many LISP dialects, though, have these same
  1337. features, and I don't seem LISP as being all that closely related to
  1338. Icon.  Perl and awk are also regexp based, which makes them very good
  1339. at recognizing simple languages and patterns (fundamentally these are
  1340. the same).  Icon, though slower at handling these same patterns, is
  1341. much more of a general-purpose programming language, and is capable of
  1342. recognizing, and effectively parsing, patterns which cannot be handled
  1343. by your run-of-the-mill DFA.  Icon really isn't very much like perl,
  1344. except in the very, very general typological sense of being geared
  1345. for more than low-level systems programming and numerical processing.
  1346.  
  1347. Put in practical terms, Icon represents a successful admixture of
  1348. Prolog-like backtracking mechanisms with an Algol-like structure and
  1349. SNOBOL-inspired string handling capabilities.  It is very strictly,
  1350. but dynamically, typed, and offers conversion facilities allowing the
  1351. user to move effortlessly from char set to string to integer or real
  1352. data-types and back again.  Icon is at its best doing string
  1353. processing, parsing, data conversion, and anything involving a more
  1354. heuristic, rather than purely algorithmic, approach.  Icon is also
  1355. good for prototyping and for small jobs that would ordinarily be done
  1356. using awk.  I use Icon mainly for medium-scale indexing and
  1357. concordance programs.  I also use it for fairly large-scale text
  1358. retrieval engines and for things like semiautomatic collation of
  1359. manuscripts, and linguistic analysis of ancient textual corpora.
  1360.  
  1361. Icon is clearly at its worst doing anything that requires close
  1362. interface with the hardware or operating system, or which requires
  1363. pointer-based access to memory locations.  Icon has no pointers, so
  1364. there is just no way to "get at" anything on this low a level without
  1365. dipping down into its C interface.  Icon also lacks OS-specific I/O
  1366. capabilities (e.g. under Unix there is no support for terminfo or
  1367. termio-based I/O, and interfacing the curses library to it is clumsy,
  1368. due to Icon's inability to store C pointers without kludges like
  1369. casting them to ints, and then converting them to its integer data
  1370. type).  If some solution to these problems could be found, Icon would
  1371. become viable for commercial software systems.  As yet, it can be used
  1372. for certain such projects.  It is, however, not suitable for many
  1373. others.
  1374.  
  1375. Icon is popular among people in the liberal arts, specifically
  1376. literary and linguistic people.  One of them - Alan Corre - has in
  1377. fact written a book on using Icon.  It is also, ironically, popular
  1378. among language theorists who like to stick offbeat and interesting
  1379. feathers in their caps.  Icon is also, naturally, popular among the
  1380. many people who have worked on it at one time or another.
  1381.  
  1382. Icon would be an ideal first language, since it offers all the
  1383. advantages of a Pascal, without many of its disadvantages.  It handles
  1384. garbage collection, storage allocation, and necessary type
  1385. conversions, freeing the beginning programmer to think about things
  1386. that are more important.  It also makes things like mathematical sets,
  1387. lists, hash tables, and strings into trivially simple data objects,
  1388. again freeing the programmer to think about the general typology of
  1389. his or her solution, and not so much about the as-yet irrelevant
  1390. details of implementation.  From Icon it is not difficult to move into
  1391. other Algol-derived dialects, since the overt structure is basically
  1392. the same.  Icon also gives one a leg up in languages like Prolog which
  1393. make use of vaguely similar backtracking mechanisms.  Though these
  1394. advantages would be important for beginning programmers planning to
  1395. move into other areas, Icon's most valuable asset as an instructional
  1396. language is that teachers competent to use it would not have to
  1397. separate out the "humanities" students (who are making up a larger and
  1398. larger share of low-level CS classes).  Icon has all the facilities
  1399. that both the "Hum" and "Sci" students would need on the introductory
  1400. level.
  1401.  
  1402. I hope that this posting clears up some of the many misconceptions
  1403. people seem to have about Icon.  If there are inaccuracies, I'm sure
  1404. that someone who's been more "officially" involved with it can clear
  1405. them up.
  1406.  
  1407.  
  1408. -- 
  1409.  
  1410.    -Richard L. Goerwitz              goer%sophist@uchicago.bitnet
  1411.    goer@sophist.uchicago.edu         rutgers!oddjob!gide!sophist!goer
  1412.  
  1413. From @um.cc.umich.edu:Paul_Abrahams@MTS.cc.Wayne.edu  Tue Apr  9 11:24:16 1991
  1414. Received: from megaron.cs.arizona.edu by cheltenham.cs.arizona.edu; Tue, 9 Apr 91 11:24:16 MST
  1415. Received: from umich.edu by megaron.cs.arizona.edu (5.61/15) via SMTP
  1416.     id AA04329; Tue, 9 Apr 91 11:24:12 -0700
  1417. Received: from um.cc.umich.edu by umich.edu (5.61/1123-1.0)
  1418.     id AA00823; Tue, 9 Apr 91 14:24:06 -0400
  1419. Received: from MTS.cc.Wayne.edu by um.cc.umich.edu via MTS-Net; Tue, 9 Apr 91 13:30:32 EDT
  1420. Date: Tue, 9 Apr 91 13:29:58 EDT
  1421. From: Paul_Abrahams@MTS.cc.Wayne.edu
  1422. To: icon-group@cs.arizona.edu
  1423. Message-Id: <317920@MTS.cc.Wayne.edu>
  1424. Subject: Portability
  1425.  
  1426.  
  1427. An example of a portable Icon function with a nonportable
  1428. implementation is the file name generator I posted a while back. 
  1429. Given a file name with wildcards, its result sequence is the set
  1430. of specific file names that match.  The DOS implementation uses a
  1431. specific system call, while the Unix implementation (I'd guess)
  1432. would use a shell echo call with redirected output (since
  1433. wildcard interpretation is generally done in the shell, not in
  1434. the underlying system.)  Note that DOS wildcards and Unix
  1435. wildcards have somewhat different interpretations: DOS
  1436. essentially ignores characters after `*', while Unix doesn't; and
  1437. the DOS treatment of the file extension is quite different from
  1438. that of Unix.
  1439.  
  1440. Path name interpretation is another example of a portable
  1441. function with a non-portable implementation, since DOS uses `\'
  1442. but Unix uses `/' (and maybe the Mac uses something else again). 
  1443. But the notion of a path makes sense in any system that has
  1444. tree-structured directories.  (Does anyone know how this maps to
  1445. the IBM OS/370 world?)
  1446.  
  1447. Paul Abrahams
  1448. Abrahams@mts.cc.wayne.edu 
  1449.  
  1450. From icon-group-request@arizona.edu  Wed Apr 10 15:02:02 1991
  1451. Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Wed, 10 Apr 91 15:02:02 MST
  1452. Resent-From: icon-group-request@arizona.edu
  1453. Received: from Arizona.edu (Merlin.Telcom.Arizona.EDU) by optima.cs.arizona.edu (4.1/15)
  1454.     id AA03042; Wed, 10 Apr 91 15:01:58 MST
  1455. Received: from ucbvax.Berkeley.EDU by Arizona.edu with PMDF#10282; Wed, 10 Apr
  1456.  1991 15:01 MST
  1457. Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA15302; Wed, 10 Apr 91
  1458.  14:39:08 -0700
  1459. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  1460.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  1461.  usenet@ucbvax.Berkeley.EDU if you have questions)
  1462. Resent-Date: Wed, 10 Apr 1991 15:01 MST
  1463. Date: 10 Apr 91 21:23:50 GMT
  1464. From: sharp@noao.edu (Nigel Sharp)
  1465. Subject: RE: Comparative Languages
  1466. Sender: icon-group-request@arizona.edu
  1467. Resent-To: icon-group@cs.arizona.edu
  1468. To: icon-group@arizona.edu
  1469. Resent-Message-Id: <CD649933C6C00DBD@Arizona.edu>
  1470. Message-Id: <1991Apr10.212350.15137@noao.edu>
  1471. X-Envelope-To: icon-group@CS.Arizona.EDU
  1472. X-Vms-To: icon-group@Arizona.edu
  1473. Organization: National Optical Astronomy Observatories, Tucson AZ
  1474. References: <C9931A3740801DA5@mis.mcw.edu>,
  1475.  <1991Apr9.151451.6713@midway.uchicago.edu>
  1476.  
  1477.  
  1478. I hope you will forgive a neophyte posting.
  1479. Some years ago I used SNOBOL/Spitbol for some tasks in pattern matching
  1480. (including literary manuscript analysis for author identification)
  1481. and algebra manipulation, and found it to be a very lovely language.
  1482. I may soon need to do some similar work, and have been following some
  1483. news groups to catch up to the state of the art.  I was wondering if one
  1484. of the current experts could tell me a) if a knowledge of Snobol helps,
  1485. b) if Icon is similar enough that I won't be starting from scratch, and
  1486. c) (sorry about this one) which books are recommended (the article I am
  1487. "following" mentioned one written by a literary type, but without
  1488. details).  My past experience lends me to favour Icon, as you might expect.
  1489.  
  1490. Before you notice I'm in Tucson and could walk across and ask the
  1491. inventors, let me say that I have too much respect to bother them
  1492. directly with such trivial questions.
  1493.  
  1494. Nigel Sharp, nsharp@noao.edu
  1495.  
  1496. From icon-group-request@arizona.edu  Wed Apr 10 19:52:42 1991
  1497. Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Wed, 10 Apr 91 19:52:42 MST
  1498. Resent-From: icon-group-request@arizona.edu
  1499. Received: from Arizona.edu (Merlin.Telcom.Arizona.EDU) by optima.cs.arizona.edu (4.1/15)
  1500.     id AA16147; Wed, 10 Apr 91 19:52:39 MST
  1501. Received: from ucbvax.Berkeley.EDU by Arizona.edu with PMDF#10282; Wed, 10 Apr
  1502.  1991 19:52 MST
  1503. Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA23947; Wed, 10 Apr 91
  1504.  19:39:30 -0700
  1505. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  1506.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  1507.  usenet@ucbvax.Berkeley.EDU if you have questions)
  1508. Resent-Date: Wed, 10 Apr 1991 19:52 MST
  1509. Date: 11 Apr 91 02:12:29 GMT
  1510. From: midway!quads.uchicago.edu!goer@handies.ucar.edu (Richard L. Goerwitz)
  1511. Subject: partial input completion utility
  1512. Sender: icon-group-request@arizona.edu
  1513. Resent-To: icon-group@cs.arizona.edu
  1514. To: icon-group@arizona.edu
  1515. Resent-Message-Id: <F603C2B7F6C009C0@Arizona.edu>
  1516. Message-Id: <1991Apr11.021229.27400@midway.uchicago.edu>
  1517. X-Envelope-To: icon-group@CS.Arizona.EDU
  1518. X-Vms-To: icon-group@Arizona.edu
  1519. Organization: University of Chicago
  1520.  
  1521.  
  1522. I just wrote this as part of a larger project, and I believe it would
  1523. be of general interest.  To anyone who tries it out:  Please let me
  1524. know if you find problems or make modifications that significantly
  1525. affect performance (ahem - for the *better*).
  1526.  
  1527. -Richard
  1528.  
  1529.  
  1530. ############################################################################
  1531. #
  1532. #    Name:     complete.icn
  1533. #
  1534. #    Title:     complete partial input string
  1535. #
  1536. #    Author:     Richard L. Goerwitz
  1537. #
  1538. #    Version: 1.2
  1539. #
  1540. ############################################################################
  1541. #
  1542. #  This file contains a single procedure, complete(s,st), which
  1543. #  completes a string (s) relative to a set or list of strings (st).
  1544. #  Put differently, complete() lets you supply a partial string, s,
  1545. #  and get back those strings in st that s is either equal to or a
  1546. #  substring of.
  1547. #
  1548. #  Lots of command interfaces allow completion of partial input.
  1549. #  Complete() simply represents my personal sentiments about how this
  1550. #  might best be done in Icon.  If you strip away the profuse comments
  1551. #  below, you end up with less than thirty lines of actual source
  1552. #  code.
  1553. #
  1554. #  I have arranged things so that only that portion of an automaton
  1555. #  which is needed to complete a given string is actually created and
  1556. #  stored.  Storing automata for later use naturally makes complete()
  1557. #  eat up more memory.  The performance gains make it worth the
  1558. #  trouble, though.  If, for some reason, there comes a time when it
  1559. #  is advisable to reclaim the space occupied by complete's static
  1560. #  structures, you can just call it without arguments.  This
  1561. #  "resets" complete() and forces an immediate garbage collection.
  1562. #  
  1563. #  Example code:
  1564. #
  1565. #      commands := ["run","stop","quit","save","load","continue"]
  1566. #      while line := read(&input) do {
  1567. #          cmds := list()
  1568. #          every put(cmds, complete(line, commands))
  1569. #          case *cmds of {
  1570. #              0 : input_error(line)
  1571. #              1 : do_command(cmds[1])
  1572. #              default : display_possible_completions(cmds)
  1573. #          }
  1574. #          etc...
  1575. #
  1576. #  More Iconish methods might include displaying successive
  1577. #  alternatives each time the user presses the tab key (this would,
  1578. #  however, require using the nonportable getch() routine).  Another
  1579. #  method might be to use the first string suspended by complete().
  1580. #
  1581. ############################################################################
  1582. #
  1583. #  Links: none
  1584. #
  1585. ############################################################################
  1586.  
  1587.  
  1588. procedure complete(s,st)
  1589.  
  1590.     local dfstn, c, l, old_char, newtbl, str, strset
  1591.     static t
  1592.     initial t := table()
  1593.  
  1594.     # No-arg invocation wipes out static structures & causes an
  1595.     # immediate garbage collection.
  1596.     if /s & /st then {
  1597.     t := table()
  1598.     collect()        # do it NOW
  1599.     fail
  1600.     }
  1601.     type(st) == ("list"|"set") |
  1602.     stop("error (complete):  list or set expected for arg2")
  1603.  
  1604.     # Seriously, all that's being done here is that possible states
  1605.     # are being represented by sets containing possible completions of
  1606.     # s relative to st.  Each time a character is snarfed from s, we
  1607.     # check to see what strings in st might represent possible
  1608.     # completions, and store these in a set for future use.  At some
  1609.     # point, we either run into a character in s that makes comple-
  1610.     # tion impossible (fail), or we run out of characters in s (in
  1611.     # which case we succeed, & suspend each of the possible
  1612.     # completions).
  1613.  
  1614.     # Store any sets we have to create in a static structure for later
  1615.     # re-use.
  1616.     /t[st] := table()
  1617.  
  1618.     # We'll call the table entry for the current set dfstn.  (It really
  1619.     # does enable us to do things deterministically.)
  1620.     dfstn := t[st]
  1621.  
  1622.     # Snarf one character at a time from s.
  1623.     every c := !s do {
  1624.  
  1625.     # The state we're in is represented by the set of all possible
  1626.     # completions before c was read.  If we haven't yet seen char
  1627.     # c in this state, run through the current-possible-completion
  1628.     # set, popping off the first character of each possible
  1629.     # completion, and then construct a table which uses these
  1630.     # initial as keys, and the completions that are possible for
  1631.     # each of these characters are the values for those keys.
  1632.     if /dfstn[st] then {
  1633.  
  1634.         # To get strings that start with the same char together,
  1635.         # sort the current string set (st).
  1636.         l := sort(st)
  1637.         newtbl := table()
  1638.         old_chr := ""
  1639.         every str := !l do {
  1640.         str ?:= (chr := move(1), tab(0)) | next
  1641.         if old_chr ~==:= chr then
  1642.             strset := set()
  1643.         insert(newtbl, chr, insert(strset, str))
  1644.         }
  1645.         insert(dfstn, st, newtbl)
  1646.     }
  1647.  
  1648.     # What we've done essentially is to create a table in which
  1649.     # the keys represent labeled arcs out of the current state,
  1650.     # and the values represent possible completion sets for those
  1651.     # paths.  What we need to do now is store that table in dfstn
  1652.     # as the value of the current state-set (i.e. the current
  1653.     # range of possible completions).  Once stored, we can then
  1654.     # see if there is any arc from the current state (dfstn[st])
  1655.     # with the label c (dfstn[st][c]).  If so, its value becomes
  1656.     # the new current state (st), and we cycle around again for
  1657.     # yet another c.
  1658.     st := \(\dfstn[st])[c] | fail     # see NB below
  1659.     }
  1660.  
  1661.     # Eventually we run out of characters in c.  The current state
  1662.     # (i.e. the set of possible completions) can simply be suspended
  1663.     # one element at a time, with s prefixed to each element.  If, for
  1664.     # instance, st had contained ["hello","help","hear"] at the outset
  1665.     # and s was equal to "hel", we would now be suspending "hel" ||
  1666.     # !set(["lo","p"]).
  1667.     suspend s || !st
  1668.  
  1669.     # NB: Slight performance gains could be had in certain cases by
  1670.     # checking the size of st.  If size = 1 and s is a substring of
  1671.     # its only element (or else matches in its entirety), then we are
  1672.     # essentially finished.  No need to go on and on creating nodes
  1673.     # and arcs.  Storage space gains could be had by only inserting
  1674.     # arcs needed in order to handle the current character, c, instead
  1675.     # of creating all possible arcs out the current state whenever a
  1676.     # new arc is needed.
  1677.  
  1678. end
  1679. -- 
  1680.  
  1681.    -Richard L. Goerwitz              goer%sophist@uchicago.bitnet
  1682.    goer@sophist.uchicago.edu         rutgers!oddjob!gide!sophist!goer
  1683.  
  1684. From isidev!nowlin@uunet.uu.net  Thu Apr 11 06:25:52 1991
  1685. Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Thu, 11 Apr 91 06:25:52 MST
  1686. Received: from relay1.UU.NET by optima.cs.arizona.edu (4.1/15)
  1687.     id AA06835; Thu, 11 Apr 91 06:25:49 MST
  1688. Received: from isidev.UUCP by relay1.UU.NET with UUCP 
  1689.     (5.61/UUNET-shadow-mx) id AA08584; Thu, 11 Apr 91 09:25:47 -0400
  1690. Date: Thu, 11 Apr 91 09:25:47 -0400
  1691. From: isidev!nowlin@uunet.uu.net
  1692. Message-Id: <9104111325.AA08584@relay1.UU.NET>
  1693. To: uunet!cs.arizona.edu!icon-group@uunet.uu.net
  1694. Subject: Re: partial input ...
  1695.  
  1696. I know I should resist but it's like a challenge.  I just can't let a
  1697. verbose Icon program go by without wanting to terse it up.  I think of Icon
  1698. as making it easier on me as a programmer.  If Icon is going to do all this
  1699. work for me why not let it?  That's only partly rhetorical.
  1700.  
  1701. Anyway, what follows contains a terser version of the complete() procedure.
  1702. I included the original version since the program below tests both.  I
  1703. took the comments (which were useful by the way) out of the original since
  1704. it was 40 lines even without them:
  1705.  
  1706. procedure main()
  1707.  
  1708.     l := ["idaho","ohio","utah","indiana","illinois","texas","iowa"]
  1709.  
  1710.     write("\nProgrammer does the work:")
  1711.     every write("\t",complete("i",l))
  1712.  
  1713.     write("\nIcon does the work:")
  1714.     every write("\t",terscomp("i",l))
  1715. end
  1716.  
  1717. procedure terscomp(s,st)
  1718.     suspend match(s,p := !st) & p
  1719. end
  1720.  
  1721. procedure complete(s,st)
  1722.  
  1723.     local dfstn, c, l, old_char, newtbl, str, strset
  1724.     static t
  1725.     initial t := table()
  1726.  
  1727.     if /s & /st then {
  1728.     t := table()
  1729.     collect()
  1730.     fail
  1731.     }
  1732.     type(st) == ("list"|"set") |
  1733.     stop("error (complete):  list or set expected for arg2")
  1734.  
  1735.     /t[st] := table()
  1736.  
  1737.     dfstn := t[st]
  1738.  
  1739.     every c := !s do {
  1740.  
  1741.     if /dfstn[st] then {
  1742.  
  1743.         l := sort(st)
  1744.         newtbl := table()
  1745.         old_chr := ""
  1746.         every str := !l do {
  1747.         str ?:= (chr := move(1), tab(0)) | next
  1748.         if old_chr ~==:= chr then
  1749.             strset := set()
  1750.         insert(newtbl, chr, insert(strset, str))
  1751.         }
  1752.         insert(dfstn, st, newtbl)
  1753.     }
  1754.  
  1755.     st := \(\dfstn[st])[c] | fail
  1756.     }
  1757.  
  1758.     suspend s || !st
  1759.  
  1760. end
  1761.  
  1762. --- ---
  1763.  | S | Iconic Software, Inc.  -  Jerry Nowlin  -  uunet!isidev!nowlin
  1764. --- ---
  1765.  
  1766.  
  1767. From icon-group-request@arizona.edu  Thu Apr 11 10:29:21 1991
  1768. Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Thu, 11 Apr 91 10:29:21 MST
  1769. Resent-From: icon-group-request@arizona.edu
  1770. Received: from Arizona.edu (Merlin.Telcom.Arizona.EDU) by optima.cs.arizona.edu (4.1/15)
  1771.     id AA13449; Thu, 11 Apr 91 10:29:19 MST
  1772. Received: from ucbvax.Berkeley.EDU by Arizona.edu with PMDF#10282; Thu, 11 Apr
  1773.  1991 10:02 MST
  1774. Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA13077; Thu, 11 Apr 91
  1775.  09:56:42 -0700
  1776. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  1777.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  1778.  usenet@ucbvax.Berkeley.EDU if you have questions)
  1779. Resent-Date: Thu, 11 Apr 1991 10:29 MST
  1780. Date: 11 Apr 91 16:27:49 GMT
  1781. From: agate!bionet!uwm.edu!linac!midway!quads.uchicago.edu!goer@ucbvax.berkeley.edu
  1782.  (Richard L. Goerwitz)
  1783. Subject: RE: partial input ...
  1784. Sender: icon-group-request@arizona.edu
  1785. Resent-To: icon-group@cs.arizona.edu
  1786. To: icon-group@arizona.edu
  1787. Resent-Message-Id: <708201BF168000B9@Arizona.edu>
  1788. Message-Id: <1991Apr11.162749.1637@midway.uchicago.edu>
  1789. X-Envelope-To: icon-group@CS.Arizona.EDU
  1790. X-Vms-To: icon-group@Arizona.edu
  1791. Organization: University of Chicago
  1792. References: <9104111325.AA08584@relay1.UU.NET>
  1793.  
  1794. In article <9104111325.AA08584@relay1.UU.NET> nowlin@isidev.UUCP writes:
  1795. >I know I should resist...
  1796.  
  1797. Jerry, the whole reason I posted was that I had hoped people would
  1798. not be able to resist :-) !
  1799.  
  1800. >Anyway, what follows contains a terser version of the complete() procedure.
  1801.  
  1802. I fooled with my program a while, and got it to run faster than the
  1803. "let Icon do the work" approach, but let me point out that the speed
  1804. difference is less than 5% in most instances, and never more than 10%.
  1805.  
  1806. If anyone wants what I came up with, I'll gladly send it out.  I don't
  1807. really see any reason why anyone should want it, though, when there is
  1808. a three-line equivalent that does pretty much the same thing (and uses
  1809. less memory to boot).
  1810.  
  1811.  
  1812. -Richard
  1813. -- 
  1814.  
  1815.    -Richard L. Goerwitz              goer%sophist@uchicago.bitnet
  1816.    goer@sophist.uchicago.edu         rutgers!oddjob!gide!sophist!goer
  1817.  
  1818. From alex@laguna.metaphor.com  Thu Apr 11 10:57:45 1991
  1819. Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Thu, 11 Apr 91 10:57:45 MST
  1820. Received: from relay.metaphor.com by optima.cs.arizona.edu (4.1/15)
  1821.     id AA14391; Thu, 11 Apr 91 10:57:42 MST
  1822. Received: from laguna.Metaphor.COM by relay.metaphor.com (4.1/SMI-4.1)
  1823.     id AA00144; Thu, 11 Apr 91 10:52:52 PDT
  1824. Received: by laguna.Metaphor.COM (4.0/SMI-4.0)
  1825.     id AA14124; Thu, 11 Apr 91 10:56:43 PDT
  1826. Date: Thu, 11 Apr 91 10:56:43 PDT
  1827. From: alex@laguna.metaphor.com (Bob Alexander)
  1828. Message-Id: <9104111756.AA14124@laguna.Metaphor.COM>
  1829. To: icon-group@cs.arizona.edu
  1830. Subject: Re: partial input ...
  1831.  
  1832. I, too, was interested in seeing how the obvious terser version of
  1833. Richard G's complete() procedure would work.  My terse version was much
  1834. like Jerry N's (before I saw Jerry's).  So I did some timings, and
  1835. here's what I found:  The terse version was faster when used with a
  1836. list with a size on the order of Richard's or Jerry's sample program
  1837. (how much faster depended on the size of input string).  *However*,
  1838. when the list gets large (~100 entries), Richard's wins hands down.
  1839.  
  1840. I guess that makes sense -- Richard's run time will vary
  1841. (predominantly) with the size of the abbreviated string, where the
  1842. terse method varies with the size of the list.
  1843.  
  1844. -- Bob Alexander
  1845.  
  1846. Metaphor Computer Systems   (415) 961-3600 x751   alex@metaphor.com
  1847. ====^=== Mountain View, CA  ...{uunet}!{decwrl,apple}!metaphor!alex
  1848.  
  1849. From icon-group-request@arizona.edu  Thu Apr 11 16:58:40 1991
  1850. Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Thu, 11 Apr 91 16:58:40 MST
  1851. Resent-From: icon-group-request@arizona.edu
  1852. Received: from Arizona.edu (Merlin.Telcom.Arizona.EDU) by optima.cs.arizona.edu (4.1/15)
  1853.     id AA29887; Thu, 11 Apr 91 16:58:36 MST
  1854. Received: from ucbvax.Berkeley.EDU by Arizona.edu with PMDF#10282; Thu, 11 Apr
  1855.  1991 16:57 MST
  1856. Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA26261; Thu, 11 Apr 91
  1857.  15:59:00 -0700
  1858. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  1859.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  1860.  usenet@ucbvax.Berkeley.EDU if you have questions)
  1861. Resent-Date: Thu, 11 Apr 1991 16:58 MST
  1862. Date: 11 Apr 91 21:22:52 GMT
  1863. From: pacbell.com!mips!sdd.hp.com!wuarchive!uwm.edu!linac!midway!ellis.uchicago.edu!goer@ucsd.edu
  1864.  (Richard L. Goerwitz)
  1865. Subject: RE: partial input ...
  1866. Sender: icon-group-request@arizona.edu
  1867. Resent-To: icon-group@cs.arizona.edu
  1868. To: icon-group@arizona.edu
  1869. Resent-Message-Id: <A6D9376E268003B6@Arizona.edu>
  1870. Message-Id: <1991Apr11.212252.14436@midway.uchicago.edu>
  1871. X-Envelope-To: icon-group@CS.Arizona.EDU
  1872. X-Vms-To: icon-group@Arizona.edu
  1873. Organization: University of Chicago
  1874. References: <9104111756.AA14124@laguna.Metaphor.COM>
  1875.  
  1876. alex@LAGUNA.METAPHOR.COM (Bob Alexander) writes:
  1877. >I, too, was interested in seeing how the obvious terser version of
  1878. >Richard G's complete() procedure would work.  My terse version was much
  1879. >like Jerry N's (before I saw Jerry's).  So I did some timings, and
  1880. >here's what I found:  The terse version was faster when used with a
  1881. >list with a size on the order of Richard's or Jerry's sample program
  1882. >(how much faster depended on the size of input string).  *However*,
  1883. >when the list gets large (~100 entries), Richard's wins hands down.
  1884. >
  1885. >I guess that makes sense -- Richard's run time will vary
  1886. >(predominantly) with the size of the abbreviated string, where the
  1887. >terse method varies with the size of the list.
  1888.  
  1889. I managed to get performance of the version I posted to a level where
  1890. it offers an acceptable increase over Jerry's version.  I confess that
  1891. one of the big reasons I wrote it was just to determine whether
  1892. Icon could offer me a fairly fast, deterministic way of handling
  1893. such problems.
  1894.  
  1895. At one point several months ago I actually wrote an Icon-only egrep-
  1896. type program that actually constructed a full-blown deterministic au-
  1897. tomaton, constructing only what it needed in order to accept or re-
  1898. ject a line.  Trouble is that it actually ran much slower than a simi-
  1899. lar program I wrote that goes to a nondeterministic pushdown automaton
  1900. under certain circumstances.  I would guess that for very complex fstns
  1901. the deterministic algorithm would be faster, but in practical use it
  1902. just didn't cut the mustard.  (The nondeterministic version of this
  1903. program is in one or another IPL update as findre.icn.)
  1904.  
  1905. Anyway, it frustrated me that Icon didn't really let me get at anything
  1906. on a low enough level to solve basic pattern-matching problems deter-
  1907. ministically and with reasonable storage requirements (I still wish
  1908. Icon had *some* form of pointers for simple data types).  This little
  1909. string completion utility was really just another attempt on my part
  1910. to solve this problem of performance and deterministic automata in
  1911. Icon.  The fact that it now runs faster than the "obvious" solution
  1912. only gratifies me in the sense that I might be able to apply the tech-
  1913. nique used here to problems where the performance gain would be a lot
  1914. more significant.
  1915.  
  1916. Since a couple of people asked for the "fixed" version, I'm reposting
  1917. it.
  1918.  
  1919. -Richard
  1920.  
  1921.  
  1922. ############################################################################
  1923. #
  1924. #    Name:     complete.icn
  1925. #
  1926. #    Title:     complete partial input string
  1927. #
  1928. #    Author:     Richard L. Goerwitz
  1929. #
  1930. #    Version: 1.3
  1931. #
  1932. ############################################################################
  1933. #
  1934. #  This file contains a single procedure, complete(s,st), which
  1935. #  completes a string (s) relative to a set or list of strings (st).
  1936. #  Put differently, complete() lets you supply a partial string, s,
  1937. #  and get back those strings in st that s is either equal to or a
  1938. #  substring of.
  1939. #
  1940. #  Lots of command interfaces allow completion of partial input.
  1941. #  Complete() simply represents my personal sentiments about how this
  1942. #  might best be done in Icon.  If you strip away the profuse comments
  1943. #  below, you end up with less than thirty lines of actual source
  1944. #  code.
  1945. #
  1946. #  I have arranged things so that only that portion of an automaton
  1947. #  which is needed to complete a given string is actually created and
  1948. #  stored.  Storing automata for later use naturally makes complete()
  1949. #  eat up more memory.  The performance gains make it worth the
  1950. #  trouble, though.  If, for some reason, there comes a time when it
  1951. #  is advisable to reclaim the space occupied by complete's static
  1952. #  structures, you can just call it without arguments.  This
  1953. #  "resets" complete() and forces an immediate garbage collection.
  1954. #  
  1955. # Example code:
  1956. #
  1957. #      commands := ["run","stop","quit","save","load","continue"]
  1958. #      while line := read(&input) do {
  1959. #          cmds := list()
  1960. #          every put(cmds, complete(line, commands))
  1961. #          case *cmds of {
  1962. #              0 : input_error(line)
  1963. #              1 : do_command(cmds[1])
  1964. #              default : display_possible_completions(cmds)
  1965. #          }
  1966. #          etc...
  1967. #
  1968. #  More Iconish methods might include displaying successive
  1969. #  alternatives each time the user presses the tab key (this would,
  1970. #  however, require using the nonportable getch() routine).  Another
  1971. #  method might be to use the first string suspended by complete().
  1972. #
  1973. #  NOTE: This entire shebang could be replaced with a slightly slower
  1974. #  and much smaller program suggested to me by Jerry Nowlin and Bob
  1975. #  Alexander.
  1976. #
  1977. #      procedure terscompl(s, st)
  1978. #          suspend match(s, p := !st) & p
  1979. #      end
  1980. #
  1981. #  This program will work fine for lists with just a few members, and
  1982. #  will use a lot less memory.
  1983. #
  1984. ############################################################################
  1985. #
  1986. #  Links: none
  1987. #
  1988. ############################################################################
  1989.  
  1990.  
  1991.  
  1992. procedure complete(s,st)
  1993.  
  1994.     local dfstn, c, l, old_char, newtbl, str, strset
  1995.     static t
  1996.     initial t := table()
  1997.  
  1998.     # No-arg invocation wipes out static structures & causes an
  1999.     # immediate garbage collection.
  2000.     if /s & /st then {
  2001.     t := table()
  2002.     collect()        # do it NOW
  2003.     fail
  2004.     }
  2005.     type(st) == ("list"|"set") |
  2006.     stop("error (complete):  list or set expected for arg2")
  2007.  
  2008.     # Seriously, all that's being done here is that possible states
  2009.     # are being represented by sets containing possible completions of
  2010.     # s relative to st.  Each time a character is snarfed from s, we
  2011.     # check to see what strings in st might represent possible
  2012.     # completions, and store these in a set for future use.  At some
  2013.     # point, we either run into a character in s that makes comple-
  2014.     # tion impossible (fail), or we run out of characters in s (in
  2015.     # which case we succeed, & suspend each of the possible
  2016.     # completions).
  2017.  
  2018.     # Store any sets we have to create in a static structure for later
  2019.     # re-use.
  2020.     /t[st] := table()
  2021.  
  2022.     # We'll call the table entry for the current set dfstn.  (It really
  2023.     # does enable us to do things deterministically.)
  2024.     dfstn := t[st]
  2025.  
  2026.     # Snarf one character at a time from s.
  2027.     every c := !s do {
  2028.  
  2029.     # The state we're in is represented by the set of all possible
  2030.     # completions before c was read.  If we haven't yet seen char
  2031.     # c in this state, run through the current-possible-completion
  2032.     # set, popping off the first character of each possible
  2033.     # completion, and then construct a table which uses these
  2034.     # initial as keys, and the completions that are possible for
  2035.     # each of these characters are the values for those keys.
  2036.     if /dfstn[st] then {
  2037.  
  2038.         # To get strings that start with the same char together,
  2039.         # sort the current string set (st).
  2040.         l := sort(st)
  2041.         newtbl := table()
  2042.         old_chr := ""
  2043.         every str := !l do {
  2044.         str ? { chr := move(1) | next; str := tab(0) }
  2045.         if old_chr ~==:= chr then {
  2046.             strset := set([str])
  2047.             insert(newtbl, chr, strset)
  2048.         }
  2049.         else insert(strset, str)
  2050.         }
  2051.         insert(dfstn, st, newtbl)
  2052.     }
  2053.  
  2054.     # What we've done essentially is to create a table in which
  2055.     # the keys represent labeled arcs out of the current state,
  2056.     # and the values represent possible completion sets for those
  2057.     # paths.  What we need to do now is store that table in dfstn
  2058.     # as the value of the current state-set (i.e. the current
  2059.     # range of possible completions).  Once stored, we can then
  2060.     # see if there is any arc from the current state (dfstn[st])
  2061.     # with the label c (dfstn[st][c]).  If so, its value becomes
  2062.     # the new current state (st), and we cycle around again for
  2063.     # yet another c.
  2064.     st := \dfstn[st][c] | fail
  2065.     if *st = 1 & match(s,!st)
  2066.     then break
  2067.     }
  2068.  
  2069.     # Eventually we run out of characters in c.  The current state
  2070.     # (i.e. the set of possible completions) can simply be suspended
  2071.     # one element at a time, with s prefixed to each element.  If, for
  2072.     # instance, st had contained ["hello","help","hear"] at the outset
  2073.     # and s was equal to "hel", we would now be suspending "hel" ||
  2074.     # !set(["lo","p"]).
  2075.     suspend s || !st
  2076.  
  2077. end
  2078. -- 
  2079.  
  2080.    -Richard L. Goerwitz              goer%sophist@uchicago.bitnet
  2081.    goer@sophist.uchicago.edu         rutgers!oddjob!gide!sophist!goer
  2082.  
  2083. From ralph  Sun Apr 14 07:34:25 1991
  2084. Date: Sun, 14 Apr 91 07:34:25 MST
  2085. From: "Ralph Griswold" <ralph>
  2086. Message-Id: <9104141434.AA08467@cheltenham.cs.arizona.edu>
  2087. Received: by cheltenham.cs.arizona.edu; Sun, 14 Apr 91 07:34:25 MST
  2088. To: icon-group
  2089. Subject: Icon Compiler for UNIX Platforms
  2090.  
  2091.         Icon Compiler for UNIX Platforms
  2092.  
  2093. As mentioned earlier, a preliminary release of the optimizing compiler for the
  2094. Icon programming language is now available for UNIX platforms. This compiler
  2095. generates stand-alone executable files unlike the Icon interpreter. The
  2096. compilation process itself is slow compared with the interpreter, but the
  2097. resulting executable files run much faster than interpreted ones.
  2098.  
  2099. The Icon compiler produces C code, so you'll need a C compiler to use it.
  2100.  
  2101. The preliminary release corresponds approximately to Version 7.6 of Icon
  2102. and does not have all Version 8 features. Version 8 of the compiler will
  2103. be released later.
  2104.  
  2105. The compiler is available in two ways: in "object" packages for specific UNIX
  2106. platforms and as source code.
  2107.  
  2108. If you want to run the compiler and there's an object package for your
  2109. platform, all you need to do is pick up the object package and install it,
  2110. which is a comparatively simple process.
  2111.  
  2112. If there's not an object package for your platform or if you are interested
  2113. in the source code, you can get that and build your own compiler. Building
  2114. the compiler takes quite a bit of machine time. It also requires about 6MB
  2115. of disk space to build.
  2116.  
  2117. At present there are object packages for the following UNIX platforms:
  2118.  
  2119.     DECstation 3100 running Ultrix
  2120.     HP 9000/300 running HP/UX
  2121.     HP 9000/800 running HP/UX
  2122.     Intel 386 running System V
  2123.     Iris 4D running IRIX
  2124.     Macintosh running A/UX
  2125.     NeXT running Mach
  2126.     PS/2 running AIX
  2127.     Sequent Symmetry running DYNIX
  2128.     Sun 3 Workstation running SunOS
  2129.     Sun 4 Workstation running SunOS
  2130.     UNIX PC (AT&T 3B1)
  2131.     VAX running 4.3 BSD
  2132.     VAX running Ultrix
  2133.  
  2134. Implementations for other platforms will be added as they are completed.
  2135.  
  2136. To get a copy of the Icon compiler, do an anonymous FTP to cs.arizona.edu.
  2137. Then cd to /icon/v8/Compiler. There are three subdirectories, Docs,
  2138. Packages, and Source.
  2139.  
  2140. The subdirectory Docs contains PostScript for documents relating to the
  2141. installation and use of the Icon compiler.
  2142.  
  2143. The subdirectory Packages contains object packages in additional
  2144. subdirectories, one for each presently supported platform. The subdirectory
  2145. names identify the platforms.
  2146.  
  2147. The subdirectory Source contains the source code for the Icon compiler.
  2148.  
  2149. See the READ.ME files in the various directories for additional information.
  2150.  
  2151. Please direct any questions to me, not icon-group.
  2152.  
  2153.  
  2154.   Ralph Griswold / Dept of Computer Science / Univ of Arizona / Tucson, AZ 85721
  2155.   +1 602 621 6609   ralph@cs.arizona.edu  uunet!arizona!ralph
  2156.     
  2157.  
  2158. From @cunyvm.cuny.edu:r1325%CSUOHIO.BITNET@CORNELLC.CIT.CORNELL.EDU  Wed Apr 17 08:00:33 1991
  2159. Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Wed, 17 Apr 91 08:00:33 MST
  2160. Message-Id: <9104171500.AA19932@optima.cs.arizona.edu>
  2161. Received: from CUNYVM.CUNY.EDU by optima.cs.arizona.edu (4.1/15)
  2162.     id AA19932; Wed, 17 Apr 91 08:00:30 MST
  2163. Received: from CSUOHIO.BITNET by CUNYVM.CUNY.EDU (IBM VM SMTP R1.2.2MX) with BSMTP id 8353; Wed, 17 Apr 91 11:00:55 EDT
  2164. Date: 91/04/17 10:57:37
  2165. From: r1325%CSUOHIO.BITNET%CORNELLC.CCS.CORNELL.EDU@cunyvm.cuny.edu
  2166. To: icon-group@cs.arizona.edu
  2167. Subject: content analysis
  2168.  
  2169.  
  2170.  
  2171.  
  2172.  
  2173.  
  2174. APRIL 17, 1991
  2175.  
  2176. BEING NEW TO ELETRONIC MAIL.....
  2177. I AM RESENDING THIS MESSAGE BECAUSE I'M UNSURE IF IT INITIALLY REACHED
  2178. THE ICON-GROUP.  I WOULD APPRECIATE ANY RESPONSE TO AFFIRM PROCEDURES ON
  2179. THIS END.  THANKS.
  2180.  
  2181. WE'RE DOING A CONTENT ANALYSIS OF SURVEY DATA THAT REQUIRES MORE
  2182. than word frequency counts, something more on the level of a qualitative
  2183. factor analysis.  I am the research associate at the Child Guidance Center of
  2184. Greater Cleveland, a non-profit 401(c)(3) organization.  Having purchased the
  2185. MS-DOS/386 version of Icon and the book Icon Programming for Humanists late
  2186. last year but only being able to upgrade memory beyond 1 meg recently, I'm in
  2187. a fix to put together a program (by 4/16/91) beyond word counts.  Can anyone
  2188. help?
  2189.  
  2190.  
  2191. Bill Burkey
  2192. Child Guidance Center
  2193. 2525 E 22
  2194. Cleveland, OH  44115
  2195. (216)696-5800 x23
  2196. bitnet <r1325@csuohio>
  2197.  
  2198.    
  2199.  
  2200. From r1325@CSUOHIO.BITNET  Wed Apr 17 08:04:56 1991
  2201. Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Wed, 17 Apr 91 08:04:56 MST
  2202. Received: from Arizona.edu (Merlin.Telcom.Arizona.EDU) by optima.cs.arizona.edu (4.1/15)
  2203.     id AA20395; Wed, 17 Apr 91 08:04:52 MST
  2204. Received: from CEARN.cern.ch (MAILER@CEARN) by Arizona.edu with PMDF#10282;
  2205.  Wed, 17 Apr 1991 08:04 MST
  2206. Received: from CSUOHIO.BITNET (R1325) by CEARN.cern.ch (Mailer R2.07B) with
  2207.  BSMTP id 0002; Wed, 17 Apr 91 17:04:05 GVA
  2208. Date: 91/04/17 11:00:20
  2209. From: r1325@CSUOHIO.BITNET
  2210. Subject: content analysis
  2211. To: icon-group@cs.arizona.edu
  2212. Message-Id: <134CA64D766014BD@Arizona.edu>
  2213. X-Envelope-To: icon-group@cs.arizona.edu
  2214.  
  2215.  
  2216.  
  2217.  
  2218.  
  2219.  
  2220. APRIL 17, 1991
  2221.  
  2222. BEING NEW TO ELETRONIC MAIL.....
  2223. I AM RESENDING THIS MESSAGE BECAUSE I'M UNSURE IF IT INITIALLY REACHED
  2224. THE ICON-GROUP.  I WOULD APPRECIATE ANY RESPONSE TO AFFIRM PROCEDURES ON
  2225. THIS END.  THANKS.
  2226.  
  2227. WE'RE DOING A CONTENT ANALYSIS OF SURVEY DATA THAT REQUIRES MORE
  2228. than word frequency counts, something more on the level of a qualitative
  2229. factor analysis.  I am the research associate at the Child Guidance Center of
  2230. Greater Cleveland, a non-profit 401(c)(3) organization.  Having purchased the
  2231. MS-DOS/386 version of Icon and the book Icon Programming for Humanists late
  2232. last year but only being able to upgrade memory beyond 1 meg recently, I'm in
  2233. a fix to put together a program (by 4/16/91) beyond word counts.  Can anyone
  2234. help?
  2235.  
  2236.  
  2237. Bill Burkey
  2238. Child Guidance Center
  2239. 2525 E 22
  2240. Cleveland, OH  44115
  2241. (216)696-5800 x23
  2242. bitnet <r1325@csuohio>
  2243.  
  2244.    
  2245.  
  2246. From r1325@CSUOHIO.BITNET  Wed Apr 17 08:09:04 1991
  2247. Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Wed, 17 Apr 91 08:09:04 MST
  2248. Received: from Arizona.edu (Merlin.Telcom.Arizona.EDU) by optima.cs.arizona.edu (4.1/15)
  2249.     id AA20949; Wed, 17 Apr 91 08:09:01 MST
  2250. Received: from UKACRL.BITNET (MAILER@UKACRL) by Arizona.edu with PMDF#10282;
  2251.  Wed, 17 Apr 1991 08:08 MST
  2252. Received: from CSUOHIO.BITNET (R1325) by UKACRL.BITNET (Mailer R2.07) with
  2253.  BSMTP id 9743; Wed, 17 Apr 91 16:04:53 BST
  2254. Date: 91/04/17 10:59:10
  2255. From: r1325@CSUOHIO.BITNET
  2256. Subject: content analysis
  2257. To: icon-group@cs.arizona.edu
  2258. Message-Id: <13DA5200B660150F@Arizona.edu>
  2259. X-Envelope-To: icon-group@cs.arizona.edu
  2260.  
  2261.  
  2262.  
  2263.  
  2264.  
  2265.  
  2266. APRIL 17, 1991
  2267.  
  2268. BEING NEW TO ELETRONIC MAIL.....
  2269. I AM RESENDING THIS MESSAGE BECAUSE I'M UNSURE IF IT INITIALLY REACHED
  2270. THE ICON-GROUP.  I WOULD APPRECIATE ANY RESPONSE TO AFFIRM PROCEDURES ON
  2271. THIS END.  THANKS.
  2272.  
  2273. WE'RE DOING A CONTENT ANALYSIS OF SURVEY DATA THAT REQUIRES MORE
  2274. than word frequency counts, something more on the level of a qualitative
  2275. factor analysis.  I am the research associate at the Child Guidance Center of
  2276. Greater Cleveland, a non-profit 401(c)(3) organization.  Having purchased the
  2277. MS-DOS/386 version of Icon and the book Icon Programming for Humanists late
  2278. last year but only being able to upgrade memory beyond 1 meg recently, I'm in
  2279. a fix to put together a program (by 4/16/91) beyond word counts.  Can anyone
  2280. help?
  2281.  
  2282.  
  2283. Bill Burkey
  2284. Child Guidance Center
  2285. 2525 E 22
  2286. Cleveland, OH  44115
  2287. (216)696-5800 x23
  2288. bitnet <r1325@csuohio>
  2289.  
  2290.    
  2291.  
  2292. From kelvin@kickapoo.cs.iastate.edu  Wed Apr 17 09:36:04 1991
  2293. Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Wed, 17 Apr 91 09:36:04 MST
  2294. Received: from judy.cs.iastate.edu by optima.cs.arizona.edu (4.1/15)
  2295.     id AA24333; Wed, 17 Apr 91 09:36:01 MST
  2296. Received: from kickapoo.cs.iastate.edu.noname by judy.cs.iastate.edu (4.1) id AA15899; Wed, 17 Apr 91 11:35:13 CDT
  2297. Received: by kickapoo.cs.iastate.edu.noname (4.1/SMI-4.1)
  2298.     id AA06833; Wed, 17 Apr 91 11:35:13 CDT
  2299. Date: Wed, 17 Apr 91 11:35:13 CDT
  2300. From: kelvin@kickapoo.cs.iastate.edu (Kelvin Don Nilsen)
  2301. Message-Id: <9104171635.AA06833@kickapoo.cs.iastate.edu.noname>
  2302. To: r1325%CSUOHIO.BITNET%CORNELLC.CCS.CORNELL.EDU@cunyvm.cuny.edu
  2303. Cc: icon-group@cs.arizona.edu
  2304. In-Reply-To: r1325%CSUOHIO.BITNET%CORNELLC.CCS.CORNELL.EDU@cunyvm.cuny.edu's message of 91/04/17 10:57:37 <9104171500.AA19932@optima.cs.arizona.edu>
  2305. Subject: content analysis
  2306.  
  2307.  
  2308. >Date: 91/04/17 10:57:37
  2309. >From: r1325%CSUOHIO.BITNET%CORNELLC.CCS.CORNELL.EDU@cunyvm.cuny.edu
  2310.  
  2311.  
  2312. >APRIL 17, 1991
  2313.  
  2314. >BEING NEW TO ELETRONIC MAIL.....
  2315. >I AM RESENDING THIS MESSAGE BECAUSE I'M UNSURE IF IT INITIALLY REACHED
  2316. >THE ICON-GROUP.  I WOULD APPRECIATE ANY RESPONSE TO AFFIRM PROCEDURES ON
  2317. >THIS END.  THANKS.
  2318.  
  2319. >WE'RE DOING A CONTENT ANALYSIS OF SURVEY DATA THAT REQUIRES MORE
  2320. >than word frequency counts, something more on the level of a qualitative
  2321. >factor analysis.  I am the research associate at the Child Guidance Center of
  2322. >Greater Cleveland, a non-profit 401(c)(3) organization.  Having purchased the
  2323. >MS-DOS/386 version of Icon and the book Icon Programming for Humanists late
  2324. >last year but only being able to upgrade memory beyond 1 meg recently, I'm in
  2325. >a fix to put together a program (by 4/16/91) beyond word counts.  Can anyone
  2326. >help?
  2327.  
  2328.  
  2329. >Bill Burkey
  2330. >Child Guidance Center
  2331. >2525 E 22
  2332. >Cleveland, OH  44115
  2333. >(216)696-5800 x23
  2334. >bitnet <r1325@csuohio>
  2335.  
  2336.  
  2337. i'm not sure i understand what your needs are.  are you looking for an
  2338.  Icon programmer to do volunteer work for you?  are you trying to find 
  2339.  an off-the-shelf package that does "qualitative factor analysis"?  what
  2340.  exactly do you mean by "qualitative factor analysis"?  what is the point
  2341.  you are trying to make about 4/16/91?  is this your deadline?  is this
  2342.  when you want the volunteers to be done?  or is this just the date on
  2343.  which you composed your message (which would be redundant and wrong, since
  2344.  you date the article 4/17/91)?
  2345.  
  2346. perhaps it would be helpful if you could provide a sample survey response,
  2347.  and accompany this with the sort of analysis report that you expect the
  2348.  icon program to provide for you.  
  2349.  
  2350. by the way, your message did reach the icon group.
  2351.  
  2352.  
  2353. Kelvin Nilsen/Dept. of Computer Science/Iowa State University/Ames, IA  50011 
  2354.  (515) 294-2259   kelvin@cs.iastate.edu  uunet!atanasoff!kelvin
  2355.  
  2356.  
  2357. From icon-group-request@arizona.edu  Thu Apr 18 21:13:09 1991
  2358. Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Thu, 18 Apr 91 21:13:09 MST
  2359. Resent-From: icon-group-request@arizona.edu
  2360. Received: from Arizona.edu (Merlin.Telcom.Arizona.EDU) by optima.cs.arizona.edu (4.1/15)
  2361.     id AA08983; Thu, 18 Apr 91 21:13:03 MST
  2362. Received: from ucbvax.Berkeley.EDU by Arizona.edu with PMDF#10282; Thu, 18 Apr
  2363.  1991 21:03 MST
  2364. Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA04514; Thu, 18 Apr 91
  2365.  20:53:55 -0700
  2366. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  2367.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  2368.  usenet@ucbvax.Berkeley.EDU if you have questions)
  2369. Resent-Date: Thu, 18 Apr 1991 21:03 MST
  2370. Date: 18 Apr 91 14:27:01 GMT
  2371. From: hsi!mlfarm!ron@uunet.uu.net (Ronald Florence)
  2372. Subject: cron.icn
  2373. Sender: icon-group-request@arizona.edu
  2374. Resent-To: icon-group@cs.arizona.edu
  2375. To: icon-group@arizona.edu
  2376. Resent-Message-Id: <4952B9C1B6800D32@Arizona.edu>
  2377. Message-Id: <797@mlfarm.com>
  2378. X-Envelope-To: icon-group@CS.Arizona.EDU
  2379. X-Vms-To: icon-group@Arizona.edu
  2380. Organization: Maple Lawn Farm, Stonington, CT
  2381.  
  2382. A friend who takes a mail/news feed from us with an ms-dos system
  2383. wanted to be able to poll when he was on-the-road.  I know next to
  2384. nothing about ms-dos, don't want to learn about things like TSRs, and
  2385. Icon is the only language our systems share.  This was the quick &
  2386. dirty solution.  The busy-loops are dumb (I anticipate flames), but
  2387. Icon tables made this fun.
  2388.  
  2389. I'd urge NOT running this code on a multi-tasking system like Unix,
  2390. unless you're interested in seeing how high your system load can
  2391. reach.
  2392. --
  2393.  
  2394. Ronald Florence            ron@mlfarm.com
  2395.  
  2396.  
  2397. #! /bin/sh
  2398. # This is a shell archive, meaning:
  2399. # 1. Remove everything above the #! /bin/sh line.
  2400. # 2. Save the resulting text in a file.
  2401. # 3. Execute the file with /bin/sh (not csh) to create:
  2402. #    cron.icn
  2403. # This archive created: Thu Apr 18 10:25:34 1991
  2404. # By:    Ronald Florence (Maple Lawn Farm, Stonington, CT)
  2405. export PATH; PATH=/bin:/usr/bin:$PATH
  2406. if test -f 'cron.icn'
  2407. then
  2408.     echo shar: "will not over-write existing file 'cron.icn'"
  2409. else
  2410. cat << \SHAR_EOF > 'cron.icn'
  2411. ############################################################################
  2412. #
  2413. #    Name:    cron.icn
  2414. #
  2415. #    Title:    Cron Daemon
  2416. #
  2417. #    Author:    Ronald Florence (ron@mlfarm.com)
  2418. #
  2419. #    Date:    18 April 1991
  2420. #
  2421. #    Version: 1.0
  2422. #
  2423. ############################################################################
  2424. #
  2425. #  This program provides a crude cron daemon for ms-dos or other
  2426. #  single-tasking systems.  If a scheduled command fails, it is 
  2427. #  retried at a specified interval.
  2428. #  
  2429. #    usage: cron [-r] [-c cmd] [-t tries] [-i interval] 0-23 [0-59]
  2430. #           cron < cron-table [ > cron.log ]
  2431. #  
  2432. #  The command-line usage invokes a single command at a specified time.
  2433. #  The -r option runs the daemon continuously.  Defaults for the command,
  2434. #  interval, and retries can be specified in the code.  The second usage 
  2435. #  reads an ascii table in the following format:
  2436. #  
  2437. #     # hour  minute  interval  retries   command
  2438. #        0      15       5         3      uuio | mail postmaster
  2439. #        1      35       0         0      rnews *.nws
  2440. #        6      30       2         2      make coffee
  2441. #  
  2442. #  Lines beginning with `#' in the table are treated as comments.
  2443. #
  2444. ############################################################################
  2445. #
  2446. #  Link: options
  2447. #  Bugs: This busy-loop should NOT be run on multi-tasking systems.
  2448. #        Commands scheduled at conflicting times may not be invoked.
  2449. #        The cron-table is not compatible with Unix cron tables.
  2450. #
  2451. ############################################################################
  2452.  
  2453. link options
  2454.  
  2455. procedure main(arg)
  2456.  
  2457.   usage := ["usage: cron [-r] [-c cmd] [-t tries] [-i interval] 0-23 [0-59]",
  2458.         "       cron < cron-table"]
  2459.  
  2460.   default_cmd := "uuio"
  2461.   default_interval := 5
  2462.   default_retries := 3
  2463.  
  2464.   cmd := table(0)
  2465.   interval := table(0)
  2466.   retries := table(0)
  2467.  
  2468.   if *arg > 0 then {
  2469.     opts := options(arg, "c:i+t+r")
  2470.     h := integer(arg[1])
  2471.     m := integer(arg[2]) | 0
  2472.     (/h | h < 0 | h > 23 | m < 0 | m > 59 ) & { every write(!usage); exit(-1) }
  2473.     t := h * 3600 + m * 60
  2474.     cmd[t] := \opts["c"] | default_cmd
  2475.     interval[t] := \opts["i"] | default_interval
  2476.     retries[t] := \opts["t"] | default_retries
  2477.   }
  2478.   else every s := !&input do s ? {
  2479.     ="#" & next
  2480.     tmp := []
  2481.     while tab(upto(&digits)) \4 do put(tmp,tab(many(&digits)))
  2482.     t := pop(tmp) * 3600 + pop(tmp) * 60
  2483.     interval[t] := pop(tmp)
  2484.     retries[t] := pop(tmp)
  2485.     cmd[t] := (tab(many(' \t')), tab(0))
  2486.   }
  2487.   
  2488.   write(&errout, "time\tint\tret\tcommand")
  2489.   write(&errout, "-------------------------------")
  2490.   every t := key(cmd) do 
  2491.     write(&errout, right(t/3600, 2, "0"), ":", left((t % 3600)/60, 2, "0"),
  2492.       "\t", interval[t], "\t", retries[t], "\t", cmd[t])
  2493.  
  2494.   while t := now() do (t = key(cmd)) & {
  2495.     try := 0
  2496.     repeat {
  2497.       (system(cmd[t]) = 0) & { 
  2498.     write(cmd[t], " completed ", &dateline)
  2499.     while t = now()
  2500.     break 
  2501.       }
  2502.       write(cmd[t], " FAILED ", &dateline)
  2503.       ((try +:= 1) >= retries[t]) & break
  2504.       repoll := now() + interval[t] * 60
  2505.       while repoll > now()
  2506.     }
  2507.     (*arg = 0) | \opts["r"] | exit(try)
  2508.   }
  2509. end
  2510.  
  2511. procedure now()
  2512.   time := []
  2513.   &clock ? while tab(upto(&digits)) do put(time,tab(many(&digits)))
  2514.   return time[1] * 60 * 60 + time[2] * 60 + time[3]
  2515. end
  2516. SHAR_EOF
  2517. if test 3218 -ne "`wc -c < 'cron.icn'`"
  2518. then
  2519.     echo shar: "error transmitting 'cron.icn'" '(should have been 3218 characters)'
  2520. fi
  2521. fi
  2522. exit 0
  2523. #    End of shell archive
  2524. --
  2525.  
  2526. Ronald Florence            ron@mlfarm.com
  2527.  
  2528. From icon-group-request@arizona.edu  Sun Apr 21 19:53:33 1991
  2529. Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Sun, 21 Apr 91 19:53:33 MST
  2530. Resent-From: icon-group-request@arizona.edu
  2531. Received: from Arizona.edu (Merlin.Telcom.Arizona.EDU) by optima.cs.arizona.edu (4.1/15)
  2532.     id AA17113; Sun, 21 Apr 91 19:53:24 MST
  2533. Received: from ucbvax.Berkeley.EDU by Arizona.edu with PMDF#10282; Sun, 21 Apr
  2534.  1991 19:52 MST
  2535. Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA03934; Sun, 21 Apr 91
  2536.  19:47:42 -0700
  2537. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  2538.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  2539.  usenet@ucbvax.Berkeley.EDU if you have questions)
  2540. Resent-Date: Sun, 21 Apr 1991 19:52 MST
  2541. Date: 21 Apr 91 13:31:23 GMT
  2542. From: eru!hagbard!sunic!mcsun!cernvax!chx400!chx400!hslrswi!naz@bloom-beacon.mit.edu
  2543.  (Norman H. Azadian)
  2544. Subject: Klondike solitaire, v3.01, part 2/6
  2545. Sender: icon-group-request@arizona.edu
  2546. Resent-To: icon-group@cs.arizona.edu
  2547. To: icon-group@arizona.edu
  2548. Resent-Message-Id: <9AEB29664C80079A@Arizona.edu>
  2549. Message-Id: <1942@hslrswi.hasler.ascom.ch>
  2550. X-Envelope-To: icon-group@CS.Arizona.EDU
  2551. X-Vms-To: icon-group@Arizona.edu
  2552. Organization: Hasler AG
  2553.  
  2554.  
  2555. #! /bin/sh
  2556. # This is a shell archive, meaning:
  2557. # 1. Remove everything above the #! /bin/sh line.
  2558. # 2. Save the resulting text in a file.
  2559. # 3. Execute the file with /bin/sh (not csh) to create the files:
  2560. #    klonstr.icn
  2561. #    getchlib.icn
  2562. # This archive created: Sun Apr 21 15:03:15 1991
  2563. # By:    Norman H. Azadian (Hasler AG)
  2564. export PATH; PATH=/bin:$PATH
  2565. echo shar: extracting "'klonstr.icn'" '(5135 characters)'
  2566. if test -f 'klonstr.icn'
  2567. then
  2568.     echo shar: will not over-write existing file "'klonstr.icn'"
  2569. else
  2570. cat << \SHAR_EOF > 'klonstr.icn'
  2571. #klonstr.icn    910309    NHA
  2572. #Routines to implement strategic play for klondike solitaire.
  2573. #For each strategy there is a procedure with the same name.
  2574. #findBest() is the interface to the rest of klondike.
  2575.  
  2576.  
  2577. #    t a k e F i r s t
  2578. # This strategy is the simplest possible, simply taking the first suggestion
  2579. # proffered by suggest().  Equivalent to find1().
  2580. # Note that it is therefore dependent on the exact implementation of suggest().
  2581. # When Thumbing, terminate upon second occurrence of *deckDown = 0.
  2582. procedure takeFirst ()
  2583. local emptySeen, s
  2584.     until (\emptySeen) & (*deckDown = 0)  do  {
  2585.         /emptySeen  :=  (*deckDown = 0)
  2586.         (s := suggest())  &  return (s || "0")        #good move found
  2587.         ((*deckUp + *deckDown) = 0)  &  break        #no cards to thumb through
  2588.         writeInfo (Vbold || "T" || Vnormal || "humb")
  2589.         push (ops, thumb())
  2590.     }
  2591.     fail                                    #nothing left to do
  2592. end                                            #takeFirst
  2593.  
  2594.  
  2595. #    i n t e r a c t i v e
  2596. # For multi-choice positions, allows the user to choose.
  2597. procedure interactive ()
  2598. local suggestions, emptySeen, s, op
  2599.     until (\emptySeen) & (*deckDown = 0)  do  {
  2600.         /emptySeen  :=  (*deckDown = 0)
  2601.         suggestions := []                    #generate a new list of suggestions
  2602.         every put (suggestions, suggest())
  2603.         (1 = *suggestions)  &  (return (suggestions[1] || "0"))    #one possibility
  2604.         if (1 < *suggestions)  then  {                    #multiple -- user picks
  2605.             outputAt (lineCount, 40, VclearEOL, Vreverse)
  2606.             every s := !suggestions  do  writes (s[2:0], " ")
  2607.             writeInfo (Vblink || "choose a move")
  2608.             until any(cset("123456789abc"[1+:*suggestions]), (s := getch()))  do
  2609.                 complain()
  2610.             op := suggestions["16r" || s]
  2611.             outputAt (lineCount, 40, VclearEOL, Vnormal)
  2612.             every s := !suggestions  do
  2613.                 if s == op  then
  2614.                     output (Vreverse, op[2:0], Vnormal, " ")
  2615.                 else
  2616.                     writes (s[2:0], " ")
  2617.             return (op || "0")
  2618.         }
  2619.         # no useful moves found -- thumb
  2620.         ((*deckUp + *deckDown) = 0)  &  break        #no cards to thumb through
  2621.         writeInfo (Vbold || "T" || Vnormal || "humb")
  2622.         push (ops, thumb())
  2623.     }
  2624.     fail                                    #nothing left to do
  2625. end                                            #interactive
  2626.  
  2627.  
  2628. #    d e c k F i r s t
  2629. # The idea here is that, if possible, nothing will get done in this
  2630. # pass through the deck until a card has been taken from the deck.
  2631. # Otherwise, the strategy is simply takeFirst.
  2632. # We run with automaticAce disabled simply so we can know when
  2633. # we take one from the deck.
  2634. # Since there is no way to know that we are starting a new game, we cannot
  2635. # guarantee that the flags are correct in the event of user intervention.
  2636. procedure deckFirst ()
  2637. local s
  2638. static taken, modified
  2639. initial    {
  2640.     taken := &null                            #assume nothing taken from deck yet
  2641.     modified := &null                        #nothing done yet on this pass
  2642. }
  2643.     automaticAce := &null
  2644.     repeat {
  2645.         every s := suggest()  do
  2646.             if (\taken) | (s[2] == "D")  then  {
  2647.                 modified := taken := 1        #[sic]
  2648.                 return (s || "0")
  2649.             }
  2650.         ((*deckUp + *deckDown) = 0)  &  break        #no cards to thumb through
  2651.         writeInfo (Vbold || "T" || Vnormal || "humb")
  2652.         push (ops, thumb())
  2653.         if 0 = *deckDown  then                #end of a pass through the deck
  2654.             if \modified  then
  2655.                 modified := taken := &null    #normal case -- reset flags
  2656.             else
  2657.                 if \taken then
  2658.                     break                    #nothing left to do  [sic]
  2659.                 else
  2660.                     taken := 1                #allow other moves for next pass
  2661.     }
  2662.     modified := taken := null                #reset flags for next game
  2663.     fail                                    #nothing useful left to do
  2664. end                                            #deckFirst
  2665.  
  2666.  
  2667. #    f i n d B e s t
  2668. # If called with a parameter, the parameter is taken to be the name of a play
  2669. # strategy and is saved for future use by findBest() after sanity checking.
  2670. # An empty string is taken to be a request to use the default strategy.
  2671. # Note that, at least for now, the name of the strategy procedure is
  2672. # necessarily identical to the name of the strategy.
  2673. #
  2674. # If called without any parameter, returns with the move selected by the
  2675. # pre-determined strategy routine.
  2676. # Largely for hysterical raisons, strategy routines are expected to do their
  2677. # own Thumbing until either they find a good move to return, or they decide
  2678. # there is no point to continuing and so return failure.
  2679. # Strategy routines are expected to keep the user informed of any moves
  2680. # (e.g. Thumbing) that they do before returning.
  2681. #
  2682. # Note that the strategy procedure may decide it is necessary to
  2683. # unilaterally disable the automaticAce option during its execution.
  2684. # Therefore automaticAce is saved here and restored before returning.
  2685. # However, if the strategy procedure leaves automaticAce intact, then
  2686. # any Ace uncovered whilst thumbing will be automaticall moved and the
  2687. # search will continue.  It does not count as a move.
  2688. procedure findBest (s)
  2689. static strategies, strategyProc
  2690. local automaticAceSave
  2691. initial {
  2692.     strategies := set ( ["takeFirst", "interactive", "deckFirst"] )
  2693. }
  2694.     if \s  then  {                            #remember strategy
  2695.         (s == "")  &  (s := "takeFirst")    #default strategy
  2696.         (s == !strategies)  |  stop ("klondike: unknown strategy  ", s)
  2697.         strategyProc := (strategy := s)        #remember for future use
  2698.     } else {                                #execute strategy
  2699.         automaticAceSave := automaticAce
  2700.         s := strategyProc()
  2701.         automaticAce := automaticAceSave
  2702.         (s === &null)  &  fail
  2703.     }
  2704.     return s
  2705. end                                            #findBest
  2706. SHAR_EOF
  2707. if test 5135 -ne "`wc -c < 'klonstr.icn'`"
  2708. then
  2709.     echo shar: error transmitting "'klonstr.icn'" '(should have been 5135 characters)'
  2710. fi
  2711. fi # end of overwriting check
  2712. echo shar: extracting "'getchlib.icn'" '(9166 characters)'
  2713. if test -f 'getchlib.icn'
  2714. then
  2715.     echo shar: will not over-write existing file "'getchlib.icn'"
  2716. else
  2717. cat << \SHAR_EOF > 'getchlib.icn'
  2718. ############################################################################
  2719. #
  2720. #    Name:     getchlib.icn
  2721. #
  2722. #    Title:     Implementation of getch() for Unix (and more)
  2723. #
  2724. #    Author:     Richard L. Goerwitz
  2725. #
  2726. #    Version: 1.13
  2727. #
  2728. ############################################################################
  2729. #
  2730. #  I place this and future versions of getchlib in the public domain - RLG
  2731. #
  2732. ############################################################################
  2733. #
  2734. #  Implementing getch() is a much, much more complex affair under Unix
  2735. #  than it is under, say, MS-DOS.  This library represents one,
  2736. #  solution to the problem - one which can be run as a library, and
  2737. #  need not be compiled into the run-time system.  Note that it will
  2738. #  not work on all systems.  In particular, certain Suns (with a
  2739. #  screwy stty command) and the NeXT 1.0 OS (lacking the -g option for
  2740. #  stty) do not run getchlib properly.  See the bugs section below for
  2741. #  workarounds.
  2742. #
  2743. #  Four basic utilities are included here:
  2744. #
  2745. #    getch()        - waits until a keystroke is available &
  2746. #        returns it without displaying it on the screen
  2747. #    getche()    - same as getch() only with echo
  2748. #    getse(s)    - like getche() only for strings.  The optional
  2749. #        argument s gives getse() something to start with.  Use this
  2750. #           if, say, you want to read single characters in cbreak mode,
  2751. #           but get more input if the character read is the first part
  2752. #           of a longer command.  If the user backspaces over everything
  2753. #           that has been input, getse() fails.  Returns on \r or \n.
  2754. #    reset_tty()    - absolutely vital routine for putting the cur-
  2755. #           rent tty line back into cooked mode; call it before exiting
  2756. #           or you will find yourself with a locked-up terminal; use it
  2757. #           also if you must temporarily restore the terminal to cooked
  2758. #           mode
  2759. #
  2760. #  Note that getse() *must* be used in place of read(&input) if you
  2761. #  are planning on using getch() or getche(), since read(&input)
  2762. #  assumes a tty with "sane" settings.
  2763. #
  2764. #  Warning:  The routines below do not do any sophisticated output
  2765. #  processing.  As noted above, they also put your tty line in raw
  2766. #  mode.  I know, I know:  "Raw is overkill - use cbreak."  But in
  2767. #  a world that includes SysV, one must pick a lowest common denomi-
  2768. #  nator.  And no, icanon != cbreak.
  2769. #
  2770. #  BUGS: These routines will not work on systems that do not imple-
  2771. #  ment the -g option for the stty command.  The NeXT workstation is
  2772. #  an example of such a system.  Tisk, tisk.  If you have a SunOS stty
  2773. #  that is too clever (read stupid) to write its output to a pipe,
  2774. #  then substitute /usr/5bin/stty (or whatever your system calls the
  2775. #  System V stty command) for /bin/stty in this file.  If you have no
  2776. #  SysV stty command online, then you can try replacing every instance
  2777. #  of "stty -g 2>&1" below with "stty -g 2>&1 1> /dev/tty" or
  2778. #  something similar.
  2779. #
  2780. ############################################################################
  2781. #
  2782. #  Example program:
  2783. #
  2784. #      The following program is a simple file viewer.  To run, it
  2785. #  needs to be linked with itlib.icn, iscreen.icn, and this file
  2786. #  (getchlib.icn).
  2787. #
  2788. #  procedure main(a)
  2789. #
  2790. #      # Simple pager/file searcher for Unix systems.  Must be linked
  2791. #      # with itlib.icn and iscreen.icn.
  2792. #  
  2793. #      local intext, c, s
  2794. #  
  2795. #      # Open input file
  2796. #      intext := open(a[1],"r") | {
  2797. #      write(&errout,"Can't open input file.")
  2798. #      exit(1)
  2799. #      }
  2800. #  
  2801. #      # Initialize screen
  2802. #      clear()
  2803. #      print_screen(intext) | exit(0)
  2804. #  
  2805. #      # Prompt & read input
  2806. #      repeat {
  2807. #      iputs(igoto(getval("cm"), 1, getval("li")))
  2808. #      emphasize()
  2809. #      writes("More? (y/n or /search):")
  2810. #      write_ce(" ")
  2811. #      case c := getche() of {
  2812. #          "y" : print_screen(intext) | break
  2813. #          " " : print_screen(intext) | break
  2814. #          "n" : break
  2815. #          "q" : break
  2816. #          "/" : {
  2817. #          iputs(igoto(getval("cm"), 1, getval("li")))
  2818. #          emphasize()
  2819. #          writes("Enter search string:")
  2820. #          write_ce(" ")
  2821. #          pattern := GetMoreInput()
  2822. #          /pattern | "" == pattern & next
  2823. #          # For more complex patterns, use findre() (IPL findre.icn)
  2824. #          if not find(pattern, s := !intext) then {
  2825. #              iputs(igoto(getval("cm"), 1, getval("li")))
  2826. #              emphasize()
  2827. #              write_ce("String not found.")
  2828. #              break
  2829. #          }
  2830. #          else print_screen(intext, s) | break
  2831. #          }
  2832. #      }
  2833. #      }
  2834. #  
  2835. #      reset_tty()
  2836. #      write()
  2837. #      exit(0)
  2838. #
  2839. #  end
  2840. #  
  2841. #  procedure GetMoreInput(c)
  2842. #  
  2843. #      local input_string
  2844. #      static BS
  2845. #      initial BS := getval("bc") | "\b"
  2846. #  
  2847. #      /c := ""
  2848. #      if any('\n\r', chr := getch())
  2849. #      then return c
  2850. #      else {
  2851. #      chr == BS & fail
  2852. #      writes(chr)
  2853. #      input_string := getse(c || chr) | fail
  2854. #      if any('\n\r', input_string)
  2855. #      then fail else (return input_string)
  2856. #      }
  2857. #  
  2858. #  end
  2859. #  
  2860. #  procedure print_screen(f,s)
  2861. #  
  2862. #      if /s then
  2863. #      begin := 1
  2864. #      # Print top line, if one is supplied
  2865. #      else {
  2866. #      iputs(igoto(getval("cm"), 1, 1))
  2867. #      write_ce(s ? tab(getval("co") | 0))
  2868. #      begin := 2
  2869. #      }
  2870. #  
  2871. #      # Fill the screen with lines from f; clear and fail on EOF.
  2872. #      every i := begin to getval("li") - 1 do {
  2873. #      iputs(igoto(getval("cm"), 1, i))
  2874. #      if not write_ce(read(f) ? tab(getval("co") | 0)) then {
  2875. #          # Clear remaining lines on the screen.
  2876. #          every j := i to getval("li") do {
  2877. #          iputs(igoto(getval("cm"), 1, j))
  2878. #          iputs(getval("ce"))
  2879. #          }
  2880. #          iputs(igoto(getval("cm"), 1, i))
  2881. #          fail
  2882. #      }
  2883. #      }
  2884. #      return
  2885. #  
  2886. #  end
  2887. #  
  2888. #  procedure write_ce(s)
  2889. #  
  2890. #      normal()
  2891. #      iputs(getval("ce")) |
  2892. #      writes(repl(" ",getval("co") - *s))
  2893. #      writes(s)
  2894. #      return
  2895. #
  2896. #  end
  2897. #
  2898. ############################################################################
  2899. #
  2900. #  Requires: UNIX
  2901. #
  2902. #  Links: itlib.icn
  2903. #
  2904. ############################################################################
  2905.  
  2906.  
  2907. global c_cc, current_mode        # what mode are we in, raw or cooked?
  2908. record termio_struct(vintr,vquit,verase,vkill)
  2909.  
  2910. procedure getse(s)
  2911.  
  2912.     # getse() - like getche, only for strings instead of single chars
  2913.     #
  2914.     # This procedure *must* be used instead of read(&input) if getch
  2915.     # and/or getche are to be used, since these put the current tty
  2916.     # line in raw mode.
  2917.     #
  2918.     # Note that the buffer can be initialized by calling getse with a
  2919.     # string argument.  Note also that, as getse now stands, it will
  2920.     # fail if the user backspaces over everything that has been input.
  2921.     # This change does not coincide with its behavior in previous ver-
  2922.     # sions.  It can be changed by commenting out the line "if *s < 1
  2923.     # then fail" below, and uncommenting the line "if *s < 1 then
  2924.     # next."
  2925.  
  2926.     local chr
  2927.     static BS
  2928.     initial {
  2929.     BS := getval("bc") | "\b"
  2930.     if not getval("bs") then {
  2931.         reset_tty()
  2932.         stop("Your terminal can't backspace!")
  2933.     }
  2934.     }
  2935.  
  2936.     /s := ""
  2937.     repeat {
  2938.     case chr := getch() | fail of {
  2939.         "\r"|"\n"    : return s
  2940.         c_cc.vkill   : {
  2941.         if *s < 1 then next
  2942.         every 1 to *s do writes(BS)
  2943.         s := ""
  2944.         }
  2945.         c_cc.verase   : {
  2946.         # if *s < 1 then next
  2947.         writes(BS) & s := s[1:-1]
  2948.         if *s < 1 then fail
  2949.         }
  2950.         default: writes(chr) & s ||:= chr
  2951.     }
  2952.     }
  2953.  
  2954. end
  2955.  
  2956.  
  2957.  
  2958. procedure setup_tty()
  2959.     change_tty_mode("setup")
  2960.     return
  2961. end
  2962.  
  2963.  
  2964.  
  2965. procedure reset_tty()
  2966.  
  2967.     # Reset (global) mode switch to &null to show we're in cooked mode.
  2968.     current_mode := &null
  2969.     change_tty_mode("reset")
  2970.     return
  2971.  
  2972. end
  2973.  
  2974.  
  2975.  
  2976. procedure getch()
  2977.  
  2978.     local chr
  2979.  
  2980.     # If the global variable current_mode is null, then we have to
  2981.     # reset the terminal to raw mode.
  2982.     if /current_mode := 1 then
  2983.     setup_tty()
  2984.  
  2985.     chr := reads(&input)
  2986.     case chr of {
  2987.     c_cc.vintr : reset_tty() & stop()  # shouldn't hard code this in
  2988.     c_cc.vquit  : reset_tty() & stop()
  2989.     default : return chr
  2990.     }
  2991.  
  2992. end
  2993.  
  2994.  
  2995.  
  2996. procedure getche()
  2997.  
  2998.     local chr
  2999.  
  3000.     # If the global variable current_mode is null, then we have to
  3001.     # reset the terminal to raw mode.
  3002.     if /current_mode := 1 then
  3003.     setup_tty()
  3004.  
  3005.     chr := reads(&input)
  3006.     case chr of {
  3007.     c_cc.vintr  : reset_tty() & stop()
  3008.     c_cc.vquit  : reset_tty() & stop()
  3009.     default : writes(chr) & return chr
  3010.     }
  3011.  
  3012. end
  3013.  
  3014.  
  3015.  
  3016. procedure change_tty_mode(switch)
  3017.  
  3018.     # global c_cc   (global record containing values for kill, etc. chars)
  3019.     local get_term_params, i
  3020.     static reset_string
  3021.     initial {
  3022.     getval("li")    # check to be sure itlib is set up
  3023.     find("unix",map(&features)) |
  3024.         stop("change_tty_mode:  These routines must run under Unix.")
  3025.     get_term_params := open("/bin/stty -g 2>&1","pr")
  3026.     reset_string := !get_term_params
  3027.     close(get_term_params)
  3028.     reset_string ? {
  3029.         # tab upto the fifth field of the output of the stty -g cmd
  3030.         # fields of stty -g seem to be the same as those of the
  3031.         # termio struct, except that the c_line field is missing
  3032.         every 1 to 4 do tab(find(":")+1)
  3033.         c_cc := termio_struct("\x03","\x1C","\x08","\x15")
  3034.         every i := 1 to 3 do {
  3035.         c_cc[i] := char(integer("16r"||tab(find(":"))))
  3036.         move(1)
  3037.         }
  3038.         c_cc[i+1] := char(integer("16r"||tab(0)))
  3039.     }
  3040.     }
  3041.  
  3042.     if switch == "setup"
  3043.     then system("/bin/stty -echo raw")
  3044.     else system("/bin/stty "||reset_string)
  3045.  
  3046.     return
  3047.  
  3048. end
  3049. SHAR_EOF
  3050. if test 9166 -ne "`wc -c < 'getchlib.icn'`"
  3051. then
  3052.     echo shar: error transmitting "'getchlib.icn'" '(should have been 9166 characters)'
  3053. fi
  3054. fi # end of overwriting check
  3055. #    End of shell archive
  3056. exit 0
  3057. -- 
  3058. PAPER:  Norman Azadian; Ascom AG; Belpstrasse 23; 3000 Berne 14; Switzerland
  3059. INTERNET:  naz%hslrswi.uucp@uunet.uu.net
  3060. UUCP:   ...{uunet,ukc,mcvax,...}!chx400!hslrswi!naz
  3061. VOICE:  +41 31 63 2178            BITNET: naz%hslrswi.UUCP@cernvax.BITNET
  3062.  
  3063. From icon-group-request@arizona.edu  Sun Apr 21 19:53:56 1991
  3064. Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Sun, 21 Apr 91 19:53:56 MST
  3065. Resent-From: icon-group-request@arizona.edu
  3066. Received: from Arizona.edu (Merlin.Telcom.Arizona.EDU) by optima.cs.arizona.edu (4.1/15)
  3067.     id AA17123; Sun, 21 Apr 91 19:53:51 MST
  3068. Received: from ucbvax.Berkeley.EDU by Arizona.edu with PMDF#10282; Sun, 21 Apr
  3069.  1991 19:52 MST
  3070. Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA03962; Sun, 21 Apr 91
  3071.  19:48:29 -0700
  3072. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  3073.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  3074.  usenet@ucbvax.Berkeley.EDU if you have questions)
  3075. Resent-Date: Sun, 21 Apr 1991 19:53 MST
  3076. Date: 21 Apr 91 14:08:13 GMT
  3077. From: eru!hagbard!sunic!mcsun!cernvax!chx400!chx400!hslrswi!naz@bloom-beacon.mit.edu
  3078.  (Norman H. Azadian)
  3079. Subject: Klondike solitaire, v3.01, part 5/6
  3080. Sender: icon-group-request@arizona.edu
  3081. Resent-To: icon-group@cs.arizona.edu
  3082. To: icon-group@arizona.edu
  3083. Resent-Message-Id: <9AF6F9FF2C800E1B@Arizona.edu>
  3084. Message-Id: <1945@hslrswi.hasler.ascom.ch>
  3085. X-Envelope-To: icon-group@CS.Arizona.EDU
  3086. X-Vms-To: icon-group@Arizona.edu
  3087. Organization: Hasler AG
  3088.  
  3089.  
  3090. #! /bin/sh
  3091. # This is a shell archive, meaning:
  3092. # 1. Remove everything above the #! /bin/sh line.
  3093. # 2. Save the resulting text in a file.
  3094. # 3. Execute the file with /bin/sh (not csh) to create the files:
  3095. #    klonsub.icn
  3096. # This archive created: Sun Apr 21 15:04:30 1991
  3097. # By:    Norman H. Azadian (Hasler AG)
  3098. export PATH; PATH=/bin:$PATH
  3099. echo shar: extracting "'klonsub.icn'" '(14804 characters)'
  3100. if test -f 'klonsub.icn'
  3101. then
  3102.     echo shar: will not over-write existing file "'klonsub.icn'"
  3103. else
  3104. cat << \SHAR_EOF > 'klonsub.icn'
  3105. #klonsub.icn    901029    NHA
  3106. #some subroutines for Klondike
  3107.  
  3108.  
  3109.  
  3110. #    d i e I f
  3111. # If the first argument succeeds, then write out the remaining args & die.
  3112. # Note that the remaining arguments must succeed.
  3113. procedure dieIf (failed, writeArgs[])
  3114.     writeCursor (1, 20)
  3115.     every writes (&output, !writeArgs)
  3116.     write (&output)
  3117.     display ()
  3118.     every writes (&errout, !writeArgs)
  3119.     write (&errout)
  3120.     runerr (500)
  3121. end                                            #dieIf
  3122.  
  3123.  
  3124. #    f i t O n S t a c k
  3125. # Given a card and a stack number, fail unless card can be added to the stack.
  3126. # Note that we disallow putting an Ace on a stack, period.  This prevents
  3127. # ever building a stack with 13 cards, which we can't display in 25 rows.
  3128. procedure fitOnStack (c, n)
  3129.     if *stackUp[n] = 0  then  {
  3130.         dieIf (*stackDown[n] ~= 0, "Up empty, Down not")
  3131.         (c.rank = 13)  |  fail                #only a king can go to empty stack
  3132.     } else {
  3133.         (c.rank = (stackUp[n][-1].rank - 1))  |  fail            #top wrong rank
  3134.         (color[c.suit] == color[stackUp[n][-1].suit])  &  fail    #top same color
  3135.         (c.rank = 1)  &  fail                                    #no aces on stak
  3136.         dieIf (*stackUp[n] >= 12, "stack too big")
  3137.     }
  3138.     return                                    #success
  3139. end                                            #fitOnStack
  3140.  
  3141.  
  3142. #    s u g g e s t
  3143. # Suggest a(nother) possible (useful) move in this situation.
  3144. # Suspends with an operation string for the suggested move.
  3145. # Fails if there is none and you should Thumb.
  3146. # This internal routine is currently the heart and soul of all program play.
  3147. procedure suggest ()
  3148. local i, j, k
  3149.     # look at deckUp to see if the top card fits on an ace pile
  3150.     (deckUp[1].rank = (pile[deckUp[1].suit] + 1))  &  suspend "MDA"
  3151.  
  3152.     # look at deckUp to see if the top card fits on a stack
  3153.     every (fitOnStack (deckUp[1], i := 1 to 7))  do  suspend "MD" || string(i)
  3154.  
  3155.     # look at each stack to see if top card can be put on an ace pile
  3156.     every (stackUp[i := 1 to 7][-1].rank  =  pile[stackUp[i][-1].suit] + 1)  do
  3157.         suspend "M" || string(i) || "A"
  3158.  
  3159.     # look at each stack to see if one can be (usefully) moved to another
  3160.     every fitOnStack (stackUp[i := 7 to 1 by -1][1], j := 1 to 7)  do
  3161.         if 0 < *stackDown[i]  then
  3162.             suspend  "M" || string(i) || string(j)
  3163.         else
  3164.             # possibility, but since there are no cards hidden under
  3165.             # this pile, we reject it UNLESS there are no empty slots
  3166.             # AND at least one of the following is true:
  3167.             #    (1) deckUp[1].rank = 13
  3168.             #    (2) there is a king with cards hidden beneath it
  3169.             if not (*stackUp[1 to 7] = 0)  then
  3170.                 if deckUp[1].rank = 13  then
  3171.                     suspend  "M" || string(i) || string(j)        #(1)
  3172.                 else
  3173.                     # only suspend once, no matter how many kings there are
  3174.                     if ( (stackUp[k := 1 to 7][1].rank = 13)  &
  3175.                          (0 < *stackDown[k]) )  then
  3176.                         suspend  "M" || string(i) || string(j)    #(2)
  3177.  
  3178.     # punt (Thumb)
  3179.     fail
  3180. end                                            #suggest
  3181.  
  3182.  
  3183. #    c h e c k 4 a c e
  3184. # Only has an effect when global automaticAce is set!
  3185. # Given a stack number, check for an ace as the top of stackUp[n].
  3186. # If present, move it over to it's ace pile, turn over the next card
  3187. # from stackDown, and check again.
  3188. # Must not be more than one up card in stack.
  3189. # Returns a string of the operations performed.
  3190. procedure check4ace (n)
  3191. local c, op
  3192.     op := ""
  3193.     if \automaticAce  then  {
  3194.         dieIf (1 < *stackUp[n])
  3195.         while stackUp[n][1].rank = 1  do  {
  3196.             op ||:= (c := pop (stackUp[n])).suit    #remove ace from the stack
  3197.             writeStack (n)
  3198.             pile[c.suit] := 1                #move to ace pile
  3199.             writePile (c.suit)
  3200.             click ()
  3201.             if push (stackUp[n], get(stackDown[n])) then {    #turn over card
  3202.                 writeStack (n)
  3203.                 click ()
  3204.             }
  3205.         }
  3206.     }
  3207.     return op
  3208. end                                            #check4ace
  3209.  
  3210.  
  3211. #    m o v e S t a c k
  3212. # Move a stack to another stack, no questions asked.
  3213. # Updates video and audio.
  3214. # Returns any automatic ace operations that were done as a consequence.
  3215. ##It would be nice to do this in a visually and audibly more satisfying way
  3216. procedure moveStack (src, dst)
  3217.     # move up cards from src stack to dst stack
  3218.     while put (stackUp[dst], get(stackUp[src]))
  3219.     writeStack (src)
  3220.     writeStack (dst)
  3221.     click ()
  3222.     # turn over new card (if any) on src stack
  3223.     put (stackUp[src], get(stackDown[src]))     |  return ""    #empty stackDown
  3224.     writeStack (src)
  3225.     click ()
  3226.     return check4ace (src)
  3227. end                                            #moveStack
  3228.  
  3229.  
  3230. #    m o v e 1
  3231. # This is the internal move, taking an operation string.  No Thumbs allowed.
  3232. # Upon success it returns the (possibly modified) operation string.
  3233. # There's some redundant code here, but it makes the action look better
  3234. # (at least on slow machines).
  3235. procedure move1 (op)
  3236. local src, dst, c
  3237.     dieIf ((op[1] ~== "M"),  op)
  3238.     src := op[2]
  3239.     dst := op[3]
  3240.     if src == "D"  then  {                    # Deck -> somewhere
  3241.         c := deckUp[1]
  3242.         if dst == "A"  then  {                # Deck -> Ace
  3243.             if c.rank = (pile[c.suit] + 1)  then  {
  3244.                 op[4] := c.suit                # Deck -> Ace:  fits - do it
  3245.                 pop (deckUp)
  3246.                 writeDeckUp ()
  3247.                 pile[c.suit] +:= 1
  3248.                 writePile (c.suit)
  3249.             } else {
  3250.                 fail                        # Deck -> Ace:  doesn't fit
  3251.             }
  3252.         } else  {                            # Deck -> stack
  3253.             if fitOnStack (c, dst)  then {
  3254.                 pop (deckUp)                # Deck -> stack:  fits - do it
  3255.                 writeDeckUp ()
  3256.                 put (stackUp[dst], c)
  3257.                 writeStack (dst)
  3258.             } else {
  3259.                 fail                        # Deck -> stack: doesn't fit
  3260.             }
  3261.         }
  3262.         click ()
  3263.         if \automaticAce  then  {
  3264.             while deckUp[1].rank = 1  do  {
  3265.                 op ||:= (c := pop(deckUp)).suit
  3266.                 writeDeckUp ()
  3267.                 pile[c.suit] := 1
  3268.                 writePile (c.suit)
  3269.                 click ()
  3270.             }
  3271.         }
  3272.     } else {                                # stack -> somewhere
  3273.         if dst == "A"  then  {                # stack -> Ace
  3274.             c := stackUp[src][-1]            #copy of card on top of stack
  3275.             if c.rank = (pile[c.suit] + 1)  then  {
  3276.                 op[4] := c.suit                # stack -> Ace:  fits - do it
  3277.                 pull (stackUp[src])
  3278.                 writeStack (src)
  3279.                 pile[c.suit] +:= 1
  3280.                 writePile (c.suit)
  3281.                 click ()
  3282.                 if 0 = *stackUp[src]  then  {
  3283.                     op[4] +:= 4                #mark this case for undo()
  3284.                     put (stackUp[src], get(stackDown[src]))    #turn over a card
  3285.                     writeStack (src)
  3286.                     if 0 < *stackUp[src]  then  {
  3287.                         click ()
  3288.                         op ||:= check4ace (src)
  3289.                     }
  3290.                 }
  3291.             } else {
  3292.                 fail                        # stack -> Ace:  doesn't fit
  3293.             }
  3294.         } else {                            # stack -> stack
  3295.             if fitOnStack (stackUp[src][1], dst)  then  {
  3296.                                             # stack -> stack:  fits - do it
  3297.                 op[4] := "123456789abcdef"[*stackUp[src]]
  3298.                 op ||:= moveStack (src, dst)
  3299.             } else {
  3300.                 fail                        # stack -> stack:  doesn't fit
  3301.             }
  3302.         }
  3303.     }
  3304.     return  op                                #success
  3305. end                                            #move1
  3306.  
  3307.  
  3308. #    t h u m b
  3309. # Move to next spot in deckDown
  3310. # Returns the operation performed (usually just "T3"), or fail if none possible.
  3311. procedure thumb ()
  3312. local c, op
  3313.     ((*deckDown) = (*deckUp) = 0)  &  (complain(), fail)    #no cards left
  3314.     if 0 = *deckDown  then  {                #no cards left in hand
  3315.         while push (deckDown, pop(deckUp))    #pick up (and turn) the face-up deck
  3316.         writeDeckUp ()                        #show the (empty) deck on table
  3317.         writeDeckDown ()                    #show the face-down deck [in hand]
  3318.         click ()
  3319.     }
  3320.     op := ( "T"  ||  ((*deckDown >= 3) | *deckDown) )
  3321.     every | push (deckUp, pop(deckDown)) \ 3
  3322.     writeDeckDown ()
  3323.     writeDeckUp ()
  3324.     click ()
  3325.     if \automaticAce  then  {
  3326.         while deckUp[1].rank = 1  do  {
  3327.             op ||:= (c := pop (deckUp)).suit
  3328.             writeDeckUp ()
  3329.             pile[c.suit] := 1
  3330.             writePile (c.suit)
  3331.             click ()
  3332.         }
  3333.     }
  3334.     return op
  3335. end                                            #thumb
  3336.  
  3337.  
  3338. #    u n d o
  3339. # Backup one move, including any automatic ace moves
  3340. # This is the internal routine.
  3341. procedure undo ()
  3342. local op, suit
  3343.     if op := pop (ops)  then  {
  3344.         writeInfo (expandOp(op))
  3345.         # op looks like:  Msdixxx
  3346.         # where x is an [optional] number 1..4 of an ace pile
  3347.         # and s is either a stack number or "D"
  3348.         # and d is either "A" or a number 1..7 of a stack
  3349.         # and i is an extra piece of info which is only occasionally used
  3350.         case op[1]  of   {
  3351.         "M"        :    {
  3352.                     dieIf ((*op < 4) | ((/automaticAce) & (4 < *op)), op)
  3353.                     if op[2] == "D"  then  {
  3354.                         #Move cards from Ace piles to deck, starting at end
  3355.                         while 4 < *op  do  {
  3356.                             suit := op[-1]
  3357.                             pile[suit] := 0
  3358.                             writePile (suit)
  3359.                             push (deckUp, card(suit,1))
  3360.                             writeDeckUp ()
  3361.                             click ()
  3362.                             op[-1] := ""
  3363.                         }
  3364.                         if op[3] == "A"  then  {
  3365.                             # unMove Deck to Ace op[4]
  3366.                             suit := op[4]
  3367.                             push (deckUp, card(suit,pile[suit]))
  3368.                             pile[suit] -:= 1
  3369.                             writePile (suit)
  3370.                         } else {
  3371.                             # unMove Deck to stack op[3]
  3372.                             push (deckUp, pull(stackUp[op[3]]))
  3373.                             writeStack (op[3])
  3374.                         }
  3375.                         writeDeckUp ()
  3376.                     } else {
  3377.                         #Move cards from Ace piles to stack, starting at end
  3378.                         while 4 < *op  do  {
  3379.                             suit := op[-1]
  3380.                             pile[suit] := 0
  3381.                             writePile (suit)
  3382.                             dieIf (1 < *stackUp[op[2]], op)
  3383.                             push (stackDown[op[2]], pull(stackUp[op[2]]))
  3384.                             push (stackUp[op[2]], card(suit,1))
  3385.                             writeStack (op[2])
  3386.                             click ()
  3387.                             op[-1] := ""
  3388.                         }
  3389.                         if op[3] == "A"  then  {
  3390.                             # unMove stack op[2] to Ace pile op[4]
  3391.                             if 4 < (suit := op[4])  then  {
  3392.                                 suit -:= 4        #ace pile card was last on stack
  3393.                                 dieIf (1 < *stackUp[op[2]], op)
  3394.                                 push (stackDown[op[2]], pull(stackUp[op[2]]))
  3395.                             }
  3396.                             put (stackUp[op[2]], card(suit,pile[suit]))
  3397.                             pile[suit] -:= 1
  3398.                             writePile (suit)
  3399.                             writeStack (op[2])
  3400.                         } else {
  3401.                             # unMove top op[4] cards on stack op[2]
  3402.                             # to stack op[3]
  3403.                             dieIf (1 < *stackUp[op[2]], op)
  3404.                             push (stackDown[op[2]], pull(stackUp[op[2]]))
  3405.                             every 1 to ("16r" || op[4])  do
  3406.                                 push (stackUp[op[2]], pull(stackUp[op[3]]))
  3407.                             writeStack (op[3])
  3408.                             writeStack (-op[2])
  3409.                         }
  3410.                     }
  3411.                 }
  3412.         "T"        :    {
  3413.                     dieIf (((/automaticAce) & (*op ~= 2)), op)
  3414.                     ## op looks like:  Tcxx
  3415.                     ## where c is the number of cards thumbed (usually 3)
  3416.                     ## and x is an optional number 1..4 of an ace pile
  3417.                     ## There can be 0,1,2, or 3 of these x's.
  3418.                     # move cards from Ace piles to deck, starting at end
  3419.                     while 2 < *op  do  {
  3420.                         suit := op[-1]
  3421.                         pile[suit] := 0
  3422.                         writePile (suit)
  3423.                         push (deckUp, card(suit,1))
  3424.                         writeDeckUp ()
  3425.                         click ()
  3426.                         op[-1] := ""
  3427.                     }
  3428.                     # then undo the Thumb operation itself
  3429.                     dieIf (0 = *deckUp)
  3430.                     every 1 to op[2]  do
  3431.                         push (deckDown, pop(deckUp))
  3432.                     if 0 = *deckUp  then
  3433.                         while push (deckUp, pop(deckDown))
  3434.                     writeDeckUp ()
  3435.                     writeDeckDown ()
  3436.                 }
  3437.         default    :    runerr (500, op)
  3438.         }
  3439.         click ()
  3440.     } else {
  3441.         ## Admittedly this is a bit of a kluge, but better than nothing ?
  3442.         (0 = *deckDown)  &  while push (deckDown, pop(deckUp))
  3443.         writeDeckUp ()
  3444.         writeDeckDown ()
  3445.         complain ("At Beginning")
  3446.     }
  3447.     return
  3448. end                                            #undo
  3449.  
  3450.  
  3451. #    s h o w L i s t
  3452. # Display a list of cards at the current cursor position.
  3453. # Intended for debugging only .
  3454. procedure showList (lst)
  3455. local c
  3456.     every c := !lst  do
  3457.         output (color[c.suit], rankID[c.rank], suitID[c.suit], Vnormal, " ")
  3458.     return
  3459. end                                            #showList
  3460.  
  3461.  
  3462. #    c a r d 2 s t r
  3463. # Given a list of card records, returns a string representation.
  3464. # Even an empty list results in a non-zero string length.
  3465. procedure card2str (lst)
  3466. local c, s
  3467.     s := "$"
  3468.     every c := !lst  do
  3469.         s ||:= string(c.suit) || "123456789abcd"[c.rank]
  3470.     return s
  3471. end                                            #card2str
  3472.  
  3473.  
  3474. #    s t r 2 c a r d
  3475. # Given a string [as generated by card2str()],
  3476. # return corresponding list of card records.
  3477. # Fails if the string is invalid.
  3478. procedure str2card (s)
  3479. local cc, i
  3480.     (s[i:=1] == "$")  |  fail
  3481.     cc := []
  3482.     while put (cc, card(s[i+:=1], integer("14r"||s[i+:=1])))
  3483.     return cc
  3484. end                                            #str2card
  3485.  
  3486.  
  3487. #    s a v e S t a t e
  3488. # Saves the current state in the named file, which is created/overwritten
  3489. # as necessary.
  3490. # Fails if the state was not successfully saved.
  3491. # Obviously the ordering here must exactly match that in restoreState().
  3492. procedure saveState (filename)
  3493. local f, i
  3494.     (f := open ((directory || filename), "c"))  |  fail
  3495.     write (f, &dateline)
  3496.     write (f, firstSeed)
  3497.     write (f, lastSeed)
  3498.     write (f, &random)
  3499.     every write (f, !pile)
  3500.     every write (f, card2str(!stackUp))
  3501.     every write (f, card2str(!stackDown))
  3502.     write (f, card2str(deckUp))
  3503.     write (f, card2str(deckDown))
  3504.     write (f, totalGames)
  3505.     write (f, totalWins)
  3506.     write (f, totalAces)
  3507.     every write (f, !ops)
  3508.     return close (f)
  3509. end                                            #saveState
  3510.  
  3511.  
  3512. #    r e s t o r e S t a t e
  3513. # Restore game from the named file.
  3514. # Fails if the file isn't there, isn't readable, or isn't correct format.
  3515. # Otherwise returns date the file was last written.
  3516. # Note that we do not update the screen here !!
  3517. # Obviously the ordering here must exactly match that in saveState().
  3518. procedure restoreState (filename)
  3519. local f, date
  3520.     (f := open ((directory || filename), "r"))  |  fail
  3521.     (25 < *(date := read(f)))  |  fail
  3522.     firstSeed    := read (f)
  3523.     lastSeed     := read (f)
  3524.     &random      := read (f)
  3525.     every ((!pile) := read(f))
  3526.     every ((!stackUp)   := str2card (read(f)))
  3527.     every ((!stackDown) := str2card (read(f)))
  3528.     deckUp   := str2card (read(f))
  3529.     deckDown := str2card (read(f))
  3530.     totalGames    := read (f)
  3531.     totalWins    := read (f)
  3532.     totalAces    := read (f)
  3533.     ops := []
  3534.     while push (ops, read (f))
  3535.     dieIf (not close (f), f)
  3536.     return date
  3537. end                                            #restoreState
  3538.  
  3539.  
  3540. #    i n i t V a r i a b l e s
  3541. # Initialize the various lists so that everyone can reference them.
  3542. procedure initVariables ()
  3543.     ops       := []                                #no operations done yet
  3544.     deckUp    := []                                #deck in hand, face-up
  3545.     deckDown  := []                                #deck in hand, face-down
  3546.     stackUp   := list(7, 0)                        #columns on table, face up
  3547.     stackDown := list(7, 0)                        #columns on table, face down
  3548.     pile      := list(4, 0)                        #aces - only top rank stored
  3549.     every put (deckDown, card(1 to 4, 1 to 13))    #take cards out of the box
  3550.     return
  3551. end                                            #initVariables
  3552.  
  3553.  
  3554. #    n e w G a m e
  3555. # Set up all the global variables for a new game.
  3556. # Returns the seed used to generate this game.
  3557. procedure newGame ()
  3558. local i, j, s, seed
  3559.     initScreen ()
  3560.  
  3561.     initVariables ()                        #reset everything to ground zero
  3562.  
  3563.     writeInfo (Vblink || "Shuffling")
  3564.     seed := &random
  3565.     every  | (?deckDown :=: ?deckDown)  \ 123
  3566.     writeInfo ("")
  3567.  
  3568.     every !stackUp   := []
  3569.     every !stackDown := []
  3570.     every  push(stackUp[i := 1 to 7], get(deckDown))  do  {
  3571.         writeStack (-i)
  3572.         click ()
  3573.         every push (stackDown[j := i+1 to 7], get(deckDown))  do  {
  3574.             writeStack (-j)
  3575.             click ()
  3576.         }
  3577. ###        writeStack (-i)                        ### this could replace 2 calls above
  3578.     }
  3579.     writeDeckDown(1)
  3580.  
  3581.     #handle any Aces which are showing
  3582.     every *(s := check4ace (i := 1 to 7)) ~= 0  do
  3583.         push (ops, "M" || string(i) || "A" || string(integer(s) + 4))
  3584.     return seed
  3585. end                                            #newGame
  3586.  
  3587.  
  3588. #    e x p a n d O p
  3589. # Given an operation string, return an expanded human-readable equivalent.
  3590. procedure expandOp (op)
  3591. static opChars
  3592. local s
  3593. initial    {
  3594.     opChars := table("oops!")
  3595.     opChars["A"] := Vbold || "A" || Vnormal || "ce"
  3596.     opChars["D"] := Vbold || "D" || Vnormal || "eck"
  3597.     every  opChars[s := !"1234567"]  :=  Vbold || s || Vnormal
  3598. }
  3599.     # This slightly more efficient scheme assumes op[1] is 1st char of result
  3600.     return (Vbold || op[1] || Vnormal ||
  3601.             case op[1]  of  {
  3602.             "M"        :    ( "ove " || opChars[op[2]] || " to " || opChars[op[3]] )
  3603.             "Q"        :    "uit"
  3604.             "T"        :    "humb"
  3605.             default    :    runerr (500, op)
  3606.             })
  3607. end                                            #expandOp
  3608. SHAR_EOF
  3609. if test 14804 -ne "`wc -c < 'klonsub.icn'`"
  3610. then
  3611.     echo shar: error transmitting "'klonsub.icn'" '(should have been 14804 characters)'
  3612. fi
  3613. fi # end of overwriting check
  3614. #    End of shell archive
  3615. exit 0
  3616. -- 
  3617. PAPER:  Norman Azadian; Ascom AG; Belpstrasse 23; 3000 Berne 14; Switzerland
  3618. INTERNET:  naz%hslrswi.uucp@uunet.uu.net
  3619. UUCP:   ...{uunet,ukc,mcvax,...}!chx400!hslrswi!naz
  3620. VOICE:  +41 31 63 2178            BITNET: naz%hslrswi.UUCP@cernvax.BITNET
  3621.  
  3622. From icon-group-request@arizona.edu  Sun Apr 21 19:54:23 1991
  3623. Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Sun, 21 Apr 91 19:54:23 MST
  3624. Resent-From: icon-group-request@arizona.edu
  3625. Received: from Arizona.edu (Merlin.Telcom.Arizona.EDU) by optima.cs.arizona.edu (4.1/15)
  3626.     id AA17137; Sun, 21 Apr 91 19:54:14 MST
  3627. Received: from ucbvax.Berkeley.EDU by Arizona.edu with PMDF#10282; Sun, 21 Apr
  3628.  1991 19:53 MST
  3629. Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA03923; Sun, 21 Apr 91
  3630.  19:47:22 -0700
  3631. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  3632.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  3633.  usenet@ucbvax.Berkeley.EDU if you have questions)
  3634. Resent-Date: Sun, 21 Apr 1991 19:53 MST
  3635. Date: 21 Apr 91 13:29:42 GMT
  3636. From: eru!hagbard!sunic!mcsun!cernvax!chx400!chx400!hslrswi!naz@bloom-beacon.mit.edu
  3637.  (Norman H. Azadian)
  3638. Subject: Klondike release, v3.01, part 1/6
  3639. Sender: icon-group-request@arizona.edu
  3640. Resent-To: icon-group@cs.arizona.edu
  3641. To: icon-group@arizona.edu
  3642. Resent-Message-Id: <9B0371FB9C80161D@Arizona.edu>
  3643. Message-Id: <1941@hslrswi.hasler.ascom.ch>
  3644. X-Envelope-To: icon-group@CS.Arizona.EDU
  3645. X-Vms-To: icon-group@Arizona.edu
  3646. Organization: Hasler AG
  3647.  
  3648. Here's a good version of the Klondike (solitaire) card game for which I
  3649. posted a beta version some time ago.  This is the result of an international
  3650. joint effort between me in Switzerland and Richard Goerwitz in Chicago.
  3651.  
  3652. Six parts are necessary to keep each one under 20KBytes.
  3653. Note that the unix end-of-line convention (just a newline) is used,
  3654. so you might need to take special measures with your editor under DOS.
  3655. Note also that the tab interval is 4.
  3656.  
  3657. NHA
  3658. ---
  3659. PAPER:  Norman Azadian; Ascom AG; Belpstrasse 23; 3000 Berne 14; Switzerland
  3660. INTERNET:  naz%hslrswi.uucp@uunet.uu.net
  3661. UUCP:   ...{uunet,ukc,mcvax,...}!chx400!hslrswi!naz
  3662. VOICE:  +41 31 63 2178            BITNET: naz%hslrswi.UUCP@cernvax.BITNET
  3663.  
  3664.  
  3665. #! /bin/sh
  3666. # This is a shell archive, meaning:
  3667. # 1. Remove everything above the #! /bin/sh line.
  3668. # 2. Save the resulting text in a file.
  3669. # 3. Execute the file with /bin/sh (not csh) to create the files:
  3670. #    readme
  3671. #    klondike.man
  3672. #    makefile.dos
  3673. #    makefile.unx
  3674. #    klonstub.icn
  3675. # This archive created: Sun Apr 21 15:03:00 1991
  3676. # By:    Norman H. Azadian (Hasler AG)
  3677. export PATH; PATH=/bin:$PATH
  3678. echo shar: extracting "'readme'" '(4587 characters)'
  3679. if test -f 'readme'
  3680. then
  3681.     echo shar: will not over-write existing file "'readme'"
  3682. else
  3683. cat << \SHAR_EOF > 'readme'
  3684. README    910330    NHA    version 3.00
  3685.  
  3686. Just when you'd about given up hope, Klondike is finally being released
  3687. in "final" form.  It's bigger and slower than ever, and chock full of
  3688. marginal features.  It should, however, run on just about any PC or unix
  3689. machine known to man.
  3690.  
  3691. In case you didn't catch the initial beta release, Klondike is an Icon
  3692. implementation of the single-player card game variously known under such
  3693. names as Solitaire or Patience.  When you get tired of playing, you can
  3694. let the machine take over for you.
  3695.  
  3696.  
  3697. INSTALLATION - DOS
  3698. ==================
  3699. For a fast start simply:
  3700.  
  3701.     icont  -c  iolib  kloncon  klonsub  klonstr
  3702.     icont  -u  -Si1000  -Sn2000  klondike
  3703.     iconx  klondike
  3704.  
  3705. Later you might want to move IOLIB.ICN to your Icon library directory,
  3706. and compile it there. If you have "make" on your machine, you can copy
  3707. "makefile.dos" to "makefile", and use make to build klondike.icx for you.
  3708.  
  3709.  
  3710. INSTALLATION - UNIX
  3711. ===================
  3712. For a fast start simply:
  3713.  
  3714.     icont  -c  iolib
  3715.     cp  makefile.unx  makefile
  3716.     make
  3717.     iconx  klondike
  3718.  
  3719. Later you might want to move IOLIB.ICN and GETCHLIB.ICN to your Icon
  3720. library directory, and compile them there.
  3721.  
  3722.  
  3723. NOTES
  3724. =====
  3725. Richard Goerwitz provided the GETCHLIB library package to allow
  3726. operation under unix.  He also provided the IOLIB library package that
  3727. is essential if your terminal isn't ANSI compatible.  He assures me that
  3728. it should be adequate for most terminals currently in use.  If, however,
  3729. you are stuck with an old slow terminal that requires padding, you
  3730. will need his industrial-strength ITLIB package instead of IOLIB.
  3731. You can get this direct from Richard at "goer%sophist@gargoyle.uchicago.edu".
  3732. All suggestions, bug reports and compliments for these libraries should
  3733. be directed to Richard.  All of these libraries will probably become
  3734. available in the Icon Program Library at some point in the future.
  3735.  
  3736. On a PC the "A" and "C" commands can be interrupted by hitting (nearly)
  3737. any key on the keyboard.  Under unix, the natural way to do this would
  3738. be to use SIGINT.  Alas, for the sake of portability we had to forgo this
  3739. feature.  This is because the terminal needs to run in raw mode to
  3740. implement the getch() function, and signals aren't available in raw mode.
  3741. With BSD this could be handily solved by using cbreak mode instead of raw
  3742. mode, but that isn't a possibility under SysV.  The kbhit() that DOS
  3743. uses doesn't port well to unix.
  3744.  
  3745. If for some reason you can't/won't run an ANSI driver on your PC, it is
  3746. possible to run with the termcap capabilities provided by IOLIB.  To do
  3747. this you will need a TERMCAP file.  I have such a beast, as does Richard,
  3748. but I have not included it in the distribution because probably no one
  3749. will actually use it.  If you are the exception, you can get it from one
  3750. of us, or you could write it yourself.
  3751.  
  3752. For terminals with only 24 lines, a kluge is necessary in order to
  3753. display the maximal-length stack of 12 cards.  The top card (at the
  3754. bottom of the screen) is moved up one row so that it covers up the
  3755. suit and rank of the card it rests upon.  However, you know it must
  3756. be a 3, and it can't be used anyway until the 2 on top of it is put
  3757. onto its ace pile.
  3758.  
  3759. One of the excuses for writing this was to have a means of evaluating
  3760. various strategies for playing klondike solitaire.  A strategy is easily
  3761. coded in klonstr.icn, and then tested with a batch file that uses the
  3762. -S, -B and -I options.  On my AT clone, Klondike can pump out nearly
  3763. 5 games per minute in batch mode, thus an overnight run can produce
  3764. 3000-4000 games worth of statistics.  And under unix you can run it
  3765. in background with "nice" to soak up those excess machine cycles.
  3766.  
  3767. On a PC, the size of the .ICX file is limited to 65KBytes.  As long as
  3768. you are running an ANSI driver, you don't actually need IOLIB, and you
  3769. can save a bunch of space in KLONDIKE.ICX by stubbing it out.  This will
  3770. probably be essential if you want to add any play strategies to
  3771. klonstr.icn.  Assuming that your IOLIB is in a library directory
  3772. distinct from where you keep your Klondike, you can accomplish this by
  3773. simply doing the following in your Klondike directory:
  3774.  
  3775.     copy  klonstub.icn  iolib.icn
  3776.     icont  -c  iolib
  3777.  
  3778. I am very interested in suggestions, ideas, speed ups, and above all,
  3779. bug reports.  I'd also like to hear about your experiences with
  3780. alternate strategies.
  3781.  
  3782. Enjoy!
  3783.  
  3784. NHA
  3785. ---
  3786. PAPER:  Norman Azadian; Ascom AG; Belpstrasse 23; 3000 Berne 14; Switzerland
  3787. INTERNET:  naz%hslrswi.uucp@uunet.uu.net
  3788. UUCP:   ...{uunet,ukc,mcvax,...}!chx400!hslrswi!naz
  3789. VOICE:  +41 31 63 2178            BITNET: naz%hslrswi.UUCP@cernvax.BITNET
  3790. SHAR_EOF
  3791. if test 4587 -ne "`wc -c < 'readme'`"
  3792. then
  3793.     echo shar: error transmitting "'readme'" '(should have been 4587 characters)'
  3794. fi
  3795. fi # end of overwriting check
  3796. echo shar: extracting "'klondike.man'" '(9788 characters)'
  3797. if test -f 'klondike.man'
  3798. then
  3799.     echo shar: will not over-write existing file "'klondike.man'"
  3800. else
  3801. cat << \SHAR_EOF > 'klondike.man'
  3802.  
  3803.     NAME
  3804.         klondike -- one of the many versions of solitaire
  3805.  
  3806.     SYNOPSIS
  3807.         klondike  [-AQZ]  [-B[gameCount]]  [-D[directory]]  [-I[reportInterval]
  3808.                     [-P[phraseFile]]  [-RrandomSeed]  [-Sstrategy]
  3809.                     [-T[termType]]")
  3810.  
  3811.     DESCRIPTION
  3812.         A popular variation on the Klondike version of Solitaire (or
  3813.         Patience) as described on page 181 of my 1963 version of "Hoyle's
  3814.         Rules of Games".  The difference is that here we go through the
  3815.         deck (stock) 3 cards at a time instead of one-by-one, and we allow
  3816.         it any number of times.
  3817.  
  3818.         This program runs best on a PC with a color monitor.  It will
  3819.         run on any system providing an ANSI-compatible screen by simply
  3820.         giving option -Tmono or -Tcolor as appropriate.  Further,
  3821.         thanks largely to Richard L. Goerwitz's encouragement, help
  3822.         and excellent iolib package, it should run on just about any
  3823.         (non-magic-cookie) terminal supported by termcap.
  3824.  
  3825.     OPTIONS
  3826.         Except for strategy, options may be either upper or lower case.
  3827.         They may be given in any order.  Parameters follow their options
  3828.         with no whitespace inbetween.  Each option must be given as a
  3829.         separate argument.  Except for toggling options, only the last
  3830.         occurence of an option is honored.
  3831.  
  3832.         -A      By default uncovered Ace cards are automatically
  3833.                 promoted to an Ace pile.  This option toggles that
  3834.                 behaviour. Note that, in any case, it is not allowed
  3835.                 to put an Ace onto a stack, as this could lead to
  3836.                 building stacks which are too big to display with
  3837.                 a 25 line screen.  Some computer-play strategies
  3838.                 will unilaterally disable this option during
  3839.                 programmed play.
  3840.  
  3841.         -B[count]
  3842.                 Batch mode.  The requested number of games is played
  3843.                 and a line of ASCII is written to standard output
  3844.                 with four tab-separated numbers: random seed, number
  3845.                 of games played, number of games won, and number of
  3846.                 cards promoted to the ace piles.  Before exiting,
  3847.                 the usual additional statistics are dumped (with
  3848.                 explanatory text) to stderr.  If the count is 0 or
  3849.                 missing, games are played forever (or until interrupted).
  3850.                 
  3851.                 In batch mode play can always be terminated with
  3852.                 an interrupt from the user, as defined by system-
  3853.                 dependent routine userInterrupt() in kloncon.icn.
  3854.                 Under DOS this consists of entering any character
  3855.                 from the keyboard.
  3856.  
  3857.                 No I/O is ever done other than that described
  3858.                 above.  In particular, the checkpoint file,
  3859.                 klondike.sav, generated by a previous Boss command,
  3860.                 is ignored in batch mode.
  3861.  
  3862.         -D[dir] gives the directory to be used for all file I/O.
  3863.                 The dir string is simply pre-pended to all filenames,
  3864.                 including the phrase file if given.  If dir is not
  3865.                 given, environment variables $HOME and then $ROOTDIR
  3866.                 are tried.  Failing these, the current directory is
  3867.                 used.
  3868.  
  3869.         -I[reportInterval]
  3870.                 enables intermediate reporting of results when
  3871.                 running in Batch mode.  Default is 1.
  3872.  
  3873.         -P[file]
  3874.                 Normally an incorrect keystroke is greeted by one
  3875.                 of a set of stock phrases.  With this option phrases
  3876.                 are instead taken from the indicated file, 1 per line,
  3877.                 up to 16 printing characters each.  For the hard of
  3878.                 humor, funny phrases may be disabled altogether by
  3879.                 giving the option without any file name.
  3880.  
  3881.         -Q      toggle Quiet mode.  Klondike is initially noisy,
  3882.                 with clicks for card movement and bells for
  3883.                 getting attention.  With this option there are
  3884.                 no clicks, and bells are visual if possible.
  3885.  
  3886.         -Rseed  set the random seed to the designated value.
  3887.  
  3888.         -Sstrategy
  3889.                 allows the user to determine which of the programmed
  3890.                 strategy play possibilities will be used for all
  3891.                 computer play (commands Automatic and Continuous).
  3892.                 The default strategy is called "takeFirst", others
  3893.                 may be discovered by reading file klonstr.icn.
  3894.                 NOTE that case IS important in the strategy name.
  3895.  
  3896.         -T[termtype]
  3897.                 use termcap instead of assuming that this is a PC with
  3898.                 an ANSI screen.  If termtype is given then that name
  3899.                 is sought in /etc/termcap, otherwise environment
  3900.                 variables TERMCAP and TERM are consulted in the usual
  3901.                 manner.  Termcap screens are always considered to be
  3902.                 monochrome.  Three special (case-independent) values
  3903.                 for termtype are defined:  PC, MONO, and COLOR.
  3904.                 PC gives the default behaviour, i.e. an ANSI driver
  3905.                 (ANSI.SYS or compatible) must be running, and the
  3906.                 BIOS is consulted to see whether it is monochrome
  3907.                 or color.  This BIOS dependency is avoided with
  3908.                 COLOR and MONO.
  3909.  
  3910.         -Z      toggle debugging mode.  In debugging mode the
  3911.                 debug command (Z) is allowed.  Debugging mode
  3912.                 is initially disabled since it allows cheating.
  3913.  
  3914.     COMMANDS
  3915.         H or ?  display a Help screen.  Under DOS, F1 also works.
  3916.  
  3917.         ^L      (control-L) redraws the screen
  3918.  
  3919.         A       Automatic mode.  Plays the game until nothing useful
  3920.                 remains to be done, or until any key is struck.
  3921.  
  3922.         B       Boss key.  The screen is blanked and the current position
  3923.                 is saved.  When the game is started again in the usual
  3924.                 way, this saved game will be automatically restored and
  3925.                 the save file deleted.
  3926.  
  3927.         C       Continuous mode.  The computer plays games automatically
  3928.                 until interrupted.  Two statistics are displayed:
  3929.                 the number of games already played, and the total number
  3930.                 of aces which have been promoted to the ace piles.
  3931.  
  3932.         F       Find next useful move, thumbing as necessary.  If invoked
  3933.                 immediately again, the move is performed and the next
  3934.                 one is sought.  Note that unless automatic ace mode
  3935.                 is disabled with the -A option, ace promotion will be
  3936.                 automatic, and not considered as a useful move.  Note
  3937.                 also that no strategy is used, i.e. the move found is
  3938.                 not necessarily the best.
  3939.  
  3940.         M       Move a card from the deck or a stack to a stack or an
  3941.                 ace pile.
  3942.  
  3943.         Q       Quit this game, with the opportunity to play another.
  3944.  
  3945.         S       Suggest a possible move.  Hitting this key multiple times
  3946.                 results in multiple suggestions being displayed.  When
  3947.                 there is nothing interesting left to do, it will suggest
  3948.                 "Thumb".  Otherwise the possibilities are listed in no
  3949.                 particular order.
  3950.  
  3951.         T       Thumb.  Remove the top 3 cards from the face-down deck
  3952.                 and turn them over (as a group) onto the face-up deck.
  3953.  
  3954.         U       Undo.  This can be used all the way back to the start
  3955.                 of the current game.
  3956.  
  3957.         Z       Debug.  This is only enabled when the -Z option has
  3958.                 been given on the command line.  There is a sub-menu
  3959.                 of commands available, including a (very brief) Help
  3960.                 summary.
  3961.  
  3962.         The Move command takes two parameters: source and destination.
  3963.         Possible sources are:  D for the Deck of face-up cards; and a
  3964.         number from 1 to 7 inclusive, meaning the corresponding stack.
  3965.         Possible destinations are the stacks (1-7) and A for the
  3966.         appropriate ace pile.  For instance, to move the visible card
  3967.         from the face-up deck to stack 4, one types the three characters:
  3968.         "MD4".  Actually, the "M" character itself is optional, which
  3969.         explains why the "debug" command isn't invoked with a "D".
  3970.  
  3971.     ENVIRONMENT VARIABLES
  3972.         KLONDIKE        the contents of this variable are pre-pended
  3973.                         to the command line.
  3974.         HOME, ROOTDIR   used for directory when -D given without arg.
  3975.         TERM, TERMCAP   used for terminal type determination as usual.
  3976.  
  3977.     FILES
  3978.         klondike.sav    Boss key checkpoints the position here.
  3979.         klondike.sv?    State checkpointed here with the S debug command.
  3980.                         "?" can be any (upper-case) character legal in
  3981.                         your filesystem.
  3982.  
  3983.     BUGS
  3984.         On 24-line terminals you will have to guess at the suit of the
  3985.         next-to-top card in a maximal-length stack.
  3986.         "Continuous" command not (gracefully) stoppable under SYS V unix.
  3987.         Slow, particularly with non-ANSI terminals.
  3988.         The program's play is simplistic; no interesting strategic play
  3989.         has yet been programmed.
  3990.         The average time statistic is sometimes wrong for PCs, and is
  3991.         always wrong when the Boss command has been used.
  3992.  
  3993.     ACKNOWLEDGEMENTS
  3994.         The termcap capability was contributed by Richard L. Goerwitz.
  3995.         The inspiration, name, and some elements of the user interface
  3996.         were lifted wholesale from a computer game copyrighted in 1985
  3997.         by Allyn Wade.
  3998.  
  3999.     VERSION
  4000.         3.01 -- 30 March, 1991
  4001.  
  4002.     AUTHOR
  4003.         Norman H. Azadian
  4004.         naz@hslrswi.com
  4005. SHAR_EOF
  4006. if test 9788 -ne "`wc -c < 'klondike.man'`"
  4007. then
  4008.     echo shar: error transmitting "'klondike.man'" '(should have been 9788 characters)'
  4009. fi
  4010. fi # end of overwriting check
  4011. echo shar: extracting "'makefile.dos'" '(506 characters)'
  4012. if test -f 'makefile.dos'
  4013. then
  4014.     echo shar: will not over-write existing file "'makefile.dos'"
  4015. else
  4016. cat << \SHAR_EOF > 'makefile.dos'
  4017. #makefile.dos    910322    NHA
  4018. #A DOS makefile for klondike
  4019. #
  4020. #Assumes that iolib.u? is already available somewhere along $IPATH.
  4021. #If you don't want to use iolib (because you have an ANSI screen/terminal
  4022. #and you are running out of memory) then you can do the following:
  4023. #    cp  klonstub.icn  iolib.icn
  4024. #    icont  -c  iolib.icn
  4025.  
  4026. .SUFFIXES:    .u1  .icn  .icx
  4027.  
  4028. .icn.u1:
  4029.     icont -c  $?
  4030.  
  4031. klondike.icx:    klondike.icn  kloncon.u1  klonstr.u1  klonsub.u1
  4032.     icont -u -Si1000 -Sn2000  klondike
  4033.  
  4034. clean:
  4035.     rm  -f  *.u?  klondike.icx
  4036. SHAR_EOF
  4037. if test 506 -ne "`wc -c < 'makefile.dos'`"
  4038. then
  4039.     echo shar: error transmitting "'makefile.dos'" '(should have been 506 characters)'
  4040. fi
  4041. fi # end of overwriting check
  4042. echo shar: extracting "'makefile.unx'" '(444 characters)'
  4043. if test -f 'makefile.unx'
  4044. then
  4045.     echo shar: will not over-write existing file "'makefile.unx'"
  4046. else
  4047. cat << \SHAR_EOF > 'makefile.unx'
  4048. #makefile.unx    910322    NHA
  4049. #An unix makefile for klondike
  4050. #
  4051. #Assumes that iolib.u? and getchlib.u? are already available somewhere
  4052. #along $IPATH.
  4053. #Note that only getchlib is linked on the command line.  Everything else
  4054. #is linked in the program.
  4055.  
  4056. .SUFFIXES:    .u1  .icn
  4057.  
  4058. .icn.u1:
  4059.     icont -c  $?
  4060.  
  4061. klondike:    klondike.icn  kloncon.u1  klonstr.u1  klonsub.u1  getchlib.u1
  4062.     icont -u -Si1000 -Sn2000  klondike  getchlib.u1
  4063.  
  4064. clean:
  4065.     rm  -f  *.u?  klondike
  4066. SHAR_EOF
  4067. if test 444 -ne "`wc -c < 'makefile.unx'`"
  4068. then
  4069.     echo shar: error transmitting "'makefile.unx'" '(should have been 444 characters)'
  4070. fi
  4071. fi # end of overwriting check
  4072. echo shar: extracting "'klonstub.icn'" '(571 characters)'
  4073. if test -f 'klonstub.icn'
  4074. then
  4075.     echo shar: will not over-write existing file "'klonstub.icn'"
  4076. else
  4077. cat << \SHAR_EOF > 'klonstub.icn'
  4078. #klonstub.icn    910310    NHA
  4079. #Stubs for iolib.icn
  4080. #Copy this file to iolib.icn to reduce runtime memory requirements.
  4081. #Obviously this will only be effective if you have an ANSI screen/terminal.
  4082.  
  4083. procedure setname (term)
  4084.     stop ("klondike:  invoked stub version of setname(", image(name), ")")
  4085. end
  4086.  
  4087. procedure getval (id)
  4088.     stop ("klondike:  invoked stub version of getval(", image(id), ")")
  4089. end
  4090.  
  4091. procedure igoto (cm, dstcol, dstline)
  4092.     stop ("klondike:  invoked stub version of igoto()")
  4093. end
  4094.  
  4095. procedure iputs (cp, affcnt)
  4096.     stop ("klondike:  invoked stub version of iputs()")
  4097. end
  4098. SHAR_EOF
  4099. if test 571 -ne "`wc -c < 'klonstub.icn'`"
  4100. then
  4101.     echo shar: error transmitting "'klonstub.icn'" '(should have been 571 characters)'
  4102. fi
  4103. fi # end of overwriting check
  4104. #    End of shell archive
  4105. exit 0
  4106. -- 
  4107. PAPER:  Norman Azadian; Ascom AG; Belpstrasse 23; 3000 Berne 14; Switzerland
  4108. INTERNET:  naz%hslrswi.uucp@uunet.uu.net
  4109. UUCP:   ...{uunet,ukc,mcvax,...}!chx400!hslrswi!naz
  4110. VOICE:  +41 31 63 2178            BITNET: naz%hslrswi.UUCP@cernvax.BITNET
  4111.  
  4112. From icon-group-request@arizona.edu  Sun Apr 21 19:54:33 1991
  4113. Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Sun, 21 Apr 91 19:54:33 MST
  4114. Resent-From: icon-group-request@arizona.edu
  4115. Received: from  by optima.cs.arizona.edu (4.1/15)
  4116.     id AB17137; Sun, 21 Apr 91 19:54:25 MST
  4117. Received: from ucbvax.Berkeley.EDU by Arizona.edu with PMDF#10282; Sun, 21 Apr
  4118.  1991 19:53 MST
  4119. Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA03945; Sun, 21 Apr 91
  4120.  19:48:06 -0700
  4121. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  4122.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  4123.  usenet@ucbvax.Berkeley.EDU if you have questions)
  4124. Resent-Date: Sun, 21 Apr 1991 19:53 MST
  4125. Date: 21 Apr 91 14:07:16 GMT
  4126. From: eru!hagbard!sunic!mcsun!cernvax!chx400!chx400!hslrswi!naz@bloom-beacon.mit.edu
  4127.  (Norman H. Azadian)
  4128. Subject: Klondike solitaire, v3.01, part 4/6
  4129. Sender: icon-group-request@arizona.edu
  4130. Resent-To: icon-group@cs.arizona.edu
  4131. To: icon-group@arizona.edu
  4132. Resent-Message-Id: <9B0FB8FCFC800E9E@Arizona.edu>
  4133. Message-Id: <1944@hslrswi.hasler.ascom.ch>
  4134. X-Envelope-To: icon-group@CS.Arizona.EDU
  4135. X-Vms-To: icon-group@Arizona.edu
  4136. Organization: Hasler AG
  4137.  
  4138.  
  4139. #! /bin/sh
  4140. # This is a shell archive, meaning:
  4141. # 1. Remove everything above the #! /bin/sh line.
  4142. # 2. Save the resulting text in a file.
  4143. # 3. Execute the file with /bin/sh (not csh) to create the files:
  4144. #    kloncon.icn
  4145. # This archive created: Sun Apr 21 15:04:11 1991
  4146. # By:    Norman H. Azadian (Hasler AG)
  4147. export PATH; PATH=/bin:$PATH
  4148. echo shar: extracting "'kloncon.icn'" '(19868 characters)'
  4149. if test -f 'kloncon.icn'
  4150. then
  4151.     echo shar: will not over-write existing file "'kloncon.icn'"
  4152. else
  4153. cat << \SHAR_EOF > 'kloncon.icn'
  4154. #kloncon.icn    901029    NHA
  4155. # Console interface routines for Klondike.
  4156. #
  4157. # TO FIX:
  4158. #
  4159. #
  4160. # TO DO:
  4161. #
  4162. # -    develop a visual indication (for isQuiet) for a PC
  4163. # -    Click for each card moved in a stack ??
  4164. #
  4165.  
  4166. link    iolib                                #non-ANSI screen output subroutines
  4167.  
  4168.  
  4169. # constants
  4170. global    rankID, suitID                        #card identification chars
  4171. global    isANSI                                # non-&null for ANSI-compatible
  4172. global    isMonochrome                        # non-&null when running Black&White
  4173. global    output                                #function for writing control chars
  4174. global    lineCount                            #total possible rows on screen
  4175. # Video control strings, etc
  4176. global    Vnormal, Vreverse, Vblink, Vbold, VclearAll, VclearEOL, VbackSpace,Vbell
  4177. global  Vcontrols, ESC                        #set of control strings, ESC char
  4178. global    visualBell                            # non-&null when Vbell is visual
  4179. global    color                                #list of suit color strings
  4180.  
  4181.  
  4182. #    u s e r I n t e r r u p t
  4183. # Succeeds iff the user wishes to interrupt the action.
  4184. # THIS ROUTINE IS SYSTEM DEPENDENT.
  4185. # For DOS, we simply look to see if any keystroke is waiting, discarding
  4186. # it/them.  Your system may be different.
  4187. procedure userInterrupt ()
  4188. static keyWaiting
  4189. initial    {
  4190.     keyWaiting  :=  if \type(kbhit)  then  "kbhit"
  4191. }
  4192.     if \isDOS  then
  4193.         while keyWaiting()  do  {
  4194.             (getch() == "\0")  &  getch()    #eat interrupting keystroke
  4195.             return                            #success means "interrupt requested"
  4196.         }
  4197.     else
  4198.         (\keyWaiting)  &  keyWaiting()  &  getch()  &  return
  4199.     fail                                    #failure = "interrupt NOT requested"
  4200. end                                            #userInterrupt
  4201.  
  4202.  
  4203. #    m y P u t s
  4204. # Output all the strings, using iputs() for control strings.
  4205. # This slightly cheesy algorithm requires that all control strings
  4206. # start with ESC.  This, however, does not apply when \isANSI,
  4207. # since this routine isn't called then.
  4208. # Note that if isQuiet changes while running (using debug command), then
  4209. # Vbell and visualBell may not be optimally set.
  4210. procedure myPuts (sl[])
  4211. static outstr
  4212. local s
  4213. initial    {
  4214.     outstr := table("Oops!")
  4215.     outstr[VclearAll]    := getval("cl")     |  (getval("ho") || getval("cd"))
  4216.     outstr[VclearEOL]    := getval("ce")
  4217.     outstr[Vnormal]        := getval("me") || getval("ue")
  4218.     outstr[Vbold]        := getval("md" | "us")
  4219.     outstr[Vblink]        := getval("mb")
  4220.     outstr[Vreverse]    := getval("mr" | "so")
  4221.     outstr[VbackSpace]    := if getval("bs")  then  "\b"  else  getval("le")
  4222.     if \isQuiet  then
  4223.         outstr[Vbell]    := (visualBell := getval("vb"))  |  getval("bl")
  4224.     else
  4225.         outstr[Vbell]    := getval ("bl")  |  "\^G";
  4226. }
  4227.     while s := string(get(sl))  do  
  4228.         s ?    {
  4229.             while writes (tab(upto(ESC)))  do
  4230.                 iputs (outstr[=(!Vcontrols)])
  4231.             writes (tab(0))
  4232.         }
  4233.     return
  4234. end                                            #myPuts
  4235.  
  4236.  
  4237. #    g e t A N S I t y p e
  4238. # Determine if this ANSI-compatible screen is monochrome or color.
  4239. # This only works on a PC with the ANSI.SYS (or similar) driver installed.
  4240. procedure getANSItype ()
  4241. local i
  4242.     if \isPC  then  {
  4243.         i := ord (Peek([16r40, 16r49]))            #BIOS display mode byte
  4244.         case i  of  {
  4245.             2        :    isMonochrome := 1
  4246.             3        :    isMonochrome := &null    #living color
  4247.             7        :    isMonochrome := 1
  4248.             default    :    stop ("Klondike:  unknown BIOS display mode ", i)
  4249.         }
  4250.     } else
  4251.         runerr (500, "Klondike:  but I thought you were on a PC !")
  4252.     return
  4253. end                                            #getANSItype
  4254.  
  4255.  
  4256. #    i n i t C o n s t a n t s
  4257. # Initialize the program "constants".  These are actually variables that
  4258. # are set just once at the beginning of the world.
  4259. procedure initConstants (termtype)
  4260. local Vred, Vblack                            #suit color strings
  4261.  
  4262.     lineCount := 25                            #assume the best
  4263.     case  (map(termtype, &lcase, &ucase))  of  {
  4264.         "PC"    :    { getANSItype ();            isANSI := 1        }
  4265.         "MONO"    :    { isMonochrome := 1;        isANSI := 1     }
  4266.         "COLOR"    :    { isMonochrome := &null;    isANSI := 1        }
  4267.         default    :    { isMonochrome := 1;        isANSI := &null
  4268.                         (0 < *termtype)  &  setname (termtype)
  4269.                         lineCount := getval("li")
  4270.         }
  4271.     }
  4272.     (lineCount < 24)  &
  4273.         stop ("klondike: need at least 24-line terminal.  Yours is ", lineCount)
  4274.  
  4275.     # Use this function for outputting any string containing control characters,
  4276.     # unless you're sure that the screen is ANSI-compatible.
  4277.     output  :=  if \isANSI  then  writes  else  myPuts
  4278.  
  4279.     # set Video control strings, plus the set of all Video control strings
  4280.     ESC                := "\e"                    #escape character
  4281.     VclearAll        := "\e[2J"                #clear screen and home cursor
  4282.     VclearEOL        := "\e[K"                #clear to End Of Line
  4283.     Vnormal            := "\e[0m"
  4284.     Vbold            := "\e[1m"
  4285.     Vblink            := "\e[5m"
  4286.     Vreverse        := "\e[7m"
  4287.     if \isANSI  then  {
  4288.         VbackSpace    := "\b"
  4289.         Vbell        := "\^G"
  4290.     } else {
  4291.         #additional escape required for myPuts()
  4292.         VbackSpace    := "\e\b"
  4293.         Vbell        := "\e\^G"                #ding dong, Avon calling
  4294.     }
  4295.     Vcontrols         := set( [VclearAll, VclearEOL, Vnormal, Vbold,
  4296.                             Vblink, Vreverse, VbackSpace, Vbell] )
  4297.  
  4298.     if \isMonochrome  then  {
  4299.         Vred    := Vnormal
  4300.         Vblack    := Vreverse
  4301.     } else {
  4302.         Vred    := "\e[0;47;31m"            # "extra" 0 seems to be necessary
  4303.         Vblack    := "\e[0;47;30m"            # "extra" 0 seems to be necessary
  4304.     }
  4305.  
  4306.     # Suits are: 1=Hearts, 2=Diamonds, 3=Clubs, 4=Spades
  4307.     suitID := if \isPC  then  "\3\4\5\6"  else  "HDCS"
  4308.     color  := [Vred, Vred, Vblack, Vblack]
  4309.     rankID := "A23456789TJQK"
  4310.     return
  4311. end                                            #initConstants
  4312.  
  4313.  
  4314. #    i n i t S c r e e n
  4315. # Initialize output and write the fixed parts of the screen.
  4316. # initConstants() must have been called earlier.
  4317. # Note that the screen and its mode must remain unmodified if \invisible.
  4318. procedure initScreen ()
  4319. local f
  4320. static vertical
  4321. initial {
  4322.     vertical  :=  if \isANSI  then  "\272"  else  "|"
  4323. }
  4324.  
  4325.     (\invisible)  &  return
  4326.     if \isANSI  then  {
  4327.         if (\isPC)  then
  4328.             if \isMonochrome  then  writes ("\e[=2h")    #25x80 B&W   text mode
  4329.             else  writes ("\e[=3h")                        #25x80 color text mode
  4330.         writes (Vnormal, VclearAll, "\e[=7l")        #clear screen, prevent wrap
  4331.     } else {
  4332.         if not iputs (getval("is"))  then  {        #terminal Init Ftring
  4333.             if f := open (getval("if"), "r") then {    #terminal Init File
  4334.                 while writes (reads(f))                ## should use iputs() ??
  4335.                 close (f)
  4336.             }
  4337.         }
  4338.         iputs (getval("ti"))                        #Termcap Init string
  4339.         output (VclearAll)
  4340.     }
  4341.  
  4342.     every writeStackNumber (1 to 7, Vnormal)
  4343.     writeCursor (2, 64)
  4344.     if \isANSI  then
  4345.         writes ("\311\315\315\315\315SOLITAIRE\315\315\315\315")
  4346.     else
  4347.         writes ("=====SOLITAIRE====")
  4348.     every writeAt (3 to lineCount, 64, vertical)
  4349.     outputAt ((if lineCount = 25 then  25  else  1),  66,
  4350.                 Vbold, "Q", Vnormal, "=Quit  ", Vbold, "H", Vnormal, "=Help")
  4351.     return
  4352. end                                            #initScreen
  4353.  
  4354.  
  4355. #    t e r m i n a t e S c r e e n
  4356. # Put the screen in the correct state prior to program termination.
  4357. procedure terminateScreen ()
  4358. static resetCooked
  4359. initial    {
  4360.     resetCooked  :=  if \type(reset_tty)  then  "reset_tty"
  4361. }
  4362.     if /invisible  then
  4363.         if \isANSI  then
  4364.             write ("\e[=7h", VclearAll, Vnormal)    #set cursor wrap mode
  4365.         else {
  4366.             output (VclearAll, Vnormal, getval("te"))
  4367.             (/isDOS)  &  (\resetCooked)  &  resetCooked ()
  4368.         }
  4369.     return
  4370. end                                            #terminateScreen
  4371.  
  4372.  
  4373. #    w r i t e C u r s o r
  4374. # Position the cursor to row,col.
  4375. # Screen origin (top left corner) is row=1 and col=1.
  4376. procedure writeCursor (row, col)
  4377. static cm
  4378. initial {
  4379.     (\isANSI)  |  (cm  :=  (getval("cm")  |  (getval("ch") || getval("cv"))))
  4380. }
  4381.     if /invisible  then
  4382.         if \isANSI  then
  4383.             writes ("\e[", row, ";", col, "H") 
  4384.         else
  4385.             iputs (igoto(cm, col, row))
  4386.     return
  4387. end                                            #writeCursor
  4388.  
  4389.  
  4390. #    w r i t e A t
  4391. # Position the cursor to row,col and then write the following string(s).
  4392. # Screen origin (top left corner) is row=1 and col=1.
  4393. # Note that the standard write() should normally not be used because the newline
  4394. # doesn't work when running in raw mode under unix.
  4395. procedure writeAt (row, col, s[])
  4396.     if /invisible  then  {
  4397.         writeCursor (row, col)
  4398.         writes! (s)
  4399.     }
  4400.     return
  4401. end                                            #writeAt
  4402.  
  4403.  
  4404. #    o u t p u t A t
  4405. # Position the cursor to row,col and then write the following string(s).
  4406. # Screen origin (top left corner) is row=1 and col=1.
  4407. procedure outputAt (row, col, s[])
  4408.     if /invisible  then  {
  4409.         writeCursor (row, col)
  4410.         output! (s)
  4411.     }
  4412.     return
  4413. end                                            #outputAt
  4414.  
  4415.  
  4416. #    w r i t e S t a c k N u m b e r
  4417. # Write the indicated stack number with the specified video attribute.
  4418. # Note that this will almost surely alter your current cursor position.
  4419. procedure writeStackNumber (num, attr)
  4420.     (\invisible)  | outputAt (1, [3,12,21,30,39,48,57][num], attr, num, Vnormal)
  4421.     return
  4422. end                                            #writeStackNumber
  4423.  
  4424.  
  4425. #    w r i t e F r o n t
  4426. # Displays an image of the specified card fronts at the specified spot.
  4427. ## WARNING: The input cards must be in a list!
  4428. # Top left corner of the first card will be placed at the specified position.
  4429. # Successive cards are displayed two rows higher (lower position on the screen).
  4430. # Cursor need not be in any particular position before this, and is left
  4431. # in a random position afterwards.  Video is always left normal (not reversed).
  4432. # Cards are 7 columns wide by 5 rows tall.
  4433. # We only display the first 2 rows of each card, except for the top card.
  4434. # With 25 rows, we can put 12 cards in a stack (assuming we start in row 2).
  4435. # But if there are 11 in the stack we can only display 4 rows of the top card.
  4436. # If there are 12 cards, we can only display 2 rows of the topmost card.
  4437. # With a 24 row screen, the topmost card (a 2) is moved up one line on a full
  4438. # stack.  This will obscure the 3 that it is resting on, but the topmost 2 will
  4439. # be visible, which is rather more important.
  4440. ##We can only write a row at a time due to a problem with ANSI col 80 handling.
  4441. procedure writeFront (cardlist, row, col)
  4442. local card
  4443. static vertical, topHorizontal, bottomHorizontal
  4444. initial {
  4445.     if \isANSI  then  {
  4446.         topHorizontal     := "\332\304\304\304\304\304\277"
  4447.         vertical         := "\263"
  4448.         bottomHorizontal := "\300\304\304\304\304\304\331"
  4449.     } else {
  4450.         topHorizontal     := "-------"
  4451.         vertical         := "|"
  4452.         bottomHorizontal := "-------"
  4453.     }
  4454. }
  4455.     dieIf (lineCount < row, row)
  4456.     # output first 2 rows of every card
  4457.     # for long stack and short screen the next-to-top card is mostly obscured
  4458.     every  card := !cardlist  do  {
  4459.         (row = lineCount)  &  (row -:= 1)            #long stack, short screen
  4460.         outputAt (row, col, Vreverse, topHorizontal)
  4461.         outputAt (row+:=1, col, vertical, color[card.suit], rankID[card.rank],
  4462.                         suitID[card.suit], Vreverse, "   ", vertical)
  4463.         row +:= 1
  4464.     }
  4465.  
  4466.     # maybe put out some more rows of the top card
  4467.     if row <= lineCount  then  {
  4468.         outputAt (row, col, Vreverse, vertical, "     ", vertical)
  4469.         if (row +:= 1) <= lineCount  then  {
  4470.             outputAt (row, col, vertical, "   ", color[card.suit],
  4471.                        rankID[card.rank], suitID[card.suit], Vreverse, vertical)
  4472.             if (row +:= 1) <= lineCount  then
  4473.                 writeAt (row, col, bottomHorizontal)    #last row of top card
  4474.         }
  4475.     }
  4476.     output (Vnormal)
  4477.     return
  4478. end                                            #writeFront
  4479.  
  4480.  
  4481. #    w r i t e B a c k
  4482. # Puts an image of the back of a card at the specified spot on the screen.
  4483. procedure writeBack (row, col)
  4484. static backLine
  4485. local i
  4486. initial {
  4487.     backLine := list(5)
  4488.     if \isANSI  then  {
  4489.         backLine[1] := "\332\304\304\304\304\304\277"
  4490.         backLine[2] := "\263\332\304\304\304\277\263"
  4491.         backLine[3] := "\263\263\040\040\040\263\263"
  4492.         backLine[4] := "\263\300\304\304\304\331\263"
  4493.         backLine[5] := "\300\304\304\304\304\304\331"
  4494.     } else {
  4495.         backLine[1] := "-------"
  4496.         backLine[2] := "| --- |"
  4497.         backLine[3] := "| | | |"
  4498.         backLine[4] := "| --- |"
  4499.         backLine[5] := "-------"
  4500.     }
  4501. }
  4502.     (\invisible)  |  (every writeAt (row, col, !backLine)  do  row +:= 1)
  4503.     return
  4504. end                                            #writeBack
  4505.  
  4506.  
  4507. #    w r i t e B l a n k
  4508. # Blanks a card-sized area at the specified spot on the screen.
  4509. procedure writeBlank (row, col)
  4510.     (\invisible)  |  (every writeAt (row + (0 to 4),  col,  "       "))
  4511.     return
  4512. end                                            #writeBlank
  4513.  
  4514.  
  4515. #    w r i t e S t a c k
  4516. # Display the specified stack.  Left end is bottom of stackUp, top of stackDown.
  4517. # Stacks start in row 2, column1; with 2 columns between stacks.
  4518. # Optimized to avoid re-writing cards that are already on the screen.
  4519. # prevs[] holds, for each stack, the total number of visible (up) cards
  4520. # on that stack as of the last time writeStack() was called.  This allows
  4521. # us to simply draw (or erase) the cards that have been added (or subtracted).
  4522. # By special arrangement, this routine can be called with a negative stack
  4523. # number!  This is a hint that our idea of what is on the display is actually
  4524. # wrong, and therefore the entire stack needs to be re-displayed.  This can
  4525. # happen in two situations:  1) in refreshScreen(), the entire screen is cleared
  4526. # before calling writeStack();  2) in undo() when undoing a move between
  4527. # stacks, the bottom card needs to be changed, although the normal algorithm
  4528. # would consider that it is already correctly displayed.  Note that in neither
  4529. # case is the stack shrinking, therefore we don't need to worry about erasing
  4530. # any cards that were displayed last time.
  4531. procedure writeStack (n)
  4532. local row, col
  4533. static prevs, blankLine, firstRow, lastRow
  4534. initial    {
  4535.     prevs := [0,0,0,0,0,0,0]                    #previous stack height displayed
  4536.     blankLine := repl (" ", 7)
  4537.     # first and last screen rows for each card in a stack
  4538.     firstRow := [2,4,6,8,10,12,14,16,18,20,22,24]
  4539.     lastRow  := [6,8,10,12,14,16,18,20,22,24,lineCount,lineCount]
  4540. }
  4541.     (\invisible)  &  return
  4542.     (n < 0)  &  (prevs[n := abs(n)] := 0)        #n < 0  forces complete re-write
  4543.     col := (n * 9) - 8                            #leftmost column for this stack
  4544.  
  4545.     if (*stackUp[n]) <= prevs[n]  then  {
  4546.         # the stack just got smaller (or stayed the same)
  4547.         # blank out two rows for each card that has been removed
  4548.         row := lastRow[prevs[n]] + 1            #<last row used by top card> + 1
  4549.         while *stackUp[n] < prevs[n]  do  {
  4550.             every  writeAt (row -:= (1 | 1),  col,  blankLine)
  4551.             prevs[n] -:= 1                        #countdown and update
  4552.         }
  4553.         dieIf (*stackUp[n] ~= prevs[n], prevs[n])
  4554.         # re-write new top card
  4555.         if *stackUp[n] = 0  then
  4556.             (if *stackDown[n] = 0  then  writeBlank  else  writeBack) (2, col)
  4557.         else
  4558.             writeFront ([stackUp[n][-1]], firstRow[prevs[n]], col)
  4559.     } else {
  4560.         # the stack just got bigger -- display new cards
  4561.         writeFront (stackUp[n][prevs[n]+1:0], firstRow[prevs[n]+1], col)
  4562.         prevs[n] := *stackUp[n]                #remember how much is displayed
  4563.     }
  4564.     # display the number of hidden cards
  4565.     writeAt (4, (7 + col), " 123456???"[1+*stackDown[n]])
  4566.     return
  4567. end                                            #writeStack
  4568.  
  4569.  
  4570. #    w r i t e P i l e
  4571. # Displays an image of the specified ace pile, face up (or blank if empty)
  4572. procedure writePile (n)
  4573. static pileRow, pileCol
  4574. initial {
  4575.     pileRow := [3,3,9,9]
  4576.     pileCol := [66,74,66,74]
  4577. }
  4578.     if /invisible  then
  4579.         if  0 = pile[n]  then
  4580.             writeBlank (pileRow[n], pileCol[n])
  4581.         else
  4582.             writeFront ([card(n,pile[n])], pileRow[n], pileCol[n])
  4583.     return
  4584. end                                            #writePile
  4585.  
  4586.  
  4587. #    w r i t e D e c k D o w n
  4588. # Displays an image of deckDown (the face-down deck) in the proper spot.
  4589. # Avoids re-displaying blank or card back that is already on the screen.
  4590. # Parameter is non-null to force displaying something (assuming not invisible).
  4591. procedure writeDeckDown (forget)
  4592. static p
  4593. initial    {
  4594.     forget := 1                                #assume the screen is blank
  4595. }
  4596.     if /invisible  then  {
  4597.         (\forget)  &  (p := writeDeckDown)    #anything but writeBlank | writeBack
  4598.         (p ~===:= (if 0 < *deckDown  then  writeBack else writeBlank)) (20, 74)
  4599.         writeAt (19, 76, right(*deckDown, 2))    #display card count in deckDown
  4600.     }
  4601.     return
  4602. end                                            #writeDeckDown
  4603.  
  4604.  
  4605. #    w r i t e D e c k U p
  4606. # Displays an image of deckUp (the face-up deck) in the proper spot.
  4607. procedure writeDeckUp ()
  4608.     if /invisible  then  {
  4609.         writeFront ([deckUp[1]], 20, 66)  |  writeBlank (20, 66)
  4610.         writeAt (19, 68, right(*deckUp, 2))        #write number of cards in deckUp
  4611.     }
  4612.     return
  4613. end                                            #writeDeckUp
  4614.  
  4615.  
  4616. #    c o u n t C o n t r o l s
  4617. # Returns a count of video control sequences in the proffered string.
  4618. # This is not a very general algorithm, being valid only for our V constants.
  4619. procedure countControls (s)
  4620. local count                                    #of [invisible] video control chars
  4621. local seq                                    #control sequence found
  4622.     count := 0
  4623.     every  find ((seq := (!Vcontrols)), s)  do  count +:= *seq
  4624.     return count
  4625. end                                            #countControls
  4626.  
  4627.  
  4628. #    w r i t e I n f o
  4629. # Displays a new short string (up to 16 printing characters) centered in the
  4630. # officially approved information area of the screen.
  4631. # All known video attributes (in set "Vcontrols") are specially handled.
  4632. # An empty string results in clearing the area.
  4633. # We always revert to normal text mode after outputting the string.
  4634. procedure writeInfo (s)
  4635.     (\invisible)  |  outputAt (15, 65, Vnormal, VclearEOL,
  4636.                             trim(center(s, 16+countControls(s)), ' '), Vnormal)
  4637.     return
  4638. end                                            #writeInfo
  4639.  
  4640.  
  4641. #    c l i c k
  4642. # Make a quick sound to accompany card transfers, if possible and not Quiet.
  4643. procedure click ()
  4644. local x
  4645.     if (not \isQuiet)  &  (\isPC)  then  {
  4646.         x := InPort (16r61)
  4647.         OutPort (16r61, 3)
  4648.         OutPort (16r61, x)
  4649.     }
  4650.     return
  4651. end                                            #click
  4652.  
  4653.  
  4654. #    b e e p
  4655. # The short beep produced under isPC is not as annoying as the normal beeeeep.
  4656. # This always puts out something, although it might be a visual indication.
  4657. procedure beep ()
  4658. local x
  4659.     if (\isPC)  then  {                        #no visual indication yet for a PC
  4660.         x := InPort (16r61)
  4661.         every  | OutPort (16r61, 3) \ 22
  4662.         OutPort (16r61, x)
  4663.     } else
  4664.         output (Vbell)
  4665.     return
  4666. end                                            #beep
  4667.  
  4668.  
  4669. #    c o m p l a i n
  4670. # Let the boob know he done something wrong, with a dash of humor.
  4671. # Complaint can be specified, otherwise a generic one will be selected for you.
  4672. # Phrases can be up to 16 visible characters long.
  4673. # Additionally there may be embedded recognized video control sequences.
  4674. # Complaint will always be bold, and will blink if isQuiet.
  4675. procedure complain (complaint)
  4676. static phrases
  4677. local f, s
  4678. initial {
  4679.     phrases := ["INVALID"]                    #irreducible minimum
  4680.     if \phraseFile  then  {
  4681.         if f := open((directory || phraseFile), "r")  then  {
  4682.             while put (phrases,
  4683.                         trim(center(s, 16+countControls(s := read(f))), ' '))
  4684.             close (f)
  4685.             (1 < *phrases)  &  pop(phrases)    #success -- remove ours
  4686.         }
  4687.     } else {
  4688.         phrases |||:= [
  4689. "cut that out!",    "oops!",            "be nice!",         "get real",
  4690. "be serious",        "What??",            "huh?",                "idiot alert",
  4691. "dummy!",            "Hey man!",            "giggle giggle",    "engage brain",
  4692. "NOW what?",        "yuk yuk",            "funky dude",        "wake up, man",
  4693. "yeah, real funny",    "totally awesome",    "boffo",            "boogie boogie",
  4694. "Bozo!",            "watch it!",        "oi vey",            "~@?$!&*=(*%^!*",
  4695. "forty lashes!",    "way cool, dude",    "ha ha ha",            "see an analyst",
  4696. "go fly a kite",    "wish upon a star",    "basket case",        "braindamaged",
  4697. "dummkopf",            "holy cow",            "reject",            "try harder",
  4698. "think again",        "watch your hands",    "We're not amused",    "adjust fingers",
  4699. "gimme a break",    "R U 4 real ?",        "that's a laugh",    "Ho Ho Ho",
  4700. "space case",        "space cadet",        "call AA",            "oh yeah?",
  4701. "dum de dum dum",    "try thinking",        "sigh",                "get a life"
  4702.         ]
  4703.     }
  4704.     (\debugging)  &  writeInfo (*phrases || " phrases")
  4705. }
  4706.     /complaint := ?phrases
  4707.     #Note that isQuiet can change while running if debugging is enabled (-Z)
  4708.     if (\isQuiet)  &  (not \visualBell)  then
  4709.         writeInfo (Vbold || Vblink || complaint)
  4710.     else {
  4711.         writeInfo (Vbold || complaint)
  4712.         beep()
  4713.     }
  4714.     return
  4715. end                                            #complain
  4716.  
  4717.  
  4718. #    g e t C m d C h a r
  4719. # Returns an upper-case command character, echoed to current cursor position.
  4720. # Fails if character wasn't "normal" and complaint was made.
  4721. # For ESC, abort information is written, and ESC is returned.
  4722. # Normal calling sequence (from within a command procedure) is thus:
  4723. #        until (s := getCmdChar ())
  4724. #        (s == ESC)  &  fail
  4725. # Under DOS, F1 [function key 1] is specially treated as a request for Help.
  4726. procedure getCmdChar ()
  4727. local s
  4728.     s := getch ()                            #get command character
  4729.     if s == "\0"  then  {                    #non-ASCII character
  4730.         s := getch ()                        #check keyboard scan code
  4731.         if (\isDOS)  &  (s == ";")  then  {
  4732.             s := "h"                        #jigger F1 to look like "Help"
  4733.         } else {
  4734.             complain ()
  4735.             fail
  4736.         }
  4737.     }
  4738.     s := map (s, &lcase, &ucase)
  4739.     if s == ESC  then
  4740.         writeInfo (Vbold || "Cmd Aborted.")
  4741.     else
  4742.         writes (s)                            #echo the command character
  4743.     return  s
  4744. end                                            #getCmdChar
  4745.  
  4746.  
  4747. #    r e f r e s h S c r e e n
  4748. # Re-write entire screen.
  4749. procedure refreshScreen ()
  4750.     if /invisible  then  {
  4751.         initScreen ()
  4752.         every writeStack (-1 to -7 by -1)
  4753.         every writePile (1 to 4)
  4754.         writeDeckDown (1)
  4755.         writeDeckUp ()
  4756.     }
  4757.     return
  4758. end                                            #refreshScreen
  4759. SHAR_EOF
  4760. if test 19868 -ne "`wc -c < 'kloncon.icn'`"
  4761. then
  4762.     echo shar: error transmitting "'kloncon.icn'" '(should have been 19868 characters)'
  4763. fi
  4764. fi # end of overwriting check
  4765. #    End of shell archive
  4766. exit 0
  4767. -- 
  4768. PAPER:  Norman Azadian; Ascom AG; Belpstrasse 23; 3000 Berne 14; Switzerland
  4769. INTERNET:  naz%hslrswi.uucp@uunet.uu.net
  4770. UUCP:   ...{uunet,ukc,mcvax,...}!chx400!hslrswi!naz
  4771. VOICE:  +41 31 63 2178            BITNET: naz%hslrswi.UUCP@cernvax.BITNET
  4772.  
  4773. From icon-group-request@arizona.edu  Sun Apr 21 19:55:13 1991
  4774. Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Sun, 21 Apr 91 19:55:13 MST
  4775. Resent-From: icon-group-request@arizona.edu
  4776. Received: from Arizona.edu (Merlin.Telcom.Arizona.EDU) by optima.cs.arizona.edu (4.1/15)
  4777.     id AA17181; Sun, 21 Apr 91 19:55:05 MST
  4778. Received: from ucbvax.Berkeley.EDU by Arizona.edu with PMDF#10282; Sun, 21 Apr
  4779.  1991 19:53 MST
  4780. Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA03979; Sun, 21 Apr 91
  4781.  19:48:51 -0700
  4782. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  4783.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  4784.  usenet@ucbvax.Berkeley.EDU if you have questions)
  4785. Resent-Date: Sun, 21 Apr 1991 19:54 MST
  4786. Date: 21 Apr 91 14:06:05 GMT
  4787. From: eru!hagbard!sunic!mcsun!cernvax!chx400!chx400!hslrswi!naz@bloom-beacon.mit.edu
  4788.  (Norman H. Azadian)
  4789. Subject: Klondike solitaire, v3.01, part 3/6
  4790. Sender: icon-group-request@arizona.edu
  4791. Resent-To: icon-group@cs.arizona.edu
  4792. To: icon-group@arizona.edu
  4793. Resent-Message-Id: <9B27C2184C800E22@Arizona.edu>
  4794. Message-Id: <1943@hslrswi.hasler.ascom.ch>
  4795. X-Envelope-To: icon-group@CS.Arizona.EDU
  4796. X-Vms-To: icon-group@Arizona.edu
  4797. Organization: Hasler AG
  4798.  
  4799.  
  4800. #! /bin/sh
  4801. # This is a shell archive, meaning:
  4802. # 1. Remove everything above the #! /bin/sh line.
  4803. # 2. Save the resulting text in a file.
  4804. # 3. Execute the file with /bin/sh (not csh) to create the files:
  4805. #    klondike.icn
  4806. # This archive created: Sun Apr 21 15:03:59 1991
  4807. # By:    Norman H. Azadian (Hasler AG)
  4808. export PATH; PATH=/bin:$PATH
  4809. echo shar: extracting "'klondike.icn'" '(19820 characters)'
  4810. if test -f 'klondike.icn'
  4811. then
  4812.     echo shar: will not over-write existing file "'klondike.icn'"
  4813. else
  4814. cat << \SHAR_EOF > 'klondike.icn'
  4815. #klondike.icn    901207    NHA
  4816. #The Klondike version of Solitaire; main program and command routines.
  4817. #
  4818. # TO FIX:
  4819. #
  4820. #
  4821. # TO DO:
  4822. #
  4823. # -    Add a "cheated" flag ??
  4824. # -    Find a better way to determine isPC.
  4825. # -    Implement an heuristic to discover optimal play
  4826. #
  4827.  
  4828. link    kloncon                                #klondike console I/O subroutines
  4829. link    klonstr                                #klondike strategy subroutines
  4830. link    klonsub                                #klondike miscellaneous subroutines
  4831.  
  4832. record card(suit, rank)                        #suit is 1..4, rank is 1..13
  4833.  
  4834. #    v a r i a b l e s
  4835. # lists of record card
  4836. global deckUp                                #face Up portion of deck (stock)
  4837. global deckDown                                #face Down portion of deck
  4838. global stackUp                                #list of face Up cards per stack
  4839. global stackDown                            #list of face Down cards per stack
  4840. # others
  4841. global pile                                    #ace piles - top rank only
  4842. global ops                                    #list of all operations ever done
  4843. global isDOS, isPC                            # "state of our world" flags
  4844. global debugging, automaticAce                #command-line flags
  4845. global invisible, isQuiet                    # for visual and audible feedback
  4846. global strategy                                #strategy to use for automatic play
  4847. global directory, phraseFile                #pathnames
  4848. global firstSeed, lastSeed                    #&random remembered
  4849. global totalGames, totalAces, totalWins        #ace pile statistics
  4850.  
  4851.  
  4852. #    u h e l p
  4853. # Provide command summary for user, plus statistics to date, if any.
  4854. procedure uhelp ()
  4855. local row, info
  4856. static helpInfo
  4857. initial    {
  4858.     helpInfo := [
  4859.         ["A", "Automatic", " mode -- finish out this game on automatic pilot"],
  4860.         ["B", "Boss", " key for when you-know-who visits"],
  4861.         ["C","Continuous"," mode -- play games continuously until interrupted"],
  4862.         ["F", "Find", " (next) useful move to do"],
  4863.         ["H,?", "Help", ", this help screen"],
  4864.         ["M", "Move", " card (or stack) from Deck/Stack to Stack/Ace pile"],
  4865.         ["Q", "Quit", " this game"],
  4866.         ["S", "Suggest", " (another) possible move"],
  4867.         ["T", "Thumb", " through the deck"],
  4868.         ["U", "Undo", " -- back up one move"],
  4869.         ["Z", "Debug", ""],
  4870.         ["^L", "re-draw", " screen"],
  4871.         ["ESC", "Escape", " -- abort current command"]
  4872.     ]
  4873. }
  4874.     output (VclearAll, Vnormal)
  4875.     output ("Klondike version 3.01  910330 NHA\t\t", &version)
  4876.     outputAt (4, 4, "The following commands are available:")
  4877.     row := 6
  4878.     every info := !helpInfo  do
  4879.         if (\debugging)  |  (info[1] ~== "Z")  then  {
  4880.             outputAt (row,  8, Vbold, info[1])
  4881.             outputAt (row, 16, info[2], Vnormal, info[3])
  4882.             row +:= 1
  4883.         }
  4884.  
  4885.     if 0 < totalGames  then
  4886.         writeAt (21, 1, "totalGames = ", totalGames,
  4887.                 "   totalWins = ", totalWins,
  4888.                 "   totalAces = ", totalAces,
  4889.                 "   average = ",
  4890.                 left (string(real(totalAces) / real(totalGames)), 6) )
  4891.     outputAt (24, 20, Vblink, "Press any key to resume game", Vnormal)
  4892.     (getch() == "\0")  &  getch()            #wait for a keystroke & swallow it
  4893.     refreshScreen ()
  4894.     return
  4895. end                                            #uhelp
  4896.  
  4897.  
  4898. #    f i n d 1
  4899. # Find the best move, thumbing as necessary to achieve it.
  4900. # Return the operation string for that move.
  4901. # Fails if there is nothing useful left to do.
  4902. # When Thumbing, fails upon second occurrence of *deckDown = 0.
  4903. # This is an internal routine but it does keep the user informed.
  4904. # Note that if automaticAce is set, any Ace uncovered whilst thumbing
  4905. # will be automatically moved and the search will continue.
  4906. procedure find1 ()
  4907. local emptySeen, s
  4908.     repeat  {
  4909.         /emptySeen  :=  (*deckDown = 0)
  4910.         (s := suggest())  &  return (s || "0")        #good move found
  4911.         ((*deckUp + *deckDown) = 0)  &  fail        #no cards to thumb through
  4912.         writeInfo (Vbold || "T" || Vnormal || "humb")
  4913.         push (ops, thumb())
  4914.         (\emptySeen)  &  (*deckDown = 0)  &  fail    #no point Thumbing forever
  4915.     }
  4916. end                                            #find1
  4917.  
  4918.  
  4919. #    u f i n d
  4920. # Thumb as necessary until a reasonable move appears, then stop and suggest it.
  4921. # When nothing is left to do, suggest "Quit".
  4922. # When invoked twice in a row, again will be non-null and we should take the
  4923. # previous suggestion and find the next.
  4924. # Returns success to request termination.
  4925. # Note that the suggestion is not necessarily the "best" suggestion.
  4926. # Note that if automaticAce is set, an uncovered Ace will be automatically
  4927. # moved and the search will continue.  It does not count as a move.
  4928. procedure ufind (again)
  4929. static lastOp
  4930. local s
  4931.     if \again  then
  4932.         if lastOp == "Q"  then  {            #pretend he typed "Q" instead of "F"
  4933.             output (VbackSpace, Vbold, "Q", Vnormal)
  4934.             return  uterminate ()            #Th.th.th.that's all, folks!
  4935.         } else  {
  4936.             writes ("ind")
  4937.             writeInfo ("")                                #clear prevs suggestion
  4938.             s := expandOp (lastOp)                        #build suggestion
  4939.             # show previous suggestion as current command
  4940.             outputAt (17, 65, "> ", left (s, 14 + countControls(s)))
  4941.             push (ops, move1(lastOp))  |  runerr (500, lastOp)        #execute it
  4942.             outputAt (17, 65, VclearEOL,Vnormal, "> F")    #go find next suggestion
  4943.         }
  4944.     writes ("ind")
  4945.     writeInfo (  expandOp (lastOp := (find1() | "Q") ) )    #suggest (next) move
  4946.     fail                                    #do NOT request a new game
  4947. end                                            #ufind
  4948.  
  4949.  
  4950. #    u s u g g e s t
  4951. # Suggest a (reasonable) possible move in this situation.
  4952. # Repeated invocations produce successive possibilities, until the
  4953. # only thing left to do is Thumb.
  4954. # "another" is non-null when this command was also the previous command.
  4955. # Suggestions are given in essentially random order, and thumbing is
  4956. # suggested only as a last resort.
  4957. procedure usuggest (another)
  4958. static suggestions, i
  4959.     writes ("uggest")
  4960.     if /another  then  {                    #prev command was NOT Suggest
  4961.         suggestions := []                    #generate a new list of suggestions
  4962.         every put ( suggestions, suggest() )
  4963.         i := 0
  4964.     }
  4965.     return  writeInfo (   expandOp (suggestions[i+:=1] | "T")   )
  4966. end                                            #usuggest
  4967.  
  4968.  
  4969. #    a u t o m a t i c
  4970. # Run the game, as far as possible, untouched by human hands
  4971. # This is an internal routine but it keeps the user informed.
  4972. # Returns total ace cards promoted when there is nothing useful left to do.
  4973. # Returns with failure when the user interrupts the proceedings.
  4974. procedure automatic ()
  4975. local op
  4976.     repeat  {
  4977.         userInterrupt()  &  fail                                #interrupted
  4978.         (!pile < 13)  |  return 52                                #victory
  4979.         if  not writeInfo (  expandOp ( op := findBest() )  )  then
  4980.             return (pile[1] + pile[2] + pile[3] + pile[4])        #no moves left
  4981.         push (ops, move1 (op))  |  runerr (500, op)
  4982.     }
  4983. end                                            #automatic
  4984.  
  4985.  
  4986. #    u a u t o m a t i c
  4987. # Play this hand automatically, untouched by human hands.
  4988. # This is the command fuction that interacts with the user.
  4989. procedure uautomatic ()
  4990.     writes ("utomatic")
  4991.     writeInfo (if automatic()  then  ""  else  "Interrupted")
  4992.     return
  4993. end                                            #uautomatic
  4994.  
  4995.  
  4996. #    u c o n t i n u o u s
  4997. # Plays automatic games -- forever (or until user interrupts)
  4998. procedure ucontinuous()
  4999.     writes ("ontinuous")
  5000.     repeat  {
  5001.         writeCursor (16, 65)                #between Info line and Command line
  5002.         writes (center ((string(totalGames) || "   " || string(totalAces)), 16))
  5003.         (totalAces +:= automatic())  |  (writeInfo ("Interrupted"),  break)
  5004.         totalGames +:= 1
  5005.         (!pile < 13)  |  (totalWins +:= 1)
  5006.         lastSeed := newGame()
  5007.         writeAt (17, 65, "> Continuous")
  5008.     }
  5009.     return
  5010. end                                            #ucontinuous
  5011.  
  5012.  
  5013. #    u m o v e
  5014. # Move a card from deck to stack, or from stack to ace pile,
  5015. # or move a stack to another stack.
  5016. # Parameter is the source [1-7 or D]; else &null to indicate that "M" was used
  5017. # and therefore source should be gathered from the keyboard.
  5018. # Fails if indicated move is not possible
  5019. # This is the routine that interacts with the user.
  5020. procedure umove (src)
  5021. local dst, c, op, moved, col
  5022.     if \src  then
  5023.         output (VbackSpace, "Move ", Vbold, src)
  5024.     else {
  5025.         output ("ove ", Vbold);
  5026.         until (src := getCmdChar ())
  5027.         (src == ESC)  &  return
  5028.     }
  5029.     col := 73
  5030.     if src == "D"  then  {
  5031.         (*deckUp = 0)  &  fail
  5032.         output (Vnormal, "eck")
  5033.         col +:= 3
  5034.     } else {
  5035.         any ('1234567', src)  |  fail
  5036.         (*stackUp[src] = 0)  &  fail
  5037.         writeStackNumber (src, Vblink)
  5038.         writeCursor (17, col)
  5039.     }
  5040.  
  5041.     output (Vnormal, " to ", Vbold)
  5042.     until (dst := getCmdChar ())
  5043.     col +:= 5
  5044.     if src ~== "D"  then  {
  5045.         writeStackNumber (src, Vnormal)
  5046.         writeCursor (17, col)
  5047.     }
  5048.     (dst == ESC)  &  return
  5049.     any ('A1234567', dst)  |  fail
  5050.     (dst == src)  &  fail
  5051.     (dst == "A")  &  (src ~== "D")  &  output (Vnormal, "ce")
  5052.  
  5053.     return  push (ops, move1("M" || src || dst || "0"))
  5054. end                                            #umove
  5055.  
  5056.  
  5057. #    u u n d o
  5058. # backup one move, including any automatic ace moves
  5059. procedure uundo ()
  5060.     writes ("ndo")
  5061.     undo()
  5062.     return
  5063. end                                            #uundo
  5064.  
  5065.  
  5066. #    u d e b u g
  5067. # Additional commands to support the implementer.
  5068. procedure udebug ()
  5069. local s, d, name
  5070.     (\debugging)  |  return complain()
  5071.     output (VbackSpace, "Debug ")
  5072.     until (s := getCmdChar ())
  5073.     case s  of  {
  5074.         ESC        :    fail                    #debug command aborted
  5075.         "A"        :    {                        #play this game again
  5076.                     writes ("gain")
  5077.                     &random := lastSeed
  5078.                     outputAt (22, 1, Vbold,
  5079.                                 "&random set.  Quit to play this game again.",
  5080.                                 Vnormal, VclearEOL)
  5081.                 }
  5082.         "D"        :    display()                #dump ICON state
  5083.         "H"|"?"    :    {
  5084.                     output (if s == "?" then (VbackSpace || "help") else  "elp")
  5085.                     outputAt (22, 1, Vbold,
  5086.                      "Again, Dump, Options, Move, Peek{1-7UD}, Restore, Save, Toggle{AQT}.",
  5087.                      Vnormal, VclearEOL)
  5088.                 }
  5089.         "M"        :    {                        #move, without legality checking
  5090.                     writes ("ove ")
  5091.                     until (s := getCmdChar ())    #Source
  5092.                     (s == ESC)  &  fail
  5093.                     (s == "A")  &  fail
  5094.                     until (d := getCmdChar ())    #Destination
  5095.                     (d == ESC)  &  fail
  5096.                     (d == s)  &  fail
  5097.                     any('1234567', d)  |  fail
  5098.                     if s == "D"  then  {
  5099.                         (*deckUp = 0)  &  fail
  5100.                         put (stackUp[d], get(deckUp))
  5101.                         writeDeckUp ()
  5102.                         writeStack (d)
  5103.                         push (ops, "MD" || d || "0")
  5104.                     } else {
  5105.                         moveStack (s, d)
  5106.                         push (ops, "M" || s || d || "123456789abcdef"[*stackUp[s]])
  5107.                     }
  5108.                 }
  5109.         "O"        :    {                        #show command-line options
  5110.                     writes ("ptions")
  5111.                     outputAt (22, 1, Vbold,
  5112.                         if \automaticAce  then  "AutomaticAce  "  else  "",
  5113.                         if 0 < *directory then  ("-D"||directory||"  ") else "",
  5114.                         if \phraseFile  then  ("-P"||phraseFile||"  ") else  "",
  5115.                         if \isQuiet  then  "Quiet  "  else  "",
  5116.                         ("-S" || strategy),  Vnormal, VclearEOL)
  5117.                     outputAt (23, 1, Vbold, "&trace=", &trace, 
  5118.                          "  firstSeed=", firstSeed, "  lastSeed=", lastSeed,
  5119.                          Vnormal, VclearEOL)
  5120.                 }
  5121.         "P"        :    {                        #look at hidden cards
  5122.                     writes ("eek ")
  5123.                     until (s := getCmdChar ())
  5124.                     (s == ESC)  &  fail
  5125.                     outputAt (22, 1, VclearEOL, Vnormal)
  5126.                     if any('1234567', s)  then  showList (stackDown[s])
  5127.                     else if s == "D"      then  showList (deckDown)
  5128.                     else if s == "U"      then  showList (deckUp)
  5129.                     else complain ()
  5130.                 }
  5131.         "R"        :    {                        #restore current state from a file
  5132.                     writes ("estore")
  5133.                     until (s := getCmdChar ())
  5134.                     (s == ESC)  &  fail
  5135.                     name := "klondike.sv" || s
  5136.                     if (d := restoreState(name))  then  {
  5137.                         refreshScreen()
  5138.                         outputAt (22, 1, Vbold, "Restored position from file ",
  5139.                                 directory || name, " of ", d, Vnormal,VclearEOL)
  5140.                     } else {
  5141.                         outputAt (22, 1, Vblink, "Can't restore from file ",
  5142.                                 directory || name, Vnormal, VclearEOL)
  5143.                     }
  5144.                 }
  5145.         "S"        :    {                        #save current state to a file
  5146.                     writes ("ave ")
  5147.                     until (s := getCmdChar ())
  5148.                     (s == ESC)  &  fail
  5149.                     name := "klondike.sv" || s
  5150.                     writeCursor (22, 1)
  5151.                     if saveState (name)  then
  5152.                         output (Vbold, "Position saved in file ",
  5153.                                 directory || name, Vnormal, VclearEOL)
  5154.                     else
  5155.                         output (Vblink, "Can't save in file ",
  5156.                                 directory || name, Vnormal, VclearEOL)
  5157.                 }
  5158.         "T"        :    {                        #toggle a command-line flag
  5159.                     writes ("oggle ")
  5160.                     until (s := getCmdChar ())
  5161.                     (s == ESC)  &  fail
  5162.                     case s  of  {
  5163.                         "A"        : automaticAce := if \automaticAce then &null
  5164.                                                                           else 1
  5165.                         "Q"        : isQuiet      := if \isQuiet then &null  else 1
  5166.                         "T"        : &trace       := if &trace = 0  then -1  else 0
  5167.                         default    : complain ()
  5168.                     }                                    #case for Toggle
  5169.                 }
  5170.         default    :    complain ()
  5171.     }                                            #case for Debug command
  5172.     return
  5173. end                                            #udebug
  5174.  
  5175.  
  5176. #    u b o s s
  5177. # Cheese it, the Fuzz.
  5178. # Quick -- clear the screen and save the position in a file.
  5179. procedure uboss ()
  5180.     writes ("oss")                # "consistency is the hobgoblin of small minds"
  5181.     terminateScreen ()                        #put screen in the correct state
  5182.     writes ("C>")                            #look innocent
  5183.     saveState ("klondike.sav")
  5184.     exit ()
  5185. end                                            #uboss
  5186.  
  5187.  
  5188. #    w r i t e S t a t i s t i c s
  5189. # Using the global counter variables, compute & write out some elementary stats.
  5190. # These are written to stderr so as not to mess up any batch file which might
  5191. # be collecting statistics whilst running klondike in -Batch mode.
  5192. # Note that write() is kosher here since this should only be called after
  5193. # terminate() has been called to restore the screen to its original state.
  5194. procedure writeStatistics ()
  5195.     if 1 < totalGames  then  {
  5196.         write (&errout, "In ", totalGames, " games you put ", totalAces,
  5197.                 " cards on the ace piles.")
  5198.         if 0 < totalAces  then
  5199.             write (&errout,
  5200.                     "Average ", real(totalAces) / real(totalGames),
  5201.                     " cards on the ace piles per game.")
  5202.         if 0 < totalWins  then
  5203.             write (&errout,
  5204.                     "You won ", totalWins, " (",
  5205.                     left((totalWins * 100.) / totalGames, 4),
  5206.                     "%) of those games.")
  5207.         write (&errout,
  5208.                 "Average ", real(&time) / totalGames / 1000,
  5209.                 " seconds per game.")
  5210.     } else {
  5211.         write (&errout,
  5212.                 "In 1 game you put ", totalAces, " cards on the ace piles.")
  5213.         write (&errout, "Total time was ", real(&time) / 1000, " seconds.")
  5214.     }
  5215.     write (&errout, "Initial random seed was ", firstSeed)
  5216.     return
  5217. end                                            #writeStatistics
  5218.  
  5219.  
  5220. #    u t e r m i n a t e
  5221. # Returns success to quit this game and start another.
  5222. # Returns failure to just continue this game.
  5223. # If program termination is wished, that is done right here.
  5224. procedure uterminate ()
  5225. local s
  5226.     if (!pile < 13)  then
  5227.         writes ("uit")
  5228.     else
  5229.         outputAt (12, 22, Vbold, Vblink, "Congratulations -- You've WON !!!",
  5230.                     Vnormal)
  5231.     writeInfo (Vbold || "Another game? ")
  5232.     until (s := getCmdChar ())
  5233.     case s  of  {
  5234.         ESC        :    fail                #didn't really want to quit after all
  5235.         "Y"        :    return                #please start a new game
  5236.         "N"        :    {                    #program termination requested
  5237.                     totalGames +:= 1
  5238.                     every totalAces +:= !pile
  5239.                     (!pile < 13)  |  (totalWins +:= 1)
  5240.                     terminateScreen ()
  5241.                     writeStatistics ()
  5242.                     exit ()
  5243.         }
  5244.         default    :    {complain(); fail}    #continue playing this game
  5245.     }
  5246.     runerr (500, s)
  5247. end                                            #uterminate
  5248.  
  5249.  
  5250. #    d o B a t c h
  5251. # Plays the requested number of games in batch mode.
  5252. # Returns three-element list of results.
  5253. # If the number of games to play is 0 or negative, then plays until interrupted.
  5254. procedure doBatch (gamesToPlay)
  5255. local games, wins, aces
  5256.     games := wins := aces := 0
  5257.     repeat  {
  5258.         newGame ()
  5259.         if aces +:= automatic()  then  {
  5260.             (!pile < 13)  |  (wins +:= 1)
  5261.             ((games +:= 1) = gamesToPlay)  &  break
  5262.         } else
  5263.             break                            #interrupted from keyboard
  5264.     }
  5265.     return  [games, wins, aces]
  5266. end                                            #doBatch
  5267.  
  5268.  
  5269. #    u b a t c h
  5270. # Plays the requested number of games (0 => infinity) in batch mode.
  5271. # Results are reported after every interval (0 => only at end) games.
  5272. # Statistics are output when done or interrupted, whichever comes first.
  5273. procedure ubatch (gamesToPlay, interval)
  5274. local veryFirstSeed, stat
  5275.     isQuiet := invisible := 1
  5276.     veryFirstSeed := &random                #remember the initial random seed
  5277.     (interval = 0)  &  (interval := gamesToPlay)
  5278.     repeat  {
  5279.         (0 < gamesToPlay)  &  (interval >:= gamesToPlay)
  5280.         firstSeed := &random                #random seed for first game this set
  5281.         stat := doBatch (interval)
  5282.         write (firstSeed, "\t", stat[1], "\t", stat[2], "\t", stat[3])
  5283.         totalGames +:= stat[1]
  5284.         totalWins  +:= stat[2]
  5285.         totalAces  +:= stat[3]
  5286.         (stat[1] ~= interval)  &  break        #interrupted by user
  5287.         (0 = (gamesToPlay -:= interval))  &  break
  5288.     }
  5289.     firstSeed := veryFirstSeed                #required for writeStatistics()
  5290.     writeStatistics ()
  5291.     exit ()
  5292. end                                            #ubatch
  5293.  
  5294.  
  5295. #    m a i n
  5296. procedure main (av)
  5297. local s, prevsCmd, batchMode, reportInterval, again, termtype
  5298.  
  5299.     # initialize
  5300.     isDOS := find("MS-DOS", &host)            #probably a reasonable assumption
  5301.     isPC  := isDOS                            #really a pretty poor assumption
  5302.     totalGames:=totalAces:=totalWins := 0    #statistics
  5303.  
  5304.     # set defaults
  5305.     findBest("")                            # set global variable strategy
  5306.     automaticAce    := 1                    # automatic ace handling
  5307.     debugging        := &null                # no debugging allowed
  5308.     directory        := ""                    # use current directory
  5309.     invisible        := &null                # let's see the action
  5310.     batchMode        := &null                # interactive mode
  5311.     reportInterval    := 0                    # report only at end of batch mode
  5312.     phraseFile        := &null                # use all built-in phrases
  5313.     isQuiet            := &null                # make clicks & beeps if possible
  5314.     termtype        := if \isPC then "pc" else "mono"
  5315.     &random            := map (&clock, ":", "7")        # randomize the seed
  5316.  
  5317.     # deal with command-line parameters
  5318.     reverse(getenv("KLONDIKE")) ?             #pre-pend env var words to cmd line
  5319.         while tab(upto(~" \t\v\f\r\n"))  do
  5320.             push (av, reverse(tab(many(~" \t\v\f\r\n"))))
  5321.     while s := get (av)  do
  5322.         case s[1:3]  of  {
  5323.             "-A" | "-a"    :    automaticAce    :=if \automaticAce then &null else 1
  5324.             "-B" | "-b"    :    batchMode        :=    (integer(s[3:0])  |  0)
  5325.             "-D" | "-d"    :    directory        :=    if *s < 3  then
  5326.                                                     getenv ("HOME" | "ROOTDIR")
  5327.                                                 else
  5328.                                                     s[3:0]
  5329.             "-I" | "-i"    :    reportInterval    :=    (integer(s[3:0])  |  1)
  5330.             "-P" | "-p"    :    phraseFile        :=    s[3:0]
  5331.             "-Q" | "-q"    :    isQuiet            :=    if \isQuiet then  &null  else  1
  5332.             "-R" | "-r"    :    &random         :=    integer (s[3:0])
  5333.             "-S" | "-s"    :    findBest (s[3:0])            #check & store strategy
  5334.             "-T" | "-t"    :    termtype        :=    s[3:0]
  5335.             "-Z" | "-z"    :    debugging        :=    if \debugging then  &null else 1
  5336.             default        :    {
  5337.                             # screen mode not yet initialized, so write() is OK
  5338.                             write ("klondike  [-AQZ]  [-B[count]]  [-D[dir]]  [-I[interval]]")
  5339.                             write ("          [-P[file]]  [-Rseed]  [-Sstrategy]  [-T[term]]")
  5340.                             # screen mode not yet initialized, so stop() is OK
  5341.                             stop ("klondike: bogus option  ", s)
  5342.             }
  5343.         }
  5344.  
  5345.     # initializations which use command-line parameters
  5346.     (map(termtype, &lcase, &ucase) == "PC")  &  isPC := 1
  5347.     initConstants (termtype)                #need updated termtype from cmdline
  5348.     initVariables ()                        #establish all the lists and such
  5349.  
  5350.     # when defined, batchMode is the number of games to play; 0 => infinity.
  5351.     ubatch (\batchMode, reportInterval)        #conditional call of no return
  5352.  
  5353.     # Establish the directory for file I/O; with a trailing "/" if non-empty.
  5354.     # It is only used directly in the open() and remove() calls.
  5355.     (0 < *directory)  &  (directory := trim(directory, '/\\')  ||  "/")
  5356.  
  5357.     # If last game was terminated via the Boss key then restore it now,
  5358.     # otherwise start up a new game.
  5359.     if restoreState ("klondike.sav")  then  {
  5360.         refreshScreen ()
  5361.         writeInfo ("Game restored")
  5362.         remove (directory || "klondike.sav")
  5363.     } else {
  5364.         firstSeed := &random                    #random seed for first game
  5365.         lastSeed := newGame ()                    #start a new game, stashing seed
  5366.     }
  5367.  
  5368.  
  5369.     repeat  {                                    #game loop
  5370.         prevsCmd := "-none-"
  5371.         repeat  {                                    #command loop
  5372.             outputAt (17, 65, VclearEOL, Vnormal, "> ")        #clear command line
  5373.             until (s := getCmdChar ())
  5374.             again := (if s == prevsCmd  then  s  else  &null)
  5375.             writeInfo ("")                                    #clear info line
  5376.             writeCursor (17, 68)                            #just after cmd char
  5377.             case  s  of  {
  5378.                 "?"|"H"    :    uhelp()
  5379.                 "1"|"2"|"3"|"4"|"5"|"6"|"7"|"D"    :            #short-cut for Move
  5380.                             umove (s)  |  complain ()
  5381.                 "A"        :    uautomatic()                    #look Ma, no hands!
  5382.                 "B"        :    uboss()                            #bail out quick
  5383.                 "C"        :    ucontinuous()                    #no hands, forever
  5384.                 "F"        :    ufind (again)  &  break            #new game
  5385.                 "M"        :    umove (&null)  |  complain ()
  5386.                 "Q"        :    uterminate ()  &  break            #new game
  5387.                 "S"        :    usuggest (again)
  5388.                 "T"        :    { writes("humb");  push(ops, thumb()) }
  5389.                 "U"        :    uundo()
  5390.                 "Z"        :    udebug()
  5391.                 "\^L"    :    refreshScreen()
  5392.                 ESC        :    s                                #do nothing here
  5393.                 default    :    complain()
  5394.             }                                #case
  5395.             prevsCmd := s
  5396.             (!pile < 13)  |  (uterminate ()  &  break)        # VICTORY!
  5397.         }                                    #repeat command
  5398.         totalGames +:= 1
  5399.         every totalAces +:= !pile
  5400.         (!pile < 13)  |  (totalWins +:= 1)
  5401.         lastSeed := newGame ()
  5402.     }                                        #repeat game
  5403. end                                            #main
  5404. SHAR_EOF
  5405. if test 19820 -ne "`wc -c < 'klondike.icn'`"
  5406. then
  5407.     echo shar: error transmitting "'klondike.icn'" '(should have been 19820 characters)'
  5408. fi
  5409. fi # end of overwriting check
  5410. #    End of shell archive
  5411. exit 0
  5412. -- 
  5413. PAPER:  Norman Azadian; Ascom AG; Belpstrasse 23; 3000 Berne 14; Switzerland
  5414. INTERNET:  naz%hslrswi.uucp@uunet.uu.net
  5415. UUCP:   ...{uunet,ukc,mcvax,...}!chx400!hslrswi!naz
  5416. VOICE:  +41 31 63 2178            BITNET: naz%hslrswi.UUCP@cernvax.BITNET
  5417.  
  5418. From icon-group-request@arizona.edu  Sun Apr 21 20:11:07 1991
  5419. Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Sun, 21 Apr 91 20:11:07 MST
  5420. Resent-From: icon-group-request@arizona.edu
  5421. Received: from Arizona.edu (Merlin.Telcom.Arizona.EDU) by optima.cs.arizona.edu (4.1/15)
  5422.     id AA17560; Sun, 21 Apr 91 20:11:02 MST
  5423. Received: from ucbvax.Berkeley.EDU by Arizona.edu with PMDF#10282; Sun, 21 Apr
  5424.  1991 20:10 MST
  5425. Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA04085; Sun, 21 Apr 91
  5426.  19:53:24 -0700
  5427. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  5428.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  5429.  usenet@ucbvax.Berkeley.EDU if you have questions)
  5430. Resent-Date: Sun, 21 Apr 1991 20:10 MST
  5431. Date: 21 Apr 91 14:09:12 GMT
  5432. From: eru!hagbard!sunic!mcsun!cernvax!chx400!chx400!hslrswi!naz@bloom-beacon.mit.edu
  5433.  (Norman H. Azadian)
  5434. Subject: Klondike solitaire, v3.01, part 6/6
  5435. Sender: icon-group-request@arizona.edu
  5436. Resent-To: icon-group@cs.arizona.edu
  5437. To: icon-group@arizona.edu
  5438. Resent-Message-Id: <9D656F0E8C8016B5@Arizona.edu>
  5439. Message-Id: <1946@hslrswi.hasler.ascom.ch>
  5440. X-Envelope-To: icon-group@CS.Arizona.EDU
  5441. X-Vms-To: icon-group@Arizona.edu
  5442. Organization: Hasler AG
  5443.  
  5444.  
  5445. #! /bin/sh
  5446. # This is a shell archive, meaning:
  5447. # 1. Remove everything above the #! /bin/sh line.
  5448. # 2. Save the resulting text in a file.
  5449. # 3. Execute the file with /bin/sh (not csh) to create the files:
  5450. #    iolib.icn
  5451. # This archive created: Sun Apr 21 15:04:45 1991
  5452. # By:    Norman H. Azadian (Hasler AG)
  5453. export PATH; PATH=/bin:$PATH
  5454. echo shar: extracting "'iolib.icn'" '(17272 characters)'
  5455. if test -f 'iolib.icn'
  5456. then
  5457.     echo shar: will not over-write existing file "'iolib.icn'"
  5458. else
  5459. cat << \SHAR_EOF > 'iolib.icn'
  5460. ########################################################################
  5461. #    
  5462. #    Name:    iolib.icn
  5463. #    
  5464. #    Title:    Icon termlib-type tools for MS-DOS and UNIX
  5465. #    
  5466. #    Author:    Richard L. Goerwitz (with help from Norman Azadian)
  5467. #
  5468. #    Version: 1.9
  5469. #
  5470. #########################################################################
  5471. #
  5472. #  The authors place this and future versions of iolib in the public
  5473. #  domain.
  5474. #
  5475. #########################################################################
  5476. #
  5477. #  The following library represents a series of rough functional
  5478. #  equivalents to the standard Unix low-level termcap routines.  It is
  5479. #  not meant as an exact termlib clone.  Nor is it enhanced to take
  5480. #  care of magic cookie terminals, terminals that use \D in their
  5481. #  termcap entries, or archaic terminals that require padding.  This
  5482. #  library is geared mainly for use with ANSI and VT-100 devices.
  5483. #  Note that this file may, in most instances, be used in place of the
  5484. #  older UNIX-only itlib.icn file.  It essentially replaces the DOS-
  5485. #  only itlibdos routines.  For DOS users not familiar with the whole
  5486. #  notion of generalized screen I/O, I've included extra documentation
  5487. #  below.  Please read it.
  5488. #
  5489. #  The sole disadvantage of this over the old itlib routines is that
  5490. #  iolib.icn cannot deal with archaic or arcane UNIX terminals and/or
  5491. #  odd system file arrangements.  Note that because these routines
  5492. #  ignore padding, they can (unlike itlib.icn) be run on the NeXT and
  5493. #  other systems which fail to implement the -g option of the stty
  5494. #  command.  Iolib.icn is also simpler and faster than itlib.icn.
  5495. #
  5496. #  I want to thank Norman Azadian for suggesting the whole idea of
  5497. #  combining itlib.icn and itlibdos.icn into one distribution, for
  5498. #  suggesting things like letting drive specifications appear in DOS
  5499. #  TERMCAP environment variables, and for finding several bugs (e.g.
  5500. #  the lack of support for %2 and %3 in cm).  Although he is loathe
  5501. #  to accept this credit, I think he deserves it.
  5502. #
  5503. #########################################################################
  5504. #
  5505. #  Contents:
  5506. #
  5507. #  setname(term)
  5508. #    Use only if you wish to initialize itermlib for a terminal
  5509. #  other than what your current environment specifies.  "Term" is the
  5510. #  name of the termcap entry to use.  Normally this initialization is
  5511. #  done automatically, and need not concern the user.
  5512. #
  5513. #  getval(id)
  5514. #    Works something like tgetnum, tgetflag, and tgetstr.  In the
  5515. #  spirit of Icon, all three have been collapsed into one routine.
  5516. #  Integer valued caps are returned as integers, strings as strings,
  5517. #  and flags as records (if a flag is set, then type(flag) will return
  5518. #  "true").  Absence of a given capability is signalled by procedure
  5519. #  failure.
  5520. #
  5521. #  igoto(cm,destcol,destline) - NB:  default 1 offset (*not* zero)!
  5522. #    Analogous to tgoto.  "Cm" is the cursor movement command for
  5523. #  the current terminal, as obtained via getval("cm").  Igoto()
  5524. #  returns a string which, when output via iputs, will cause the
  5525. #  cursor to move to column "destcol" and line "destline."  Column and
  5526. #  line are always calculated using a *one* offset.  This is far more
  5527. #  Iconish than the normal zero offset used by tgoto.  If you want to
  5528. #  go to the first square on your screen, then include in your program
  5529. #  "iputs(igoto(getval("cm"),1,1))."
  5530. #
  5531. #  iputs(cp,affcnt)
  5532. #    Equivalent to tputs.  "Cp" is a string obtained via getval(),
  5533. #  or, in the case of "cm," via igoto(getval("cm"),x,y).  Affcnt is a
  5534. #  count of affected lines.  It is completely irrelevant for most
  5535. #  modern terminals, and is supplied here merely for the sake of
  5536. #  backward compatibility with itlib, a UNIX-only version of these
  5537. #  routines (one which handles padding on archaic terminals).
  5538. #
  5539. ##########################################################################
  5540. #
  5541. #  Notes for MS-DOS users:
  5542. #
  5543. #    There are two basic reasons for using the I/O routines
  5544. #  contained in this package.  First, by using a set of generalized
  5545. #  routines, your code will become much more readable.  Secondly, by
  5546. #  using a high level interface, you can avoid the cardinal
  5547. #  programming error of hard coding things like screen length and
  5548. #  escape codes into your programs.
  5549. #
  5550. #    To use this collection of programs, you must do two things.
  5551. #  First, you must add the line "device=ansi.sys" (or the name of some
  5552. #  other driver, like zansi.sys, nansi.sys, or nnansi.sys [=new
  5553. #  nansi.sys]) to your config.sys file.  Secondly, you must add two
  5554. #  lines to your autoexec.bat file: 1) "set TERM=ansi-mono" and 2)
  5555. #  "set TERMCAP=\location\termcap."  The purpose of setting the TERM
  5556. #  variable is to tell this program what driver you are using.  If you
  5557. #  have a color system, you could use "ansi-color" instead of
  5558. #  "ansi-mono," although for compatibility with a broader range of
  5559. #  users, it would perhaps be better to stick with mono.  The purpose
  5560. #  of setting TERMCAP is to make it possible to determine where the
  5561. #  termcap database file is located.  The termcap file (which should
  5562. #  have been packed with this library as termcap.dos) is a short
  5563. #  database of all the escape sequences used by the various terminal
  5564. #  drivers.  Set TERMCAP so that it reflects the location of this file
  5565. #  (which should be renamed as termcap, for the sake of consistency
  5566. #  across UNIX and MS-DOS spectra).  If desired, you can also try
  5567. #  using termcap2.dos.  Certain games work a lot better using this
  5568. #  alternate file.  To try it out, rename it to termcap, and set
  5569. #  the environment variable TERMCAP to its location.
  5570. #
  5571. #    Although the authors make no pretense of providing here a
  5572. #  complete introduction to the format of the termcap database file,
  5573. #  it will be useful, we believe, to explain a few basic facts about
  5574. #  how to use this program in conjunction with it.  If, say, you want
  5575. #  to clear the screen, add the line,
  5576. #
  5577. #    iputs(getval("cl"))
  5578. #
  5579. #  to your program.  The function iputs() outputs screen control
  5580. #  sequences.  Getval retrieves a specific sequence from the termcap
  5581. #  file.  The string "cl" is the symbol used in the termcap file to
  5582. #  mark the code used to clear the screen.  By executing the
  5583. #  expression "iputs(getval("cl"))," you are 1) looking up the "cl"
  5584. #  (clear) code in the termcap database entry for your terminal, and
  5585. #  the 2) outputting that sequence to the screen.
  5586. #
  5587. #    Some other useful termcap symbols are "ce" (clear to end of
  5588. #  line), "ho" (go to the top left square on the screen), "so" (begin
  5589. #  standout mode), and "se" (end standout mode).  To output a
  5590. #  boldfaced string, str, to the screen, you would write -
  5591. #
  5592. #    iputs(getval("so"))
  5593. #    writes(str)
  5594. #    iputs(getval("se"))
  5595. #
  5596. #  You can also write "writes(getval("so") || str || getval("se")),
  5597. #  but this would make reimplementation for UNIX terminals that
  5598. #  require padding rather difficult.
  5599. #
  5600. #    It is also heartily to be recommended that MS-DOS programmers
  5601. #  try not to assume that everyone will be using a 25-line screen.
  5602. #  Most terminals are 24-line.  Some 43.  Some have variable window
  5603. #  sizes.  If you want to put a status line on, say, the 2nd-to-last
  5604. #  line of the screen, then determine what that line is by executing
  5605. #  "getval("li")."  The termcap database holds not only string-valued
  5606. #  sequences, but numeric ones as well.  The value of "li" tells you
  5607. #  how many lines the terminal has (compare "co," which will tell you
  5608. #  how many columns).  To go to the beginning of the second-to-last
  5609. #  line on the screen, type in:
  5610. #
  5611. #    iputs(igoto(getval("cm"), 1, getval("li")-1))
  5612. #
  5613. #  The "cm" capability is a special capability, and needs to be output
  5614. #  via igoto(cm,x,y), where cm is the sequence telling your computer
  5615. #  to move the cursor to a specified spot, x is the column, and y is
  5616. #  the row.  The expression "getval("li")-1" will return the number of
  5617. #  the second-to-last line on your screen.
  5618. #
  5619. ##########################################################################
  5620. #
  5621. #  Requires: UNIX or MS-DOS, co-expressions
  5622. #
  5623. #  See also: itlib.icn, iscreen.icn
  5624. #
  5625. ##########################################################################
  5626.  
  5627.  
  5628. global tc_table, isDOS
  5629. record true()
  5630.  
  5631.  
  5632. procedure check_features()
  5633.  
  5634.     initial {
  5635.  
  5636.     if find("UNIX",&features) then
  5637.         isDOS := &null
  5638.     else if find("MS-DOS", &features) then
  5639.         isDOS := 1
  5640.     else stop("check_features:  OS not (yet?) supported.")
  5641.  
  5642.     find("expressi",&features) |
  5643.         er("check_features","co-expressions not implemented - &$#!",1)
  5644.     }
  5645.  
  5646.     return
  5647.  
  5648. end
  5649.  
  5650.  
  5651.  
  5652. procedure setname(name)
  5653.  
  5654.     # Sets current terminal type to "name" and builds a new termcap
  5655.     # capability database (residing in tc_table).  Fails if unable to
  5656.     # find a termcap entry for terminal type "name."  If you want it
  5657.     # to terminate with an error message under these circumstances,
  5658.     # comment out "| fail" below, and uncomment the er() line.
  5659.  
  5660.     #tc_table is global
  5661.     
  5662.     check_features()
  5663.  
  5664.     tc_table := table()
  5665.     tc_table := maketc_table(getentry(name)) | fail
  5666.     # er("setname","no termcap entry found for "||name,3)
  5667.     return "successfully reset for terminal " || name
  5668.  
  5669. end
  5670.  
  5671.  
  5672.  
  5673. procedure getname()
  5674.  
  5675.     # Getname() first checks to be sure we're running under DOS or
  5676.     # UNIX, and, if so, tries to figure out what the current terminal
  5677.     # type is, checking successively the value of the environment
  5678.     # variable TERM, and then (under UNIX) the output of "tset -".
  5679.     # Terminates with an error message if the terminal type cannot be
  5680.     # ascertained.  DOS defaults to "mono."
  5681.  
  5682.     local term, tset_output
  5683.  
  5684.     check_features()
  5685.  
  5686.     if \isDOS then {
  5687.         term := getenv("TERM") | "mono"
  5688.     }
  5689.     else {
  5690.     if not (term := getenv("TERM")) then {
  5691.         tset_output := open("/bin/tset -","pr") |
  5692.         er("getname","can't find tset command",1)
  5693.         term := !tset_output
  5694.         close(tset_output)
  5695.     }
  5696.     }
  5697.  
  5698.     return \term |
  5699.     er("getname","can't seem to determine your terminal type",1)
  5700.  
  5701. end
  5702.  
  5703.  
  5704.  
  5705. procedure er(func,msg,errnum)
  5706.  
  5707.     # short error processing utility
  5708.     write(&errout,func,":  ",msg)
  5709.     exit(errnum)
  5710.  
  5711. end
  5712.  
  5713.  
  5714.  
  5715. procedure getentry(name, termcap_string)
  5716.  
  5717.     # "Name" designates the current terminal type.  Getentry() scans
  5718.     # the current environment for the variable TERMCAP.  If the
  5719.     # TERMCAP string represents a termcap entry for a terminal of type
  5720.     # "name," then getentry() returns the TERMCAP string.  Otherwise,
  5721.     # getentry() will check to see if TERMCAP is a file name.  If so,
  5722.     # getentry() will scan that file for an entry corresponding to
  5723.     # "name."  If the TERMCAP string does not designate a filename,
  5724.     # getentry() will scan the termcap file for the correct entry.
  5725.     # Whatever the input file, if an entry for terminal "name" is
  5726.     # found, getentry() returns that entry.  Otherwise, getentry()
  5727.     # fails.
  5728.  
  5729.     local isFILE, f, getline, line, nm, ent1, ent2
  5730.     static slash, termcap_names
  5731.     initial {
  5732.     if \isDOS then {
  5733.         slash := "\\"
  5734.         termcap_names := ["termcap","termcap.dos","termcap2.dos"]
  5735.     }
  5736.     else {
  5737.         slash := "/"
  5738.         termcap_names := ["/etc/termcap"]
  5739.     }
  5740.     }
  5741.  
  5742.  
  5743.     # You can force getentry() to use a specific termcap file by cal-
  5744.     # ling it with a second argument - the name of the termcap file
  5745.     # to use instead of the regular one, or the one specified in the
  5746.     # termcap environment variable.
  5747.     /termcap_string := getenv("TERMCAP")
  5748.  
  5749.     if \isDOS then {
  5750.     if \termcap_string then {
  5751.         if termcap_string ? (
  5752.          not ((tab(any(&letters)), match(":")) | match(slash)),
  5753.          pos(1) | tab(find("|")+1), =name)
  5754.         then return termcap_string
  5755.         else isFILE := 1
  5756.     }
  5757.     }
  5758.     else {
  5759.     if \termcap_string then {
  5760.         if termcap_string ? (
  5761.             not match(slash), pos(1) | tab(find("|")+1), =name)
  5762.         then return termcap_string
  5763.         else isFILE := 1
  5764.     }
  5765.     }
  5766.  
  5767.     # The logic here probably isn't clear.  The idea is to try to use
  5768.     # the termcap environment variable successively as 1) a termcap en-
  5769.     # try and then 2) as a termcap file.  If neither works, 3) go to
  5770.     # the /etc/termcap file.  The else clause here does 2 and, if ne-
  5771.     # cessary, 3.  The "\termcap_string ? (not match..." expression
  5772.     # handles 1.
  5773.  
  5774.     if \isFILE            # if find(slash, \termcap_string)
  5775.     then f := open(termcap_string)
  5776.     /f := open(!termcap_names) |
  5777.     er("getentry","I can't access your termcap file.  Read iolib.icn.",1)
  5778.     
  5779.     getline := create read_file(f)
  5780.     
  5781.     while line := @getline do {
  5782.     if line ? (pos(1) | tab(find("|")+1), =name, any(':|')) then {
  5783.         entry := ""
  5784.         while (\line | @getline) ? {
  5785.         if entry ||:= 1(tab(find(":")+1), pos(0))
  5786.         then {
  5787.             close(f)
  5788.             # if entry ends in tc= then add in the named tc entry
  5789.             entry ?:= tab(find("tc=")) ||
  5790.             # recursively fetch the new termcap entry
  5791.             (move(3), getentry(tab(find(":"))) ?
  5792.              # remove the name field from the new entry
  5793.              (tab(find(":")+1), tab(0)))
  5794.             return entry
  5795.         }
  5796.         else {
  5797.             \line := &null # must precede the next line
  5798.             entry ||:= trim(trim(tab(0),'\\'),':')
  5799.         }
  5800.         }
  5801.     }
  5802.     }
  5803.  
  5804.     close(f)
  5805.     er("getentry","can't find and/or process your termcap entry",3)
  5806.  
  5807. end
  5808.  
  5809.  
  5810.  
  5811. procedure read_file(f)
  5812.  
  5813.     # Suspends all non #-initial lines in the file f.
  5814.     # Removes leading tabs and spaces from lines before suspending
  5815.     # them.
  5816.  
  5817.     local line
  5818.  
  5819.     \f | er("read_tcap_file","no valid termcap file found",3)
  5820.     while line := read(f) do {
  5821.     match("#",line) & next
  5822.     line ?:= (tab(many('\t ')) | &null, tab(0))
  5823.     suspend line
  5824.     }
  5825.  
  5826.     fail
  5827.  
  5828. end
  5829.  
  5830.  
  5831.  
  5832. procedure maketc_table(entry)
  5833.  
  5834.     # Maketc_table(s) (where s is a valid termcap entry for some
  5835.     # terminal-type): Returns a table in which the keys are termcap
  5836.     # capability designators, and the values are the entries in
  5837.     # "entry" for those designators.
  5838.  
  5839.     local k, v
  5840.  
  5841.     /entry & er("maketc_table","no entry given",8)
  5842.     if entry[-1] ~== ":" then entry ||:= ":"
  5843.     
  5844.     /tc_table := table()
  5845.  
  5846.     entry ? {
  5847.  
  5848.     tab(find(":")+1)    # tab past initial (name) field
  5849.  
  5850.     while tab((find(":")+1) \ 1) ? {
  5851.         &subject == "" & next
  5852.         if k := 1(move(2), ="=") then {
  5853.         # Get rid of null padding information.  Iolib can't
  5854.         # handle it (unlike itlib.icn).  Leave star in.  It
  5855.         # indicates a real dinosaur terminal, and will later
  5856.         # prompt an abort.
  5857.         str := ="*" | ""; tab(many(&digits))
  5858.         tc_table[k] := Decode(str || tab(find(":")))
  5859.         }
  5860.         else if k := 1(move(2), ="#")
  5861.         then tc_table[k] := integer(tab(find(":")))
  5862.         else if k := 1(tab(find(":")), pos(-1))
  5863.         then tc_table[k] := true()
  5864.         else er("maketc_table", "your termcap file has a bad entry",3)
  5865.     }
  5866.     }
  5867.  
  5868.     return tc_table
  5869.  
  5870. end
  5871.  
  5872.  
  5873.  
  5874. procedure getval(id)
  5875.  
  5876.     /tc_table := maketc_table(getentry(getname())) |
  5877.     er("getval","can't make a table for your terminal",4)
  5878.  
  5879.     return \tc_table[id] | fail
  5880.     # er("getval","the current terminal doesn't support "||id,7)
  5881.  
  5882. end
  5883.  
  5884.  
  5885.  
  5886. procedure Decode(s)
  5887.  
  5888.     # Does things like turn ^ plus a letter into a genuine control
  5889.     # character.
  5890.  
  5891.     new_s := ""
  5892.  
  5893.     s ? {
  5894.  
  5895.     while new_s ||:= tab(upto('\\^')) do {
  5896.         chr := move(1)
  5897.         if chr == "\\" then {
  5898.         new_s ||:= {
  5899.             case chr2 := move(1) of {
  5900.             "\\" : "\\"
  5901.             "^"  : "^"
  5902.             "E"  : "\e"
  5903.             "b"  : "\b"
  5904.             "f"  : "\f"
  5905.             "n"  : "\n"
  5906.             "r"  : "\r"
  5907.             "t"  : "\t"
  5908.             default : {
  5909.                 if any(&digits,chr2) then {
  5910.                 char(integer("8r"||chr2||move(2 to 0 by -1))) |
  5911.                     er("Decode","bad termcap entry",3)
  5912.                 }
  5913.                else chr2
  5914.             }
  5915.             }
  5916.         }
  5917.         }
  5918.         else new_s ||:= char(ord(map(move(1),&lcase,&ucase)) - 64)
  5919.     }
  5920.     new_s ||:= tab(0)
  5921.     }
  5922.  
  5923.     return new_s
  5924.  
  5925. end
  5926.  
  5927.  
  5928.  
  5929. procedure igoto(cm,col,line)
  5930.  
  5931.     local colline, range, increment, padding, str, outstr, chr, x, y
  5932.  
  5933.     if col > (tc_table["co"]) | line > (tc_table["li"]) then {
  5934.     colline := string(\col) || "," || string(\line) | string(\col|line)
  5935.     range := "(" || tc_table["co"]-1 || "," || tc_table["li"]-1 || ")"
  5936.     er("igoto",colline || " out of range " || (\range|""),9)
  5937.     } 
  5938.  
  5939.     # Use the Iconish 1;1 upper left corner & not the C-ish 0 offsets
  5940.     increment := -1
  5941.     outstr := ""
  5942.     
  5943.     cm ? {
  5944.     while outstr ||:= tab(find("%")) do {
  5945.         tab(match("%"))
  5946.         if padding := integer(tab(any('23')))
  5947.         then chr := (="d" | "d")
  5948.         else chr := move(1)
  5949.         if case \chr of {
  5950.         "." :  outstr ||:= char(line + increment)
  5951.         "+" :  outstr ||:= char(line + ord(move(1)) + increment)
  5952.         "d" :  {
  5953.             str := string(line + increment)
  5954.             outstr ||:= right(str, \padding, "0") | str
  5955.         }
  5956.         }
  5957.         then line :=: col
  5958.         else {
  5959.         case chr of {
  5960.             "n" :  line := ixor(line,96) & col := ixor(col,96)
  5961.             "i" :  increment := 0
  5962.             "r" :  line :=: col
  5963.             "%" :  outstr ||:= "%"
  5964.             "B" :  line := ior(ishift(line / 10, 4), line % 10)
  5965.             ">" :  {
  5966.             x := move(1); y := move(1)
  5967.             line > ord(x) & line +:= ord(y)
  5968.             &null
  5969.             }
  5970.         } | er("goto","bad termcap entry",5)
  5971.         }
  5972.     }
  5973.     return outstr || tab(0)
  5974.     }
  5975.  
  5976. end
  5977.  
  5978.  
  5979.  
  5980. procedure iputs(cp, affcnt)
  5981.  
  5982.     # Writes cp to the screen.  Use this instead of writes() for
  5983.     # compatibility with itlib (a UNIX-only version which can handle
  5984.     # albeit inelegantly) terminals that need padding.
  5985.  
  5986.     static num_chars
  5987.     initial num_chars := &digits ++ '.'
  5988.  
  5989.     type(cp) == "string" |
  5990.     er("iputs","you can't iputs() a non-string value!",10)
  5991.  
  5992.     cp ? {
  5993.     if tab(many(num_chars)) & ="*" then
  5994.         stop("iputs:  iolib can't use terminals that require padding.")
  5995.     writes(tab(0))
  5996.     }
  5997.  
  5998.     return
  5999.  
  6000. end
  6001. SHAR_EOF
  6002. if test 17272 -ne "`wc -c < 'iolib.icn'`"
  6003. then
  6004.     echo shar: error transmitting "'iolib.icn'" '(should have been 17272 characters)'
  6005. fi
  6006. fi # end of overwriting check
  6007. #    End of shell archive
  6008. exit 0
  6009. -- 
  6010. PAPER:  Norman Azadian; Ascom AG; Belpstrasse 23; 3000 Berne 14; Switzerland
  6011. INTERNET:  naz%hslrswi.uucp@uunet.uu.net
  6012. UUCP:   ...{uunet,ukc,mcvax,...}!chx400!hslrswi!naz
  6013. VOICE:  +41 31 63 2178            BITNET: naz%hslrswi.UUCP@cernvax.BITNET
  6014.  
  6015. From icon-group-request@arizona.edu  Mon Apr 22 01:53:37 1991
  6016. Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Mon, 22 Apr 91 01:53:37 MST
  6017. Resent-From: icon-group-request@arizona.edu
  6018. Received: from Arizona.edu (Merlin.Telcom.Arizona.EDU) by optima.cs.arizona.edu (4.1/15)
  6019.     id AA26295; Mon, 22 Apr 91 01:53:34 MST
  6020. Received: from ucbvax.Berkeley.EDU by Arizona.edu with PMDF#10282; Mon, 22 Apr
  6021.  1991 01:53 MST
  6022. Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA11154; Mon, 22 Apr 91
  6023.  01:50:41 -0700
  6024. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  6025.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  6026.  usenet@ucbvax.Berkeley.EDU if you have questions)
  6027. Resent-Date: Mon, 22 Apr 1991 01:53 MST
  6028. Date: 22 Apr 91 06:53:31 GMT
  6029. From: agate!stanford.edu!unixhub!linac!midway!ellis.uchicago.edu!goer@ucbvax.berkeley.edu (Richard L.
  6030.  Goerwitz)
  6031. Subject: UNIX diffs, klondike
  6032. Sender: icon-group-request@arizona.edu
  6033. Resent-To: icon-group@cs.arizona.edu
  6034. To: icon-group@arizona.edu
  6035. Resent-Message-Id: <CD42F585CC80089A@Arizona.edu>
  6036. Message-Id: <1991Apr22.065331.13394@midway.uchicago.edu>
  6037. X-Envelope-To: icon-group@CS.Arizona.EDU
  6038. X-Vms-To: icon-group@Arizona.edu
  6039. Organization: University of Chicago
  6040.  
  6041.  
  6042. These are a some fairly minor patches which I applied to klondike
  6043. in order to get it to run on my local system here.  Since the vast,
  6044. vast majority of UNIX systems out there don't use the PC character
  6045. set, I've changed the defaults around so that klondike doesn't as-
  6046. sume a PC character set if \isPC and \isDOS are not defined.  I did
  6047. a few other things here and there to get klondike to run on a vt100
  6048. terminal at my home using my (poor) system termcap file.  Really,
  6049. though, I didn't do much.
  6050.  
  6051. I don't believe I've ever seen such a nice piece of software posted
  6052. on this newsgroup.  (N.A., why not cross-post to comp.sources.games
  6053. when we've all had our fun with it?)  What's especially interesting
  6054. about klondike is that the author - who used to claim novice-hood at
  6055. Icon - clearly has come into full mastery of his medium, and has
  6056. gone to great lengths to write clean and readable code.  It'll be a
  6057. pleasure to stick this in my source tree!
  6058.  
  6059. -Richard
  6060.  
  6061.  
  6062. P.S. Unix users:  Apply these using patch -p < patchfilename.
  6063.  
  6064. ----------------------- diffs for klondike -------------------------
  6065.  
  6066. *** kloncon.icn~    Sun Apr 21 22:30:15 1991
  6067. --- kloncon.icn    Mon Apr 22 01:27:44 1991
  6068. ***************
  6069. *** 32,48 ****
  6070.   # For DOS, we simply look to see if any keystroke is waiting, discarding
  6071.   # it/them.  Your system may be different.
  6072.   procedure userInterrupt ()
  6073. ! static keyWaiting
  6074. ! initial    {
  6075. !     keyWaiting  :=  if \type(kbhit)  then  "kbhit"
  6076. ! }
  6077.       if \isDOS  then
  6078. !         while keyWaiting()  do  {
  6079.               (getch() == "\0")  &  getch()    #eat interrupting keystroke
  6080.               return                            #success means "interrupt requested"
  6081.           }
  6082.       else
  6083. !         (\keyWaiting)  &  keyWaiting()  &  getch()  &  return
  6084.       fail                                    #failure = "interrupt NOT requested"
  6085.   end                                            #userInterrupt
  6086.   
  6087. --- 32,45 ----
  6088.   # For DOS, we simply look to see if any keystroke is waiting, discarding
  6089.   # it/them.  Your system may be different.
  6090.   procedure userInterrupt ()
  6091.       if \isDOS  then
  6092. !         while kbhit()  do  {
  6093.               (getch() == "\0")  &  getch()    #eat interrupting keystroke
  6094.               return                            #success means "interrupt requested"
  6095.           }
  6096.       else
  6097. !         (\kbhit)()  &  getch()  &  return
  6098.       fail                                    #failure = "interrupt NOT requested"
  6099.   end                                            #userInterrupt
  6100.   
  6101. ***************
  6102. *** 58,69 ****
  6103.   static outstr
  6104.   local s
  6105.   initial    {
  6106. !     outstr := table("Oops!")
  6107.       outstr[VclearAll]    := getval("cl")     |  (getval("ho") || getval("cd"))
  6108.       outstr[VclearEOL]    := getval("ce")
  6109. !     outstr[Vnormal]        := getval("me") || getval("ue")
  6110.       outstr[Vbold]        := getval("md" | "us")
  6111. !     outstr[Vblink]        := getval("mb")
  6112.       outstr[Vreverse]    := getval("mr" | "so")
  6113.       outstr[VbackSpace]    := if getval("bs")  then  "\b"  else  getval("le")
  6114.       if \isQuiet  then
  6115. --- 55,66 ----
  6116.   static outstr
  6117.   local s
  6118.   initial    {
  6119. !     outstr := table(getval("me" | "se") || getval("ue"))
  6120.       outstr[VclearAll]    := getval("cl")     |  (getval("ho") || getval("cd"))
  6121.       outstr[VclearEOL]    := getval("ce")
  6122. !     outstr[Vnormal]        := getval("me" | "se") || (getval("ue") | "")
  6123.       outstr[Vbold]        := getval("md" | "us")
  6124. !     outstr[Vblink]        := getval("mb" | "us" | "md")
  6125.       outstr[Vreverse]    := getval("mr" | "so")
  6126.       outstr[VbackSpace]    := if getval("bs")  then  "\b"  else  getval("le")
  6127.       if \isQuiet  then
  6128. ***************
  6129. *** 107,118 ****
  6130.   local Vred, Vblack                            #suit color strings
  6131.   
  6132.       lineCount := 25                            #assume the best
  6133. !     case  (map(termtype, &lcase, &ucase))  of  {
  6134.           "PC"    :    { getANSItype ();            isANSI := 1        }
  6135.           "MONO"    :    { isMonochrome := 1;        isANSI := 1     }
  6136.           "COLOR"    :    { isMonochrome := &null;    isANSI := 1        }
  6137.           default    :    { isMonochrome := 1;        isANSI := &null
  6138. !                         (0 < *termtype)  &  setname (termtype)
  6139.                           lineCount := getval("li")
  6140.           }
  6141.       }
  6142. --- 104,116 ----
  6143.   local Vred, Vblack                            #suit color strings
  6144.   
  6145.       lineCount := 25                            #assume the best
  6146. !     termtype := (map(\termtype, &lcase, &ucase))
  6147. !     case  termtype  of  {
  6148.           "PC"    :    { getANSItype ();            isANSI := 1        }
  6149.           "MONO"    :    { isMonochrome := 1;        isANSI := 1     }
  6150.           "COLOR"    :    { isMonochrome := &null;    isANSI := 1        }
  6151.           default    :    { isMonochrome := 1;        isANSI := &null
  6152. !                         setname (map("" ~== \termtype))
  6153.                           lineCount := getval("li")
  6154.           }
  6155.       }
  6156. ***************
  6157. *** 202,218 ****
  6158.   #    t e r m i n a t e S c r e e n
  6159.   # Put the screen in the correct state prior to program termination.
  6160.   procedure terminateScreen ()
  6161. - static resetCooked
  6162. - initial    {
  6163. -     resetCooked  :=  if \type(reset_tty)  then  "reset_tty"
  6164. - }
  6165.       if /invisible  then
  6166. !         if \isANSI  then
  6167.               write ("\e[=7h", VclearAll, Vnormal)    #set cursor wrap mode
  6168. !         else {
  6169. !             output (VclearAll, Vnormal, getval("te"))
  6170. !             (/isDOS)  &  (\resetCooked)  &  resetCooked ()
  6171.           }
  6172.       return
  6173.   end                                            #terminateScreen
  6174.   
  6175. --- 200,215 ----
  6176.   #    t e r m i n a t e S c r e e n
  6177.   # Put the screen in the correct state prior to program termination.
  6178.   procedure terminateScreen ()
  6179.       if /invisible  then
  6180. !         if \isANSI  then {
  6181.               write ("\e[=7h", VclearAll, Vnormal)    #set cursor wrap mode
  6182. !             (\reset_tty) ()
  6183.           }
  6184. +         else {
  6185. +             output (VclearAll, Vnormal)
  6186. +             iputs (getval("te"))
  6187. +             (\reset_tty) ()        # will be nonnull only if getchlib
  6188. +         }                        # is linked
  6189.       return
  6190.   end                                            #terminateScreen
  6191.   
  6192. *** klondike.icn~    Sun Apr 21 22:30:14 1991
  6193. --- klondike.icn    Mon Apr 22 00:42:25 1991
  6194. ***************
  6195. *** 44,50 ****
  6196.       helpInfo := [
  6197.           ["A", "Automatic", " mode -- finish out this game on automatic pilot"],
  6198.           ["B", "Boss", " key for when you-know-who visits"],
  6199. !         ["C","Continuous"," mode -- play games continuously until interrupted"],
  6200.           ["F", "Find", " (next) useful move to do"],
  6201.           ["H,?", "Help", ", this help screen"],
  6202.           ["M", "Move", " card (or stack) from Deck/Stack to Stack/Ace pile"],
  6203. --- 44,50 ----
  6204.       helpInfo := [
  6205.           ["A", "Automatic", " mode -- finish out this game on automatic pilot"],
  6206.           ["B", "Boss", " key for when you-know-who visits"],
  6207. !         ["C","Continuous"," mode -- play until interrupted (not UNIX)"],
  6208.           ["F", "Find", " (next) useful move to do"],
  6209.           ["H,?", "Help", ", this help screen"],
  6210.           ["M", "Move", " card (or stack) from Deck/Stack to Stack/Ace pile"],
  6211. ***************
  6212. *** 365,371 ****
  6213.   procedure uboss ()
  6214.       writes ("oss")                # "consistency is the hobgoblin of small minds"
  6215.       terminateScreen ()                        #put screen in the correct state
  6216. -     writes ("C>")                            #look innocent
  6217.       saveState ("klondike.sav")
  6218.       exit ()
  6219.   end                                            #uboss
  6220. --- 365,370 ----
  6221. ***************
  6222. *** 457,464 ****
  6223.   # Results are reported after every interval (0 => only at end) games.
  6224.   # Statistics are output when done or interrupted, whichever comes first.
  6225.   procedure ubatch (gamesToPlay, interval)
  6226. ! local veryFirstSeed, stat
  6227. !     isQuiet := invisible := 1
  6228.       veryFirstSeed := &random                #remember the initial random seed
  6229.       (interval = 0)  &  (interval := gamesToPlay)
  6230.       repeat  {
  6231. --- 456,463 ----
  6232.   # Results are reported after every interval (0 => only at end) games.
  6233.   # Statistics are output when done or interrupted, whichever comes first.
  6234.   procedure ubatch (gamesToPlay, interval)
  6235. !     local veryFirstSeed, stat
  6236. !     isQuiet := invisible := 1
  6237.       veryFirstSeed := &random                #remember the initial random seed
  6238.       (interval = 0)  &  (interval := gamesToPlay)
  6239.       repeat  {
  6240. ***************
  6241. *** 472,479 ****
  6242.           (stat[1] ~= interval)  &  break        #interrupted by user
  6243.           (0 = (gamesToPlay -:= interval))  &  break
  6244.       }
  6245. !     firstSeed := veryFirstSeed                #required for writeStatistics()
  6246. !     writeStatistics ()
  6247.       exit ()
  6248.   end                                            #ubatch
  6249.   
  6250. --- 471,479 ----
  6251.           (stat[1] ~= interval)  &  break        #interrupted by user
  6252.           (0 = (gamesToPlay -:= interval))  &  break
  6253.       }
  6254. !     firstSeed := veryFirstSeed                #required for writeStatistics()
  6255. !     (\reset_tty)()
  6256. !     writeStatistics ()
  6257.       exit ()
  6258.   end                                            #ubatch
  6259.   
  6260. ***************
  6261. *** 483,490 ****
  6262.   local s, prevsCmd, batchMode, reportInterval, again, termtype
  6263.   
  6264.       # initialize
  6265. !     isDOS := find("MS-DOS", &host)            #probably a reasonable assumption
  6266. !     isPC  := isDOS                            #really a pretty poor assumption
  6267.       totalGames:=totalAces:=totalWins := 0    #statistics
  6268.   
  6269.       # set defaults
  6270. --- 483,491 ----
  6271.   local s, prevsCmd, batchMode, reportInterval, again, termtype
  6272.   
  6273.       # initialize
  6274. !     if isDOS := find("MS-DOS",
  6275. !                      &host|&features)        #probably a reasonable assumption
  6276. !     then isPC  := isDOS                        #really a pretty poor assumption
  6277.       totalGames:=totalAces:=totalWins := 0    #statistics
  6278.   
  6279.       # set defaults
  6280. ***************
  6281. *** 497,503 ****
  6282.       reportInterval    := 0                    # report only at end of batch mode
  6283.       phraseFile        := &null                # use all built-in phrases
  6284.       isQuiet            := &null                # make clicks & beeps if possible
  6285. !     termtype        := if \isPC then "pc" else "mono"
  6286.       &random            := map (&clock, ":", "7")        # randomize the seed
  6287.   
  6288.       # deal with command-line parameters
  6289. --- 498,504 ----
  6290.       reportInterval    := 0                    # report only at end of batch mode
  6291.       phraseFile        := &null                # use all built-in phrases
  6292.       isQuiet            := &null                # make clicks & beeps if possible
  6293. !     termtype        := if \isPC then "pc"    # default term type for PCs
  6294.       &random            := map (&clock, ":", "7")        # randomize the seed
  6295.   
  6296.       # deal with command-line parameters
  6297. ***************
  6298. *** 518,523 ****
  6299. --- 519,525 ----
  6300.               "-R" | "-r"    :    &random         :=    integer (s[3:0])
  6301.               "-S" | "-s"    :    findBest (s[3:0])            #check & store strategy
  6302.               "-T" | "-t"    :    termtype        :=    s[3:0]
  6303. +                 
  6304.               "-Z" | "-z"    :    debugging        :=    if \debugging then  &null else 1
  6305.               default        :    {
  6306.                               # screen mode not yet initialized, so write() is OK
  6307. ***************
  6308. *** 529,535 ****
  6309.           }
  6310.   
  6311.       # initializations which use command-line parameters
  6312. !     (map(termtype, &lcase, &ucase) == "PC")  &  isPC := 1
  6313.       initConstants (termtype)                #need updated termtype from cmdline
  6314.       initVariables ()                        #establish all the lists and such
  6315.   
  6316. --- 531,537 ----
  6317.           }
  6318.   
  6319.       # initializations which use command-line parameters
  6320. !     (map(\termtype, &lcase, &ucase) == "PC")  &  isPC := 1
  6321.       initConstants (termtype)                #need updated termtype from cmdline
  6322.       initVariables ()                        #establish all the lists and such
  6323.   
  6324. ***************
  6325. *** 566,572 ****
  6326.                               umove (s)  |  complain ()
  6327.                   "A"        :    uautomatic()                    #look Ma, no hands!
  6328.                   "B"        :    uboss()                            #bail out quick
  6329. !                 "C"        :    ucontinuous()                    #no hands, forever
  6330.                   "F"        :    ufind (again)  &  break            #new game
  6331.                   "M"        :    umove (&null)  |  complain ()
  6332.                   "Q"        :    uterminate ()  &  break            #new game
  6333. --- 568,574 ----
  6334.                               umove (s)  |  complain ()
  6335.                   "A"        :    uautomatic()                    #look Ma, no hands!
  6336.                   "B"        :    uboss()                            #bail out quick
  6337. !                 "C"        :    \isDOS & ucontinuous()                    #no hands, forever
  6338.                   "F"        :    ufind (again)  &  break            #new game
  6339.                   "M"        :    umove (&null)  |  complain ()
  6340.                   "Q"        :    uterminate ()  &  break            #new game
  6341. *** makefile.unx~    Sun Apr 21 22:30:12 1991
  6342. --- makefile.unx    Mon Apr 22 00:45:46 1991
  6343. ***************
  6344. *** 1,18 ****
  6345.   #makefile.unx    910322    NHA
  6346. ! #An unix makefile for klondike
  6347.   #
  6348. ! #Assumes that iolib.u? and getchlib.u? are already available somewhere
  6349. ! #along $IPATH.
  6350. ! #Note that only getchlib is linked on the command line.  Everything else
  6351. ! #is linked in the program.
  6352.   
  6353. ! .SUFFIXES:    .u1  .icn
  6354.   
  6355.   .icn.u1:
  6356.       icont -c  $?
  6357.   
  6358. ! klondike:    klondike.icn  kloncon.u1  klonstr.u1  klonsub.u1  getchlib.u1
  6359. !     icont -u -Si1000 -Sn2000  klondike  getchlib.u1
  6360.   
  6361.   clean:
  6362.       rm  -f  *.u?  klondike
  6363. --- 1,19 ----
  6364.   #makefile.unx    910322    NHA
  6365. ! #Unix makefile for klondike
  6366.   #
  6367. ! #Note that only getchlib and iolib are explicitly linked on the command
  6368. ! #line; other auxiliary files are loaded by link directives withing klon-
  6369. ! #dike.icn.
  6370.   
  6371. ! .SUFFIXES: .u1  .icn
  6372.   
  6373.   .icn.u1:
  6374.       icont -c  $?
  6375.   
  6376. ! SHELL = /bin/sh
  6377. ! klondike: klondike.icn  kloncon.u1  klonstr.u1  klonsub.u1 getchlib.u1 iolib.u1
  6378. !     icont -u -Si1000 -Sn2000  klondike  getchlib.u1 iolib.u1
  6379.   
  6380.   clean:
  6381.       rm  -f  *.u?  klondike
  6382. -- 
  6383.  
  6384.    -Richard L. Goerwitz              goer%sophist@uchicago.bitnet
  6385.    goer@sophist.uchicago.edu         rutgers!oddjob!gide!sophist!goer
  6386.  
  6387. From icon-group-request@arizona.edu  Mon Apr 22 17:24:51 1991
  6388. Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Mon, 22 Apr 91 17:24:51 MST
  6389. Resent-From: icon-group-request@arizona.edu
  6390. Received: from Arizona.edu (Merlin.Telcom.Arizona.EDU) by optima.cs.arizona.edu (4.1/15)
  6391.     id AA29076; Mon, 22 Apr 91 17:24:48 MST
  6392. Received: from ucbvax.Berkeley.EDU by Arizona.edu with PMDF#10282; Mon, 22 Apr
  6393.  1991 17:24 MST
  6394. Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA05600; Mon, 22 Apr 91
  6395.  17:11:33 -0700
  6396. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  6397.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  6398.  usenet@ucbvax.Berkeley.EDU if you have questions)
  6399. Resent-Date: Mon, 22 Apr 1991 17:24 MST
  6400. Date: 22 Apr 91 23:07:34 GMT
  6401. From: swrinde!zaphod.mps.ohio-state.edu!pacific.mps.ohio-state.edu!linac!midway!ellis.uchicago.edu!goer@ucsd.edu (Richard L.
  6402.  Goerwitz)
  6403. Subject: RE: UNIX diffs, klondike
  6404. Sender: icon-group-request@arizona.edu
  6405. Resent-To: icon-group@cs.arizona.edu
  6406. To: icon-group@arizona.edu
  6407. Resent-Message-Id: <4F57807CCC8019A1@Arizona.edu>
  6408. Message-Id: <1991Apr22.230734.1432@midway.uchicago.edu>
  6409. X-Envelope-To: icon-group@CS.Arizona.EDU
  6410. X-Vms-To: icon-group@Arizona.edu
  6411. Organization: University of Chicago
  6412. References: <1991Apr22.065331.13394@midway.uchicago.edu>
  6413.  
  6414. Just a note - an IMPORTANT one - to tack onto the preceding:  Please
  6415. read through the getchlib docs if you are on a system that does not
  6416. implement the -g option for stty.  Also if your stty command can't
  6417. write its output to a pipe (what a sorry world this is), check the
  6418. getchlib.icn file as well.  OTHERWISE YOUR TERMINAL ENDS UP IN RAW
  6419. MODE!
  6420.  
  6421. People with regular System V stty commands or older BSD ones (or some
  6422. newer BSD ones -it apparently works here on our Sun3) should have no-
  6423. thing to worry about.
  6424.  
  6425. I'm sorry I didn't mention this sooner.
  6426.  
  6427. -Richard
  6428. -- 
  6429.  
  6430.    -Richard L. Goerwitz              goer%sophist@uchicago.bitnet
  6431.    goer@sophist.uchicago.edu         rutgers!oddjob!gide!sophist!goer
  6432.  
  6433. From @um.cc.umich.edu:Paul_Abrahams@MTS.cc.Wayne.edu  Mon Apr 22 19:26:15 1991
  6434. Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Mon, 22 Apr 91 19:26:15 MST
  6435. Received: from umich.edu by optima.cs.arizona.edu (4.1/15)
  6436.     id AA02566; Mon, 22 Apr 91 19:26:13 MST
  6437. Received: from um.cc.umich.edu by umich.edu (5.61/1123-1.0)
  6438.     id AA17068; Mon, 22 Apr 91 22:26:09 -0400
  6439. Received: from MTS.cc.Wayne.edu by um.cc.umich.edu via MTS-Net; Mon, 22 Apr 91 22:21:45 EDT
  6440. Date: Mon, 22 Apr 91 22:21:50 EDT
  6441. From: Paul_Abrahams@mts.cc.wayne.edu
  6442. To: icon-group@cs.arizona.edu
  6443. Message-Id: <322705@MTS.cc.Wayne.edu>
  6444. Subject: Evaluation rules for !set
  6445.  
  6446.  
  6447. I'm puzzled by the behavior of the following tiny program:
  6448.  
  6449. procedure main()
  6450.     x := set([1,2,3])
  6451.     every writes(e := !x, " ") do insert(x, e+10)
  6452. end
  6453.  
  6454. In MS-DOS Icon V8 it prints:
  6455.  
  6456.   1 2 3 11 12 21
  6457.  
  6458. The question is: what happens when you iterate over a set and modify
  6459. it at the same time?  I would have expected either just "1 2 3" (if the
  6460. value of x is saved) or an infinite sequence (if x is continually modified.)
  6461. I don't understand what accounts for the result I got.  Is there an
  6462. explanation of this somewhere in the (new) Icon book?    
  6463.  
  6464. Paul Abrahams
  6465.  
  6466. From ralph  Mon Apr 22 19:31:43 1991
  6467. Date: Mon, 22 Apr 91 19:31:43 MST
  6468. From: "Ralph Griswold" <ralph>
  6469. Message-Id: <9104230231.AA05065@cheltenham.cs.arizona.edu>
  6470. Received: by cheltenham.cs.arizona.edu; Mon, 22 Apr 91 19:31:43 MST
  6471. To: Paul_Abrahams@mts.cc.wayne.edu, icon-group@cs.arizona.edu
  6472. Subject: Re:  Evaluation rules for !set
  6473.  
  6474. It's bad policy to iterate over a aggregate that has no defined
  6475. order while modifying that aggregate.  That's basically asking
  6476. for trouble.
  6477.  
  6478. We've taken some pains to make sure you don't get garbage or get
  6479. in a loop, but beyond that what you get is implementation dependent.
  6480.  
  6481.   Ralph Griswold / Dept of Computer Science / Univ of Arizona / Tucson, AZ 85721
  6482.   +1 602 621 6609   ralph@cs.arizona.edu  uunet!arizona!ralph
  6483.  
  6484. From icon-group-request@arizona.edu  Thu Apr 25 04:18:45 1991
  6485. Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Thu, 25 Apr 91 04:18:45 MST
  6486. Resent-From: icon-group-request@arizona.edu
  6487. Received: from Arizona.edu (Merlin.Telcom.Arizona.EDU) by optima.cs.arizona.edu (4.1/15)
  6488.     id AA21780; Thu, 25 Apr 91 04:18:42 MST
  6489. Received: from ucbvax.Berkeley.EDU by Arizona.edu with PMDF#10282; Thu, 25 Apr
  6490.  1991 04:18 MST
  6491. Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA05315; Thu, 25 Apr 91
  6492.  04:12:45 -0700
  6493. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  6494.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  6495.  usenet@ucbvax.Berkeley.EDU if you have questions)
  6496. Resent-Date: Thu, 25 Apr 1991 04:18 MST
  6497. Date: 25 Apr 91 11:01:24 GMT
  6498. From: eru!hagbard!sunic!news.funet.fi!hydra!cc.helsinki.fi!veijalainen@bloom-beacon.mit.edu
  6499. Subject: Icon Version 8 fot Acorn Archimedes needed!
  6500. Sender: icon-group-request@arizona.edu
  6501. Resent-To: icon-group@cs.arizona.edu
  6502. To: icon-group@arizona.edu
  6503. Resent-Message-Id: <3D068E126C802944@Arizona.edu>
  6504. Message-Id: <1991Apr25.110125.6122@cc.helsinki.fi>
  6505. X-Envelope-To: icon-group@CS.Arizona.EDU
  6506. X-Vms-To: icon-group@Arizona.edu
  6507. Organization: University of Helsinki
  6508.  
  6509. ICON VERSION 8 FOR ACORN ACHIMEDES NEEDED
  6510.  
  6511. I have sources off poring library of Icon version 8 for hierarchical filing
  6512. systems. I have however considerable difficulty off adapting the language to
  6513. extensionless filing system names of British/Italian Acorn Archimedes. I have
  6514. conditionally compiled hierarchical name references of the icon source #include
  6515. statements, but language itself needs to refer to files and that part I have
  6516. not fixed (yet). If somebody has allready done the work, I don't want to tackle
  6517. the project myself. Also after seeing article about coroutines in latest
  6518. Archive magazine, I would like an icon with coroutines implemented. My
  6519. C-compiler is however is old Arthur version ( I think ver. 1.54, is there any
  6520. way to link programs to shared C library with it? ), so the routine is not 
  6521. suitable for my own use. If you do have done the conversion, I hope you
  6522. send it to Newcastle (info-server@newcastle.ac.uk) 
  6523. and Oulu, Finland ( tolsun.oulu.fi, directory incoming/acorn) or 
  6524. of course mail it to me. 
  6525.  
  6526. Tony Veijalainen
  6527. Veijalainen@cc.helsinki.FI
  6528.  
  6529. From gudeman  Mon Apr 29 12:16:59 1991
  6530. Received: from orator.cs.arizona.edu by cheltenham.cs.arizona.edu; Mon, 29 Apr 91 12:16:59 MST
  6531. Date: Mon, 29 Apr 91 12:16:57 MST
  6532. From: "David Gudeman" <gudeman>
  6533. Message-Id: <9104291916.AA23734@orator.cs.arizona.edu>
  6534. Received: by orator.cs.arizona.edu; Mon, 29 Apr 91 12:16:57 MST
  6535. To: icon-group
  6536. Subject: augmented assignment
  6537.  
  6538. Someone in another newsgroup suggested that C should have the
  6539. augmented assignment "a ->= b" which means "a = a->b".  In Icon this
  6540. would translate to "a .:= b" which means "a := a.b".  It seems to me
  6541. that this could be useful in Icon even though it might be a little
  6542. hard to parse.  (It wouldn't be quite as useful as in C, where you
  6543. write code like "p = p->next" all the time.)
  6544.  
  6545. From kelvin@kickapoo.cs.iastate.edu  Mon Apr 29 12:41:44 1991
  6546. Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Mon, 29 Apr 91 12:41:44 MST
  6547. Received: from judy.cs.iastate.edu by optima.cs.arizona.edu (4.1/15)
  6548.     id AA22268; Mon, 29 Apr 91 12:41:34 MST
  6549. Received: from kickapoo.cs.iastate.edu.noname by judy.cs.iastate.edu (4.1) id AA15244; Mon, 29 Apr 91 14:40:09 CDT
  6550. Received: by kickapoo.cs.iastate.edu.noname (4.1/SMI-4.1)
  6551.     id AA07045; Mon, 29 Apr 91 14:40:43 CDT
  6552. Date: Mon, 29 Apr 91 14:40:43 CDT
  6553. From: kelvin@kickapoo.cs.iastate.edu (Kelvin Don Nilsen)
  6554. Message-Id: <9104291940.AA07045@kickapoo.cs.iastate.edu.noname>
  6555. To: gudeman@cs.arizona.edu
  6556. Cc: icon-group@cs.arizona.edu
  6557. In-Reply-To: "David Gudeman"'s message of Mon, 29 Apr 91 12:16:57 MST <9104291916.AA23734@orator.cs.arizona.edu>
  6558. Subject: augmented assignment
  6559.  
  6560.  
  6561. Here's a minor point to consider regarding the proposal of adding ".:="
  6562.   as another augmented assignment operator:
  6563.  
  6564.     If this operation were added to the language, it would represent
  6565.     a "special case" in that the right hand subexpression argument is
  6566.     really not an arbitrary expression, but must represent a record field
  6567.     name.
  6568.  
  6569. On the other hand, many users likely view its omission as a special case.
  6570.   I did, until I started to consider implementation concerns.
  6571.  
  6572.  
  6573. Kelvin Nilsen/Dept. of Computer Science/Iowa State University/Ames, IA  50011 
  6574.  (515) 294-2259   kelvin@cs.iastate.edu  uunet!atanasoff!kelvin
  6575.  
  6576.  
  6577. From pbewig@netcom.netcom.com  Tue May 14 10:16:02 1991
  6578. Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Tue, 14 May 91 10:16:02 MST
  6579. Received: from netcom.netcom.com ([192.100.81.100]) by optima.cs.arizona.edu (4.1/15)
  6580.     id AA24070; Tue, 14 May 91 10:15:57 MST
  6581. Received: by netcom.netcom.com (/\==/\ Smail3.1.20.1 #20.6)
  6582.     id <m0jd2Wx-000CPgC@netcom.netcom.com>; Tue, 14 May 91 09:47 PDT
  6583. Message-Id: <m0jd2Wx-000CPgC@netcom.netcom.com>
  6584. Date: Tue, 14 May 91 10:15 PDT
  6585. From: pbewig@netcom.com (Phil Bewig)
  6586. X-Mailer: Mail User's Shell (7.2.0 10/31/90)
  6587. To: icon-group@cs.arizona.edu
  6588.  
  6589. Shown below is a superset of the c language printf family of functions
  6590. for icon.  I am new enough to icon that most of the procedures can
  6591. doubtless be rewritten; see float2str for a particularly bad example. 
  6592.  
  6593.  
  6594. ############################################################################
  6595. #
  6596. #       Name:   printf.icn
  6597. #
  6598. #       Title:  print formatted output
  6599. #
  6600. #       Author: Philip L. Bewig
  6601. #
  6602. #       Date:   May 13, 1991
  6603. #
  6604. ############################################################################
  6605. #
  6606. #  The printf procedures provide general formatted output.  They share a
  6607. #  common syntax, differing only in the place where output is sent:
  6608. #
  6609. #      printf(fmt, expr, expr ...)      - send output to stdout
  6610. #      sprintf(fmt, expr, expr ...)     - return output as value of function
  6611. #      fprintf(fd, fmt, expr, expr ...) - send output to file fd
  6612. #
  6613. #  Essentially, the printf functions work by copying the format string to
  6614. #  the output.  Regular characters are copied unchanged.  Escape sequences
  6615. #  are converted to their corresponding string values; the same escape
  6616. #  sequences recognized by the icon language are recognized by printf.  The
  6617. #  only real processing performed is to interpret conversion specifications
  6618. #  which begin with the "%" character; each conversion specification trans-
  6619. #  forms the next expression in the procedure call to the desired form.
  6620. #
  6621. #  Conversion specifications have the form
  6622. #
  6623. #      %[-|=][w][.p]c
  6624. #
  6625. #  where
  6626. #
  6627. #      -   left justifies the field
  6628. #      =   centers the field
  6629. #      w   is the minimum field width
  6630. #      p   is the precision
  6631. #      c   is the conversion character
  6632. #
  6633. #  By default, the field is right justified in a field of width w, which
  6634. #  has a default value of zero; the "-" and "=" specifiers override the
  6635. #  default.  In a string, the precision is the maximum number of characters
  6636. #  to be printed; in a floating point number, the precision is the number
  6637. #  of digits to be printed to the right of the decimal point and has a
  6638. #  default value of six.  If "w" or "p" is "*" (star), the minimum field
  6639. #  width or precision will be the value of the next expr in the function
  6640. #  call.  For a numeric field, if "w" begins with zero the field will be
  6641. #  padded to the left with zeros instead of blank spaces; this implemen-
  6642. #  tation faithfully reproduces a bug in many printf functions which causes 
  6643. #  sprintf("%05d", -2) to produce the string "000-2".
  6644. #
  6645. #  The conversion character c is one of the following:
  6646. #
  6647. #      a   positive integer, using letters as digits; the integers
  6648. #              1 through 256 are counted a, b, ..., z, aa, ab, ...
  6649. #              az, ba, bb, ..., iv (same as Lotus 1-2-3 columns)
  6650. #      A   same as a, but print upper-case letters
  6651. #      b   unsigned binary integer
  6652. #      c   single character of an integer value
  6653. #      d   decimal integer
  6654. #      e   floating point (scientific notation)
  6655. #      E   same as e, but print upper-case "E"
  6656. #      f   floating point
  6657. #      g   the shorter of e and f (suppresses non-significant zeros)
  6658. #      G   same as g, but print upper-case "E"
  6659. #      o   unsigned octal integer
  6660. #      r   integer in range 1 to 3999, converted to roman numerals
  6661. #      R   same as r, but print upper-case letters
  6662. #      s   string
  6663. #      S   string, with all letters converted to upper-case
  6664. #      u   unsigned decimal integer
  6665. #      w   integer with absolute value less than one billion, converted
  6666. #              to english words
  6667. #      W   same as x, but print letters as upper-case
  6668. #      x   unsigned hexadecimal integer
  6669. #      X   same as x, but print hex digit letters as upper-case
  6670. #      $   similar to f, but with a "$" prepended to the output;
  6671. #              negative numbers are parenthesized, and an extra
  6672. #              print position is allowed to the right of positive
  6673. #              numbers
  6674. #      %   literal percent sign; no expr is consumed
  6675. #
  6676. #  There may be any number of expressions following the format string;
  6677. #  extra expressions are ignored, but missing expressions cause a run-time
  6678. #  error.
  6679. #
  6680. #  This printf function is a strict superset of the features provided by
  6681. #  the standard c or awk printf function; any format specification which
  6682. #  they provide is provided identically here.
  6683. #
  6684. #  There are several local functions which provide a single type of con-
  6685. #  version which may be more useful than a general-purpose formatter in
  6686. #  some situations.  They are float2str(num, prec), float2sci(num, prec), 
  6687. #  float2dollar(num, prec), int2alpha(num), int2roman(num), int2words(num),
  6688. #  unsigned2hex(num), unsigned2dec(num), unsigned2oct(num), and
  6689. #  unsigned2bin(num).  All of these functions return lower-case letters
  6690. #  where appropriate which may be converted to upper-case by the function
  6691. #  map(...,&lcase,&ucase).
  6692. #
  6693. ############################################################################
  6694. #
  6695. #  test driver
  6696. #  procedure main()
  6697. #      repeat {
  6698. #          writes("enter a format specification (null to quit):  ")
  6699. #          fmt := read()
  6700. #          if *fmt = 0 then break
  6701. #          exprlist := []
  6702. #          repeat {
  6703. #              writes("enter an expression (null to print):  ")
  6704. #              temp := read()
  6705. #              if *temp = 0 then break
  6706. #              put(exprlist, temp)
  6707. #          }
  6708. #          write("the output is |" || sprintf(fmt, exprlist) || "|")
  6709. #          write()
  6710. #      }
  6711. #  end
  6712. #
  6713. ############################################################################
  6714.  
  6715. # sprintf - return formatted string
  6716. procedure sprintf(fmt, exprlist)
  6717.     local out, just, wid, prec, conv, pad, val, v1, v2, i, s
  6718.     out := ""
  6719.     fmt ? repeat {
  6720.         (out ||:= tab(upto('%\\'))) | (out ||:= tab(0) & break)
  6721.         case move(1) of {
  6722.         "%": { # format specification
  6723.             # initialize
  6724.             just := right
  6725.             wid := prec := conv := pad := val := &null
  6726.             # parse the format specification
  6727.             tab(match("-")) & just := left
  6728.             tab(match("=")) & just := center
  6729.             wid := (tab(many(&digits)) | tab(match("*")))
  6730.             (\wid)[1] == "*" & wid := get(exprlist)
  6731.             tab(match(".")) & (prec := (tab(many(&digits)) | tab(match("*"))))
  6732.             (\prec)[1] == "*" & prec := get(exprlist)
  6733.             conv := move(1)
  6734.             # perform the specified conversion
  6735.             val := get(exprlist)
  6736.             case map(conv) of {
  6737.             "a": { if not(val := int2alpha(val)) then val := &null }
  6738.             "b": { (\wid)[1] == "0" & pad := "0"
  6739.                     if not(val := unsigned2bin(val)) then val := &null }
  6740.             "c": { val := char(val) }
  6741.             "d": { (\wid)[1] == "0" & pad := "0"; val := integer(val) }
  6742.             "e": { (\wid)[1] == "0" & pad := "0"; val := float2sci(val, prec) }
  6743.             "f": { (\wid)[1] == "0" & pad := "0"; val := float2str(val, prec) }
  6744.             "g": { (\wid)[1] == "0" & pad := "0"
  6745.                     v1 := float2sci(val, prec)
  6746.                     v2 := float2str(val, prec)
  6747.                     val := (if *v1 < *v2 then v1 else v2) }
  6748.             "o": { (\wid)[1] == "0" & pad := "0"
  6749.                     if not(val := unsigned2oct(val)) then val := &null }
  6750.             "r": { if not(val := int2roman(val)) then val := &null }
  6751.             "s": { if \prec then val := left(val, prec) }
  6752.             "u": { (\wid)[1] == "0" & pad := "0"
  6753.                     if not(val := unsigned2dec(val)) then val := &null }
  6754.             "w": { if not(val := int2words(val)) then val := &null }
  6755.             "x": { (\wid)[1] == "0" & pad := "0"
  6756.                     if not(val := unsigned2hex(val)) then val := &null }
  6757.             "$": { (\wid)[1] == "0" & pad := "0"
  6758.                     val := float2dollar(val, prec) }
  6759.             "%": { push(exprlist, val); val := "%" }
  6760.             default: { out := &null; break }
  6761.             }
  6762.             if conv ~== map(conv) then val := map(val, &lcase, &ucase)
  6763.             if \wid & *val < wid then val := just(val, wid, pad)
  6764.             out ||:= val
  6765.         }
  6766.         "\\": { # escape sequence
  6767.             # escape handler derived from an ipl proc by William H. Mitchell
  6768.             out ||:= case c := map(move(1)) of {
  6769.             "b": "\b"
  6770.             "d": "\d"
  6771.             "e": "\e"
  6772.             "f": "\f"
  6773.             "l": "\l"
  6774.             "n": "\n"
  6775.             "r": "\r"
  6776.             "t": "\t"
  6777.             "v": "\v"
  6778.             "'": "'"
  6779.             "\"": "\""
  6780.             "x": {
  6781.                 move(i := 2 | 1) ? s := tab(upto(~'0123456789ABCDEFabcdef') | 0)
  6782.                 move(*s - i)
  6783.                 char("16r" || s)
  6784.             }
  6785.             "^": char(iand(ord(move(1)), 16r1f))
  6786.             !"01234567": {
  6787.                 move(-1)
  6788.                 move(i := 3 | 2 | 1) ? s := tab(upto(~'01234567') | 0)
  6789.                 move(*s - i)
  6790.                 if s > 377 then {
  6791.                     s := s[1:3]
  6792.                     move(-1)
  6793.                 }
  6794.                 char("8r" || s)
  6795.             }
  6796.             default: c
  6797.             }
  6798.         }
  6799.         }
  6800.     }
  6801.     return out
  6802. end
  6803.  
  6804. # printf - print formatted string
  6805. procedure printf(fmt, exprlist)
  6806.     writes(sprintf(fmt, exprlist))
  6807.     return
  6808. end
  6809.  
  6810. # fprintf - write formatted string to file
  6811. procedure fprintf(fd, fmt, exprlist)
  6812.     writes(fd, sprintf(fmt, exprlist))
  6813.     return
  6814. end
  6815.  
  6816. # float2str - convert floating point number to string format
  6817. # this procedure looks more like pascal than icon
  6818. procedure float2str(num, ndigs)
  6819.     local out, nbefore, i, digit
  6820.     nbefore := 1; /ndigs := 6 # initialize, set default
  6821.     if num < 0 then { out := "-"; num *:= -1 } else { out := "" }
  6822.     num +:= 0.5 / 10.0 ^ ndigs # round to desired precision
  6823.     while num >= 10.0 do { num /:= 10.0; nbefore +:= 1 } # normalize
  6824.     every i := 1 to (nbefore + ndigs) do {
  6825.         if i = nbefore + 1 then out ||:= "."
  6826.         digit := integer(num)
  6827.         out ||:= char(digit + 48)
  6828.         num := 10.0 * (num - digit)
  6829.     }
  6830.     return out
  6831. end
  6832.  
  6833. # float2sci - convert floating point number to string in scientific format
  6834. procedure float2sci(num, ndigs)
  6835.     local frac, expo
  6836.     frac := num; expo := 0
  6837.     if abs(frac) >= 10.0 then {
  6838.         until abs(frac) < 10.0 do {
  6839.             frac /:= 10.0; expo +:= 1
  6840.         }
  6841.     } else if abs(frac) < 1.0 & frac ~= 0.0 then {
  6842.         until abs(frac) > 1.0 do {
  6843.             frac *:= 10.0; expo -:= 1
  6844.         }
  6845.     }
  6846.     return float2str(frac, ndigs) || "e" || string(expo)
  6847. end
  6848.  
  6849. # float2dollar - convert floating point number to string, prepend dollar sign
  6850. procedure float2dollar(num, prec)
  6851.     if num >= 0 then
  6852.         return "$" || float2str(num, prec) || " "
  6853.     else
  6854.         return "($" || float2str(-num, prec) || ")"
  6855. end
  6856.  
  6857. # unsigned2hex - convert unsigned int to hex string
  6858. procedure unsigned2hex(num)
  6859.     local out, nonzero, digit
  6860.     static hexdigit
  6861.     initial { hexdigit := "0123456789abcdef" }
  6862.     if num ~= integer(num) then fail
  6863.     if num > 2147483647 then fail
  6864.     if num < -2147483648 then fail
  6865.     out := ""; nonzero := &null
  6866.     every i := 28 to 0 by -4 do {
  6867.         digit := hexdigit[iand(ishift(num,-i),15)+1]
  6868.         if digit == "0" & /nonzero then next
  6869.         nonzero := ""; out ||:= digit
  6870.     }
  6871.     return out
  6872. end
  6873.  
  6874. # unsigned2oct - convert unsigned int to octal string
  6875. procedure unsigned2oct(num)
  6876.     local out, nonzero, digit
  6877.     if num ~= integer(num) then fail
  6878.     if num > 2147483647 then fail
  6879.     if num < -2147483648 then fail
  6880.     out := ""; nonzero := &null
  6881.     every i := 30 to 0 by -3 do {
  6882.         digit := string(iand(ishift(num,-i),7))
  6883.         if digit == "0" & /nonzero then next
  6884.         nonzero := ""; out ||:= digit
  6885.     }
  6886.     return out
  6887. end
  6888.  
  6889. # unsigned2bin - convert unsigned int to binary string
  6890. procedure unsigned2bin(num)
  6891.     local out, nonzero, digit
  6892.     if num ~= integer(num) then fail
  6893.     if num > 2147483647 then fail
  6894.     if num < -2147483648 then fail
  6895.     out := ""; nonzero := &null
  6896.     every i := 31 to 0 by -1 do {
  6897.         digit := string(iand(ishift(num,-i),1))
  6898.         if digit == "0" & /nonzero then next
  6899.         nonzero := ""; out ||:= digit
  6900.     }
  6901.     return out
  6902. end
  6903.  
  6904. # unsigned2dec - convert unsigned int to decimal string
  6905. procedure unsigned2dec(num)
  6906.     if num ~= integer(num) then fail
  6907.     else if num > 2147483647 then fail
  6908.     else if num < -2147483648 then fail
  6909.     else if num >= 0 then return string(num)
  6910.     else return string(4294967296 - -num)
  6911. end
  6912.  
  6913. # int2alpha - convert integer to alpha string
  6914. procedure int2alpha(num)
  6915.     local out
  6916.     static alpha
  6917.     initial alpha := string(&lcase)
  6918.     if num ~= integer(num) then fail
  6919.     if num <= 0 then fail
  6920.     num -:= 1
  6921.     out := alpha[num % 26 + 1]
  6922.     while (num := num / 26 - 1) >= 0 do
  6923.         out ||:= alpha[num % 26 + 1]
  6924.     return reverse(out)
  6925. end
  6926.  
  6927. # int2roman - convert integer to roman numerals
  6928. # this procedure derived from a program by Ralph E. Griswold
  6929. procedure int2roman(num)
  6930.     local arabic, result
  6931.     static equiv
  6932.     initial equiv := ["","i","ii","iii","iv","v","vi","vii","viii","ix"]
  6933.     integer(num) > 0 | fail
  6934.     result := ""
  6935.     every arabic := !num do
  6936.         result := map(result,"ivxlcdm","xlcdm**") || equiv[arabic+1]
  6937.     if find("*",result) then fail else return result
  6938. end
  6939.  
  6940. # int2words - convert integer to english words
  6941. procedure int2words(num)
  6942.     local out
  6943.     static tens, nums
  6944.     initial {
  6945.         nums := ["one", "two", "three", "four", "five", "six", "seven",
  6946.                 "eight", "nine", "ten", "eleven", "twelve", "thirteen",
  6947.                 "fourteen", "fifteen", "sixteen", "seventeen",
  6948.                 "eighteen", "nineteen"]
  6949.         tens := ["ten", "twenty", "thirty", "forty", "fifty", "sixty",
  6950.                 "seventy", "eighty", "ninety"]
  6951.     }
  6952.     if num ~= integer(num) then fail
  6953.     if num < 0 then
  6954.         return "negative " || int2words(-num)
  6955.     if num >= 1000000000 then {
  6956.         fail
  6957.     } else if num >= 1000000 then {
  6958.         out := int2words(num/1000000) || " million"
  6959.         if num%1000000 ~= 0 then out ||:= " " || int2words(num%1000000)
  6960.     } else if num >= 1000 then {
  6961.         out := int2words(num/1000) || " thousand"
  6962.         if num%1000 ~= 0 then out ||:= " " || int2words(num%1000)
  6963.     } else if num >= 100 then {
  6964.         out := int2words(num/100) || " hundred"
  6965.         if num%100 ~= 0 then out ||:= " " || int2words(num%100)
  6966.     } else if num >= 20 then {
  6967.         out := tens[integer(num/10)]
  6968.         if num%10 ~= 0 then out ||:= " " || int2words(num%10)
  6969.     } else if num > 0 then {
  6970.         out := nums[num]
  6971.     } else out := "zero"
  6972.     return out
  6973. end
  6974.  
  6975. From pbewig@netcom.netcom.com  Tue May 14 15:25:46 1991
  6976. Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Tue, 14 May 91 15:25:46 MST
  6977. Received: from netcom.netcom.com ([192.100.81.100]) by optima.cs.arizona.edu (4.1/15)
  6978.     id AA08666; Tue, 14 May 91 15:25:42 MST
  6979. Received: by netcom.netcom.com (/\==/\ Smail3.1.20.1 #20.6)
  6980.     id <m0jd7nj-000CSEC@netcom.netcom.com>; Tue, 14 May 91 15:25 PDT
  6981. Message-Id: <m0jd7nj-000CSEC@netcom.netcom.com>
  6982. Date: Tue, 14 May 91 15:25 PDT
  6983. From: pbewig@netcom.com (Phil Bewig)
  6984. X-Mailer: Mail User's Shell (7.2.0 10/31/90)
  6985. To: icon-group@cs.arizona.edu
  6986.  
  6987. Hello,
  6988.  
  6989. Here's another little procedure for formatted output.  Enjoy! !
  6990.  
  6991.  
  6992. ############################################################################
  6993. #
  6994. #       Name:   prdate.icn
  6995. #
  6996. #       Title:  print formatted dates
  6997. #
  6998. #       Author: Philip L. Bewig
  6999. #
  7000. #       Date:   May 13, 1991
  7001. #
  7002. ############################################################################
  7003. #
  7004. # The prdate family of procedures provide formatted date output.  They
  7005. # share a common syntax, differing only in the place where output is sent:
  7006. #
  7007. #     prdate(fmt, date)      - send output to stdout
  7008. #     sprdate(fmt, date)     - return output as value of function
  7009. #     fprdate(fd, fmt, date) - send output to file fd
  7010. #
  7011. # Essentially, the prdate functions work by copying the format string to
  7012. # the output.  Regular characters are copied unchanged.  Escape sequences
  7013. # are converted to their corresponding string values; the same escape
  7014. # sequences recognized by the icon language are recognized by prdate.  The
  7015. # only real processing performed is to interpret conversion specifications
  7016. # which begin with the "%" character.
  7017. #
  7018. # Conversion specifications have the form
  7019. #
  7020. #     %xx
  7021. #
  7022. # where xx may be any of the following:
  7023. #
  7024. #     m1 - month number in range 1 to 12
  7025. #     m2 - month number in range 01 to 12
  7026. #     m3 - month name in range Jan to Dec
  7027. #     M3 - month name in range JAN to DEC
  7028. #     m4 - month name in range January to December
  7029. #     M4 - month name in range JANUARY to DECEMBER
  7030. #
  7031. #     d1 - day number in range 1 to 31
  7032. #     d2 - day number in range 01 to 31
  7033. #
  7034. #     y1 - year number in range 0 to 99
  7035. #     y2 - year number in range 00 to 99
  7036. #     y3 - year number in range 0 to 9999
  7037. #     y4 - year number in range 0000 to 9999
  7038. #
  7039. #     n1 - day name in range Sun to Sat
  7040. #     N1 - day name in range SUN to SAT
  7041. #     n2 - day name in range Sunday to Saturday
  7042. #     N2 - day name in range SUNDAY to SATURDAY
  7043. #
  7044. # A percent sign may be input literally by "%%".
  7045. #
  7046. # The date may be specified in one of two formats.  An eight-digit number
  7047. # is assumed to be a date of the form "CCYYMMDD".  A smaller number is
  7048. # assumed to be a julian number representing a date, calculated using the
  7049. # jdate.icn code posted to icon-group by Cary Coutant.  Dates preceeding
  7050. # the christian era are not supported.
  7051. #
  7052. # For example, the function call sprdate("n2, m4 d1, y3", 17760704)
  7053. # returns the string "Thursday, July 4, 1776" and the function call
  7054. # sprdate("m2/d2/y4", 17760704) returns the string "07/04/1776".
  7055. #
  7056. ############################################################################
  7057. #
  7058. # links:  julian.icn - Cary Coutant's julian date routines
  7059. #             (gregorian, julian, datestring, dayofweek,
  7060. #             tomdy, and floor procedures)
  7061. #
  7062. ############################################################################
  7063. #
  7064. # test driver
  7065. # procedure main()
  7066. #     repeat {
  7067. #         writes("enter a format specification (null to quit):  ")
  7068. #         fmt := read()
  7069. #         if *fmt = 0 then break
  7070. #         writes("enter a date in CCYYMMDD or julian number form:  ")
  7071. #         expr := read()
  7072. #         write("the output is |" || sprdate(fmt, expr) || "|")
  7073. #         write()
  7074. #     }
  7075. # end
  7076. #
  7077. ############################################################################
  7078.  
  7079. link julian
  7080.  
  7081. # sprdate - return formatted date string
  7082. procedure sprdate(fmt, expr)
  7083.     local out, i, s, g, m, d, y, dow, val
  7084.     static months
  7085.     initial {
  7086.         months := ["January", "February", "March", "April",
  7087.                    "May", "June", "July", "August", "September",
  7088.                    "October", "November", "December"]
  7089.     }
  7090.  
  7091.     if *expr >= 8 then {
  7092.         m := integer(expr[5:7])
  7093.         d := integer(expr[7:9])
  7094.         y := integer(expr[1:5])
  7095.         dow := dayofweek(gregorian(m,d,y))
  7096.     } else {
  7097.         mdy := tomdy(expr)
  7098.         m := mdy[1]; d := mdy[2]; y := mdy[3]
  7099.         dow := dayofweek(expr)
  7100.     }
  7101.     out := ""
  7102.     fmt ? repeat {
  7103.         (out ||:= tab(upto('%\\'))) | (out ||:= tab(0) & break)
  7104.         case move(1) of {
  7105.         "%": { # format specification
  7106.             if match('%') then {
  7107.                 out ||:= "%"
  7108.                 move(1)
  7109.             } else {
  7110.                 conv := move(2)
  7111.                 case conv of {
  7112.                 "m1": { val := m }
  7113.                 "m2": { val := right(m, 2, "0") }
  7114.                 "m3": { val := left(months[m], 3) }
  7115.                 "M3": { val := map(left(months[m], 3), &lcase, &ucase) }
  7116.                 "m4": { val := months[m] }
  7117.                 "M4": { val := map(months[m], &lcase, &ucase) }
  7118.                 "d1": { val := d }
  7119.                 "d2": { val := right(d, 2, "0") }
  7120.                 "y1": { val := y % 100 }
  7121.                 "y2": { val := right(y % 100, 2, "0") }
  7122.                 "y3": { val := y }
  7123.                 "y4": { val := right(y, 4, "0") }
  7124.                 "n1": { val := left(dow, 3) }
  7125.                 "N1": { val := map(left(dow, 3), &lcase, &ucase) }
  7126.                 "n2": { val := dow }
  7127.                 "N2": { val := map(dow, &lcase, &ucase) }
  7128.                 default: { val := &null; break }
  7129.                 }
  7130.                 out ||:= val
  7131.             }
  7132.         }
  7133.         "\\": { # escape sequence
  7134.             # escape handler derived from an ipl proc by William H. Mitchell
  7135.             out ||:= case c := map(move(1)) of {
  7136.             "b": "\b"
  7137.             "d": "\d"
  7138.             "e": "\e"
  7139.             "f": "\f"
  7140.             "l": "\l"
  7141.             "n": "\n"
  7142.             "r": "\r"
  7143.             "t": "\t"
  7144.             "v": "\v"
  7145.             "'": "'"
  7146.             "\"": "\""
  7147.             "x": {
  7148.                 move(i := 2 | 1) ? s := tab(upto(~'0123456789ABCDEFabcdef') | 0)
  7149.                 move(*s - i)
  7150.                 char("16r" || s)
  7151.             }
  7152.             "^": char(iand(ord(move(1)), 16r1f))
  7153.             !"01234567": {
  7154.                 move(-1)
  7155.                 move(i := 3 | 2 | 1) ? s := tab(upto(~'01234567') | 0)
  7156.                 move(*s - i)
  7157.                 if s > 377 then {
  7158.                     s := s[1:3]
  7159.                     move(-1)
  7160.                 }
  7161.                 char("8r" || s)
  7162.             }
  7163.             default: c
  7164.             }
  7165.         }
  7166.         }
  7167.     }
  7168.     return out
  7169. end
  7170.  
  7171. # prdate - write date to standard output
  7172. procedure prdate(fmt, expr)
  7173.     writes(sprdate(fmt, expr))
  7174.     return
  7175. end
  7176.  
  7177. # fprdate - write date to file
  7178. procedure fprdate(fd, fmt, expr)
  7179.     writes(fd, sprdate(fmt, expr))
  7180.     return
  7181. end
  7182.  
  7183. From icon-group-request@arizona.edu  Tue May 14 16:03:38 1991
  7184. Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Tue, 14 May 91 16:03:38 MST
  7185. Resent-From: icon-group-request@arizona.edu
  7186. Received: from Arizona.edu (Merlin.Telcom.Arizona.EDU) by optima.cs.arizona.edu (4.1/15)
  7187.     id AA10944; Tue, 14 May 91 16:03:36 MST
  7188. Received: from ucbvax.Berkeley.EDU by Arizona.edu with PMDF#10282; Tue, 14 May
  7189.  1991 16:03 MST
  7190. Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA19587; Tue, 14 May 91
  7191.  15:52:26 -0700
  7192. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  7193.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  7194.  usenet@ucbvax.Berkeley.EDU if you have questions)
  7195. Resent-Date: Tue, 14 May 1991 16:03 MST
  7196. Date: 14 May 91 22:26:51 GMT
  7197. From: midway!ellis.uchicago.edu!goer@handies.ucar.edu (Richard L. Goerwitz)
  7198. Subject: Algol->Icon & Pascal
  7199. Sender: icon-group-request@arizona.edu
  7200. Resent-To: icon-group@cs.arizona.edu
  7201. To: icon-group@arizona.edu
  7202. Resent-Message-Id: <8DA76AF1E6401602@Arizona.edu>
  7203. Message-Id: <1991May14.222651.16502@midway.uchicago.edu>
  7204. X-Envelope-To: icon-group@CS.Arizona.EDU
  7205. X-Vms-To: icon-group@Arizona.edu
  7206. Organization: University of Chicago
  7207.  
  7208. I've always wondered why Icon uses the brace notation (rather than
  7209. begin ... end;) for most groupings, but yet for procedures, a kind
  7210. of mixed procedure name(vars)...end notation is used.  I'm also a
  7211. bit curious why the notion of functions and procedures was collap-
  7212. sed into procedures, and yet with retention of the notion that a
  7213. procedure is a value (i.e. like what we normally associate with fun-
  7214. ctions).
  7215.  
  7216. Just curious.
  7217.  
  7218. -- 
  7219.  
  7220.    -Richard L. Goerwitz              goer%sophist@uchicago.bitnet
  7221.    goer@sophist.uchicago.edu         rutgers!oddjob!gide!sophist!goer
  7222.  
  7223. From gudeman  Tue May 14 16:13:39 1991
  7224. Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Tue, 14 May 91 16:13:39 MST
  7225. Resent-From: "David Gudeman" <gudeman>
  7226. Received: from Arizona.edu (Merlin.Telcom.Arizona.EDU) by optima.cs.arizona.edu (4.1/15)
  7227.     id AA11319; Tue, 14 May 91 16:13:37 MST
  7228. Received: from optima.cs.arizona.edu by Arizona.edu with PMDF#10282; Tue, 14
  7229.  May 1991 16:13 MST
  7230. Received: from orator.cs.arizona.edu by optima.cs.arizona.edu (4.1/15) id
  7231.  AA11267; Tue, 14 May 91 16:13:01 MST
  7232. Received: by orator.cs.arizona.edu; Tue, 14 May 91 16:12:59 MST
  7233. Resent-Date: Tue, 14 May 1991 16:13 MST
  7234. Date: Tue, 14 May 91 16:12:59 MST
  7235. From: David Gudeman <gudeman@cs.arizona.edu>
  7236. Subject: Algol->Icon & Pascal
  7237. In-Reply-To: Richard L. Goerwitz's message of 14 May 91 22:26:51 GMT
  7238.  <1991May14.222651.16502@midway.uchicago.edu>
  7239. Resent-To: icon-group@cs.arizona.edu
  7240. To: midway!ellis.uchicago.edu!goer@handies.ucar.edu
  7241. Cc: icon-group@arizona.edu
  7242. Resent-Message-Id: <8F0D1523C6401611@Arizona.edu>
  7243. Message-Id: <9105142312.AA11405@orator.cs.arizona.edu>
  7244. X-Envelope-To: icon-group@CS.Arizona.EDU
  7245. X-Vms-To: midway!ellis.uchicago.edu!goer@handies.ucar.edu
  7246. X-Vms-Cc: icon-group@Arizona.edu
  7247.  
  7248. >From: Richard L. Goerwitz
  7249.  
  7250. >...  I'm also a
  7251. >bit curious why the notion of functions and procedures was collap-
  7252. >sed into procedures, and yet with retention of the notion that a
  7253. >procedure is a value (i.e. like what we normally associate with fun-
  7254. >ctions).
  7255.  
  7256. I assume you are talking about the Pascal distinction that functions
  7257. are expression (things that return values) and procedures are
  7258. statements (things that change variables but don't return values).
  7259. But Icon doesn't have statements --only expressions-- so there is no
  7260. such distinction to make.
  7261.  
  7262. As to procedures being values, there is nothing unlikely about
  7263. procedures-as-values even for Pascal-style procedures.  It's just not
  7264. traditional for Pascal-like languages to have procedures or functions
  7265. as first-class values.
  7266.  
  7267. From R.J.Hare@edinburgh.ac.uk  Thu May 16 01:06:48 1991
  7268. Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Thu, 16 May 91 01:06:48 MST
  7269. Received: from Arizona.edu (Merlin.Telcom.Arizona.EDU) by optima.cs.arizona.edu (4.1/15)
  7270.     id AA23169; Thu, 16 May 91 01:06:45 MST
  7271. Received: from UKACRL.BITNET (MAILER@UKACRL) by Arizona.edu with PMDF#10282;
  7272.  Thu, 16 May 1991 01:06 MST
  7273. Received: from RL.IB by UKACRL.BITNET (Mailer R2.07) with BSMTP id 2380; Thu,
  7274.  16 May 91 09:02:59 BST
  7275. Received: from RL.IB by UK.AC.RL.IB (Mailer R2.07) with BSMTP id 5317; Thu, 16
  7276.  May 91 09:00:21 BST
  7277. Date: 16 May 91  08:57:28 bst
  7278. From: R.J.Hare@edinburgh.ac.uk
  7279. Subject: Language 'tutors'
  7280. To: icon-group@cs.arizona.edu
  7281. Message-Id: <16 May 91  08:57:28 bst  060957@EMAS-A>
  7282. X-Envelope-To: icon-group@cs.arizona.edu
  7283. Via:        UK.AC.ED.EMAS-A; 16 MAY 91  9:00:19 BST
  7284.  
  7285. Has anyone used Icon to develop 'tutors' for learning foreign languages
  7286. in any way - for example, vocabulary drills, simple phrase translation,
  7287. etc.?
  7288.  
  7289. If yes, are such programs available?
  7290.  
  7291. Thanks.
  7292.  
  7293. Roger Hare.
  7294.  
  7295. From KKTK_KOTUS@cc.helsinki.fi  Thu May 16 04:25:57 1991
  7296. Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Thu, 16 May 91 04:25:57 MST
  7297. Received: from HYLKA.HELSINKI.FI by optima.cs.arizona.edu (4.1/15)
  7298.     id AA02858; Thu, 16 May 91 04:25:45 MST
  7299. Date: Thu, 16 May 1991 14:25 EET
  7300. From: KKTK_KOTUS@cc.helsinki.fi
  7301. Subject: A word/line procedure
  7302. To: icon-group@cs.arizona.edu
  7303. Message-Id: <124E207800E17F06@cc.Helsinki.FI>
  7304. X-Envelope-To: icon-group@cs.arizona.edu
  7305. X-Vms-To: IN%"icon-group@cs.arizona.edu"
  7306.  
  7307.  
  7308. Dear iconists,
  7309.  
  7310. I have a following, obviosly simple problem. I have made a nice
  7311. Icon procedure, which divides a text file one word/line. It is much easier,
  7312. simpler and faster than the one given in Icon book. It goes like this 
  7313. (the original idea is, I believe, from some Unix-procedure, and it is the same
  7314. thing you would do with any editor or text processing program, if you had to
  7315. use them for the work):
  7316.  
  7317.  
  7318.     procedure main()
  7319.            while line:=read() do write(map(line," ","\l"))
  7320.     end 
  7321.  
  7322.  
  7323. It works fine and fast, but it produces also empty lines which I cannot get rid
  7324. off in the same procedure, although I try to filter them out with something
  7325. like 
  7326.  
  7327.  
  7328.     if *line > 0 then write(line)
  7329.  
  7330.  
  7331. But if I make the first procedure to write the stuff in a file and then process
  7332. that file with the procedure
  7333.  
  7334.  
  7335.     procedure main()
  7336.           while line:=read() do if *line > 0 then write(line)
  7337.     end
  7338.  
  7339.  
  7340.  
  7341. I get rid off the empty lines. It is easy to make a .bat or .com or whatever
  7342. from these two procedures, and the whole thing still works at least as fast or
  7343. even faster than the procedure in the Icon book. But
  7344. I would still like to know, how I actually could make it work in one shot. I
  7345. have tried different solutions, but they do not work. Can anybody
  7346. explain it?
  7347.  
  7348.  
  7349.  
  7350. Greetings,
  7351.  
  7352. Kimmo Kettunen
  7353. KKTK_KOTUS@CC.HELSINKI.FI 
  7354.  
  7355.  
  7356.  
  7357.  
  7358.  
  7359.  
  7360.     
  7361.  
  7362.  
  7363.  
  7364.  
  7365.  
  7366.  
  7367.  
  7368.  
  7369. From isidev!nowlin@uunet.uu.net  Thu May 16 07:53:49 1991
  7370. Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Thu, 16 May 91 07:53:49 MST
  7371. Received: from relay1.UU.NET by optima.cs.arizona.edu (4.1/15)
  7372.     id AA06729; Thu, 16 May 91 07:53:46 MST
  7373. Received: from isidev.UUCP (LOCALHOST.UU.NET) by relay1.UU.NET with SMTP 
  7374.     (5.61/UUNET-internet-primary) id AA23636; Thu, 16 May 91 10:53:42 -0400
  7375. Date: Thu, 16 May 91 10:53:42 -0400
  7376. From: isidev!nowlin@uunet.uu.net
  7377. Message-Id: <9105161453.AA23636@relay1.UU.NET>
  7378. To: uunet!cs.arizona.edu!icon-group@uunet.uu.net
  7379. Subject: Re: word/line procedure
  7380.  
  7381.  > From Kimmo Kettunen
  7382.  > 
  7383.  > I have a following, obviosly simple problem. I have made a nice Icon
  7384.  > procedure, which divides a text file one word/line.  It is much easier,
  7385.  > ...
  7386.  >     procedure main()
  7387.  >            while line:=read() do write(map(line," ","\l"))
  7388.  >     end 
  7389.  > 
  7390.  > It works fine and fast, but it produces also empty lines which I cannot get
  7391.  > rid off in the same procedure, although I try to filter them out with
  7392.  > something like
  7393.  > 
  7394.  >     if *line > 0 then write(line)
  7395.  
  7396. First you have to remember that in Icon you're working on strings, NOT
  7397. lines.  The result of the map() is not a series of lines but the same basic
  7398. string with spaces changed to newlines.  The length of the string hasn't
  7399. changed.  Testing the length of the string to discard empty lines won't do
  7400. any good at this point.
  7401.  
  7402.  > But if I make the first procedure to write the stuff in a file and then
  7403.  > process that file with the procedure
  7404.  > 
  7405.  >     procedure main()
  7406.  >           while line:=read() do if *line > 0 then write(line)
  7407.  >     end
  7408.  
  7409. The reason testing the length works on the second pass is that now you're
  7410. reading in the original string in little pieces, one line at a time.  If
  7411. some of these pieces are empty lines they now exhibit zero length and can
  7412. be discarded.
  7413.  
  7414.  > ...
  7415.  > I would still like to know, how I actually could make it work in one shot.
  7416.  > I have tried different solutions, but they do not work. Can anybody
  7417.  > explain it?
  7418.  
  7419. I diddled your basic design, which is a neat idea by the way, and instead
  7420. of writing out the entire mapped string I write it out in pieces that are
  7421. delimited by the newlines that were mapped into the string.  This allows
  7422. the program to skip over consecutive bunches of newlines and thereby
  7423. discard the "blank lines" in one pass.  You'll have to test its speed.  It
  7424. may not be that fast now.
  7425.  
  7426.     procedure main()
  7427.  
  7428.         # convert input spaces to newlines and scan the result
  7429.         while line := map(read()," ","\l") do line ?  {
  7430.  
  7431.             # skip initial newlines
  7432.             tab(many('\l'))
  7433.  
  7434.             # write out substrings delimited by newlines
  7435.             while write(tab(upto('\l'))) do
  7436.  
  7437.                 # skip newlines
  7438.                 tab(many('\l'))
  7439.  
  7440.             # write out the last substring
  7441.             if not pos(0) then write(tab(0))
  7442.         }
  7443.  
  7444.     end
  7445.  
  7446. I'd assign the newline cset to a variable since it's used several places
  7447. now and maybe change the map to handle more "white space" characters than
  7448. just the space.  The tab comes to mind.  It's a good program idea.
  7449.  
  7450.  
  7451.   --- ---
  7452.    | S | Iconic Software, Inc.  -  Jerry Nowlin  -  uunet!isidev!nowlin
  7453.   --- ---
  7454.  
  7455.  
  7456. From cargo@cherry.cray.com  Thu May 16 08:34:24 1991
  7457. Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Thu, 16 May 91 08:34:24 MST
  7458. Received: from timbuk (timbuk.cray.com) by optima.cs.arizona.edu (4.1/15)
  7459.     id AA07941; Thu, 16 May 91 08:34:19 MST
  7460. Received: from cherry04.cray.com by timbuk (4.1/CRI-MX 1.6d)
  7461.     id AA17236; Thu, 16 May 91 10:34:07 CDT
  7462. Received: by cherry04.cray.com
  7463.     id AA23758; 4.1/CRI-5.6; Thu, 16 May 91 10:34:04 CDT
  7464. Date: Thu, 16 May 91 10:34:04 CDT
  7465. From: cargo@cherry.cray.com (David S. Cargo)
  7466. Message-Id: <9105161534.AA23758@cherry04.cray.com>
  7467. To: icon-group@cs.arizona.edu
  7468. Subject: input pushbacks
  7469.  
  7470. I'm writing a program that is simplified by having a mechanism for
  7471. "unreading" a line (or group of lines).  I'm looking a various
  7472. implementations for doing that.  Some use an input list that checked
  7473. for size before reading from a file.  Others use more elaborate
  7474. structures.
  7475.  
  7476. I'm curious about possible solutions the problem and whether other
  7477. people have found a need for such mechanisms themselves.
  7478.                          o       o
  7479. cargo@escargot.cray.com   \_____/
  7480. (612) 683-5591            /-o-o-\     _______
  7481. DDDD      SSSS   CCCC    /   ^   \   /\\\\\\\\
  7482. D   D    S      C        \ \___/ /  /\   ___  \
  7483. D   D     SSS   C         \_   _/  /\   /\\\\  \
  7484. D   D        S  C           \  \__/\   /\ @_/  /
  7485. DDDDavid SSSS.   CCCCargo    \____\____\______/
  7486.  
  7487. From shafto@eos.arc.nasa.gov  Thu May 16 12:27:50 1991
  7488. Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Thu, 16 May 91 12:27:50 MST
  7489. Received: from eos.arc.nasa.gov by optima.cs.arizona.edu (4.1/15)
  7490.     id AA16754; Thu, 16 May 91 12:27:48 MST
  7491. Received: Thu, 16 May 91 12:27:44 -0700 by eos.arc.nasa.gov (5.65/1.2)
  7492. Date: Thu, 16 May 91 12:27:44 -0700
  7493. From: Michael Shafto <shafto@eos.arc.nasa.gov>
  7494. Message-Id: <9105161927.AA25003@eos.arc.nasa.gov>
  7495. To: cargo@cherry.cray.com, icon-group@cs.arizona.edu
  7496. Subject: Re:  input pushbacks
  7497. Cc: shafto@eos.arc.nasa.gov
  7498.  
  7499. Have you looked at the routine in Gimpel's
  7500. _Algorithms in SNOBOL4_, pp. 167ff.?
  7501.  
  7502. Mike
  7503.  
  7504. From icon-group-request@arizona.edu  Thu May 16 13:43:26 1991
  7505. Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Thu, 16 May 91 13:43:26 MST
  7506. Resent-From: icon-group-request@arizona.edu
  7507. Received: from Arizona.edu (Merlin.Telcom.Arizona.EDU) by optima.cs.arizona.edu (4.1/15)
  7508.     id AA20127; Thu, 16 May 91 13:43:23 MST
  7509. Received: from ucbvax.Berkeley.EDU by Arizona.edu with PMDF#10282; Thu, 16 May
  7510.  1991 13:42 MST
  7511. Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA27814; Thu, 16 May 91
  7512.  10:12:27 -0700
  7513. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  7514.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  7515.  usenet@ucbvax.Berkeley.EDU if you have questions)
  7516. Resent-Date: Thu, 16 May 1991 13:43 MST
  7517. Date: 16 May 91 15:30:40 GMT
  7518. From: usc!zaphod.mps.ohio-state.edu!pacific.mps.ohio-state.edu!linac!midway!ellis.uchicago.edu!goer@ucsd.edu (Richard L.
  7519.  Goerwitz)
  7520. Subject: RE: A word/line procedure
  7521. Sender: icon-group-request@arizona.edu
  7522. Resent-To: icon-group@cs.arizona.edu
  7523. To: icon-group@arizona.edu
  7524. Resent-Message-Id: <0C637EE0B6401F3A@Arizona.edu>
  7525. Message-Id: <1991May16.153040.9843@midway.uchicago.edu>
  7526. X-Envelope-To: icon-group@CS.Arizona.EDU
  7527. X-Vms-To: icon-group@Arizona.edu
  7528. Organization: University of Chicago
  7529. References: <124E207800E17F06@cc.Helsinki.FI>
  7530.  
  7531. In article <124E207800E17F06@cc.Helsinki.FI> KKTK_KOTUS@cc.helsinki.fi writes:
  7532. >
  7533. >I have a following, obviously simple problem. I have made a nice
  7534. >Icon procedure, which divides a text file one word/line....:
  7535. >
  7536. >    procedure main()
  7537. >           while line:=read() do write(map(line," ","\l"))
  7538. >    end 
  7539. >
  7540. >It works fine and fast, but it produces also empty lines which I cannot get rid
  7541. >off in the same procedure, although I try to filter them out with something
  7542. >like 
  7543. >
  7544. >    if *line > 0 then write(line)
  7545.  
  7546. I don't see how you can eliminate blank lines that are due to adjacent
  7547. spaces.  If all words are guaranteed to be separated by one space, and
  7548. no more, then naturally you could say
  7549.  
  7550.     ... do write("" ~== map(line, " ", "\l"))
  7551.  
  7552. This would eliminate lines with no words on them.  If, though, your files
  7553. distance words from each other using more than one blank space, you will
  7554. surely need to scan the lines by hand.  I don't know what was in the Icon
  7555. book, but I'd probably just use:
  7556.  
  7557. procedure main(a)
  7558.  
  7559.     separators := \a[1] | ',":<>,._+-=)(*&^%$#!@~`\'?/|\\][} {\t;'
  7560.  
  7561.     while read(&input) ? {
  7562.         tab(many(separators))
  7563.     if not pos(0) then {
  7564.             while write(tab(upto(separators))) do
  7565.             tab(many(separators))
  7566.         }
  7567.     pos(0) | write(tab(0))
  7568.     }
  7569.  
  7570. end
  7571.  
  7572. If you add in control characters to your separator list, and add a test
  7573. for length, you'll have something like the UNIX strings command.
  7574.  
  7575. Quiz time:
  7576.  
  7577.     Why must the line "pos(0) | write(tab(0))" stand after the if..then
  7578.     expression?
  7579.  
  7580. If you are stumped, here is a hint (don't peek):
  7581.  
  7582.  
  7583.  
  7584.  
  7585.  
  7586.  
  7587.     Notice how I called "if...then" an "expression."  That means it pro-
  7588.     duces a result.  What is that result?
  7589.  
  7590. If you are still stumped, here is the (or rather one) answer:
  7591.  
  7592.  
  7593.  
  7594.  
  7595.  
  7596.     The read(&input) ? { if...then; junk } expression always succeeds,
  7597.     because "junk" (i.e. "pos(0) | write(tab(0))") always succeeds.  If
  7598.     junk were not present, then we'd have read(&input) ? { if...then }.
  7599.     If the if-condition fails, the if...then expression fails.  More-
  7600.     over, if it succeeds, the then { expression } is evaluated.  Since
  7601.     "expression" is a while loop, it will eventually fail, causing the
  7602.     entire if...then expression to fail.  When it fails, the read(&input)
  7603.     ? { etc. } expression will fail, which will cause termination of the
  7604.     while construct it is part of, and ultimately termination of the
  7605.     program.  The upshot is that junk must be present, and must always
  7606.     succeed.
  7607.  
  7608. I probably should have tested the above program, but I have to run.  If
  7609. there are any errors, then I apologize (though I really don't see where
  7610. any could be [famous last words]).
  7611.  
  7612. -- 
  7613.  
  7614.    -Richard L. Goerwitz              goer%sophist@uchicago.bitnet
  7615.    goer@sophist.uchicago.edu         rutgers!oddjob!gide!sophist!goer
  7616.  
  7617. From belli@adt.uni-paderborn.de  Fri May 17 05:31:08 1991
  7618. Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Fri, 17 May 91 05:31:08 MST
  7619. Received: from pbinfo.uni-paderborn.de by optima.cs.arizona.edu (4.1/15)
  7620.     id AA23185; Fri, 17 May 91 05:30:35 MST
  7621. Received: from [131.234.128.175] by pbinfo.uni-paderborn.de with SMTP
  7622.     (5.65+/PB-3.85+yp+master) id AA03987; Fri, 17 May 91 14:32:00 +0200
  7623. Received: by alpha.uni-paderborn.de
  7624.     (5.61++/PB-3.41) id AA00712; Fri, 17 May 91 14:29:08 -0100
  7625. Date: Fri, 17 May 91 14:29:08 -0100
  7626. From: Fevzi Belli <belli@adt.uni-paderborn.de>
  7627. Message-Id: <9105171529.AA00712@alpha.uni-paderborn.de>
  7628. To: icon-group@cs.arizona.edu
  7629. Subject: Call for Papers IEA/AIE-92
  7630.  
  7631. We would like to inform you about our conference and would be
  7632. appreciated if you could also inform your colleagues about the
  7633. IEA/AIE-92. Please forward the Call for Papers to anyone who
  7634. is interested in the scope of the conference. Thank you very
  7635. much.
  7636.  
  7637. Bernhard Hoppe-Biermeyer 
  7638. Univ. Paderborn
  7639. Arrangements & Publicity-Chair
  7640. phone: (+49) 5251 60 3283
  7641. fax  : (+49) 5251 60 2519/3238
  7642. email: bernhard@adt.uni-paderborn.de
  7643.  
  7644. -----------------------------------------------------------------------
  7645.                  C A L L     F O R     P A P E R S
  7646. -----------------------------------------------------------------------
  7647.  
  7648.    THE FIFTH INTERNATIONAL CONFERENCE ON INDUSTRIAL AND ENGINEERING
  7649. APPLICATIONS OF ARTIFICIAL INTELLIGENCE AND EXPERT SYSTEMS (IEA/AIE-92)
  7650.  
  7651. June 9-12, 1992                    The University of Paderborn, Germany
  7652.  
  7653.  
  7654. Sponsored by:
  7655.  
  7656. Daimler-Benz AG
  7657. Dornier Deutsche Aerospace
  7658. Siemens Nixdorf Informationssysteme AG
  7659. The University of Tennessee Space Institute
  7660. Universitaet-Gesamthochschule Paderborn
  7661.  
  7662. In Cooperation with:
  7663.  
  7664. American Association for Artificial Intelligence
  7665. Association for Computing Machinery/SIGART
  7666. Canadian Society for Computational Studies of Intelligence
  7667. European Coordinating Committee for AI
  7668. Gesellschaft fuer Informatik e.V. (Germany)
  7669. IEEE Computer Society
  7670. International Society of Applied Intelligence
  7671. International Association of Knowledge Engineers
  7672. International Neural Network Society
  7673. Japanese Society of Artificial Intelligence
  7674.  
  7675. This conference continues its tradition of emphasizing applications of 
  7676. artificial intelligence and expert/knowledge-based systems to engineering 
  7677. and industrial problems. One of the specialities of the IEA/AIE-92 will 
  7678. be the Industrial Program. Topics of interest include but are not 
  7679. limited to:
  7680.  
  7681. Pattern Recognition                        Knowledge Representation          
  7682. Neural Networks                            Knowledge Acquisition
  7683. Machine Learning                           Robotics
  7684. Model-Based & Qualitative Reasoning        Machine Vision
  7685. Computer Aided Manufacturing               Natural Language Processing
  7686. Computer Aided Design                      Reasoning Under Uncertainty
  7687. Expert & Diagnostic Systems                Distributed AI Architectures
  7688. Intelligent Databases                      Planning/Scheduling
  7689. Intelligent Interfaces                     Sensor Fusion
  7690. AI In Administration & Government          Intelligent Tutoring
  7691. Verifaction, Validation,                   Software Engineering & AI/ES
  7692. Dependability & AI/ES        
  7693.  
  7694. Please indicate the area of submission as shwon above, and submit by 
  7695. November 1, 1991 six copies of your paper (single spaced, minimum length 
  7696. of 6 and maximum length of 10 pages) to the Program Chair. Authors will 
  7697. be notified of the status of their manuscript by February 11, 1992. Final 
  7698. copies of papers will be due for inclusion in the conference proceedings 
  7699. by March 16, 1992.
  7700.  
  7701. Program Chair                            General Chair
  7702. Dr. Fevzi Belli                          Dr. Moonis Ali
  7703. Universitaet-GH Paderborn                Computer Science Department
  7704. Postfach 1621                            Univ. of Tennessee Space Inst.
  7705. 4790 Paderborn                           Tullahoma, TN 37388
  7706. Germany                                  USA
  7707. Tel. (+49) 5251 60-3283                  Tel. (+1) 615 455-0631
  7708. E-mail: belli@adt.uni-paderborn.de       E-mail: alif@utsiv1.bitnet
  7709. Fax: (+49) 5251 60-3238                  Fax: (+1) 615 454-2354
  7710.  
  7711. General information and registration materials may be obtained from: 
  7712.  
  7713. Alireza Azem                                   Ms. Sandy Shankle
  7714. Univ.-GH Paderborn, FB 14                      UTSI
  7715. 4790 Paderborn                                 Tullahoma, TN 37388-8897
  7716. Germany                                        USA
  7717.  
  7718. The proceedings will be available at the conference. Proceedings of 
  7719. earlier conferences are available -- contact: Ms. Nancy Wise at 
  7720. (+1) 615 455-0631, ext. 236.
  7721.                                                                       
  7722. Program Co-Chairs:
  7723.  
  7724. Graham Forsyth, DSTO Aeronautical/Melbourne
  7725. Edward Grant, Univ. of Strathclyde
  7726. Franz-Josef Radermacher, FAW Ulm
  7727.  
  7728. Program Committee                           
  7729.  
  7730. Olaf Abeln, ASEA Brown-Bov./Mannheim                      
  7731. J. H. Andreae, Univ. of Canterbury
  7732. W. Bibel, TH Darmstadt                                    
  7733. Gautam Biswas, Vanderbilt Univ./Nashville
  7734. Hinrich Bonin, Polytechnic Lueneburg                      
  7735. Ivan Bratko, Univ. of Ljubljana
  7736. Luigia Carlucci Aiello, Univ. di Roma                     
  7737. Thomas Christaller, GMD/St. Augustin
  7738. Paul Chung, University of Edingburgh                      
  7739. A. G. Cohn, University of Leeds
  7740. Alain Costes, LAAS-CNRS/Toulouse                          
  7741. Thore Danielsen, Norw. Telecom/Tromso
  7742. R. Freedman, Polytechnic Univ./New York                   
  7743. Toshio Fukuda, Nagoya University
  7744. Oliver Guenther, FAW Ulm                                  
  7745. Uwe L. Haass, FORWISS/Erlangen
  7746. Georg Hartmann, Univ. Paderborn                           
  7747. K. M. van Hee, Eindhoven Univ. of Techn.
  7748. Alexander Herold/ECRC Munich                              
  7749. P. Jedrzejowicz, Merch. Mar. Acad./Gdynia
  7750. M. Klein, HEC GSM, Jouy-en-Josas                          
  7751. Jay Liebowitz, G. Washington Univ./Washington
  7752. Ramon Lopez de Mantaras, CSIC/Blanes                      
  7753. Bernard Moulin, Universite Laval/Quebec
  7754. Lee Naish, Univ. Melbourne                                
  7755. Bernd Neumann, LKI Hamburg
  7756. Setsuo Ohsuga, University of Tokyo                        
  7757. Dick Peacocke, BNR/Ottawa
  7758. Ivan Plander, ITCSAC/Bratislava                           
  7759. M. M. Richter, Univ. Kaiserslautern
  7760. Enrique Ruspini, SRI Internat./Menlo Park                 
  7761. Erik Sandewall, Linkoeping University
  7762. Jonathan Shapiro, The Turing Inst./Glasgow                
  7763. Peter Sydenham, Univ. of South Australia
  7764. Ludger Thomas, Siemens Nixdorf/Paderborn                  
  7765. M. Trivedi, Univ. of Tennessee/Knoxville
  7766. Ian Witten, University of Calgary                         
  7767. T. Yamakawa, Kyushu Inst. of Technology          
  7768.  
  7769. Ex-Officio
  7770. Jim Bezdek, Univ. of W. Florida/Pensacola                 
  7771. M. Matthews, Univ. of s. Carolina/Columbia
  7772.  
  7773. Proceedings Editors                 Tutorial Chair
  7774. F. Belli & Alfred Schmidt           Oliver Guenther, FAW Ulm
  7775. Univ. Paderborn            
  7776.  
  7777. Arrangements & Publicity Chair      Industrial Program & Exhibits Chair
  7778. Bernhard Hoppe-Biermeyer            Stefan Omlor, Telenorma Frankfurt
  7779. Univ. Paderborn                           
  7780.  
  7781. Registration Chair                  Administration Chair
  7782. Sandy Shankle, UTSI Tullahoma       Alireza Azem, Univ. Paderborn
  7783. -----------------------------------------------------------------------
  7784.  
  7785. From icon-group-request@arizona.edu  Sat May 18 07:10:11 1991
  7786. Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Sat, 18 May 91 07:10:11 MST
  7787. Resent-From: icon-group-request@arizona.edu
  7788. Received: from Arizona.edu (Merlin.Telcom.Arizona.EDU) by optima.cs.arizona.edu (4.1/15)
  7789.     id AA24544; Sat, 18 May 91 07:10:07 MST
  7790. Received: from ucbvax.Berkeley.EDU by Arizona.edu with PMDF#10282; Sat, 18 May
  7791.  1991 07:09 MST
  7792. Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA26823; Sat, 18 May 91
  7793.  06:57:43 -0700
  7794. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  7795.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  7796.  usenet@ucbvax.Berkeley.EDU if you have questions)
  7797. Resent-Date: Sat, 18 May 1991 07:09 MST
  7798. Date: 17 May 91 18:36:46 GMT
  7799. From: agate!bionet!ucselx!usc!cs.utexas.edu!sdd.hp.com!spool.mu.edu!cs.umn.edu!msi.umn.edu!noc.MR.NET!ns!ns!dean@ucbvax.berkeley.edu (Dean C.
  7800.  Gahlon)
  7801. Subject: RE: Language 'tutors'
  7802. Sender: icon-group-request@arizona.edu
  7803. Resent-To: icon-group@cs.arizona.edu
  7804. To: icon-group@arizona.edu
  7805. Resent-Message-Id: <67C978A7F64025A3@Arizona.edu>
  7806. Message-Id: <1991May17.183646.28895@ns.network.com>
  7807. X-Envelope-To: icon-group@CS.Arizona.EDU
  7808. X-Vms-To: icon-group@Arizona.edu
  7809. Organization: Network Systems Corporation
  7810. References: <16.May.91..08:57:28.bst..060957@EMAS-A>
  7811.  
  7812. In article <16.May.91..08:57:28.bst..060957@EMAS-A> R.J.Hare@edinburgh.ac.uk writes:
  7813. >Has anyone used Icon to develop 'tutors' for learning foreign languages
  7814. >in any way - for example, vocabulary drills, simple phrase translation,
  7815. >etc.?
  7816. >If yes, are such programs available?
  7817. >Thanks.
  7818. >Roger Hare.
  7819.  
  7820. Yes, as a matter of fact. I have a couple of Japanese tutoring programs
  7821. written in Icon. They're not very fancy (and in fact don't use an incredible
  7822. number of the more advanced features of the language (i.e., I suspect that
  7823. they could be written to be better)), but they work.  If I remember, I will
  7824. try to upload them to this machine and then post them on the network
  7825. sometime soon.
  7826.  
  7827.                         Dean C. Gahlon
  7828.                         dean@ns.network.com
  7829.  
  7830. From icon-group-request@arizona.edu  Thu May 23 08:00:37 1991
  7831. Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Thu, 23 May 91 08:00:37 MST
  7832. Resent-From: icon-group-request@arizona.edu
  7833. Received: from Arizona.edu (Merlin.Telcom.Arizona.EDU) by optima.cs.arizona.edu (4.1/15)
  7834.     id AA28264; Thu, 23 May 91 08:00:34 MST
  7835. Received: from ucbvax.Berkeley.EDU by Arizona.edu with PMDF#10282; Thu, 23 May
  7836.  1991 08:00 MST
  7837. Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA11969; Thu, 23 May 91
  7838.  07:54:41 -0700
  7839. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  7840.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  7841.  usenet@ucbvax.Berkeley.EDU if you have questions)
  7842. Resent-Date: Thu, 23 May 1991 08:00 MST
  7843. Date: 23 May 91 00:31:56 GMT
  7844. From: mvb.saic.com!unogate!unocal!genisco!arcturus!felix!ka%felix.UUCP@ucsd.edu
  7845.  (Kenneth Almquist)
  7846. Subject: RE: Algol->Icon & Pascal
  7847. Sender: icon-group-request@arizona.edu
  7848. Resent-To: icon-group@cs.arizona.edu
  7849. To: icon-group@arizona.edu
  7850. Resent-Message-Id: <5CAA2B07ECC00A9C@Arizona.edu>
  7851. Message-Id: <163508@felix.UUCP>
  7852. X-Envelope-To: icon-group@CS.Arizona.EDU
  7853. X-Vms-To: icon-group@Arizona.edu
  7854. Organization: FileNet Corp., Costa Mesa, CA
  7855. References: <1991May14.222651.16502@midway.uchicago.edu>
  7856.  
  7857. goer@ellis.uchicago.edu (Richard L. Goerwitz) writes:
  7858. > I've always wondered why Icon uses the brace notation (rather than
  7859. > begin ... end;) for most groupings, but yet for procedures, a kind
  7860. > of mixed procedure name(vars)...end notation is used.
  7861.  
  7862. My guess is that this produces better diagnostics when braces are
  7863. omitted.  If you omit an open brace in C, the compiler will eventually
  7864. encounter a closing brace in the middle of the procedure which appears
  7865. to match the start of the procedure.  None of the C compilers that I
  7866. have seen are capable of recognizing this situation and determining
  7867. that the procedure hasn't actually ended.  Instead, they treat the
  7868. procedure as ended and squawk about every line from the closing brace
  7869. until the actual end of the procedure.  Using something other than a
  7870. closing brace to mark the end of a procedure avoids this problem.
  7871.  
  7872. > I'm also a bit curious why the notion of functions and procedures
  7873. > was collapsed into procedures, and yet with retention of the notion
  7874. > that a procedure is a value (i.e. like what we normally associate
  7875. > with functions).
  7876.  
  7877. I'm not sure what you mean by a procedure being a value.  Calling ICON
  7878. procedures "functions" would be a mistake because the term "function"
  7879. is defined by mathematicians to be something that returns exactly one
  7880. value.  In contrast, "procedure" is defined by usage within the compu-
  7881. ter science community.  In Algol and Pascal, a procedure can return
  7882. values by setting parameters, but not by returning a value using the
  7883. syntax for returning a value from a function.  In PL/1 (which is more
  7884. widely used than either Algol or Pascal) this restriction was lifted
  7885. and a procedure can return a value using a "return" statement.  So
  7886. ICON's use of the term "procedure" to refer to something that can
  7887. return zero or more values is a natural extension of prior practice.
  7888.                 Kenneth Almquist
  7889.  
  7890. From icon-group-request@arizona.edu  Thu May 23 23:16:13 1991
  7891. Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Thu, 23 May 91 23:16:13 MST
  7892. Resent-From: icon-group-request@arizona.edu
  7893. Received: from Arizona.edu (Merlin.Telcom.Arizona.EDU) by optima.cs.arizona.edu (4.1/15)
  7894.     id AA08193; Thu, 23 May 91 23:16:10 MST
  7895. Received: from ucbvax.Berkeley.EDU by Arizona.edu with PMDF#10282; Thu, 23 May
  7896.  1991 23:15 MST
  7897. Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA09418; Thu, 23 May 91
  7898.  23:08:59 -0700
  7899. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  7900.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  7901.  usenet@ucbvax.Berkeley.EDU if you have questions)
  7902. Resent-Date: Thu, 23 May 1991 23:15 MST
  7903. Date: 24 May 91 05:12:31 GMT
  7904. From: mips!news.cs.indiana.edu!ux1.cso.uiuc.edu!midway!ellis.uchicago.edu!goer@apple.com (Richard L.
  7905.  Goerwitz)
  7906. Subject: icont .el files
  7907. Sender: icon-group-request@arizona.edu
  7908. Resent-To: icon-group@cs.arizona.edu
  7909. To: icon-group@arizona.edu
  7910. Resent-Message-Id: <DC9272BC8CC00C3E@Arizona.edu>
  7911. Message-Id: <1991May24.051231.9618@midway.uchicago.edu>
  7912. X-Envelope-To: icon-group@CS.Arizona.EDU
  7913. X-Vms-To: icon-group@Arizona.edu
  7914. Organization: University of Chicago
  7915.  
  7916. I recall seeing something like a describe-icon-function.el file
  7917. some months ago.  I guess I'm wondering just what has been done
  7918. in the way of Emacs utility files for Icon programmers (aside from
  7919. the icon.el file that comes with the standard distribution).  If
  7920. anyone could point me in the right direction (or send some code),
  7921. I'd appreciate it very much.
  7922.  
  7923. Naturally, I'll summarize if there's interest.
  7924.  
  7925. -- 
  7926.  
  7927.    -Richard L. Goerwitz              goer%sophist@uchicago.bitnet
  7928.    goer@sophist.uchicago.edu         rutgers!oddjob!gide!sophist!goer
  7929.  
  7930. From uunet!men2a!aquin!luvthang!talmage  Fri May 24 12:18:29 1991
  7931. Received: from univers.cs.arizona.edu by cheltenham.cs.arizona.edu; Fri, 24 May 91 12:18:29 MST
  7932. Received: from uunet.UUCP by univers.cs.arizona.edu; Fri, 24 May 91 12:18:27 MST
  7933. Received: from men2a.UUCP (localhost.UU.NET) by relay1.UU.NET with SMTP 
  7934.     (5.61/UUNET-internet-primary) id AA14737; Fri, 24 May 91 15:03:36 -0400
  7935. Received: by men2a.ori-cal.com (smail2.5)
  7936.     id AA10279; 24 May 91 15:08:22 EDT (Fri)
  7937. Received: by aquin.ORI-CAL.COM (smail2.5)
  7938.     id AA07256; 24 May 91 14:56:30 EDT (Fri)
  7939. Received: by luvthang.UUCP (1.05D/Amiga)
  7940.     id AA02127; Fri, 24 May 91 13:25:29 EST
  7941. Date: Fri, 24 May 91 13:25:29 EST
  7942. Message-Id: <9105241825.AA02127@luvthang.UUCP>
  7943. From: uunet!luvthang!talmage (David W. Talmage)
  7944. To: uunet!icon-group
  7945. Subject: Icon debugging tools? -REPOST-
  7946.  
  7947. On or about 4 May, I asked about Icon tools.  I've had major mailer
  7948. problems since then, so I have no idea if my note made it out to the
  7949. icon-group or if anyone replied to it.  Because I'm still
  7950. interested, I post again:
  7951.  
  7952. >What tools do you use to debug your Icon programs?  I have a poor
  7953. >man's profiler which I use on occasion.  What I'd really like is a
  7954. >symbolic debugger that works like Sun's dbxtool or like Digital's
  7955. >run-time debugger.  It would be a win for me if said tools can run on
  7956. >my Amiga.
  7957.  
  7958. In my original posting, I included an Icon implementation of pmp, Dan
  7959. Berenstein's Poor Man's Profiler.  If anyone wants it, please drop me
  7960. a line.  If more than 10 people ask for it, I'll post it.
  7961.  
  7962. -----------------------------------------------------------------------------
  7963. David W. Talmage (talmage@luvthang.aquin.ori-cal.com)
  7964. "I need fifty dollars to make you hollar.  I get paid to run this luvthang."
  7965.  
  7966. From icon-group-request@arizona.edu  Sat May 25 03:32:43 1991
  7967. Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Sat, 25 May 91 03:32:43 MST
  7968. Resent-From: icon-group-request@arizona.edu
  7969. Received: from Arizona.edu (Merlin.Telcom.Arizona.EDU) by optima.cs.arizona.edu (4.1/15)
  7970.     id AA08320; Sat, 25 May 91 03:32:39 MST
  7971. Received: from ucbvax.Berkeley.EDU by Arizona.edu with PMDF#10282; Sat, 25 May
  7972.  1991 03:32 MST
  7973. Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA21070; Sat, 25 May 91
  7974.  03:14:33 -0700
  7975. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  7976.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  7977.  usenet@ucbvax.Berkeley.EDU if you have questions)
  7978. Resent-Date: Sat, 25 May 1991 03:32 MST
  7979. Date: 25 May 91 09:57:43 GMT
  7980. From: munnari.oz.au!deakin.OZ.AU!rand!rdb@uunet.uu.net (Rodney Brown)
  7981. Subject: MS-DOS ICON binaries
  7982. Sender: icon-group-request@arizona.edu
  7983. Resent-To: icon-group@cs.arizona.edu
  7984. To: icon-group@arizona.edu
  7985. Resent-Message-Id: <C991B478ECC012B8@Arizona.edu>
  7986. Message-Id: <283@rand.mel.cocam.oz.au>
  7987. X-Envelope-To: icon-group@CS.Arizona.EDU
  7988. X-Vms-To: icon-group@Arizona.edu
  7989. Organization: Co-Cam Computer Group, Melbourne, OZ
  7990.  
  7991. I have a MS-DOS Icon binary dating from 1985 distributed through PC-Blue.
  7992. Is there a more recent version available? 8086 or 80386 extended mode binaries?
  7993. I checked SIMTEL a while back & every mention of ICON seemed to be aimed
  7994. at MS Windows & GUIs.
  7995.  
  7996. Rodney Brown, Co-Cam Computer Group,    ACSNet: rdb@rand.mel.cocam.oz.au
  7997.  
  7998. From icon-group-request@arizona.edu  Sat May 25 23:23:29 1991
  7999. Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Sat, 25 May 91 23:23:29 MST
  8000. Resent-From: icon-group-request@arizona.edu
  8001. Received: from Arizona.edu (Merlin.Telcom.Arizona.EDU) by optima.cs.arizona.edu (4.1/15)
  8002.     id AA09375; Sat, 25 May 91 23:23:27 MST
  8003. Received: from ucbvax.Berkeley.EDU by Arizona.edu with PMDF#10282; Sat, 25 May
  8004.  1991 23:22 MST
  8005. Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA17485; Sat, 25 May 91
  8006.  23:18:38 -0700
  8007. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  8008.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  8009.  usenet@ucbvax.Berkeley.EDU if you have questions)
  8010. Resent-Date: Sat, 25 May 1991 23:23 MST
  8011. Date: 26 May 91 06:10:00 GMT
  8012. From: andrew@arizona.edu (Andrei V. Zaitsev)
  8013. Subject: Comments in ICON
  8014. Sender: icon-group-request@arizona.edu
  8015. Resent-To: icon-group@cs.arizona.edu
  8016. To: icon-group@arizona.edu
  8017. Resent-Message-Id: <6FE990FA6CC01339@Arizona.edu>
  8018. Message-Id: <1537@caslon.cs.arizona.edu>
  8019. X-Envelope-To: icon-group@CS.Arizona.EDU
  8020. X-Vms-To: icon-group@Arizona.edu
  8021. Organization: U of Arizona CS Dept, Tucson
  8022.  
  8023. Here is an extremely simple question : how
  8024. to put a comment into a ICON program ?
  8025. (I tried /**/,(**),REM and * , none of them works).
  8026.  
  8027. From isidev!nowlin@uunet.uu.net  Sun May 26 10:55:10 1991
  8028. Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Sun, 26 May 91 10:55:10 MST
  8029. Received: from relay1.UU.NET by optima.cs.arizona.edu (4.1/15)
  8030.     id AA25285; Sun, 26 May 91 10:55:08 MST
  8031. Received: from isidev.UUCP (LOCALHOST.UU.NET) by relay1.UU.NET with SMTP 
  8032.     (5.61/UUNET-internet-primary) id AA07484; Sun, 26 May 91 13:55:06 -0400
  8033. Date: Sun, 26 May 91 13:55:06 -0400
  8034. From: isidev!nowlin@uunet.uu.net
  8035. Message-Id: <9105261755.AA07484@relay1.UU.NET>
  8036. To: uunet!cs.arizona.edu!icon-group@uunet.uu.net
  8037. Subject: Re: icon comments
  8038.  
  8039.  > Date: 26 May 91 06:10:00 GMT
  8040.  > From: uunet!arizona!arizona.edu!andrew (Andrei V. Zaitsev)
  8041.  >
  8042.  > Here is an extremely simple question : how
  8043.  > to put a comment into a ICON program ?
  8044.  > (I tried /**/,(**),REM and * , none of them works).
  8045.  
  8046. You must be young since you still have stars in your eyes.  Think pound
  8047. signs instead.  Examples follow:
  8048.  
  8049.     procedure main()
  8050.         write(&clock)    # print the current time
  8051.  
  8052.         write(&date)    # print the current date
  8053.  
  8054.         # print more information on the time and date
  8055.         write(&dateline)
  8056.     end
  8057.  
  8058. At least you're thinking about comments!
  8059.  
  8060.   --- ---
  8061.    | S | Iconic Software, Inc.  -  Jerry Nowlin  -  uunet!isidev!nowlin
  8062.   --- ---
  8063.  
  8064.  
  8065. From TENAGLIA@mis.mcw.edu  Tue May 28 06:42:52 1991
  8066. Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Tue, 28 May 91 06:42:52 MST
  8067. Received: from MIS1.MIS.MCW.EDU by optima.cs.arizona.edu (4.1/15)
  8068.     id AA02919; Tue, 28 May 91 06:42:46 MST
  8069. Received: from mis.mcw.edu (MCWMI3) by MIS1.MIS.MCW.EDU with PMDF#10477; Tue,
  8070.  28 May 1991 08:42 CST
  8071. Date: Tue, 28 May 1991 08:42 CST
  8072. From: Chris Tenaglia - 257-8765 <TENAGLIA@mis.mcw.edu>
  8073. Subject: Holiday TidBit
  8074. To: icon-group@cs.arizona.edu
  8075. Message-Id: <50632F0EE04001B8@mis.mcw.edu>
  8076. X-Organization: Medical College of Wisconsin MIS Department (Milwaukee, WI)
  8077. X-Vms-To: IN%"icon-group@cs.arizona.edu"
  8078.  
  8079.  
  8080. Another holiday has passed, and with it came another icon game. This is
  8081. Yahtzee, the poker dice game. I use ICON 8 under VMS 5.4-1, but I tried
  8082. to avoid system specific stuff. I'll probably get flamed again for my
  8083. screen management methods (I tried a little something different.) It's
  8084. written for VT100,2XX,3XX,4XX and compatible terminals, since that's all
  8085. I have at this site. Bye the way, this version allows for multiple players.
  8086. I've played it several times with my daughter and it seems pretty solid.
  8087.  
  8088. Game design involves many tricky decisions. The two in this implementation
  8089. were.. 
  8090.           o Not to repaint dice if the value stayed the same
  8091.             This is seen in procedure depict(). I use a list
  8092.             'od' to remember former values. Then when choosen
  8093.             dice are shaken, the unshaken ones stay put. But,
  8094.             so do the ones that come up the same. Oh well.
  8095.           o To give the player the feel of the three shakes,
  8096.             I provide a prompt saying whose turn it is, and
  8097.             asking them to press <RETURN>. These lines can be
  8098.             found at the beginning of procedure play(name).
  8099.             I also ask them to press return after their turn
  8100.             is over in order to allow some time to read their
  8101.             scorecard and think about future strategy.
  8102.  
  8103. So here's the code. Enjoy!
  8104.  
  8105. Chris Tenaglia (System Manager) | Medical College of Wisconsin
  8106. 8701 W. Watertown Plank Rd.     | Milwaukee, WI 53226
  8107. (414)257-8765                   | tenaglia@mis.mcw.edu, mcwmis!tenaglia
  8108.  
  8109. #
  8110. # YAHT.ICN          5/27/91          BY TENAGLIA
  8111. #
  8112. # YAHTZEE GAME
  8113. #
  8114. global players,slot,team,d,od,dice,round
  8115. procedure main(param)
  8116.   paint()
  8117.   assign_players()
  8118.   every round := 1 to 13 do
  8119.     every play(!team)
  8120.   summarize()
  8121.   end
  8122.  
  8123. #
  8124. # DISPLAYS THE HEADER AND SEPARATOR LINE AT BEGINNING OF GAME
  8125. #
  8126. procedure paint()
  8127.   write(cls(),high(uhalf("             Y A H T Z E E              ")))
  8128.   write(high(lhalf("             Y A H T Z E E              ")))
  8129.   write(at(1,10),graf(repl("q",75)))
  8130.   end
  8131.  
  8132. #
  8133. # DISPLAYS THE FINAL SCORE OF ALL THE PLAYERS
  8134. #
  8135. procedure summarize()
  8136.   write(at(1,11),blink(high(inverse(chop("Final Score Summary")))))
  8137.   every player := key(players) do
  8138.     {
  8139.     card := players[player]
  8140.     top  := 0 ; every i := 1 to 6 do top +:= card[i]
  8141.     if top > 62 then top +:= 35
  8142.     bottom := 0 ; every i := 7 to 13 do bottom +:= card[i]
  8143.     write("Player ",high(left(player,14))," Top = ",right(top,5),
  8144.                                        " Bottom = ",right(bottom,5),
  8145.                                        "  Total = ",right(top+bottom,5))
  8146.     }
  8147.   input("<press return>")
  8148.   end
  8149.  
  8150. #
  8151. # SETUP AND INITIALIZATION OF YAHTZEE ENVIRONMENT
  8152. #
  8153. procedure assign_players()
  8154.   n := 1 ; team := [] ; slot := [] ; d := list(6,"") ; od := list(5,0)
  8155.   &random := map(&clock,":","9")
  8156.   players := table("n/a")
  8157.   repeat
  8158.     {
  8159.     (player := input(("Name of player #" || n || ":"))) | stop("Game called off.")
  8160.     if player == "" then break
  8161.     n +:= 1
  8162.     put(team,player)
  8163.     players[player] := list(13,"*")
  8164.     }
  8165.   if n = 1 then stop("Nobody wants to play!")
  8166.  
  8167.   put(slot,"Ones")   ; put(slot,"Twos")  ; put(slot,"Threes")
  8168.   put(slot,"Fours")  ; put(slot,"Fives") ; put(slot,"Sixes")
  8169.   put(slot,"3oK")    ; put(slot,"4oK")   ; put(slot,"FullH")
  8170.   put(slot,"SmStr")  ; put(slot,"LgStr") ; put(slot,"Yahtzee")
  8171.   put(slot,"Chance")
  8172.   
  8173.   d[1] := "lqqqqqkx     xx  `  xx     xmqqqqqj"
  8174.   d[2] := "lqqqqqkx     xx ` ` xx     xmqqqqqj"
  8175.   d[3] := "lqqqqqkx`    xx  `  xx    `xmqqqqqj"
  8176.   d[4] := "lqqqqqkx`   `xx     xx`   `xmqqqqqj"
  8177.   d[5] := "lqqqqqkx`   `xx  `  xx`   `xmqqqqqj"
  8178.   d[6] := "lqqqqqkx` ` `xx     xx` ` `xmqqqqqj"
  8179.   end
  8180.  
  8181. #
  8182. # THIS ROUTINE LETS A PLAYER TAKE THEIR TURN
  8183. #
  8184. procedure play(name)
  8185.   writes(at(1,11),"It's ",high(name),"'s turn",chop())
  8186.   writes(at(1,12),high(name)) ; input(", Please press <RETURN> to begin.")
  8187.   score(name)
  8188.   dice := [] ; every 1 to 5 do put(dice,?6)
  8189.   depict()
  8190.   shake := obtain("Shake which ones :")
  8191.   (shake === []) | (every dice[!shake] := ?6)
  8192.   depict()
  8193.   shake := obtain("(Last Chance) Shake which ones :")
  8194.   (shake === []) | (every dice[!shake] := ?6)
  8195.   depict()
  8196.   repeat
  8197.     {
  8198.     select := input(at(1,22) || clip("Tally to which category (1 -> 13) :"))
  8199.     numeric(select)                | next
  8200.     (1 <= select <= 13)            | next
  8201.     (players[name][select] == "*") | next
  8202.     break
  8203.     }
  8204.   tally(name,select)
  8205.   score(name)
  8206.   input(at(1,22) || clip("Press <RETURN>"))
  8207.   end
  8208.  
  8209. #
  8210. # THIS ROUTINE DRAWS THE DICE
  8211. #
  8212. procedure depict()
  8213.   every i := 1 to 5 do
  8214.     {
  8215.     if od[i] = dice[i] then next
  8216.     x := 1
  8217.     writes(at(i*10+4,3),inverse(i))
  8218. #    writes(at(i*10+4,9),inverse(dice[i]))
  8219.     every j := 4 to 8 do
  8220.       {
  8221.       writes(at(i*10,j),graf(d[dice[i]][x:x+7]))
  8222.       x +:= 7
  8223.       }
  8224.     od[i] := dice[i]
  8225.     }
  8226.   end
  8227.  
  8228. #
  8229. # THIS ROUTINE LETS THE PLAYER DECIDE WHAT TO APPLY THE SHAKES TO
  8230. #
  8231. procedure tally(name,area)
  8232.   case integer(area) of
  8233.     {
  8234.     1 : {                        # ones
  8235.         sum := 0 ; every unit := !dice do if unit = 1 then sum +:= 1
  8236.         players[name][1] := sum
  8237.         }
  8238.     2 : {                        # twos
  8239.         sum := 0 ; every unit := !dice do if unit = 2 then sum +:= 2
  8240.         players[name][2] := sum
  8241.         }
  8242.     3 : {                        # threes
  8243.         sum := 0 ; every unit := !dice do if unit = 3 then sum +:= 3
  8244.         players[name][3] := sum
  8245.         }
  8246.     4 : {                        # fours
  8247.         sum := 0 ; every unit := !dice do if unit = 4 then sum +:= 4
  8248.         players[name][4] := sum
  8249.         }
  8250.     5 : {                        # fives
  8251.         sum := 0 ; every unit := !dice do if unit = 5 then sum +:= 5
  8252.         players[name][5] := sum
  8253.         }
  8254.     6 : {                        # sixes
  8255.         sum := 0 ; every unit := !dice do if unit = 6 then sum +:= 6
  8256.         players[name][6] := sum
  8257.         }
  8258.     7 : {                        # 3 of a kind
  8259.         sum := 0 ; flag := 0
  8260.         tmp := table(0) ; every unit := !dice do tmp[unit] +:= 1
  8261.         every piece := key(tmp) do
  8262.           if tmp[piece] >= 3 then flag := 1
  8263.         if flag = 1 then every sum +:= !dice
  8264.         players[name][7] := sum
  8265.         }
  8266.     8 : {                        # four of a kind
  8267.         sum := 0 ; flag := 0
  8268.         tmp := table(0) ; every unit := !dice do tmp[unit] +:= 1
  8269.         every piece := key(tmp) do
  8270.           if tmp[piece] >= 4 then flag := 1
  8271.         if flag = 1 then every sum +:= !dice
  8272.         players[name][8] := sum
  8273.         }
  8274.     9 : {                        # full house
  8275.         sum := 0 ; flag := 0
  8276.         tmp := table(0) ; every unit := !dice do tmp[unit] +:= 1
  8277.         every piece := key(tmp) do
  8278.           {
  8279.           if tmp[piece] = 3 then flag +:= 1
  8280.           if tmp[piece] = 2 then flag +:= 1
  8281.           }
  8282.         if flag = 2 then sum := 25
  8283.         players[name][9] := sum
  8284.         }
  8285.    10 : {                        # small straight
  8286.         sum  := 0 ; flag := 0
  8287.         hold := set() ; every insert(hold,!dice)
  8288.         tmp  := sort(hold)
  8289.         if tmp[1]+1 = tmp[2] &
  8290.            tmp[2]+1 = tmp[3] &
  8291.            tmp[3]+1 = tmp[4] then flag := 1
  8292.         if tmp[2]+1 = tmp[3] &
  8293.            tmp[3]+1 = tmp[4] &
  8294.            tmp[4]+1 = tmp[5] then flag := 1
  8295.         if flag = 1 then sum := 30
  8296.         players[name][10] := sum
  8297.         }
  8298.    11 : {                        # large straight
  8299.         sum := 0 ; flag := 0  
  8300.         tmp := sort(dice)
  8301.         if tmp[1]+1 = tmp[2] &
  8302.            tmp[2]+1 = tmp[3] &
  8303.            tmp[3]+1 = tmp[4] &
  8304.            tmp[4]+1 = tmp[5] then flag := 1
  8305.         if flag = 1 then sum := 40
  8306.         players[name][11] := sum
  8307.         }
  8308.    12 : {                        # yahtzee
  8309.         sum := 0 ; flag := 0
  8310.         tmp := table(0) ; every unit := !dice do tmp[unit] +:= 1
  8311.         every piece := key(tmp) do
  8312.           if tmp[piece] = 5 then flag := 1
  8313.         if flag = 1 then sum := 50
  8314.         players[name][12] := sum
  8315.         }
  8316.    13 : {                        # chance
  8317.         sum := 0 ; every sum +:= !dice
  8318.         players[name][13] := sum
  8319.         }
  8320.     }
  8321.   end
  8322.  
  8323. #
  8324. # THIS ROUTINE OBTAINS A VALID SHAKER REQUEST
  8325. #
  8326. procedure obtain(prompt)
  8327.   repeat
  8328.     {
  8329.     writes(at(1,22),prompt)
  8330.     (line := read()) | next
  8331.     if match("q",map(line)) then stop("Game Quit")
  8332.     if trim(line) == "" then return []
  8333.     units := parse(line,', \t')
  8334.     every unit := !units do
  8335.       (1 <= unit <= 5) | next
  8336.     break
  8337.     }
  8338.   return units
  8339.   end
  8340.  
  8341. #
  8342. # THIS ROUTINE PAINTS THE SCORECARD FOR A GIVEN PLAYER
  8343. #
  8344. procedure score(name)
  8345.   writes(at(1,11),chop(),at(25,11),under(),"Player = ",name,"     Round = ",under(round))
  8346.   writes(at(10,12)," 1 : Ones    = ",players[name][1])
  8347.   writes(at(10,13)," 2 : Twos    = ",players[name][2])
  8348.   writes(at(10,14)," 3 : Threes  = ",players[name][3])
  8349.   writes(at(10,15)," 4 : Fours   = ",players[name][4])
  8350.   writes(at(10,16)," 5 : Fives   = ",players[name][5])
  8351.   writes(at(10,17)," 6 : Sixes   = ",players[name][6])
  8352.   writes(at(40,12)," 7 : 3oK     = ",players[name][7])
  8353.   writes(at(40,13)," 8 : 4oK     = ",players[name][8])
  8354.   writes(at(40,14)," 9 : FullH   = ",players[name][9])
  8355.   writes(at(40,15),"10 : SmStr   = ",players[name][10])
  8356.   writes(at(40,16),"11 : LgStr   = ",players[name][11])
  8357.   writes(at(40,17),"12 : Yahtzee = ",players[name][12])
  8358.   writes(at(40,18),"13 : Chance  = ",players[name][13])
  8359.   st1 := 0 ; every i := 1 to 6 do st1 +:= numeric(players[name][i])
  8360.   if st1 > 62 then bonus := 35 else bonus := 0
  8361.   st2 := 0 ; every i := 7 to 13 do st2 +:= numeric(players[name][i])
  8362.   writes(at(10,19),"Bonus = ",clip(bonus))
  8363.   writes(at(10,20),"Subtotal = ",st1+bonus)
  8364.   writes(at(40,20),"Subtotal = ",st2)
  8365.   writes(at(37,21),"Grand Total = ",st1+st2+bonus)
  8366.   end
  8367.  
  8368. #
  8369. # VIDEO ROUTINE CLEARS SCREEN
  8370. #
  8371. procedure cls(str)
  8372.   /str := ""
  8373.   return "\e[2J\e[H" || str
  8374.   end
  8375.  
  8376. #
  8377. # VIDEO ROUTINE ERASES REST OF SCREEN
  8378. #
  8379. procedure chop(str)
  8380.   /str := ""
  8381.   return "\e[J" || str
  8382.   end
  8383.  
  8384. #
  8385. # VIDEO ROUTINE OUTPUTS UPPER HALF OF DOUBLE SIZE MESSAGES
  8386. #
  8387. procedure uhalf(str)
  8388.   /str := ""
  8389.   if str == "" then return "\e#3"
  8390.   return "\e#3" || str
  8391.   end
  8392.   
  8393. #
  8394. # VIDEO ROUTINE OUTPUTS BOTTOM HALF OF DOUBLE SIZE MESSAGES
  8395. #
  8396. procedure lhalf(str)
  8397.   /str := ""
  8398.   if str == "" then return "\e#4"
  8399.   return "\e#4" || str
  8400.   end
  8401.  
  8402. #
  8403. # VIDEO ROUTINE OUTPUTS STRING AND CLEARS TO EOL
  8404. #
  8405. procedure clip(str)
  8406.   /str := ""
  8407.   if str == "" then return "\e[K "
  8408.   return str ||:= "\e[K"
  8409.   end
  8410.   
  8411. #
  8412. # VIDEO ROUTINE OUTPUTS HIGHLIGHTED STRINGS
  8413. #
  8414. procedure high(str)
  8415.   /str := ""
  8416.   if str == "" then return "\e[1m"
  8417.   str := "\e[1m" || str
  8418.   if (str[-3:0] == "\e[m") | (str[-4:0] == "\e[0m")
  8419.     then return str
  8420.     else return str || "\e[m"
  8421.   end
  8422.  
  8423. #
  8424. # VIDEO ROUTINE OUTPUTS INVERSE VIDEO STRINGS
  8425. #
  8426. procedure inverse(str)
  8427.   /str := ""
  8428.   if str == "" then return "\e[7m"
  8429.   str := "\e[7m" || str
  8430.   if (str[-3:0] == "\e[m") | (str[-4:0] == "\e[0m")
  8431.     then return str
  8432.     else return str || "\e[m"
  8433.   end
  8434.  
  8435. #
  8436. # VIDEO ROUTINE OUTPUTS UNDERLINED STRINGS
  8437. #
  8438. procedure under(str)
  8439.   /str := ""
  8440.   if str == "" then return "\e[4m"
  8441.   str := "\e[4m" || str
  8442.   if (str[-3:0] == "\e[m") | (str[-4:0] == "\e[0m")
  8443.     then return str
  8444.     else return str || "\e[m"
  8445.   end
  8446.  
  8447. #
  8448. # VIDEO ROUTINE OUTPUTS BLINKING STRINGS
  8449. #
  8450. procedure blink(str)
  8451.   /str := ""
  8452.   if str == "" then return "\e[5m"
  8453.   str := "\e[5m" || str
  8454.   if (str[-3:0] == "\e[m") | (str[-4:0] == "\e[0m")
  8455.     then return str
  8456.     else return str || "\e[m"
  8457.   end
  8458.  
  8459. #
  8460. # VIDEO ROUTINE SETS NORMAL VIDEO MODE
  8461. #
  8462. procedure norm(str)
  8463.   /str := ""
  8464.   if str == "" then return "\e[m"
  8465.   str := "\e[m" || str
  8466.   return str
  8467.   end
  8468.  
  8469. #
  8470. # VIDEO ROUTINE TURNS ON VT GRAPHICS CHARACTERS
  8471. #
  8472. procedure graf(str)
  8473.   /str := ""
  8474.   if str == "" then return "\e(0"
  8475.   str := "\e(0" || str
  8476.   if (str[-3:0] == "\e(B")
  8477.     then return str
  8478.     else return str || "\e(B"
  8479.   end
  8480.  
  8481. #
  8482. # VIDEO ROUTINE TURNS OFF VT GRAPHICS CHARACTERS
  8483. #
  8484. procedure nograf(str)
  8485.   /str := ""
  8486.   if str == "" then return "\e(B"
  8487.   str := "\e(B" || str
  8488.   return str
  8489.   end
  8490.  
  8491. #
  8492. # VIDEO ROUTINE SETS CURSOR TO GIVEN X,Y COORDINATES
  8493. #
  8494. procedure at(x,y)   
  8495.   return "\e[" || y || ";" || x || "f"
  8496.   end
  8497.  
  8498. #
  8499. # PARSES A STRING INTO A LIST WITH RESPECT TO A GIVEN DELIMITER
  8500. #
  8501. procedure parse(line,delims)
  8502.   static chars
  8503.   chars  := &cset -- delims
  8504.   tokens := []
  8505.   line ? while tab(upto(chars)) do put(tokens,tab(many(chars)))
  8506.   return tokens
  8507.   end
  8508.  
  8509. #
  8510. # TAKE AN INPUT STRING VIA GIVEN PROMPT
  8511. #
  8512. procedure input(prompt)       
  8513.   writes(prompt)
  8514.   return read()
  8515.   end
  8516. #
  8517. # DISCLAIMER
  8518. #
  8519. #########################################################################
  8520. #                                                                       #
  8521. #  Copyright (c) 1991, Chris D. Tenaglia # 12p                          #
  8522. #                                                                       #
  8523. #  This software is intended for free and unrestricted distribution.    #
  8524. #  I place only two conditions on its use:  1) That you clearly mark    #
  8525. #  any additions or changes you make to the source code, and 2) that    #
  8526. #  you do not delete this message therefrom.  In order to protect       #
  8527. #  myself from spurious litigation, it must also be stated here that,   #
  8528. #  because this is free software, I, Chris tenaglia, make no claim      #
  8529. #  about the applicability or fitness of this software for any          #
  8530. #  purpose, and expressly disclaim any responsibility for any damages   #
  8531. #  that might be incurred in conjunction with its use.                  #
  8532. #                                                                       #
  8533. #########################################################################
  8534.  
  8535.  
  8536. From icon-group-request@arizona.edu  Tue May 28 07:35:18 1991
  8537. Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Tue, 28 May 91 07:35:18 MST
  8538. Resent-From: icon-group-request@arizona.edu
  8539. Received: from Arizona.edu (Merlin.Telcom.Arizona.EDU) by optima.cs.arizona.edu (4.1/15)
  8540.     id AA04097; Tue, 28 May 91 07:35:15 MST
  8541. Received: from ucbvax.Berkeley.EDU (128.32.133.1) by Arizona.edu with
  8542.  PMDF#10282; Tue, 28 May 1991 03:48 MST
  8543. Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA13404; Tue, 28 May 91
  8544.  03:22:47 -0700
  8545. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  8546.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  8547.  usenet@ucbvax.Berkeley.EDU if you have questions)
  8548. Resent-Date: Tue, 28 May 1991 03:48 MST
  8549. Date: 28 May 91 07:46:01 GMT
  8550. From: cis.ohio-state.edu!pacific.mps.ohio-state.edu!linac!midway!ellis.uchicago.edu!goer@tut.cis.ohio-state.edu (Richard L.
  8551.  Goerwitz)
  8552. Subject: list scanning routines
  8553. Sender: icon-group-request@arizona.edu
  8554. Resent-To: icon-group@cs.arizona.edu
  8555. To: icon-group@arizona.edu
  8556. Resent-Message-Id: <274E1C38BCC01BB5@Arizona.edu>
  8557. Message-Id: <1991May28.074601.23950@midway.uchicago.edu>
  8558. X-Envelope-To: icon-group@CS.Arizona.EDU
  8559. X-Vms-To: icon-group@Arizona.edu
  8560. Organization: University of Chicago
  8561.  
  8562.  
  8563. ############################################################################
  8564. #
  8565. #    Name:    lscan.icn
  8566. #
  8567. #    Title:    Quasi ? scanning routines for lists.
  8568. #
  8569. #    Author:    Richard L. Goerwitz
  8570. #
  8571. #    Version: 1.20
  8572. #
  8573. ############################################################################
  8574. #
  8575. #  PURPOSE: String scanning is terrific, but often I am forced to
  8576. #  tokenize and work with lists.  So as to make operations on these
  8577. #  lists as close to corresponding string operations as possible, I've
  8578. #  implemented a series of list analogues to any(), bal(), find(),
  8579. #  many(), match(), move(), pos(), tab(), and upto().  Their names are
  8580. #  just like corresponding string functions, except with a prepended
  8581. #  "l_" (e.g. l_any()).  Functionally, the list routines parallel the
  8582. #  string ones closely, except that in place of strings, l_find and
  8583. #  l_match accept lists as their first argument.  L_any(), l_many(),
  8584. #  and l_upto() all take either sets of lists or lists of lists (e.g.
  8585. #  l_tab(l_upto([["a"],["b"],["j","u","n","k"]])).  Note that l_bal(),
  8586. #  unlike the builtin bal(), has no defaults for the first four
  8587. #  arguments.  This just seemed appropriate, given that no precise
  8588. #  list analogue to &cset, etc. occurs.
  8589. #
  8590. #  The default subject for list scans (analogous to &subject) is
  8591. #  l_SUBJ.  The equivalent of &pos is l_POS.  Naturally, these
  8592. #  variables are both global.  They are used pretty much like &subject
  8593. #  and &pos, except that they are null until a list scanning
  8594. #  expression has been encountered containing a call to l_Bscan() (on
  8595. #  which, see below).
  8596. #
  8597. #  Note that environments cannot be maintained quite as elegantly as
  8598. #  they can be for the builtin string-scanning functions.  One must
  8599. #  use instead a set of nested procedure calls, as explained in the
  8600. #  _Icon Analyst_ 1:6 (June, 1991), p. 1-2.  In particular, one cannot
  8601. #  suspend, return, or otherwise break out of the nested procedure
  8602. #  calls.  They can only be exited via failure.  The names of these
  8603. #  procedures, at least in this implementation, are l_Escan and
  8604. #  l_Bscan.  Here is one example of how they might be invoked:
  8605. #
  8606. #      suspend l_Escan(l_Bscan(some_list_or_other), {
  8607. #          l_tab(10 to *l_SUBJ) & {
  8608. #              if l_any(l1) | l_match(l2) then
  8609. #                  old_l_POS + (l_POS-1)
  8610. #          }
  8611. #      })
  8612. #
  8613. #  Note that you cannot do this:
  8614. #
  8615. #      l_Escan(l_Bscan(some_list_or_other), {
  8616. #          l_tab(10 to *l_SUBJ) & {
  8617. #              if l_any(l1) | l_match(l2) then
  8618. #                  suspend old_l_POS + (l_POS-1)
  8619. #          }
  8620. #      })
  8621. #
  8622. #  Remember, it's no fair to use suspend within the list scanning
  8623. #  expression.  l_Escan must do all the suspending.  It is perfectly OK,
  8624. #  though, to nest well-behaved list scanning expressions.  And they can
  8625. #  be reliably used to generate a series of results as well.
  8626. #
  8627. ############################################################################
  8628. #
  8629. #  Here's another simple example of how one might invoke the l_scan
  8630. #  routines:
  8631. #
  8632. #  procedure main()
  8633. #
  8634. #      l := ["h","e","l","l","o"," ","t","t","t","h","e","r","e"]
  8635. #
  8636. #      l_Escan(l_Bscan(l), {
  8637. #          hello_list := l_tab(l_match(["h","e","l","l","o"]))
  8638. #          every writes(!hello_list)
  8639. #          write()
  8640. #
  8641. #          # Note the nested list-scanning expressions.
  8642. #       l_Escan(l_Bscan(l_tab(0)), {
  8643. #           l_tab(l_many([[" "],["t"]]) - 1)
  8644. #              every writes(!l_tab(0))
  8645. #           write()
  8646. #          })
  8647. #      })
  8648. #  
  8649. #  end
  8650. #
  8651. #  The above program simply writes "hello" and "there" on successive
  8652. #  lines to the standard output.
  8653. #
  8654. ############################################################################
  8655. #
  8656. #  PITFALLS: In general, note that we are comparing lists here instead
  8657. #  of strings, so l_find("h", l), for instance, will yield an error
  8658. #  message (use l_find(["h"], l) instead).  The point at which I
  8659. #  expect this nuance will be most confusing will be in cases where
  8660. #  one is looking for lists within lists.  Suppose we have a list,
  8661. #
  8662. #      l1 := ["junk",[["hello"]," ",["there"]],"!","m","o","r","e","junk"]
  8663. #
  8664. #  and suppose, moreover, that we wish to find the position in l1 at
  8665. #  which the list
  8666. #
  8667. #      [["hello"]," ",["there"]]
  8668. #
  8669. #  occurs.  If, say, we assign [["hello"]," ",["there"]] to the
  8670. #  variable l2, then our l_find() expression will need to look like
  8671. #
  8672. #      l_find([l2],l1)
  8673. #
  8674. ############################################################################
  8675. #
  8676. #  Extending scanning to lists is really very difficult.  What I think
  8677. #  (at least tonight) is that scanning should never have been
  8678. #  restricted to strings.  It should have been designed to operate on
  8679. #  all homogenous one-dimensional arrays (vectors, for you LISPers).
  8680. #  You should be able, in other words, to scan vectors of ints, longs,
  8681. #  characters - any data type that seems useful.  The only question in
  8682. #  my mind is how to represent vectors as literals.  Extending scanning
  8683. #  to lists goes beyond the bounds of scanning per-se.  This library is
  8684. #  therefore something of a stab in the dark.
  8685. #
  8686. ############################################################################
  8687.  
  8688.  
  8689. global l_POS
  8690. global l_SUBJ
  8691. record l_ScanEnvir(subject,pos)
  8692.  
  8693. procedure l_Bscan(e1)
  8694.  
  8695.     #
  8696.     # Prototype list scan initializer.  Based on code published in
  8697.     # the _Icon Analyst_ 1:6 (June, 1991), p. 1-2.
  8698.     #
  8699.     local l_OuterEnvir
  8700.     initial {
  8701.     l_SUBJ := []
  8702.     l_POS := 1
  8703.     }
  8704.  
  8705.     #
  8706.     # Save outer scanning environment.
  8707.     #
  8708.     l_OuterEnvir := l_ScanEnvir(l_SUBJ, l_POS)
  8709.  
  8710.     #
  8711.     # Set current scanning environment to subject e1 (arg 1).  Pos
  8712.     # defaults to 1.  Suspend the saved environment.  Later on, the
  8713.     # l_Escan procedure will need this in case the scanning expres-
  8714.     # sion as a whole sends a result back to the outer environment,
  8715.     # and the outer environment changes l_SUBJ and l_POS.
  8716.     #
  8717.     l_SUBJ := e1
  8718.     l_POS  := 1
  8719.     suspend l_OuterEnvir
  8720.  
  8721.     #
  8722.     # Restore the saved environment (plus any changes that might have
  8723.     # been made to it as noted in the previous run of comments).
  8724.     #
  8725.     l_SUBJ := l_OuterEnvir.subject
  8726.     l_POS := l_OuterEnvir.pos
  8727.  
  8728.     #
  8729.     # Signal failure of the scanning expression (we're done producing
  8730.     # results if we get to here).
  8731.     #
  8732.     fail
  8733.  
  8734. end
  8735.  
  8736.  
  8737.  
  8738. procedure l_Escan(l_OuterEnvir, e2)
  8739.  
  8740.     local l_InnerEnvir
  8741.  
  8742.     #
  8743.     # Set the inner scanning environment to the values assigned to it
  8744.     # by l_Bscan.  Remember that l_SUBJ and l_POS are global.  They
  8745.     # don't need to be passed as parameters from l_Bscan.  What
  8746.     # l_Bscan() needs to pass on is the l_OuterEnvir record,
  8747.     # containing the values of l_SUBJ and l_POS before l_Bscan() was
  8748.     # called.  l_Escan receives this "outer environment" as its first
  8749.     # argument, l_OuterEnvir.
  8750.     #
  8751.     l_InnerEnvir := l_ScanEnvir(l_SUBJ, l_POS)
  8752.  
  8753.     #
  8754.     # Whatever expression produced e2 has passed us a result.  Now we
  8755.     # restore l_SUBJ and l_POS, and send that result back to the outer
  8756.     # environment.
  8757.     #
  8758.     l_SUBJ := l_OuterEnvir.subject
  8759.     l_POS := l_OuterEnvir.pos
  8760.     suspend e2
  8761.  
  8762.     #
  8763.     # Okay, we've resumed to (attempt to) produce another result.  Re-
  8764.     # store the inner scanning environment (the one we're using in the
  8765.     # current scanning expression).  Remember?  It was saved in l_Inner-
  8766.     # Envir just above.
  8767.     #
  8768.     l_SUBJ := l_InnerEnvir.subject
  8769.     l_POS := l_InnerEnvir.pos
  8770.  
  8771.     #
  8772.     # Fail so that the second argument (the one that produced e2) gets
  8773.     # resumed.  If it fails to produce another result, then the first
  8774.     # argument is resumed, which is l_Bscan().  If l_Bscan is resumed, it
  8775.     # will restore the outer environment and fail, causing the entire
  8776.     # scanning expression to fail.
  8777.     #
  8778.     fail
  8779.  
  8780. end
  8781.  
  8782.     
  8783.  
  8784. procedure l_move(i)
  8785.  
  8786.     /i & stop("l_move:  Null argument.")
  8787.     if /l_POS | /l_SUBJ then
  8788.     stop("l_move:  Call l_Bscan() first.")
  8789.  
  8790.     #
  8791.     # Sets l_POS to l_POS+i; suspends that portion of l_SUBJ extending
  8792.     # from the old l_POS to the new one.  Resets l_POS if resumed,
  8793.     # just the way matching procedures are supposed to.  Fails if l_POS
  8794.     # plus i is larger than l_SUBJ+1 or if l_POS+i is less than 1.
  8795.     #
  8796.     suspend l_SUBJ[.l_POS:l_POS <- (0 < (*l_SUBJ+1 >= l_POS+i))]
  8797.  
  8798. end
  8799.  
  8800.  
  8801.  
  8802. procedure l_tab(i)
  8803.  
  8804.     /i & stop("l_tab:  Null argument.")
  8805.     if /l_POS | /l_SUBJ then
  8806.     stop("l_tab:  Call l_Bscan() first.")
  8807.  
  8808.     if i <= 0
  8809.     then suspend l_SUBJ[.l_POS:l_POS <- 0 < (*l_SUBJ+1 >= (*l_SUBJ+1)+i)]
  8810.     else suspend l_SUBJ[.l_POS:l_POS <- 0 < (*l_SUBJ+1 >= i)]
  8811.  
  8812. end
  8813.  
  8814.  
  8815.  
  8816. procedure l_any(l1,l2,i,j)
  8817.  
  8818.     #
  8819.     # Like any(c,s2,i,j) except that the string & cset arguments are
  8820.     # replaced by list arguments.  l1 must be a list of one-element
  8821.     # lists, while l2 can be any list (l_SUBJ by default).
  8822.     #
  8823.  
  8824.     local sub_l
  8825.  
  8826.     /l1 & stop("l_any:  Null first argument!")
  8827.     if type(l1) == "set" then l1 := sort(l1)
  8828.  
  8829.     /l2 := l_SUBJ
  8830.     if \i then {
  8831.     if i < 1 then
  8832.         i := *l2 + (i+1)
  8833.     }
  8834.     else i := \l_POS | 1
  8835.     if \j then {
  8836.     if j < 1 then
  8837.         j := *l2 + (j+1)
  8838.     }
  8839.     else j := *l_SUBJ+1
  8840.  
  8841.     (i+1) > j & i :=: j
  8842.     every sub_l := !l1 do {
  8843.     if not (type(sub_l) == "list", *sub_l = 1) then
  8844.         stop("l_any:  Elements of l1 must be lists of length 1.")
  8845.     # Let l_match check to see if i+1 is out of range.
  8846.     if x := l_match(sub_l,l2,i,i+1) then
  8847.         return x
  8848.     }
  8849.     
  8850. end
  8851.  
  8852.  
  8853.  
  8854. procedure l_match(l1,l2,i,j)
  8855.  
  8856.     #
  8857.     # Analogous to match(s1,s2,i,j), except that s1 and s2 are lists,
  8858.     # and l_match returns the next position in l2 after that portion
  8859.     # (if any) which is structurally identical to l1.  If a match is not
  8860.     # found, l_match fails.
  8861.     #
  8862.  
  8863.     if /l1
  8864.     then stop("l_match:  Null first argument!")
  8865.     if type(l1) ~== "list"
  8866.     then stop("l_match:  Call me with a list as the first arg.")
  8867.  
  8868.     /l2 := l_SUBJ
  8869.     if \i then {
  8870.     if i < 1 then
  8871.         i := *l2 + (i+1)
  8872.     }
  8873.     else i := \l_POS | 1
  8874.     
  8875.     if \j then {
  8876.     if j < 1 then
  8877.         j := *l2 + (j+1)
  8878.     }
  8879.     else j := *l_SUBJ+1
  8880.  
  8881.     i + *l1 > j & i :=: j
  8882.     i + *l1 > j & fail
  8883.     if l_comp(l1,l2[i+:*l1]) then
  8884.     return i + *l1
  8885.  
  8886. end
  8887.  
  8888.     
  8889.  
  8890. procedure l_comp(l1,l2)
  8891.  
  8892.     #
  8893.     # List comparison routine basically taken from Griswold & Griswold
  8894.     # (1st ed.), p. 174.
  8895.     #
  8896.  
  8897.     local i
  8898.  
  8899.     /l1 | /l2 & stop("l_comp:  Null argument!")
  8900.     l1 === l2 & (return l2)
  8901.  
  8902.     if type(l1) == type(l2) == "list" then {
  8903.     *l1 ~= *l2 & fail
  8904.     every i := 1 to *l1
  8905.     do l_comp(l1[i],l2[i]) | fail
  8906.     return l2
  8907.     }
  8908.  
  8909. end
  8910.  
  8911.  
  8912.  
  8913. procedure l_find(l1,l2,i,j)
  8914.  
  8915.     #
  8916.     # Like the builtin find(s1,s2,i,j), but for lists.
  8917.     #
  8918.  
  8919.     local x
  8920.  
  8921.     /l1 & stop("l_find:  Null first argument!")
  8922.  
  8923.     /l2 := l_SUBJ
  8924.     if \i then {
  8925.     if i < 1 then
  8926.         i := *l2 + (i+1)
  8927.     }
  8928.     else i := \l_POS | 1
  8929.     if \j then {
  8930.     if j < 1 then
  8931.         j := *l2 + (j+1)
  8932.     }
  8933.     else j := *l_SUBJ+1
  8934.  
  8935.     #
  8936.     # See l_upto() below for a discussion of why things have to be done
  8937.     # in this manner.
  8938.     #
  8939.     old_l_POS := l_POS
  8940.  
  8941.     suspend l_Escan(l_Bscan(l2[i:j]), {
  8942.     l_tab(1 to *l_SUBJ) & {
  8943.         if l_match(l1) then
  8944.         old_l_POS + (l_POS-1)
  8945.     }
  8946.     })
  8947.     
  8948. end
  8949.  
  8950.  
  8951.  
  8952. procedure l_upto(l1,l2,i,j)
  8953.  
  8954.     #
  8955.     # See l_any() above.  This procedure just moves through l2, calling
  8956.     # l_any() for each member of l2[i:j].
  8957.     #
  8958.  
  8959.     local old_l_POS
  8960.  
  8961.     /l1 & stop("l_upto:  Null first argument!")
  8962.     if type(l1) == "set" then l1 := sort(l1)
  8963.  
  8964.     /l2 := l_SUBJ
  8965.     if \i then {
  8966.     if i < 1 then
  8967.         i := *l2 + (i+1)
  8968.     }
  8969.     else i := \l_POS | 1
  8970.     if \j then {
  8971.     if j < 1 then
  8972.         j := *l2 + (j+1)
  8973.     }
  8974.     else j := *l_SUBJ+1
  8975.  
  8976.     #
  8977.     # Save the old pos, then try arb()ing through the list to see if we
  8978.     # can do an l_any(l1) at any position.
  8979.     #
  8980.     old_l_POS := l_POS
  8981.  
  8982.     suspend l_Escan(l_Bscan(l2[i:j]), {
  8983.     l_tab(1 to *l_SUBJ) & {
  8984.         if l_any(l1) then
  8985.         old_l_POS + (l_POS-1)
  8986.     }
  8987.     })
  8988.  
  8989.     #
  8990.     # Note that it WILL NOT WORK if you say:
  8991.     #
  8992.     # l_Escan(l_Bscan(l2[i:j]), {
  8993.     #     l_tab(1 to *l_SUBJ) & {
  8994.     #         if l_any(l1) then
  8995.     #             suspend old_l_POS + (l_POS-1)
  8996.     #     }
  8997.     # })
  8998.     #
  8999.     # If we are to suspend a result, l_Escan must suspend that result.
  9000.     # Otherwise scanning environments are not saved and/or restored
  9001.     # properly.
  9002.     #
  9003.     
  9004. end
  9005.  
  9006.  
  9007.  
  9008. procedure l_many(l1,l2,i,j)
  9009.  
  9010.     local x, old_l_POS
  9011.  
  9012.     /l1 & stop("l_many:  Null first argument!")
  9013.     if type(l1) == "set" then l1 := sort(l1)
  9014.  
  9015.     /l2 := l_SUBJ
  9016.     if \i then {
  9017.     if i < 1 then
  9018.         i := *l2 + (i+1)
  9019.     }
  9020.     else i := \l_POS | 1
  9021.     if \j then {
  9022.     if j < 1 then
  9023.         j := *l2 + (j+1)
  9024.     }
  9025.     else j := *l_SUBJ+1
  9026.  
  9027.     #
  9028.     # L_many(), like many(), is not a generator.  We can therefore
  9029.     # save one final result in x, and then later return (rather than
  9030.     # suspend) that result.
  9031.     #
  9032.     old_l_POS := l_POS
  9033.     l_Escan(l_Bscan(l2[i:j]), {
  9034.     while l_tab(l_any(l1))
  9035.     x := old_l_POS + (l_POS-1)
  9036.     })
  9037.  
  9038.     #
  9039.     # Fails if there was no positional change (i.e. l_any() did not
  9040.     # succeed even once).
  9041.     #
  9042.     return old_l_POS ~= x
  9043.  
  9044. end
  9045.  
  9046.  
  9047.  
  9048. procedure l_pos(i)
  9049.  
  9050.     local x
  9051.  
  9052.     if /l_POS | /l_SUBJ
  9053.     then stop("l_move:  Call l_Bscan() first.")
  9054.  
  9055.     if i <= 0
  9056.     then x := 0 < (*l_SUBJ+1 >= (*l_SUBJ+1)+i) | fail
  9057.     else x := 0 < (*l_SUBJ+1 >= i) | fail
  9058.  
  9059.     if x = l_POS
  9060.     then return x
  9061.     else fail
  9062.  
  9063. end
  9064.  
  9065.  
  9066.  
  9067. procedure l_bal(l1,l2,l3,l,i,j)
  9068.  
  9069.     local l2_count, l3_count, x, position
  9070.  
  9071.     /l1 & stop("l_bal:  Null first argument!")
  9072.     if type(l1) == "set" then l1 := sort(l1)  # convert to a list
  9073.     if type(l2) == "set" then l1 := sort(l2)
  9074.     if type(l3) == "set" then l1 := sort(l3)
  9075.  
  9076.     /l2 := l_SUBJ
  9077.     if \i then {
  9078.     if i < 1 then
  9079.         i := *l2 + (i+1)
  9080.     }
  9081.     else i := \l_POS | 1
  9082.     if \j then {
  9083.     if j < 1 then
  9084.         j := *l2 + (j+1)
  9085.     }
  9086.     else j := *l_SUBJ+1
  9087.  
  9088.     l2_count := l3_count := 0
  9089.  
  9090.     every x := i to j-1 do {
  9091.  
  9092.     if l_any(l2, l, x, x+1) then {
  9093.         l2_count +:= 1
  9094.     }
  9095.     if l_any(l3, l, x, x+1) then {
  9096.         l3_count +:= 1
  9097.     }
  9098.     if l2_count = l3_count then {
  9099.         if l_any(l1,l,x,x+1)
  9100.         then suspend x
  9101.     }
  9102.     }
  9103.  
  9104. end
  9105. -- 
  9106.  
  9107.    -Richard L. Goerwitz              goer%sophist@uchicago.bitnet
  9108.    goer@sophist.uchicago.edu         rutgers!oddjob!gide!sophist!goer
  9109.  
  9110. From R.J.Hare@edinburgh.ac.uk  Tue May 28 10:03:39 1991
  9111. Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Tue, 28 May 91 10:03:39 MST
  9112. Received: from Arizona.edu (Merlin.Telcom.Arizona.EDU) by optima.cs.arizona.edu (4.1/15)
  9113.     id AA15448; Tue, 28 May 91 10:03:35 MST
  9114. Received: from UKACRL.BITNET (MAILER@UKACRL) by Arizona.edu with PMDF#10282;
  9115.  Tue, 28 May 1991 10:03 MST
  9116. Received: from RL.IB by UKACRL.BITNET (Mailer R2.07) with BSMTP id 5763; Tue,
  9117.  28 May 91 17:32:02 BST
  9118. Received: from RL.IB by UK.AC.RL.IB (Mailer R2.07) with BSMTP id 6741; Tue, 28
  9119.  May 91 17:32:02 BST
  9120. Date: 28 May 91  17:32:28 bst
  9121. From: R.J.Hare@edinburgh.ac.uk
  9122. Subject: Records
  9123. To: icon-group@cs.arizona.edu
  9124. Message-Id: <28 May 91  17:32:28 bst  060196@EMAS-A>
  9125. X-Envelope-To: icon-group@cs.arizona.edu
  9126. Via:        UK.AC.ED.EMAS-A; 28 MAY 91 17:31:57 BST
  9127.  
  9128. I'm just about to start writing my first program which uses records.
  9129. Question, can I write a record straight to a file without separating the
  9130. fields - like this:
  9131.  
  9132. record line(a,b,c,d)
  9133. procedure(main)
  9134.   .
  9135.   .
  9136. output_line:=line(w,x,y,z)
  9137. write(file,output_line)
  9138.   .
  9139.   .
  9140.  
  9141. or do I have to do it a field at a time:
  9142.  
  9143.   .
  9144. every i := 1 to 4 do write(file,output_line[i])
  9145.   .
  9146.  
  9147. Any advice appreciated.
  9148.  
  9149. Thanks.
  9150.  
  9151. Roger Hare.
  9152.  
  9153. From ralph  Tue May 28 10:07:54 1991
  9154. Date: Tue, 28 May 91 10:07:54 MST
  9155. From: "Ralph Griswold" <ralph>
  9156. Message-Id: <9105281707.AA08271@cheltenham.cs.arizona.edu>
  9157. Received: by cheltenham.cs.arizona.edu; Tue, 28 May 91 10:07:54 MST
  9158. To: R.J.Hare@edinburgh.ac.uk
  9159. Subject: Re:  Records
  9160. Cc: icon-group
  9161.  
  9162. You have to write each field separatey.  However, you can generate the
  9163. fields of a record.  E.g., if x is a record,
  9164.  
  9165.     every write(!x)
  9166.  
  9167. writes all the fields of x, one per line.
  9168.  
  9169.   Ralph Griswold / Dept of Computer Science / Univ of Arizona / Tucson, AZ 85721
  9170.   +1 602 621 6609   ralph@cs.arizona.edu  uunet!arizona!ralph
  9171.  
  9172. From gmt  Tue May 28 10:27:02 1991
  9173. Received: from owl.cs.arizona.edu by cheltenham.cs.arizona.edu; Tue, 28 May 91 10:27:02 MST
  9174. Date: Tue, 28 May 91 10:27:00 MST
  9175. From: "Gregg Townsend" <gmt>
  9176. Message-Id: <9105281727.AA22946@owl.cs.arizona.edu>
  9177. Received: by owl.cs.arizona.edu; Tue, 28 May 91 10:27:00 MST
  9178. To: icon-group
  9179. Subject: Re:  Records
  9180.  
  9181. To write the record as a single line I would do this:
  9182.  
  9183.     every writes (!output_line | "\n")
  9184.  
  9185.     Gregg Townsend / Computer Science Dept / Univ of Arizona / Tucson, AZ 85721
  9186.     +1 602 621 4325     gmt@cs.arizona.edu     110 57 16 W / 32 13 45 N / +758m
  9187.  
  9188. From icon-group-request@arizona.edu  Tue May 28 21:12:26 1991
  9189. Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Tue, 28 May 91 21:12:26 MST
  9190. Resent-From: icon-group-request@arizona.edu
  9191. Received: from Arizona.edu (Merlin.Telcom.Arizona.EDU) by optima.cs.arizona.edu (4.1/15)
  9192.     id AA04640; Tue, 28 May 91 21:12:24 MST
  9193. Received: from ucbvax.Berkeley.EDU by Arizona.edu with PMDF#10282; Tue, 28 May
  9194.  1991 21:11 MST
  9195. Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA25558; Tue, 28 May 91
  9196.  21:05:29 -0700
  9197. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  9198.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  9199.  usenet@ucbvax.Berkeley.EDU if you have questions)
  9200. Resent-Date: Tue, 28 May 1991 21:12 MST
  9201. Date: 29 May 91 04:00:11 GMT
  9202. From: cis.ohio-state.edu!pacific.mps.ohio-state.edu!linac!midway!ellis.uchicago.edu!goer@ucbvax.berkeley.edu (Richard L.
  9203.  Goerwitz)
  9204. Subject: RE: Holiday TidBit
  9205. Sender: icon-group-request@arizona.edu
  9206. Resent-To: icon-group@cs.arizona.edu
  9207. To: icon-group@arizona.edu
  9208. Resent-Message-Id: <B91A8B4E56C00210@Arizona.edu>
  9209. Message-Id: <1991May29.040011.2409@midway.uchicago.edu>
  9210. X-Envelope-To: icon-group@CS.Arizona.EDU
  9211. X-Vms-To: icon-group@Arizona.edu
  9212. Organization: University of Chicago
  9213. References: <50632F0EE04001B8@mis.mcw.edu>
  9214.  
  9215. If anyone wants a Unix version of Chris Tenaglia's yahtzee game (will
  9216. probably work for DOS, too), please let me know.  If I get more than
  9217. a few requests, I'll post it.
  9218.  
  9219. -Richard
  9220. -- 
  9221.  
  9222.    -Richard L. Goerwitz              goer%sophist@uchicago.bitnet
  9223.    goer@sophist.uchicago.edu         rutgers!oddjob!gide!sophist!goer
  9224.  
  9225. From icon-group-request@arizona.edu  Wed May 29 08:14:10 1991
  9226. Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Wed, 29 May 91 08:14:10 MST
  9227. Resent-From: icon-group-request@arizona.edu
  9228. Received: from Arizona.edu (Merlin.Telcom.Arizona.EDU) by optima.cs.arizona.edu (4.1/15)
  9229.     id AA24922; Wed, 29 May 91 08:14:04 MST
  9230. Received: from ucbvax.Berkeley.EDU by Arizona.edu with PMDF#10282; Wed, 29 May
  9231.  1991 08:12 MST
  9232. Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA09005; Wed, 29 May 91
  9233.  07:53:42 -0700
  9234. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  9235.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  9236.  usenet@ucbvax.Berkeley.EDU if you have questions)
  9237. Resent-Date: Wed, 29 May 1991 08:13 MST
  9238. Date: 29 May 91 14:56:04 GMT
  9239. From: cis.ohio-state.edu!pacific.mps.ohio-state.edu!linac!midway!ellis.uchicago.edu!goer@ucbvax.berkeley.edu (Richard L.
  9240.  Goerwitz)
  9241. Subject: RE: Holiday TidBit, part 1 of 3 of Unix port
  9242. Sender: icon-group-request@arizona.edu
  9243. Resent-To: icon-group@cs.arizona.edu
  9244. To: icon-group@arizona.edu
  9245. Resent-Message-Id: <1586849566C00422@Arizona.edu>
  9246. Message-Id: <1991May29.145604.4017@midway.uchicago.edu>
  9247. X-Envelope-To: icon-group@CS.Arizona.EDU
  9248. X-Vms-To: icon-group@Arizona.edu
  9249. Organization: University of Chicago
  9250. References: <50632F0EE04001B8@mis.mcw.edu>,
  9251.  <1991May29.040011.2409@midway.uchicago.edu>
  9252.  
  9253. I logged in this morning, and had six requests for the game.  I suspect
  9254. I'll get more, so let me just post the Unix (test!) port of Chris Tenaglia's
  9255. yahtzee game.  It's been tested by me alone, and this only on ansi terminals.
  9256. I believe it will work, though, on just about any non-cookie terminal that
  9257. has cd capability.  Part 1 follows.  Parts 2 & 3 come in separate mailings.
  9258. Please let me know about bugs.
  9259.  
  9260.  
  9261. ---- Cut Here and feed the following to sh ----
  9262. #!/bin/sh
  9263. # This is a shell archive (produced by shar 3.49)
  9264. # To extract the files from this archive, save it to a file, remove
  9265. # everything above the "!/bin/sh" line above, and type "sh file_name".
  9266. #
  9267. # made 05/29/1991 05:23 UTC by goer@sophist.uchicago.edu
  9268. # Source directory /u/richard/Yahtz
  9269. #
  9270. # existing files will NOT be overwritten unless -c is specified
  9271. # This format requires very little intelligence at unshar time.
  9272. # "if test", "cat", "rm", "echo", "true", and "sed" may be needed.
  9273. #
  9274. # This is part 1 of a multipart archive                                    
  9275. # do not concatenate these parts, unpack them in order with /bin/sh        
  9276. #
  9277. # This shar contains:
  9278. # length  mode       name
  9279. # ------ ---------- ------------------------------------------
  9280. #  15750 -r--r--r-- yahtz.icn
  9281. #  17272 -r--r--r-- iolib.icn
  9282. #   2391 -r--r--r-- termcap.dos
  9283. #    994 -rw-r--r-- Makefile.dist
  9284. #   1194 -rw-r--r-- README
  9285. #
  9286. if test -r _shar_seq_.tmp; then
  9287.     echo 'Must unpack archives in sequence!'
  9288.     echo Please unpack part `cat _shar_seq_.tmp` next
  9289.     exit 1
  9290. fi
  9291. # ============= yahtz.icn ==============
  9292. if test -f 'yahtz.icn' -a X"$1" != X"-c"; then
  9293.     echo 'x - skipping yahtz.icn (File already exists)'
  9294.     rm -f _shar_wnt_.tmp
  9295. else
  9296. > _shar_wnt_.tmp
  9297. echo 'x - extracting yahtz.icn (Text)'
  9298. sed 's/^X//' << 'SHAR_EOF' > 'yahtz.icn' &&
  9299. X############################################################################
  9300. X#
  9301. X#    Name:     yahtz.icn
  9302. X#
  9303. X#    Title:     yahtz (alias yahtzee, without a naming conflict)
  9304. X#
  9305. X#    Author:     Chris Tenaglia, modified by Richard Goerwitz
  9306. X#
  9307. X#    Version: 1.3 (beta!)
  9308. X#
  9309. X#########################################################################
  9310. X#
  9311. X#  Copyright (c) 1991, Chris D. Tenaglia # 12p
  9312. X#
  9313. X#  This software is intended for free and unrestricted distribution.
  9314. X#  I place only two conditions on its use:  1) That you clearly mark
  9315. X#  any additions or changes you make to the source code, and 2) that
  9316. X#  you do not delete this message therefrom.  In order to protect
  9317. X#  myself from spurious litigation, it must also be stated here that,
  9318. X#  because this is free software, I, Chris tenaglia, make no claim
  9319. X#  about the applicability or fitness of this software for any
  9320. X#  purpose, and expressly disclaim any responsibility for any damages
  9321. X#  that might be incurred in conjunction with its use.
  9322. X#
  9323. X#########################################################################
  9324. X#
  9325. X#  This hacked version will run under UNIX, and under DOS as well.  It
  9326. X#  should run out of the box on DOS as long as you stay in the current
  9327. X#  directory.  See the README file.
  9328. X#
  9329. X#  This is a test version!!  In accordance with the author's wishes,
  9330. X#  I'd like to make it clear that I've altered all the screen I/O
  9331. X#  routines, and have removed characters peculiar to VT terminals.
  9332. X#  I've tried to keep intact the author's indentation and brace style.
  9333. X#  Changes, where present, have been indicated by my initials.  The
  9334. X#  IPL-style header was added by me.  I also moved Chris's copyright
  9335. X#  notice to the top of the document.  It seems to me that such no-
  9336. X#  tices have to be prominently displayed in order to be considered
  9337. X#  valid.
  9338. X#
  9339. X#  -Richard Goerwitz.
  9340. X#
  9341. X############################################################################
  9342. X
  9343. X
  9344. Xglobal players,slot,team,d,od,dice,round
  9345. Xprocedure main(param)
  9346. X  paint()
  9347. X  assign_players()
  9348. X  every round := 1 to 13 do
  9349. X    every play(!team)
  9350. X  summarize()
  9351. X  end
  9352. X
  9353. X#
  9354. X# DISPLAYS THE HEADER AND SEPARATOR LINE AT BEGINNING OF GAME
  9355. X#
  9356. Xprocedure paint()
  9357. X  # Clear first, separately.  Screws up on some terminals of you don't.
  9358. X  writes(cls())
  9359. X  # Check to be sure the terminal is big enough, and won't leave magic
  9360. X  # cookies on the screen.  -RLG
  9361. X  if getval("ug"|"sg") > 0
  9362. X  then stop("abort:  Can't do magic cookie terminals!") 
  9363. X  if getval("li") < 24 | getval("co") < 80 then
  9364. X    stop("abort:  Your terminal is too small!")
  9365. X  write(high(uhalf("             Y A H T Z E E              ")))
  9366. X  write(high(lhalf("             Y A H T Z E E              ")))
  9367. X  write(at(1,10),graf(repl("=",75)))
  9368. X  end
  9369. X
  9370. X#
  9371. X# DISPLAYS THE FINAL SCORE OF ALL THE PLAYERS
  9372. X#
  9373. Xprocedure summarize()
  9374. X  # blink, high, inverse was just too much for my terminal to handle -RLG
  9375. X  write(at(1,11), high(chop("Final Score Summary")))
  9376. X  every player := key(players) do
  9377. X    {
  9378. X    card := players[player]
  9379. X    top  := 0 ; every i := 1 to 6 do top +:= card[i]
  9380. X    if top > 62 then top +:= 35
  9381. X    bottom := 0 ; every i := 7 to 13 do bottom +:= card[i]
  9382. X    write("Player ",high(left(player,14))," Top = ",right(top,5),
  9383. X                                       " Bottom = ",right(bottom,5),
  9384. X                                       "  Total = ",right(top+bottom,5))
  9385. X    }
  9386. X  input("<press return>")
  9387. X  end
  9388. X
  9389. X#
  9390. X# SETUP AND INITIALIZATION OF YAHTZEE ENVIRONMENT
  9391. X#
  9392. Xprocedure assign_players()
  9393. X  n := 1 ; team := [] ; slot := [] ; d := list(6,"") ; od := list(5,0)
  9394. X  &random := map(&clock,":","9")
  9395. X  players := table("n/a")
  9396. X  repeat
  9397. X    {
  9398. X    (player := input(("Name of player #" || n || ": "))) |
  9399. X      stop("Game called off.")
  9400. X    if player == "" then break
  9401. X    n +:= 1
  9402. X    put(team,player)
  9403. X    players[player] := list(13,"*")
  9404. X    }
  9405. X  if n = 1 then stop("Nobody wants to play!")
  9406. X
  9407. X  put(slot,"Ones")   ; put(slot,"Twos")  ; put(slot,"Threes")
  9408. X  put(slot,"Fours")  ; put(slot,"Fives") ; put(slot,"Sixes")
  9409. X  put(slot,"3oK")    ; put(slot,"4oK")   ; put(slot,"FullH")
  9410. X  put(slot,"SmStr")  ; put(slot,"LgStr") ; put(slot,"Yahtzee")
  9411. X  put(slot,"Chance")
  9412. X
  9413. X  # VT-specific characters removed.  -RLG
  9414. X  d[1] := "+-----+|     ||  o  ||     |+-----+"
  9415. X  d[2] := "+-----+|     || o o ||     |+-----+"
  9416. X  d[3] := "+-----+|o    ||  o  ||    o|+-----+"
  9417. X  d[4] := "+-----+|o   o||     ||o   o|+-----+"
  9418. X  d[5] := "+-----+|o   o||  o  ||o   o|+-----+"
  9419. X  d[6] := "+-----+|o o o||     ||o o o|+-----+"
  9420. X  end
  9421. X
  9422. X#
  9423. X# THIS ROUTINE LETS A PLAYER TAKE THEIR TURN
  9424. X#
  9425. Xprocedure play(name)
  9426. X  writes(at(1,11),"It's ",high(name),"'s turn",chop())
  9427. X  writes(at(1,getval("li")-1),high(name))
  9428. X  input(", please press <RETURN> to begin.")
  9429. X  score(name)
  9430. X  dice := [] ; every 1 to 5 do put(dice,?6)
  9431. X  depict()
  9432. X  shake := obtain("Shake which ones : ")
  9433. X  (shake === []) | (every dice[!shake] := ?6)
  9434. X  depict()
  9435. X  shake := obtain("Shake which ones (last chance) : ")
  9436. X  (shake === []) | (every dice[!shake] := ?6)
  9437. X  depict()
  9438. X  repeat
  9439. X    {
  9440. X    select := input(at(1,22) || clip("Tally to which category (1-13) : "))
  9441. X    numeric(select)                | next
  9442. X    (1 <= select <= 13)            | next
  9443. X    (players[name][select] == "*") | next
  9444. X    break
  9445. X    }
  9446. X  tally(name,select)
  9447. X  score(name)
  9448. X  input(at(1,22) || clip("Press <RETURN>"))
  9449. X  end
  9450. X
  9451. X#
  9452. X# THIS ROUTINE DRAWS THE DICE
  9453. X#
  9454. Xprocedure depict()
  9455. X  every i := 1 to 5 do
  9456. X    {
  9457. X    if od[i] = dice[i] then next
  9458. X    x := 1
  9459. X    writes(at(i*10+3,3),inverse(i))
  9460. X#    writes(at(i*10+4,9),inverse(dice[i]))
  9461. X    every j := 4 to 8 do
  9462. X      {
  9463. X      writes(at(i*10,j),graf(d[dice[i]][x:x+7]))
  9464. X      x +:= 7
  9465. X      }
  9466. X    od[i] := dice[i]
  9467. X    }
  9468. X  end
  9469. X
  9470. X#
  9471. X# THIS ROUTINE LETS THE PLAYER DECIDE WHAT TO APPLY THE SHAKES TO
  9472. X#
  9473. Xprocedure tally(name,area)
  9474. X  case integer(area) of
  9475. X    {
  9476. X    1 : {                        # ones
  9477. X        sum := 0 ; every unit := !dice do if unit = 1 then sum +:= 1
  9478. X        players[name][1] := sum
  9479. X        }
  9480. X    2 : {                        # twos
  9481. X        sum := 0 ; every unit := !dice do if unit = 2 then sum +:= 2
  9482. X        players[name][2] := sum
  9483. X        }
  9484. X    3 : {                        # threes
  9485. X        sum := 0 ; every unit := !dice do if unit = 3 then sum +:= 3
  9486. X        players[name][3] := sum
  9487. X        }
  9488. X    4 : {                        # fours
  9489. X        sum := 0 ; every unit := !dice do if unit = 4 then sum +:= 4
  9490. X        players[name][4] := sum
  9491. X        }
  9492. X    5 : {                        # fives
  9493. X        sum := 0 ; every unit := !dice do if unit = 5 then sum +:= 5
  9494. X        players[name][5] := sum
  9495. X        }
  9496. X    6 : {                        # sixes
  9497. X        sum := 0 ; every unit := !dice do if unit = 6 then sum +:= 6
  9498. X        players[name][6] := sum
  9499. X        }
  9500. X    7 : {                        # 3 of a kind
  9501. X        sum := 0 ; flag := 0
  9502. X        tmp := table(0) ; every unit := !dice do tmp[unit] +:= 1
  9503. X        every piece := key(tmp) do
  9504. X          if tmp[piece] >= 3 then flag := 1
  9505. X        if flag = 1 then every sum +:= !dice
  9506. X        players[name][7] := sum
  9507. X        }
  9508. X    8 : {                        # four of a kind
  9509. X        sum := 0 ; flag := 0
  9510. X        tmp := table(0) ; every unit := !dice do tmp[unit] +:= 1
  9511. X        every piece := key(tmp) do
  9512. X          if tmp[piece] >= 4 then flag := 1
  9513. X        if flag = 1 then every sum +:= !dice
  9514. X        players[name][8] := sum
  9515. X        }
  9516. X    9 : {                        # full house
  9517. X        sum := 0 ; flag := 0
  9518. X        tmp := table(0) ; every unit := !dice do tmp[unit] +:= 1
  9519. X        every piece := key(tmp) do
  9520. X          {
  9521. X          if tmp[piece] = 3 then flag +:= 1
  9522. X          if tmp[piece] = 2 then flag +:= 1
  9523. X          }
  9524. X        if flag = 2 then sum := 25
  9525. X        players[name][9] := sum
  9526. X        }
  9527. X   10 : {                        # small straight
  9528. X        sum  := 0 ; flag := 0
  9529. X        hold := set() ; every insert(hold,!dice)
  9530. X        tmp  := sort(hold)
  9531. X        if tmp[1]+1 = tmp[2] &
  9532. X           tmp[2]+1 = tmp[3] &
  9533. X           tmp[3]+1 = tmp[4] then flag := 1
  9534. X        if tmp[2]+1 = tmp[3] &
  9535. X           tmp[3]+1 = tmp[4] &
  9536. X           tmp[4]+1 = tmp[5] then flag := 1
  9537. X        if flag = 1 then sum := 30
  9538. X        players[name][10] := sum
  9539. X        }
  9540. X   11 : {                        # large straight
  9541. X        sum := 0 ; flag := 0  
  9542. X        tmp := sort(dice)
  9543. X        if tmp[1]+1 = tmp[2] &
  9544. X           tmp[2]+1 = tmp[3] &
  9545. X           tmp[3]+1 = tmp[4] &
  9546. X           tmp[4]+1 = tmp[5] then flag := 1
  9547. X        if flag = 1 then sum := 40
  9548. X        players[name][11] := sum
  9549. X        }
  9550. X   12 : {                        # yahtzee
  9551. X        sum := 0 ; flag := 0
  9552. X        tmp := table(0) ; every unit := !dice do tmp[unit] +:= 1
  9553. X        every piece := key(tmp) do
  9554. X          if tmp[piece] = 5 then flag := 1
  9555. X        if flag = 1 then sum := 50
  9556. X        players[name][12] := sum
  9557. X        }
  9558. X   13 : {                        # chance
  9559. X        sum := 0 ; every sum +:= !dice
  9560. X        players[name][13] := sum
  9561. X        }
  9562. X    }
  9563. X  end
  9564. X
  9565. X#
  9566. X# THIS ROUTINE OBTAINS A VALID SHAKER REQUEST
  9567. X#
  9568. Xprocedure obtain(prompt)
  9569. X  repeat
  9570. X    {
  9571. X    writes(at(1,22),prompt)
  9572. X    (line := read()) | next
  9573. X    if match("q",map(line)) then stop("Game Quit")
  9574. X    if trim(line) == "" then return []
  9575. X    units := parse(line,', \t')
  9576. X    every unit := !units do
  9577. X      (1 <= unit <= 5) | next
  9578. X    break
  9579. X    }
  9580. X  return units
  9581. X  end
  9582. X
  9583. X#
  9584. X# THIS ROUTINE PAINTS THE SCORECARD FOR A GIVEN PLAYER
  9585. X#
  9586. Xprocedure score(name)
  9587. X  # Slight realignment.  -RLG
  9588. X  writes(at(1,11),chop(),at(18,11),under(),"Player = ",name,"     Round = ",under(round))
  9589. X  writes(at(10,12)," 1 : Ones    = ",players[name][1])
  9590. X  writes(at(10,13)," 2 : Twos    = ",players[name][2])
  9591. X  writes(at(10,14)," 3 : Threes  = ",players[name][3])
  9592. X  writes(at(10,15)," 4 : Fours   = ",players[name][4])
  9593. X  writes(at(10,16)," 5 : Fives   = ",players[name][5])
  9594. X  writes(at(10,17)," 6 : Sixes   = ",players[name][6])
  9595. X  writes(at(40,12)," 7 : 3oK     = ",players[name][7])
  9596. X  writes(at(40,13)," 8 : 4oK     = ",players[name][8])
  9597. X  writes(at(40,14)," 9 : FullH   = ",players[name][9])
  9598. X  writes(at(40,15),"10 : SmStr   = ",players[name][10])
  9599. X  writes(at(40,16),"11 : LgStr   = ",players[name][11])
  9600. X  writes(at(40,17),"12 : Yahtzee = ",players[name][12])
  9601. X  writes(at(40,18),"13 : Chance  = ",players[name][13])
  9602. X  st1 := 0 ; every i := 1 to 6 do st1 +:= numeric(players[name][i])
  9603. X  if st1 > 62 then bonus := 35 else bonus := 0
  9604. X  st2 := 0 ; every i := 7 to 13 do st2 +:= numeric(players[name][i])
  9605. X  writes(at(10,19),"Bonus = ",clip(bonus))
  9606. X  writes(at(10,20),"Subtotal = ",st1+bonus)
  9607. X  writes(at(40,20),"Subtotal = ",st2)
  9608. X  writes(at(37,21),"Grand Total = ",st1+st2+bonus)
  9609. X  end
  9610. X
  9611. X#
  9612. X# From here down, all CT's VT-specific I/O codes have been replaced
  9613. X# with calls to iolib/itlib routines.  The replacements were quite
  9614. X# easy to do because of the great modularity of the original program.
  9615. X# -RLG
  9616. X#
  9617. X
  9618. X#
  9619. X# VIDEO ROUTINE CLEARS SCREEN
  9620. X#
  9621. Xprocedure cls(str)
  9622. X  static clear_string
  9623. X  initial {
  9624. X    clear_string := getval("cl") |
  9625. X    (igoto(getval("cm"),1,1) || getval("cd")) |
  9626. X    stop("abort:  Your terminal can't clear screen!")
  9627. X    }
  9628. X  /str := ""
  9629. X  return clear_string || str
  9630. X  end
  9631. X
  9632. X#
  9633. X# VIDEO ROUTINE ERASES REST OF SCREEN
  9634. X#
  9635. Xprocedure chop(str)
  9636. X  static clear_rest
  9637. X  initial {
  9638. X    clear_rest := getval("cd") |
  9639. X    stop("abort:  Sorry, your terminal must have cd capability.")
  9640. X  }
  9641. X  /str := ""
  9642. X  return clear_rest || str
  9643. X  end
  9644. X
  9645. X#
  9646. X# VIDEO ROUTINE OUTPUTS UPPER HALF OF DOUBLE SIZE MESSAGES
  9647. X#
  9648. Xprocedure uhalf(str)
  9649. X  # Disabled for non-VT{2,3,4}XX terminals.  I'd have left them in for
  9650. X  # vt100s, but there are so many vt100 terminal emulation programs out
  9651. X  # there that don't do the big characters that I thought better of it.
  9652. X  # -RLG
  9653. X  static isVT
  9654. X  initial
  9655. X    {
  9656. X    if map(getname()) ? (tab(find("vt")+2), tab(any('234')), integer(tab(0)))
  9657. X    then isVT := 1
  9658. X    }
  9659. X  if \isVT then
  9660. X    {
  9661. X    /str := ""
  9662. X    if str == "" then return "\e#3"
  9663. X    return "\e#3" || str
  9664. X    }
  9665. X  end
  9666. X  
  9667. X#
  9668. X# VIDEO ROUTINE OUTPUTS BOTTOM HALF OF DOUBLE SIZE MESSAGES
  9669. X#
  9670. Xprocedure lhalf(str)
  9671. X  static isVT
  9672. X  initial
  9673. X    {
  9674. X    if map(getname()) ? (tab(find("vt")+2), tab(any('234')), integer(tab(0)))
  9675. X    then isVT := 1
  9676. X    }
  9677. X  if \isVT then
  9678. X    {
  9679. X    /str := ""
  9680. X    if str == "" then return "\e#4"
  9681. X    return "\e#4" || str
  9682. X    }
  9683. X  end
  9684. X
  9685. X#
  9686. X# VIDEO ROUTINE OUTPUTS STRING AND CLEARS TO EOL
  9687. X#
  9688. Xprocedure clip(str)
  9689. X  static clear_line
  9690. X  initial
  9691. X    {
  9692. X    clear_line := getval("ce") | "                "
  9693. X    }
  9694. X  /str := ""
  9695. X  if str == "" then return clear_line
  9696. X  return str ||:= clear_line
  9697. X  end
  9698. X  
  9699. X#
  9700. X# VIDEO ROUTINE OUTPUTS HIGHLIGHTED STRINGS
  9701. X#
  9702. Xprocedure high(str)
  9703. X  static bold_code, off_other_modes
  9704. X  initial
  9705. X    {
  9706. X    off_other_modes := ""
  9707. X    every off_other_modes ||:= getval("me"|"ue"|"se")
  9708. X    bold_code := off_other_modes || getval("md"|"us"|"so")
  9709. X    }
  9710. X  /str := ""
  9711. X  return bold_code || str || off_other_modes
  9712. X  end
  9713. X
  9714. X#
  9715. X# VIDEO ROUTINE OUTPUTS INVERSE VIDEO STRINGS
  9716. X#
  9717. Xprocedure inverse(str)
  9718. X  static reverse_code, off_other_modes
  9719. X  initial
  9720. X    {
  9721. X    off_other_modes := ""
  9722. X    every off_other_modes ||:= getval("se"|"ue"|"me")
  9723. X    reverse_code := off_other_modes || getval("so"|"us"|"md")
  9724. X    }
  9725. X  /str := ""
  9726. X  return reverse_code || str || off_other_modes
  9727. X  end
  9728. X
  9729. X#
  9730. X# VIDEO ROUTINE OUTPUTS UNDERLINED STRINGS
  9731. X#
  9732. Xprocedure under(str)
  9733. X  static underline_code, off_other_modes
  9734. X  initial
  9735. X    {
  9736. X    off_other_modes := ""
  9737. X    every off_other_modes ||:= getval("ue"|"me"|"se")
  9738. X    underline_code := off_other_modes || getval("us"|"md"|"so")
  9739. X    }
  9740. X  /str := ""
  9741. X  return underline_code || str || off_other_modes
  9742. X  end
  9743. X
  9744. X#
  9745. X# VIDEO ROUTINE OUTPUTS BLINKING STRINGS
  9746. X#
  9747. Xprocedure blink(str)
  9748. X  static blink_code, off_other_modes
  9749. X  initial
  9750. X    {
  9751. X    off_other_modes := ""
  9752. X    every off_other_modes ||:= getval("me"|"se"|"ue")
  9753. X    blink_code := off_other_modes || getval("mb"|"md"|"so"|"us")
  9754. X    }
  9755. X  /str := ""
  9756. X  return blink_code || str || off_other_modes
  9757. X  end
  9758. X
  9759. X#
  9760. X# VIDEO ROUTINE SETS NORMAL VIDEO MODE
  9761. X#
  9762. Xprocedure norm(str)
  9763. X  static off_modes
  9764. X  initial
  9765. X    {
  9766. X    off_modes := ""
  9767. X    every off_modes ||:= getval("me"|"se"|"ue")
  9768. X    }
  9769. X  /str := ""
  9770. X  return off_modes || str
  9771. X  end
  9772. X
  9773. X#
  9774. X# VIDEO ROUTINE TURNS ON VT GRAPHICS CHARACTERS
  9775. X#
  9776. Xprocedure graf(str)
  9777. X  # Again, disabled for non-VT{234}XX terminals.  -RLG
  9778. X  static isVT
  9779. X  initial
  9780. X    {
  9781. X    if map(getname()) ? (tab(find("vt")+2), tab(any('234')), integer(tab(0)))
  9782. X    then isVT := 1
  9783. X    }
  9784. X  /str := ""
  9785. X  if \isVT then
  9786. X    {
  9787. X    if str == "" then return "\e(0"
  9788. X    str := "\e(0" || str
  9789. X    if (str[-3:0] == "\e(B")
  9790. X      then return str
  9791. X      else return str || "\e(B"
  9792. X    }
  9793. X  else return str
  9794. X  end
  9795. X
  9796. X#
  9797. X# VIDEO ROUTINE TURNS OFF VT GRAPHICS CHARACTERS
  9798. X#
  9799. Xprocedure nograf(str)
  9800. X  static isVT
  9801. X  initial
  9802. X    {
  9803. X    if map(getname()) ? (tab(find("vt")+2), tab(any('234')), integer(tab(0)))
  9804. X    then isVT := 1
  9805. X    }
  9806. X  /str := ""
  9807. X  if \isVT then
  9808. X    {
  9809. X    if str == "" then return "\e(B"
  9810. X    str := "\e(B" || str
  9811. X    }
  9812. X  return str
  9813. X  end
  9814. X
  9815. X#
  9816. X# VIDEO ROUTINE SETS CURSOR TO GIVEN X,Y COORDINATES
  9817. X#
  9818. Xprocedure at(x,y) 
  9819. X  return igoto(getval("cm"), x, y)  
  9820. X  end
  9821. X
  9822. X#########  Here end the I/O routines I needed to alter.  -RLG
  9823. X
  9824. X#
  9825. X# PARSES A STRING INTO A LIST WITH RESPECT TO A GIVEN DELIMITER
  9826. X#
  9827. Xprocedure parse(line,delims)
  9828. X  local i, tokens
  9829. X  static chars
  9830. X  chars  := &cset -- delims
  9831. X  tokens := []
  9832. X  line ? while tab(upto(chars)) do put(tokens,tab(many(chars)))
  9833. X  #
  9834. X  # My first time playing, I didn't put spaces between the numbers
  9835. X  # for the dice.  When you think about it, though, why bother?
  9836. X  # They can't be any longer than one digit each, so there's no
  9837. X  # ambiguity.  This bit of code makes the game a bit more idiot-
  9838. X  # proof.  -RLG (one of the idiots)
  9839. X  #
  9840. X  if *!tokens > 1 then line ?
  9841. X    {
  9842. X    tokens := []
  9843. X    if tab(upto(&digits)) then
  9844. X      {
  9845. X      while put(tokens, move(1)) do
  9846. X        tab(upto(&digits)) | break
  9847. X      put(tokens, integer(tab(0)))
  9848. X      }
  9849. X    }
  9850. X  return tokens
  9851. X  end
  9852. X
  9853. X#
  9854. X# TAKE AN INPUT STRING VIA GIVEN PROMPT
  9855. X#
  9856. Xprocedure input(prompt)       
  9857. X  writes(prompt)
  9858. X  return read()
  9859. X  end
  9860. SHAR_EOF
  9861. true || echo 'restore of yahtz.icn failed'
  9862. rm -f _shar_wnt_.tmp
  9863. fi
  9864. # ============= iolib.icn ==============
  9865. if test -f 'iolib.icn' -a X"$1" != X"-c"; then
  9866.     echo 'x - skipping iolib.icn (File already exists)'
  9867.     rm -f _shar_wnt_.tmp
  9868. else
  9869. > _shar_wnt_.tmp
  9870. echo 'x - extracting iolib.icn (Text)'
  9871. sed 's/^X//' << 'SHAR_EOF' > 'iolib.icn' &&
  9872. X########################################################################
  9873. X#    
  9874. X#    Name:    iolib.icn
  9875. X#    
  9876. X#    Title:    Icon termlib-type tools for MS-DOS and UNIX
  9877. X#    
  9878. X#    Author:    Richard L. Goerwitz (with help from Norman Azadian)
  9879. X#
  9880. X#    Version: 1.9
  9881. X#
  9882. X#########################################################################
  9883. X#
  9884. X#  The authors place this and future versions of iolib in the public
  9885. X#  domain.
  9886. X#
  9887. X#########################################################################
  9888. X#
  9889. X#  The following library represents a series of rough functional
  9890. X#  equivalents to the standard Unix low-level termcap routines.  It is
  9891. X#  not meant as an exact termlib clone.  Nor is it enhanced to take
  9892. X#  care of magic cookie terminals, terminals that use \D in their
  9893. X#  termcap entries, or archaic terminals that require padding.  This
  9894. X#  library is geared mainly for use with ANSI and VT-100 devices.
  9895. X#  Note that this file may, in most instances, be used in place of the
  9896. X#  older UNIX-only itlib.icn file.  It essentially replaces the DOS-
  9897. X#  only itlibdos routines.  For DOS users not familiar with the whole
  9898. X#  notion of generalized screen I/O, I've included extra documentation
  9899. X#  below.  Please read it.
  9900. X#
  9901. X#  The sole disadvantage of this over the old itlib routines is that
  9902. X#  iolib.icn cannot deal with archaic or arcane UNIX terminals and/or
  9903. X#  odd system file arrangements.  Note that because these routines
  9904. X#  ignore padding, they can (unlike itlib.icn) be run on the NeXT and
  9905. X#  other systems which fail to implement the -g option of the stty
  9906. X#  command.  Iolib.icn is also simpler and faster than itlib.icn.
  9907. X#
  9908. X#  I want to thank Norman Azadian for suggesting the whole idea of
  9909. X#  combining itlib.icn and itlibdos.icn into one distribution, for
  9910. SHAR_EOF
  9911. true || echo 'restore of iolib.icn failed'
  9912. fi
  9913. echo 'End of  part 1'
  9914. echo 'File iolib.icn is continued in part 2'
  9915. echo 2 > _shar_seq_.tmp
  9916. exit 0
  9917. -- 
  9918.  
  9919.    -Richard L. Goerwitz              goer%sophist@uchicago.bitnet
  9920.    goer@sophist.uchicago.edu         rutgers!oddjob!gide!sophist!goer
  9921.  
  9922. From icon-group-request@arizona.edu  Wed May 29 08:28:34 1991
  9923. Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Wed, 29 May 91 08:28:34 MST
  9924. Resent-From: icon-group-request@arizona.edu
  9925. Received: from Arizona.edu (Merlin.Telcom.Arizona.EDU) by optima.cs.arizona.edu (4.1/15)
  9926.     id AA25313; Wed, 29 May 91 08:28:31 MST
  9927. Received: from ucbvax.Berkeley.EDU by Arizona.edu with PMDF#10282; Wed, 29 May
  9928.  1991 08:27 MST
  9929. Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA09529; Wed, 29 May 91
  9930.  08:14:33 -0700
  9931. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  9932.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  9933.  usenet@ucbvax.Berkeley.EDU if you have questions)
  9934. Resent-Date: Wed, 29 May 1991 08:28 MST
  9935. Date: 29 May 91 14:57:12 GMT
  9936. From: cis.ohio-state.edu!zaphod.mps.ohio-state.edu!maverick.ksu.ksu.edu!ux1.cso.uiuc.edu!midway!ellis.uchicago.edu!goer@ucbvax.berkeley.edu
  9937.  (Richard L. Goerwitz)
  9938. Subject: RE: Holiday TidBit, part 3 of 3
  9939. Sender: icon-group-request@arizona.edu
  9940. Resent-To: icon-group@cs.arizona.edu
  9941. To: icon-group@arizona.edu
  9942. Resent-Message-Id: <178CE29C26C00433@Arizona.edu>
  9943. Message-Id: <1991May29.145712.4616@midway.uchicago.edu>
  9944. X-Envelope-To: icon-group@CS.Arizona.EDU
  9945. X-Vms-To: icon-group@Arizona.edu
  9946. Organization: University of Chicago
  9947. References: <50632F0EE04001B8@mis.mcw.edu>,
  9948.  <1991May29.040011.2409@midway.uchicago.edu>
  9949.  
  9950.  
  9951. ---- Cut Here and feed the following to sh ----
  9952. #!/bin/sh
  9953. # this is yahtz.03 (part 3 of a multipart archive)
  9954. # do not concatenate these parts, unpack them in order with /bin/sh
  9955. # file Makefile.dist continued
  9956. #
  9957. if test ! -r _shar_seq_.tmp; then
  9958.     echo 'Please unpack part 1 first!'
  9959.     exit 1
  9960. fi
  9961. (read Scheck
  9962.  if test "$Scheck" != 3; then
  9963.     echo Please unpack part "$Scheck" next!
  9964.     exit 1
  9965.  else
  9966.     exit 0
  9967.  fi
  9968. ) < _shar_seq_.tmp || exit 1
  9969. if test ! -f _shar_wnt_.tmp; then
  9970.     echo 'x - still skipping Makefile.dist'
  9971. else
  9972. echo 'x - continuing file Makefile.dist'
  9973. sed 's/^X//' << 'SHAR_EOF' >> 'Makefile.dist' &&
  9974. XPROGNAME = yahtz
  9975. X
  9976. X# You may need to change this.
  9977. XICONC = /usr/icon/v8/bin/icont
  9978. X
  9979. X# Don't change this, unless you happen to have a copy of itlib.icn
  9980. X# around, and know it works for your system.
  9981. XITLIB = iolib
  9982. X
  9983. X# Please edit these to reflect your local file structure & conventions.
  9984. XDESTDIR = /usr/local/games
  9985. XOWNER = root
  9986. XGROUP = root
  9987. X
  9988. X# Please don't change these.
  9989. XSRC = $(PROGNAME).icn $(ITLIB).icn
  9990. XSHELL = /bin/sh
  9991. X
  9992. X# I hope you won't have to use this.
  9993. X# DEBUGFLAG = -t
  9994. X
  9995. X$(PROGNAME): $(SRC)
  9996. X    $(ICONC) $(DEBUGFLAG) -o $(PROGNAME) $(SRC)
  9997. X
  9998. X# Pessimistic assumptions regarding the environment (in particular,
  9999. X# I don't assume you have the BSD "install" shell script).
  10000. Xinstall: $(PROGNAME)
  10001. X    test -d $(DESTDIR) || (mkdir $(DESTDIR) && chmod 755 $(DESTDIR))
  10002. X    cp $(PROGNAME) $(DESTDIR)/
  10003. X    chgrp $(GROUP) $(DESTDIR)/$(PROGNAME)
  10004. X    chown $(OWNER) $(DESTDIR)/$(PROGNAME)
  10005. X    @echo "\nInstallation done.\n"
  10006. X
  10007. Xclobber:
  10008. X    -rm -f *~ .u?
  10009. X    -rm -f $(PROGNAME)
  10010. SHAR_EOF
  10011. echo 'File Makefile.dist is complete' &&
  10012. true || echo 'restore of Makefile.dist failed'
  10013. rm -f _shar_wnt_.tmp
  10014. fi
  10015. # ============= README ==============
  10016. if test -f 'README' -a X"$1" != X"-c"; then
  10017.     echo 'x - skipping README (File already exists)'
  10018.     rm -f _shar_wnt_.tmp
  10019. else
  10020. > _shar_wnt_.tmp
  10021. echo 'x - extracting README (Text)'
  10022. sed 's/^X//' << 'SHAR_EOF' > 'README' &&
  10023. XThis hacked version of Chris Tenaglia's yahtzee program will run under
  10024. XUNIX, and under DOS as well.  To run it under DOS, you need
  10025. Xnnansi.sys.  Sorry, but the old ansi driver doesn't cut it.  Check out
  10026. Xthe iolib.icn file for directions on how to set your environment
  10027. Xvariables so that iolib can find your termcap file regardless of what
  10028. Xdirectory it's in, and so that you can tell iolib that you aren't
  10029. Xusing the old ansi.sys driver.
  10030. X
  10031. XUnix users, type "make" and relax.  If you have root privileges, type
  10032. X"make install," and relax.  If you're worried, check the default vari-
  10033. Xables in the makefile.  Oh, be sure to cp Makefile.dist makefile before
  10034. Xtrying to make anything.
  10035. X
  10036. XThis is a test version!!  In accordance with the author's wishes, I'd
  10037. Xlike to make it clear that I've altered all the screen I/O routines,
  10038. Xand have removed characters peculiar to VT terminals.  I've tried to
  10039. Xkeep intact the author's indentation and brace style.  Changes, where
  10040. Xpresent, have been indicated by my initials.
  10041. X
  10042. XOne more thing: There are lots of yahtzee programs out there, so I had
  10043. Xto rename the program.  I've seen yahtzee, yahtzee2, and yaht.  I guess
  10044. Xyahtz was all that was left ;-).
  10045. X
  10046. X-Richard Goerwitz.
  10047. SHAR_EOF
  10048. true || echo 'restore of README failed'
  10049. rm -f _shar_wnt_.tmp
  10050. fi
  10051. rm -f _shar_seq_.tmp
  10052. echo You have unpacked the last part
  10053. exit 0
  10054. -- 
  10055.  
  10056.    -Richard L. Goerwitz              goer%sophist@uchicago.bitnet
  10057.    goer@sophist.uchicago.edu         rutgers!oddjob!gide!sophist!goer
  10058.  
  10059. From icon-group-request@arizona.edu  Wed May 29 08:28:55 1991
  10060. Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Wed, 29 May 91 08:28:55 MST
  10061. Resent-From: icon-group-request@arizona.edu
  10062. Received: from Arizona.edu (Merlin.Telcom.Arizona.EDU) by optima.cs.arizona.edu (4.1/15)
  10063.     id AA25328; Wed, 29 May 91 08:28:52 MST
  10064. Received: from ucbvax.Berkeley.EDU by Arizona.edu with PMDF#10282; Wed, 29 May
  10065.  1991 08:28 MST
  10066. Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA09522; Wed, 29 May 91
  10067.  08:14:21 -0700
  10068. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  10069.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  10070.  usenet@ucbvax.Berkeley.EDU if you have questions)
  10071. Resent-Date: Wed, 29 May 1991 08:28 MST
  10072. Date: 29 May 91 14:56:34 GMT
  10073. From: cis.ohio-state.edu!zaphod.mps.ohio-state.edu!maverick.ksu.ksu.edu!ux1.cso.uiuc.edu!midway!ellis.uchicago.edu!goer@ucbvax.berkeley.edu
  10074.  (Richard L. Goerwitz)
  10075. Subject: RE: Holiday TidBit, part 2 of 3
  10076. Sender: icon-group-request@arizona.edu
  10077. Resent-To: icon-group@cs.arizona.edu
  10078. To: icon-group@arizona.edu
  10079. Resent-Message-Id: <179AEB4AB6C00434@Arizona.edu>
  10080. Message-Id: <1991May29.145634.4276@midway.uchicago.edu>
  10081. X-Envelope-To: icon-group@CS.Arizona.EDU
  10082. X-Vms-To: icon-group@Arizona.edu
  10083. Organization: University of Chicago
  10084. References: <50632F0EE04001B8@mis.mcw.edu>,
  10085.  <1991May29.040011.2409@midway.uchicago.edu>
  10086.  
  10087.  
  10088. ---- Cut Here and feed the following to sh ----
  10089. #!/bin/sh
  10090. # this is yahtz.02 (part 2 of a multipart archive)
  10091. # do not concatenate these parts, unpack them in order with /bin/sh
  10092. # file iolib.icn continued
  10093. #
  10094. if test ! -r _shar_seq_.tmp; then
  10095.     echo 'Please unpack part 1 first!'
  10096.     exit 1
  10097. fi
  10098. (read Scheck
  10099.  if test "$Scheck" != 2; then
  10100.     echo Please unpack part "$Scheck" next!
  10101.     exit 1
  10102.  else
  10103.     exit 0
  10104.  fi
  10105. ) < _shar_seq_.tmp || exit 1
  10106. if test ! -f _shar_wnt_.tmp; then
  10107.     echo 'x - still skipping iolib.icn'
  10108. else
  10109. echo 'x - continuing file iolib.icn'
  10110. sed 's/^X//' << 'SHAR_EOF' >> 'iolib.icn' &&
  10111. X#  suggesting things like letting drive specifications appear in DOS
  10112. X#  TERMCAP environment variables, and for finding several bugs (e.g.
  10113. X#  the lack of support for %2 and %3 in cm).  Although he is loathe
  10114. X#  to accept this credit, I think he deserves it.
  10115. X#
  10116. X#########################################################################
  10117. X#
  10118. X#  Contents:
  10119. X#
  10120. X#  setname(term)
  10121. X#    Use only if you wish to initialize itermlib for a terminal
  10122. X#  other than what your current environment specifies.  "Term" is the
  10123. X#  name of the termcap entry to use.  Normally this initialization is
  10124. X#  done automatically, and need not concern the user.
  10125. X#
  10126. X#  getval(id)
  10127. X#    Works something like tgetnum, tgetflag, and tgetstr.  In the
  10128. X#  spirit of Icon, all three have been collapsed into one routine.
  10129. X#  Integer valued caps are returned as integers, strings as strings,
  10130. X#  and flags as records (if a flag is set, then type(flag) will return
  10131. X#  "true").  Absence of a given capability is signalled by procedure
  10132. X#  failure.
  10133. X#
  10134. X#  igoto(cm,destcol,destline) - NB:  default 1 offset (*not* zero)!
  10135. X#    Analogous to tgoto.  "Cm" is the cursor movement command for
  10136. X#  the current terminal, as obtained via getval("cm").  Igoto()
  10137. X#  returns a string which, when output via iputs, will cause the
  10138. X#  cursor to move to column "destcol" and line "destline."  Column and
  10139. X#  line are always calculated using a *one* offset.  This is far more
  10140. X#  Iconish than the normal zero offset used by tgoto.  If you want to
  10141. X#  go to the first square on your screen, then include in your program
  10142. X#  "iputs(igoto(getval("cm"),1,1))."
  10143. X#
  10144. X#  iputs(cp,affcnt)
  10145. X#    Equivalent to tputs.  "Cp" is a string obtained via getval(),
  10146. X#  or, in the case of "cm," via igoto(getval("cm"),x,y).  Affcnt is a
  10147. X#  count of affected lines.  It is completely irrelevant for most
  10148. X#  modern terminals, and is supplied here merely for the sake of
  10149. X#  backward compatibility with itlib, a UNIX-only version of these
  10150. X#  routines (one which handles padding on archaic terminals).
  10151. X#
  10152. X##########################################################################
  10153. X#
  10154. X#  Notes for MS-DOS users:
  10155. X#
  10156. X#    There are two basic reasons for using the I/O routines
  10157. X#  contained in this package.  First, by using a set of generalized
  10158. X#  routines, your code will become much more readable.  Secondly, by
  10159. X#  using a high level interface, you can avoid the cardinal
  10160. X#  programming error of hard coding things like screen length and
  10161. X#  escape codes into your programs.
  10162. X#
  10163. X#    To use this collection of programs, you must do two things.
  10164. X#  First, you must add the line "device=ansi.sys" (or the name of some
  10165. X#  other driver, like zansi.sys, nansi.sys, or nnansi.sys [=new
  10166. X#  nansi.sys]) to your config.sys file.  Secondly, you must add two
  10167. X#  lines to your autoexec.bat file: 1) "set TERM=ansi-mono" and 2)
  10168. X#  "set TERMCAP=\location\termcap."  The purpose of setting the TERM
  10169. X#  variable is to tell this program what driver you are using.  If you
  10170. X#  have a color system, you could use "ansi-color" instead of
  10171. X#  "ansi-mono," although for compatibility with a broader range of
  10172. X#  users, it would perhaps be better to stick with mono.  The purpose
  10173. X#  of setting TERMCAP is to make it possible to determine where the
  10174. X#  termcap database file is located.  The termcap file (which should
  10175. X#  have been packed with this library as termcap.dos) is a short
  10176. X#  database of all the escape sequences used by the various terminal
  10177. X#  drivers.  Set TERMCAP so that it reflects the location of this file
  10178. X#  (which should be renamed as termcap, for the sake of consistency
  10179. X#  across UNIX and MS-DOS spectra).  If desired, you can also try
  10180. X#  using termcap2.dos.  Certain games work a lot better using this
  10181. X#  alternate file.  To try it out, rename it to termcap, and set
  10182. X#  the environment variable TERMCAP to its location.
  10183. X#
  10184. X#    Although the authors make no pretense of providing here a
  10185. X#  complete introduction to the format of the termcap database file,
  10186. X#  it will be useful, we believe, to explain a few basic facts about
  10187. X#  how to use this program in conjunction with it.  If, say, you want
  10188. X#  to clear the screen, add the line,
  10189. X#
  10190. X#    iputs(getval("cl"))
  10191. X#
  10192. X#  to your program.  The function iputs() outputs screen control
  10193. X#  sequences.  Getval retrieves a specific sequence from the termcap
  10194. X#  file.  The string "cl" is the symbol used in the termcap file to
  10195. X#  mark the code used to clear the screen.  By executing the
  10196. X#  expression "iputs(getval("cl"))," you are 1) looking up the "cl"
  10197. X#  (clear) code in the termcap database entry for your terminal, and
  10198. X#  the 2) outputting that sequence to the screen.
  10199. X#
  10200. X#    Some other useful termcap symbols are "ce" (clear to end of
  10201. X#  line), "ho" (go to the top left square on the screen), "so" (begin
  10202. X#  standout mode), and "se" (end standout mode).  To output a
  10203. X#  boldfaced string, str, to the screen, you would write -
  10204. X#
  10205. X#    iputs(getval("so"))
  10206. X#    writes(str)
  10207. X#    iputs(getval("se"))
  10208. X#
  10209. X#  You can also write "writes(getval("so") || str || getval("se")),
  10210. X#  but this would make reimplementation for UNIX terminals that
  10211. X#  require padding rather difficult.
  10212. X#
  10213. X#    It is also heartily to be recommended that MS-DOS programmers
  10214. X#  try not to assume that everyone will be using a 25-line screen.
  10215. X#  Most terminals are 24-line.  Some 43.  Some have variable window
  10216. X#  sizes.  If you want to put a status line on, say, the 2nd-to-last
  10217. X#  line of the screen, then determine what that line is by executing
  10218. X#  "getval("li")."  The termcap database holds not only string-valued
  10219. X#  sequences, but numeric ones as well.  The value of "li" tells you
  10220. X#  how many lines the terminal has (compare "co," which will tell you
  10221. X#  how many columns).  To go to the beginning of the second-to-last
  10222. X#  line on the screen, type in:
  10223. X#
  10224. X#    iputs(igoto(getval("cm"), 1, getval("li")-1))
  10225. X#
  10226. X#  The "cm" capability is a special capability, and needs to be output
  10227. X#  via igoto(cm,x,y), where cm is the sequence telling your computer
  10228. X#  to move the cursor to a specified spot, x is the column, and y is
  10229. X#  the row.  The expression "getval("li")-1" will return the number of
  10230. X#  the second-to-last line on your screen.
  10231. X#
  10232. X##########################################################################
  10233. X#
  10234. X#  Requires: UNIX or MS-DOS, co-expressions
  10235. X#
  10236. X#  See also: itlib.icn, iscreen.icn
  10237. X#
  10238. X##########################################################################
  10239. X
  10240. X
  10241. Xglobal tc_table, isDOS
  10242. Xrecord true()
  10243. X
  10244. X
  10245. Xprocedure check_features()
  10246. X
  10247. X    initial {
  10248. X
  10249. X    if find("UNIX",&features) then
  10250. X        isDOS := &null
  10251. X    else if find("MS-DOS", &features) then
  10252. X        isDOS := 1
  10253. X    else stop("check_features:  OS not (yet?) supported.")
  10254. X
  10255. X    find("expressi",&features) |
  10256. X        er("check_features","co-expressions not implemented - &$#!",1)
  10257. X    }
  10258. X
  10259. X    return
  10260. X
  10261. Xend
  10262. X
  10263. X
  10264. X
  10265. Xprocedure setname(name)
  10266. X
  10267. X    # Sets current terminal type to "name" and builds a new termcap
  10268. X    # capability database (residing in tc_table).  Fails if unable to
  10269. X    # find a termcap entry for terminal type "name."  If you want it
  10270. X    # to terminate with an error message under these circumstances,
  10271. X    # comment out "| fail" below, and uncomment the er() line.
  10272. X
  10273. X    #tc_table is global
  10274. X    
  10275. X    check_features()
  10276. X
  10277. X    tc_table := table()
  10278. X    tc_table := maketc_table(getentry(name)) | fail
  10279. X    # er("setname","no termcap entry found for "||name,3)
  10280. X    return "successfully reset for terminal " || name
  10281. X
  10282. Xend
  10283. X
  10284. X
  10285. X
  10286. Xprocedure getname()
  10287. X
  10288. X    # Getname() first checks to be sure we're running under DOS or
  10289. X    # UNIX, and, if so, tries to figure out what the current terminal
  10290. X    # type is, checking successively the value of the environment
  10291. X    # variable TERM, and then (under UNIX) the output of "tset -".
  10292. X    # Terminates with an error message if the terminal type cannot be
  10293. X    # ascertained.  DOS defaults to "mono."
  10294. X
  10295. X    local term, tset_output
  10296. X
  10297. X    check_features()
  10298. X
  10299. X    if \isDOS then {
  10300. X        term := getenv("TERM") | "mono"
  10301. X    }
  10302. X    else {
  10303. X    if not (term := getenv("TERM")) then {
  10304. X        tset_output := open("/bin/tset -","pr") |
  10305. X        er("getname","can't find tset command",1)
  10306. X        term := !tset_output
  10307. X        close(tset_output)
  10308. X    }
  10309. X    }
  10310. X
  10311. X    return \term |
  10312. X    er("getname","can't seem to determine your terminal type",1)
  10313. X
  10314. Xend
  10315. X
  10316. X
  10317. X
  10318. Xprocedure er(func,msg,errnum)
  10319. X
  10320. X    # short error processing utility
  10321. X    write(&errout,func,":  ",msg)
  10322. X    exit(errnum)
  10323. X
  10324. Xend
  10325. X
  10326. X
  10327. X
  10328. Xprocedure getentry(name, termcap_string)
  10329. X
  10330. X    # "Name" designates the current terminal type.  Getentry() scans
  10331. X    # the current environment for the variable TERMCAP.  If the
  10332. X    # TERMCAP string represents a termcap entry for a terminal of type
  10333. X    # "name," then getentry() returns the TERMCAP string.  Otherwise,
  10334. X    # getentry() will check to see if TERMCAP is a file name.  If so,
  10335. X    # getentry() will scan that file for an entry corresponding to
  10336. X    # "name."  If the TERMCAP string does not designate a filename,
  10337. X    # getentry() will scan the termcap file for the correct entry.
  10338. X    # Whatever the input file, if an entry for terminal "name" is
  10339. X    # found, getentry() returns that entry.  Otherwise, getentry()
  10340. X    # fails.
  10341. X
  10342. X    local isFILE, f, getline, line, nm, ent1, ent2
  10343. X    static slash, termcap_names
  10344. X    initial {
  10345. X    if \isDOS then {
  10346. X        slash := "\\"
  10347. X        termcap_names := ["termcap","termcap.dos","termcap2.dos"]
  10348. X    }
  10349. X    else {
  10350. X        slash := "/"
  10351. X        termcap_names := ["/etc/termcap"]
  10352. X    }
  10353. X    }
  10354. X
  10355. X
  10356. X    # You can force getentry() to use a specific termcap file by cal-
  10357. X    # ling it with a second argument - the name of the termcap file
  10358. X    # to use instead of the regular one, or the one specified in the
  10359. X    # termcap environment variable.
  10360. X    /termcap_string := getenv("TERMCAP")
  10361. X
  10362. X    if \isDOS then {
  10363. X    if \termcap_string then {
  10364. X        if termcap_string ? (
  10365. X         not ((tab(any(&letters)), match(":")) | match(slash)),
  10366. X         pos(1) | tab(find("|")+1), =name)
  10367. X        then return termcap_string
  10368. X        else isFILE := 1
  10369. X    }
  10370. X    }
  10371. X    else {
  10372. X    if \termcap_string then {
  10373. X        if termcap_string ? (
  10374. X            not match(slash), pos(1) | tab(find("|")+1), =name)
  10375. X        then return termcap_string
  10376. X        else isFILE := 1
  10377. X    }
  10378. X    }
  10379. X
  10380. X    # The logic here probably isn't clear.  The idea is to try to use
  10381. X    # the termcap environment variable successively as 1) a termcap en-
  10382. X    # try and then 2) as a termcap file.  If neither works, 3) go to
  10383. X    # the /etc/termcap file.  The else clause here does 2 and, if ne-
  10384. X    # cessary, 3.  The "\termcap_string ? (not match..." expression
  10385. X    # handles 1.
  10386. X
  10387. X    if \isFILE            # if find(slash, \termcap_string)
  10388. X    then f := open(termcap_string)
  10389. X    /f := open(!termcap_names) |
  10390. X    er("getentry","I can't access your termcap file.  Read iolib.icn.",1)
  10391. X    
  10392. X    getline := create read_file(f)
  10393. X    
  10394. X    while line := @getline do {
  10395. X    if line ? (pos(1) | tab(find("|")+1), =name, any(':|')) then {
  10396. X        entry := ""
  10397. X        while (\line | @getline) ? {
  10398. X        if entry ||:= 1(tab(find(":")+1), pos(0))
  10399. X        then {
  10400. X            close(f)
  10401. X            # if entry ends in tc= then add in the named tc entry
  10402. X            entry ?:= tab(find("tc=")) ||
  10403. X            # recursively fetch the new termcap entry
  10404. X            (move(3), getentry(tab(find(":"))) ?
  10405. X             # remove the name field from the new entry
  10406. X             (tab(find(":")+1), tab(0)))
  10407. X            return entry
  10408. X        }
  10409. X        else {
  10410. X            \line := &null # must precede the next line
  10411. X            entry ||:= trim(trim(tab(0),'\\'),':')
  10412. X        }
  10413. X        }
  10414. X    }
  10415. X    }
  10416. X
  10417. X    close(f)
  10418. X    er("getentry","can't find and/or process your termcap entry",3)
  10419. Xend
  10420. X
  10421. X
  10422. X
  10423. Xprocedure read_file(f)
  10424. X
  10425. X    # Suspends all non #-initial lines in the file f.
  10426. X    # Removes leading tabs and spaces from lines before suspending
  10427. X    # them.
  10428. X
  10429. X    local line
  10430. X
  10431. X    \f | er("read_tcap_file","no valid termcap file found",3)
  10432. X    while line := read(f) do {
  10433. X    match("#",line) & next
  10434. X    line ?:= (tab(many('\t ')) | &null, tab(0))
  10435. X    suspend line
  10436. X    }
  10437. X
  10438. X    fail
  10439. X
  10440. Xend
  10441. X
  10442. X
  10443. X
  10444. Xprocedure maketc_table(entry)
  10445. X
  10446. X    # Maketc_table(s) (where s is a valid termcap entry for some
  10447. X    # terminal-type): Returns a table in which the keys are termcap
  10448. X    # capability designators, and the values are the entries in
  10449. X    # "entry" for those designators.
  10450. X
  10451. X    local k, v
  10452. X
  10453. X    /entry & er("maketc_table","no entry given",8)
  10454. X    if entry[-1] ~== ":" then entry ||:= ":"
  10455. X    
  10456. X    /tc_table := table()
  10457. X
  10458. X    entry ? {
  10459. X
  10460. X    tab(find(":")+1)    # tab past initial (name) field
  10461. X
  10462. X    while tab((find(":")+1) \ 1) ? {
  10463. X        &subject == "" & next
  10464. X        if k := 1(move(2), ="=") then {
  10465. X        # Get rid of null padding information.  Iolib can't
  10466. X        # handle it (unlike itlib.icn).  Leave star in.  It
  10467. X        # indicates a real dinosaur terminal, and will later
  10468. X        # prompt an abort.
  10469. X        str := ="*" | ""; tab(many(&digits))
  10470. X        tc_table[k] := Decode(str || tab(find(":")))
  10471. X        }
  10472. X        else if k := 1(move(2), ="#")
  10473. X        then tc_table[k] := integer(tab(find(":")))
  10474. X        else if k := 1(tab(find(":")), pos(-1))
  10475. X        then tc_table[k] := true()
  10476. X        else er("maketc_table", "your termcap file has a bad entry",3)
  10477. X    }
  10478. X    }
  10479. X
  10480. X    return tc_table
  10481. X
  10482. Xend
  10483. X
  10484. X
  10485. X
  10486. Xprocedure getval(id)
  10487. X
  10488. X    /tc_table := maketc_table(getentry(getname())) |
  10489. X    er("getval","can't make a table for your terminal",4)
  10490. X
  10491. X    return \tc_table[id] | fail
  10492. X    # er("getval","the current terminal doesn't support "||id,7)
  10493. X
  10494. Xend
  10495. X
  10496. X
  10497. X
  10498. Xprocedure Decode(s)
  10499. X
  10500. X    # Does things like turn ^ plus a letter into a genuine control
  10501. X    # character.
  10502. X
  10503. X    new_s := ""
  10504. X
  10505. X    s ? {
  10506. X
  10507. X    while new_s ||:= tab(upto('\\^')) do {
  10508. X        chr := move(1)
  10509. X        if chr == "\\" then {
  10510. X        new_s ||:= {
  10511. X            case chr2 := move(1) of {
  10512. X            "\\" : "\\"
  10513. X            "^"  : "^"
  10514. X            "E"  : "\e"
  10515. X            "b"  : "\b"
  10516. X            "f"  : "\f"
  10517. X            "n"  : "\n"
  10518. X            "r"  : "\r"
  10519. X            "t"  : "\t"
  10520. X            default : {
  10521. X                if any(&digits,chr2) then {
  10522. X                char(integer("8r"||chr2||move(2 to 0 by -1))) |
  10523. X                    er("Decode","bad termcap entry",3)
  10524. X                }
  10525. X               else chr2
  10526. X            }
  10527. X            }
  10528. X        }
  10529. X        }
  10530. X        else new_s ||:= char(ord(map(move(1),&lcase,&ucase)) - 64)
  10531. X    }
  10532. X    new_s ||:= tab(0)
  10533. X    }
  10534. X
  10535. X    return new_s
  10536. X
  10537. Xend
  10538. X
  10539. X
  10540. X
  10541. Xprocedure igoto(cm,col,line)
  10542. X
  10543. X    local colline, range, increment, padding, str, outstr, chr, x, y
  10544. X
  10545. X    if col > (tc_table["co"]) | line > (tc_table["li"]) then {
  10546. X    colline := string(\col) || "," || string(\line) | string(\col|line)
  10547. X    range := "(" || tc_table["co"]-1 || "," || tc_table["li"]-1 || ")"
  10548. X    er("igoto",colline || " out of range " || (\range|""),9)
  10549. X    } 
  10550. X
  10551. X    # Use the Iconish 1;1 upper left corner & not the C-ish 0 offsets
  10552. X    increment := -1
  10553. X    outstr := ""
  10554. X    
  10555. X    cm ? {
  10556. X    while outstr ||:= tab(find("%")) do {
  10557. X        tab(match("%"))
  10558. X        if padding := integer(tab(any('23')))
  10559. X        then chr := (="d" | "d")
  10560. X        else chr := move(1)
  10561. X        if case \chr of {
  10562. X        "." :  outstr ||:= char(line + increment)
  10563. X        "+" :  outstr ||:= char(line + ord(move(1)) + increment)
  10564. X        "d" :  {
  10565. X            str := string(line + increment)
  10566. X            outstr ||:= right(str, \padding, "0") | str
  10567. X        }
  10568. X        }
  10569. X        then line :=: col
  10570. X        else {
  10571. X        case chr of {
  10572. X            "n" :  line := ixor(line,96) & col := ixor(col,96)
  10573. X            "i" :  increment := 0
  10574. X            "r" :  line :=: col
  10575. X            "%" :  outstr ||:= "%"
  10576. X            "B" :  line := ior(ishift(line / 10, 4), line % 10)
  10577. X            ">" :  {
  10578. X            x := move(1); y := move(1)
  10579. X            line > ord(x) & line +:= ord(y)
  10580. X            &null
  10581. X            }
  10582. X        } | er("goto","bad termcap entry",5)
  10583. X        }
  10584. X    }
  10585. X    return outstr || tab(0)
  10586. X    }
  10587. X
  10588. Xend
  10589. X
  10590. X
  10591. X
  10592. Xprocedure iputs(cp, affcnt)
  10593. X
  10594. X    # Writes cp to the screen.  Use this instead of writes() for
  10595. X    # compatibility with itlib (a UNIX-only version which can handle
  10596. X    # albeit inelegantly) terminals that need padding.
  10597. X
  10598. X    static num_chars
  10599. X    initial num_chars := &digits ++ '.'
  10600. X
  10601. X    type(cp) == "string" |
  10602. X    er("iputs","you can't iputs() a non-string value!",10)
  10603. X
  10604. X    cp ? {
  10605. X    if tab(many(num_chars)) & ="*" then
  10606. X        stop("iputs:  iolib can't use terminals that require padding.")
  10607. X    writes(tab(0))
  10608. X    }
  10609. X
  10610. X    return
  10611. X
  10612. Xend
  10613. SHAR_EOF
  10614. echo 'File iolib.icn is complete' &&
  10615. true || echo 'restore of iolib.icn failed'
  10616. rm -f _shar_wnt_.tmp
  10617. fi
  10618. # ============= termcap.dos ==============
  10619. if test -f 'termcap.dos' -a X"$1" != X"-c"; then
  10620.     echo 'x - skipping termcap.dos (File already exists)'
  10621.     rm -f _shar_wnt_.tmp
  10622. else
  10623. > _shar_wnt_.tmp
  10624. echo 'x - extracting termcap.dos (Text)'
  10625. sed 's/^X//' << 'SHAR_EOF' > 'termcap.dos' &&
  10626. Xansi|color|ansi-color|ibm|ibmpc|ANSI.SYS color:\
  10627. X    :co#80:li#25:bs:pt:bl=^G:le=^H:do=^J:\
  10628. X    :cl=\E[H\E[2J:ce=\E[K:\
  10629. X    :ho=\E[H:cm=\E[%i%d;%dH:\
  10630. X    :up=\E[A:do=\E[B:le=\E[C:ri=\E[D:nd=\E[C:\
  10631. X    :ti=\E[0;44m:te=\E[0m:\
  10632. X    :so=\E[1;35;44m:se=\E[0;44m:\
  10633. X    :us=\E[1;31;44m:ue=\E[0;44m:\
  10634. X    :mb=\E[5m:md=\E[1m:me=\E[0;44m:
  10635. Xmono|ansi-mono|ANSI.SYS:\
  10636. X    :co#80:li#25:bs:pt:bl=^G:le=^H:do=^J:\
  10637. X    :cl=\E[H\E[2J:ce=\E[K:\
  10638. X    :ho=\E[H:cm=\E[%i%d;%dH:\
  10639. X    :up=\E[A:do=\E[B:le=\E[C:ri=\E[D:nd=\E[C:\
  10640. X    :so=\E[7m:se=\E[m:us=\E[4m:ue=\E[m:\
  10641. X    :mb=\E[5m:md=\E[1m:me=\E[m:
  10642. Xnnansi-mono|NNANSI.SYS:\
  10643. X    :co#80:li#25:bs:pt:bl=^G:le=^H:do=^J:\
  10644. X    :cl=\E[2J:cd=\E[J:ce=\E[K:\
  10645. X    :ho=\E[H:cm=\E[%i%d;%dH:\
  10646. X    :up=\E[A:do=\E[B:le=\E[C:ri=\E[D:nd=\E[C:\
  10647. X    :so=\E[7m:se=\E[2m:\
  10648. X    :us=\E[4m:ue=\E[24m:\
  10649. X    :mb=\E[5m:md=\E[1m:mh=\E[2m:mr=\E[7m:me=\E[m:\
  10650. X    :al=\E[L:dl=\E[M:ic=\E[@:dc=\E[P:
  10651. Xnnansi|nnansi-color|NNANSI.SYS color:\
  10652. X    :co#80:li#25:bs:pt:bl=^G:le=^H:do=^J:\
  10653. X    :cl=\E[2J:cd=\E[J:ce=\E[K:\
  10654. X    :ho=\E[H:cm=\E[%i%d;%dH:\
  10655. X    :up=\E[A:do=\E[B:le=\E[C:ri=\E[D:nd=\E[C:\
  10656. X    :ti=\E[0;44m:te=\E[0m:\
  10657. X    :so=\E[1;35;44m:se=\E[2;37m:\
  10658. X    :us=\E[4m:ue=\E[24m:\
  10659. X    :mb=\E[5m:md=\E[1m:mh=\E[2m:mr=\E[7m:me=\E[0;44m:\
  10660. X    :al=\E[L:dl=\E[M:ic=\E[@:dc=\E[P:
  10661. Xnansi-mono|zansi-mono|N/ZANSI.SYS:\
  10662. X    :co#80:li#25:bs:pt:bl=^G:le=^H:do=^J:\
  10663. X    :cl=\E[2J:ce=\E[K:\
  10664. X    :ho=\E[H:cm=\E[%i%d;%dH:\
  10665. X    :up=\E[A:do=\E[B:le=\E[C:ri=\E[D:nd=\E[C:\
  10666. X    :ti=\E[0m:te=\E[0m:\
  10667. X    :so=\E[7;35m:se=\E[0m:\
  10668. X    :us=\E[1;31m:ue=\E[0m:\
  10669. X    :mb=\E[5m:md=\E[1m:mr=\E[7m:me=\E[m:\
  10670. X    :al=\E[L:dl=\E[M:ic=\E[@:dc=\E[P:
  10671. Xnansi|zansi|nansi-color|zansi-color|N/ZANSI.SYS color:\
  10672. X    :co#80:li#25:bs:pt:bl=^G:le=^H:do=^J:\
  10673. X    :cl=\E[2J:ce=\E[K:\
  10674. X    :ho=\E[H:cm=\E[%i%d;%dH:\
  10675. X    :up=\E[A:do=\E[B:le=\E[C:ri=\E[D:nd=\E[C:\
  10676. X    :ti=\E[0;44m:te=\E[0m:\
  10677. X    :so=\E[1;35;44m:se=\E[0;44m:\
  10678. X    :us=\E[1;31;44m:ue=\E[0;44m:\
  10679. X    :mb=\E[5m:md=\E[1m:mr=\E[7m:me=\E[0;44m:\
  10680. X    :al=\E[L:dl=\E[M:ic=\E[@:dc=\E[P:
  10681. XAX|ANSI X3.64|full ANSI X3.64 (1977) standard:\
  10682. X    :co#80:li#25:bs:pt:am:mi:bl=^G:le=^H:\
  10683. X    :cl=\E[2J:ce=\E[K:cd=\E[J:\
  10684. X    :ho=\E[H:cm=\E[%i%d;%dH:cs=\E[%i%d;%dr:\
  10685. X    :up=\E[A:do=\E[B:le=\E[C:ri=\E[D:nd=\E[C:\
  10686. X    :UP=\E[%dA:DO=\E[%dB:LE=\E[%dC:RI=\E[%dD:\
  10687. X    :so=\E[7m:se=\E[m:us=\E[4m:ue=\E[m:\
  10688. X    :mb=\E[5m:md=\E[1m:mr=\E[7m:me=\E[m:as=^N:ae=^O:\
  10689. X    :ku=\E[A:kd=\E[B:kl=\E[C:kr=\E[D:kb=^H:\
  10690. X    :kn#4:k1=\EOP:k2=\EOQ:k3=\EOR:k4=\EOS:\
  10691. X    :im=\E[4h:ei=\E[4l:al=\E[L:dl=\E[M:ic=\E[@:dc=\E[P:sf=\ED:sr=\EM:
  10692. SHAR_EOF
  10693. true || echo 'restore of termcap.dos failed'
  10694. rm -f _shar_wnt_.tmp
  10695. fi
  10696. # ============= Makefile.dist ==============
  10697. if test -f 'Makefile.dist' -a X"$1" != X"-c"; then
  10698.     echo 'x - skipping Makefile.dist (File already exists)'
  10699.     rm -f _shar_wnt_.tmp
  10700. else
  10701. > _shar_wnt_.tmp
  10702. echo 'x - extracting Makefile.dist (Text)'
  10703. sed 's/^X//' << 'SHAR_EOF' > 'Makefile.dist' &&
  10704. X# Don't change this unless you're sure of what you're doing.
  10705. SHAR_EOF
  10706. true || echo 'restore of Makefile.dist failed'
  10707. fi
  10708. echo 'End of  part 2'
  10709. echo 'File Makefile.dist is continued in part 3'
  10710. echo 3 > _shar_seq_.tmp
  10711. exit 0
  10712. -- 
  10713.  
  10714.    -Richard L. Goerwitz              goer%sophist@uchicago.bitnet
  10715.    goer@sophist.uchicago.edu         rutgers!oddjob!gide!sophist!goer
  10716.  
  10717. From goer%sophist@gargoyle.uchicago.edu  Thu May 30 20:12:40 1991
  10718. Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Thu, 30 May 91 20:12:40 MST
  10719. Received: from gargoyle.uchicago.edu by optima.cs.arizona.edu (4.1/15)
  10720.     id AA19642; Thu, 30 May 91 20:12:33 MST
  10721. Received: by gargoyle.uchicago.edu from sophist (sophist.uchicago.edu) (4.0/1.14)
  10722.     id AA03009; Thu, 30 May 91 22:12:31 CDT
  10723. Return-Path: <goer@sophist.uchicago.edu>
  10724. Received:  by sophist (4.1/UofC3.1X)
  10725.     id AA03062; Thu, 30 May 91 22:13:41 CDT
  10726. Date: Thu, 30 May 91 22:13:41 CDT
  10727. From: Richard Goerwitz <goer%sophist@gargoyle.uchicago.edu>
  10728. Message-Id: <9105310313.AA03062@sophist>
  10729. To: icon-group@cs.arizona.edu
  10730. Subject: utilities
  10731.  
  10732. I've got a fairly large library of utilities for things like rewrapping
  10733. text, excizing sentences from ASCII files, comma-izing ints and reals,
  10734. outputting non-byte-width int/chars, stripping chars from strings, an
  10735. extended snapshot routine, and other stuff.  I've posted bits here and
  10736. there, but I'd like to disseminate this material more widely, and in a
  10737. more complete form.  I'm interested in helping anyone out who thinks
  10738. he or she might be helped by them.  I'm really interested (deep down),
  10739. though, in rooting up bugs.
  10740.  
  10741. If anyone wants these routines, please drop me a line.  Promise me you
  10742. will let me know about any changes that you make or about any bugs you
  10743. find.
  10744.  
  10745. -Richard (goer@sophist.uchicago.edu)
  10746.  
  10747. From R.J.Hare@edinburgh.ac.uk  Fri May 31 04:21:37 1991
  10748. Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Fri, 31 May 91 04:21:37 MST
  10749. Received: from Arizona.edu (Merlin.Telcom.Arizona.EDU) by optima.cs.arizona.edu (4.1/15)
  10750.     id AA09625; Fri, 31 May 91 04:21:29 MST
  10751. Received: from UKACRL.BITNET (MAILER@UKACRL) by Arizona.edu with PMDF#10282;
  10752.  Fri, 31 May 1991 04:21 MST
  10753. Received: from RL.IB by UKACRL.BITNET (Mailer R2.07) with BSMTP id 2445; Fri,
  10754.  31 May 91 11:22:45 BST
  10755. Received: from RL.IB by UK.AC.RL.IB (Mailer R2.07) with BSMTP id 0929; Fri, 31
  10756.  May 91 11:22:45 BST
  10757. Date: 31 May 91  11:23:12 bst
  10758. From: R.J.Hare@edinburgh.ac.uk
  10759. Subject: Records
  10760. To: icon-group@cs.arizona.edu
  10761. Message-Id: <31 May 91  11:23:12 bst  060024@EMAS-A>
  10762. X-Envelope-To: icon-group@cs.arizona.edu
  10763. Via:        UK.AC.ED.EMAS-A; 31 MAY 91 11:22:43 BST
  10764.  
  10765. Thanks to all those who answered my query about records.
  10766.  
  10767. Next question - I am using records as the basis for a simple database
  10768. program. Given that the program will be written in a tight enough way to
  10769. ensure that it won't be possible to write a list with more elements than
  10770. there are in a database entry, what is the advantage of using a record
  10771. to store a database entry as opposed to a list?
  10772.  
  10773. I've got my own ideas on this, but I'd like to canvass a few other
  10774. opinions.
  10775.  
  10776.  
  10777. Thanks.
  10778.  
  10779. Roger Hare.
  10780.  
  10781. From cargo@cherry.cray.com  Fri May 31 06:13:47 1991
  10782. Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Fri, 31 May 91 06:13:47 MST
  10783. Received: from timbuk (timbuk.cray.com) by optima.cs.arizona.edu (4.1/15)
  10784.     id AA11503; Fri, 31 May 91 06:13:44 MST
  10785. Received: from cherry04.cray.com by timbuk (4.1/CRI-MX 1.6e)
  10786.     id AA13694; Fri, 31 May 91 08:13:40 CDT
  10787. Received: by cherry04.cray.com
  10788.     id AA03855; 4.1/CRI-5.6; Fri, 31 May 91 08:13:31 CDT
  10789. Date: Fri, 31 May 91 08:13:31 CDT
  10790. From: cargo@cherry.cray.com (David S. Cargo)
  10791. Message-Id: <9105311313.AA03855@cherry04.cray.com>
  10792. To: icon-group@cs.arizona.edu
  10793. Subject: Records
  10794.  
  10795. I use records instead of lists in cases where I want a more
  10796. mnemonic way of accessing structures.  In a program I'm working
  10797. on right now, I can tell what structures are compatible because
  10798. I have named the fields the same names in the same order.  It
  10799. would not be possible to decide that so easily if the lists were
  10800. simply the same size.
  10801.  
  10802. Likewise, the fact that records are their own types allows me to
  10803. base actions based on the type of a particular parameter.  I have
  10804. exploited these factors together in the following fragment of code.
  10805. Because the name of the record type is also the name of the record
  10806. constructor for that type, the following routine returns a value
  10807. whose type is the same as the type passed to it without knowing
  10808. what that type is.  As long as the type is a record with at least
  10809. one field named entries, this fragment will work.
  10810.  
  10811. ## entry_name -- return the entry portion of an absolute path
  10812. procedure entry_name(a_path)
  10813. #   Uses globals
  10814. #       verified   (record constructor)
  10815. #       unverified (record constructor)
  10816. #   record verified(entries)
  10817. #   record unverified(entries)
  10818.     if *a_path.entries > 1
  10819.     then return type(a_path)(a_path.entries[-1])
  10820. end
  10821.  
  10822. A lot of the code I write takes advantage of the type information
  10823. carried along by record values.
  10824.  
  10825. David S. Cargo (cargo@cray.com)
  10826.  
  10827. From TENAGLIA@mis.mcw.edu  Fri May 31 06:55:19 1991
  10828. Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Fri, 31 May 91 06:55:19 MST
  10829. Received: from MIS1.MIS.MCW.EDU by optima.cs.arizona.edu (4.1/15)
  10830.     id AA12408; Fri, 31 May 91 06:55:12 MST
  10831. Received: from mis.mcw.edu (MCWMI3) by MIS1.MIS.MCW.EDU with PMDF#10477; Fri,
  10832.  31 May 1991 08:53 CST
  10833. Date: Fri, 31 May 1991 08:52 CST
  10834. From: Chris Tenaglia - 257-8765 <TENAGLIA@mis.mcw.edu>
  10835. Subject: Re: database
  10836. To: icon-group@cs.arizona.edu
  10837. Message-Id: <AD537D3440400955@mis.mcw.edu>
  10838. X-Organization: Medical College of Wisconsin MIS Department (Milwaukee, WI)
  10839. X-Vms-To: IN%"icon-group@cs.arizona.edu"
  10840.  
  10841. Regarding:    Records
  10842.  
  10843. > Thanks to all those who answered my query about records.
  10844.  
  10845. > Next question - I am using records as the basis for a simple database
  10846. > program. Given that the program will be written in a tight enough way to
  10847. > ensure that it won't be possible to write a list with more elements than
  10848. > there are in a database entry, what is the advantage of using a record
  10849. > to store a database entry as opposed to a list?
  10850. > I've got my own ideas on this, but I'd like to canvass a few other
  10851. > opinions.
  10852. > Thanks.
  10853. > Roger Hare.
  10854.  
  10855. Perhaps I don't understand the true use of records, or the true meaning of
  10856. database. I wrote a useful little database. I call it 'AtterCop'. It's
  10857. nomenclature and early evolution is too bizaare for this message. In it's
  10858. first ICON manifestation it used lists. Lists worked well. If you wanted
  10859. the data sorted, I had a menu entry that would ask for which fields. It
  10860. was slow especially on inquiry serially scanning through the list elements.
  10861. Deletion was slower. I moved all the elements back one to cover up the
  10862. unwanted record and popped off the last element (duplicate). It permitted
  10863. multiple occurences of the key, and printed pretty fast.
  10864.  
  10865. Records? I always thought of records as ICONs method for creating user
  10866. defined datatypes. I once thought it was a database component, but after
  10867. a few experiments, it's true purpose became clear.
  10868.  
  10869. Tables? After a database contains 1000 or so items, lists become very slow.
  10870. So I rewrote 'AtterCop' using icon tables instead. The database key is a
  10871. concatenated string from the key fields, is the index to the table. The
  10872. entire record (string with fields delimited including the key ones) is a
  10873. list element to that table entry. Thus the database is actually a table of
  10874. lists. This still allows multiple occurences to a key, and lookup, and
  10875. maintenance functions are handled quite speedily. Also, no explicit sort
  10876. is needed. Sorting is done optionally at print or view time. Speed of loading,
  10877. saving, printing seems to take a little longer though. See example.
  10878.  
  10879. Writing out the database as a list     Writing it as a table of lists
  10880.     out := open(database,"w")              out := open(database,"w")
  10881.     every write(out,!db)                   every lookup := key(db) do
  10882.                                              every write(out,!db[lookup])
  10883.     close(out)
  10884.  
  10885. Chris Tenaglia (System Manager) | Medical College of Wisconsin
  10886. 8701 W. Watertown Plank Rd.     | Milwaukee, WI 53226
  10887. (414)257-8765                   | tenaglia@mis.mcw.edu, mcwmis!tenaglia
  10888.  
  10889. From sboisen@bbn.com  Fri May 31 07:38:41 1991
  10890. Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Fri, 31 May 91 07:38:41 MST
  10891. Message-Id: <9105311438.AA13650@optima.cs.arizona.edu>
  10892. Received: from REGULUS.BBN.COM by optima.cs.arizona.edu (4.1/15)
  10893.     id AA13650; Fri, 31 May 91 07:38:37 MST
  10894. To: icon-group@cs.arizona.edu
  10895. Subject: GNU Emacs utility for short on-line summary of Icon syntax
  10896. From: Sean Boisen <sboisen@bbn.com>
  10897. Sender: sboisen@bbn.com
  10898. Reply-To: sboisen@bbn.com
  10899. Date: Fri, 31 May 91 10:28:15 EDT
  10900.  
  10901. Appended below (in shar format) is a simple GNU Emacs utility that
  10902. lets you check the syntax of Icon expressions: for example, while
  10903. editing a program, i may forget the arguments to "any". I can then
  10904. call the Emacs function describe-icon-symbol, which displays
  10905.  
  10906.     any(cset,string,i,j)
  10907.  
  10908. Much easier than reaching for the manual!
  10909.  
  10910. Richard Goerwitz encouraged me to post it here: no guarantees, but
  10911. enjoy. I'd be particularly interested if somebody has more complete
  10912. descriptions (mine are only a single line, not always enough to keep
  10913. me from reaching for the manual).
  10914.  
  10915. ........................................
  10916. Sean Boisen -- sboisen@bbn.com
  10917. BBN Systems and Technologies, Cambridge MA
  10918.  
  10919.  
  10920. ------------------------------ snip snip ------------------------------
  10921. #! /bin/sh
  10922. # To extract, remove mail header lines and type "sh filename"
  10923. echo x - icon-describe.text
  10924. sed -e 's/^X//' > icon-describe.text << '!FaR!OuT!'
  10925. XThis is a quick syntax helper for Icon users that work with GNU Emacs.
  10926. XThe idea is a simple one: while creating a program, say, you're unsure
  10927. Xabout the arguments or their orders for push(). With icon-describe, you
  10928. Xsimple execute the function "describe-icon-symbol" with point
  10929. Xsomewhere around the word push, and the following information
  10930. Xis displayed in the mini-buffer:
  10931. X
  10932. Xpush(list,x)
  10933. X
  10934. XThis works with procedures, infix/prefix operators, control
  10935. Xstructures/reserved words, and keywords. Note that you get notified if
  10936. Xsomething isn't in the documentation file, so you can also use it to
  10937. Xcheck whether you've got the right symbol name or not (but you'd have
  10938. Xto actually go look at the file to see what the _right_ one is).
  10939. X
  10940. X
  10941. XCaveats:
  10942. X
  10943. XSee your Emacs manual for how to load this automatically when you
  10944. Xvisit .icn files (look at auto-mode-alist and icon-mode-hook, assuming
  10945. Xyou're using an icon-mode).
  10946. X
  10947. Xdescribe-icon-symbol is not initially bound to a key, but you'll
  10948. Xprobably want to do so.
  10949. X
  10950. XThe format of the documentation file is one to a line: this is nice
  10951. Xbecause it can be displayed in the minibuffer instead of a pop-up
  10952. Xwhich then has to be gotten rid of. It's not so nice in that it limits
  10953. Xthe amount of information pretty severely. If somebody wants to
  10954. Xprovide a larger documentation file i might provide a pop-up version
  10955. X(or some hybrid): i'm too lazy to do all the typing, for one thing!
  10956. XThere's also an uneven mix of bare syntax description with some
  10957. Xdiscussion of what (especially prefix) operators do. A few keywords
  10958. Xhave no description because they're newer than the Icon book, and i
  10959. Xdidn't have a description handy. Please contribute to this doc file if
  10960. Xyou can!
  10961. X
  10962. XThe function which determines the symbol at point isn't perfect
  10963. X(surprise surprise!). In particular it depends on the syntax tables to
  10964. Xdetermine what punctuation is, so if your syntax tables aren't right,
  10965. Xthis won't be either. I'm open to suggestions for better algorithms.
  10966. XThe current version has a preference for looking backward if not
  10967. Xactually on part of a symbol: this seemed more useful for those cases
  10968. Xwhere you become hesitant about the arguments to a function just after
  10969. Xtyping it.
  10970. X
  10971. XWhile the usual lack of warranty and support applies, i'd still like
  10972. Xto hear if there are problems with this.
  10973. X
  10974. XSean Boisen
  10975. XBBN Systems and Technologies Corporation
  10976. X
  10977. X
  10978. XTwo files follow: i call the first icon-describe.el (don't forget to
  10979. Xbyte-compile it!), and the second icondoc.txt. Whatever you decide to
  10980. Xcall the latter, make sure you set the variable icon-doc-file accordingly! 
  10981. !FaR!OuT!
  10982. echo x - icon-describe.el
  10983. sed -e 's/^X//' > icon-describe.el << '!FaR!OuT!'
  10984. X;;; Icon syntax describer: by Sean Boisen, BBN Systems and
  10985. X;;; Technologies Corporation, sboisen@bbn.com. Standard lack of
  10986. X;;; warranty applies: may be freely distributed subject to the
  10987. X;;; restrictions of the GNU Emacs copyright. Please send me any bug
  10988. X;;; fixes and/or improvements!
  10989. X;;;
  10990. X;;; This still has at least the following known deficiences:
  10991. X;;;
  10992. X;;; The descriptive text file lacks descriptions for the newer
  10993. X;;; keywords. Please add them and send me a version if you can!
  10994. X;;;
  10995. X;;; It might be nice if icon-symbol-at-point did escape sequences as
  10996. X;;; well: it doesn't.
  10997. X;;;
  10998. X;;; Someday it might be more useful to provide more than one line of
  10999. X;;; information, especially for procedures: the main hurdle here is
  11000. X;;; that i'm too lazy to type all the text in.
  11001. X
  11002. X;;; additions:
  11003. X;;;
  11004. X;;; sboisen 2/23/89: i noticed that &pos gets
  11005. X;;; picked up as pos. Hacked describe-icon-symbol for this as a
  11006. X;;; special case. Still imperfect if point in just past the colon in
  11007. X;;; 0:&pos however...
  11008. X;;;
  11009. X;;; sboisen 2/23/89: symbols which contain characters with special
  11010. X;;; meanings in regexps don't get handled properly! not yet fixed...
  11011. X
  11012. X(require 'icon-mode)
  11013. X
  11014. X(provide 'icon-describe)
  11015. X
  11016. X(defvar icon-doc-file "/d4m/sboisen/emacs/icondoc.txt"
  11017. X  "Where the documentation file can be found.")
  11018. X
  11019. X;; a helper function: get a string containing all the characters matching
  11020. X;; some spec in a syntax table. Class is an atom. Useful in conjunction with
  11021. X;; skip-chars-forward. Doesn't do the eighth bit.
  11022. X
  11023. X(defun get-chars-in-class (class syntax-table)
  11024. X  (let ((classcode
  11025. X      (cond
  11026. X        ((eq class 'whitespace) 0)
  11027. X        ((eq class 'punctuation) 1)
  11028. X        ((eq class 'word) 2)
  11029. X        ((eq class 'symbol) 3)
  11030. X        ((eq class 'open) 4)    ;this doesn't work!
  11031. X        ((eq class 'close) 5)
  11032. X        ((eq class 'prefix) 6)
  11033. X        ((eq class 'stringquote) 7)
  11034. X        ((eq class 'charquote) 9)
  11035. X        ((eq class 'startcomment) 11)
  11036. X        ((eq class 'endcomment) 12)
  11037. X        ))
  11038. X    (index 0)
  11039. X    (str ""))
  11040. X    (while (< index 128)
  11041. X      (if (eql (aref syntax-table index) classcode)
  11042. X      (setq str (concat str (char-to-string index))))
  11043. X      (setq index (1+ index)))
  11044. X    str))
  11045. X
  11046. X(defvar wordchars "a-zA-Z0-9_")
  11047. X(defvar junkchars (concat " \n\t\r" "({[)}]"))
  11048. X(defvar punct (get-chars-in-class 'punctuation icon-mode-syntax-table))
  11049. X
  11050. X(defun icon-symbol-at-point ()
  11051. X  "Get the closest Icon symbol to point, but don't change your
  11052. X       position. Has a preference for looking backward when not
  11053. X       directly on a symbol."
  11054. X  (let (start end symbol)
  11055. X    (save-excursion
  11056. X      ;; first see if you're just past a symbol
  11057. X      (if (looking-at "\\s-\\|\\s(\\|\\s)\\|\\s>")
  11058. X      (skip-chars-backward junkchars)
  11059. X    ;; else move forward one character, presumably either a \w or
  11060. X    ;; a symbol: but not if at the end of the buffer
  11061. X    (or (= (point) (point-max))
  11062. X        (forward-char 1)))
  11063. X      
  11064. X      (cond
  11065. X    ;; special case for (potential) keywords: just past a &
  11066. X    ((eql (preceding-char) 38)
  11067. X     (setq start (1- (point)))
  11068. X     (cond
  11069. X       ((looking-at "\\w")
  11070. X        (skip-chars-forward wordchars))
  11071. X       ((looking-at "\\s.")
  11072. X        (skip-chars-forward punct))
  11073. X       ;; else whitespace?
  11074. X       ))
  11075. X    ;; just past a \\w
  11076. X    ((eql (aref icon-mode-syntax-table (preceding-char)) 2)
  11077. X     (skip-chars-backward wordchars)
  11078. X     ;; worry about being in the middle of a keyword
  11079. X     (if (eql (preceding-char) 38)
  11080. X         (setq start (1- (point)))
  11081. X       (setq start (point)))
  11082. X     (skip-chars-forward wordchars))
  11083. X    ;; else a symbol?
  11084. X    (t
  11085. X      (skip-chars-backward punct)
  11086. X      (setq start (point))
  11087. X      (skip-chars-forward punct)))
  11088. X      ;; THE OLD WAY THAT LOOKED FORWARD INSTEAD OF BACKWARD
  11089. X;;      ;; skip past whitespace and parens
  11090. X;;      (while (looking-at "\\s-\\|\\s(\\|\\s)\\|\\s>")
  11091. X;;    (skip-chars-forward junkchars))
  11092. X;;      (if (looking-at "\\w")
  11093. X;;      (progn
  11094. X;;        (skip-chars-forward wordchars)
  11095. X;;        (setq start (point))
  11096. X;;        (skip-chars-backward wordchars))
  11097. X;;    ;; else a symbol?
  11098. X;;    (progn
  11099. X;;        (skip-chars-forward punct)
  11100. X;;        (setq start (point))
  11101. X;;        (skip-chars-backward punct)))
  11102. X      (buffer-substring start (point)))))
  11103. X
  11104. X(defun describe-icon-symbol (symbol)
  11105. X  "Display the documentation of SYMBOL, an Icon operator."
  11106. X  (interactive
  11107. X    (let ((fn (icon-symbol-at-point))
  11108. X      (enable-recursive-minibuffers t)
  11109. X      (case-fold-search nil)    ;require that case match for search
  11110. X      val args-file regexp)
  11111. X      (setq val (read-from-minibuffer
  11112. X          (if fn
  11113. X              (format "Symbol (default %s): " fn)
  11114. X            "Symbol: ")))
  11115. X      (if (string= val "")
  11116. X      (setq val fn))
  11117. X      ;; this may not work for characters which are special to regexp
  11118. X      ;; (like ".")
  11119. X      (setq regexp (concat "^" val "[ \t(]"))
  11120. X      (if (not (get-file-buffer icon-doc-file))
  11121. X      (progn
  11122. X        (setq args-file
  11123. X          (find-file-noselect icon-doc-file))
  11124. X        (set-buffer args-file)
  11125. X        (rename-buffer "*ICON-DOC*")))
  11126. X      (set-buffer (get-file-buffer icon-doc-file))
  11127. X      (goto-char (point-min))
  11128. X      (list (if (re-search-forward regexp (point-max) t)
  11129. X      (save-excursion
  11130. X        (beginning-of-line 1)
  11131. X        (let ((lnstart (point)))
  11132. X          (end-of-line)
  11133. X          (message (buffer-substring lnstart (point)))))
  11134. X    (error (format "No definition for %s" val)))))))
  11135. !FaR!OuT!
  11136. echo x - icondoc.txt
  11137. sed -e 's/^X//' > icondoc.txt << '!FaR!OuT!'
  11138. XFORMAT: a regexp like "^word(args)" of "^word[\t ]descriptive_text 
  11139. Xabs(numeric)
  11140. Xany(cset,string,i,j)
  11141. Xbal(cset1,cset2,cset3,string,i,j)
  11142. Xcenter(string1,i,string2)
  11143. Xchar(i)
  11144. Xclose(file)
  11145. Xcollect()
  11146. Xcopy(x)
  11147. Xcset(x)
  11148. Xdelete(x1,x2)
  11149. Xdetab(string,i1,i2,...,in)
  11150. Xdisplay(i,file)
  11151. Xentab(string,i1,i2,...,in)
  11152. Xerrorclear()
  11153. Xexit(i)
  11154. Xfind(string1,string2,i,j)
  11155. Xget(list)
  11156. Xgetenv(string)
  11157. Xiand(i,j)
  11158. Xicom(i)
  11159. Ximage(x)
  11160. Xinsert(x1,x2,x3)
  11161. Xinteger(x)
  11162. Xior(i,j)
  11163. Xixor(i,h)
  11164. Xishift(i,j)
  11165. Xleft(string1,i,string2)
  11166. Xlist(i,x)
  11167. Xmany(cset,string,i,j)
  11168. Xmap(string1,string2,string3)
  11169. Xmatch(string1,string2,i,j)
  11170. Xmember(x1,x2)
  11171. Xmove(i)
  11172. Xnumeric(x)
  11173. Xopen(string1,string2)
  11174. Xord(string)
  11175. Xpop(list)
  11176. Xpos(i)
  11177. Xproc(x)
  11178. Xpull(list)
  11179. Xpush(list,x)
  11180. Xput(list,x)
  11181. Xread(file)
  11182. Xreads(file,i)
  11183. Xreal(x)
  11184. Xremove(string)
  11185. Xrename(string1,string2)
  11186. Xrepl(string,i)
  11187. Xreverse(string)
  11188. Xright(string1,i,string2)
  11189. Xrunerr(i,x)
  11190. Xsave(string)
  11191. Xseek(file,i)
  11192. Xseq(i,j)
  11193. Xset(list)
  11194. Xsort(list)
  11195. Xsort(table,i)
  11196. Xstop(x1,x2,...,xn)
  11197. Xstring(x)
  11198. Xsystem(string)
  11199. Xtab(i)
  11200. Xtable(x)
  11201. Xtrim(string,cset)
  11202. Xtype(x)
  11203. Xupto(cset,string,i,j)
  11204. Xwhere(file)
  11205. Xwrite(x1,x2,...,xn)
  11206. Xwrites(x1,x2,...,xn)
  11207. XCONTROL STRUCTURES/RESERVED WORDS
  11208. Xbreak expr
  11209. Xby    i to j by k
  11210. Xcase expr of {...}
  11211. Xcreate x
  11212. Xdefault : expr
  11213. Xdo    every expr1 do expr2; until expr1 do expr2; while expr1 do expr2
  11214. Xdynamic identifiers
  11215. Xelse    if expr1 then expr2 else expr3
  11216. Xend 
  11217. Xevery expr1 do expr2
  11218. Xfail 
  11219. Xglobal identifiers
  11220. Xif expr1 then expr2 else expr3
  11221. Xinitial expr
  11222. Xlink file1,file2,...filen
  11223. Xlocal identifiers
  11224. Xnext 
  11225. Xnot expr
  11226. Xof    case expr of {...}
  11227. Xprocedure identifier(identifiers)
  11228. Xrecord identifiers(fields)
  11229. Xrepeat expr
  11230. Xreturn expr
  11231. Xstatic identifiers
  11232. Xsuspend expr
  11233. Xthen    if expr1 then expr2 else expr3
  11234. Xto    i to j by k
  11235. Xuntil expr1 do expr2
  11236. Xwhile expr1 do expr2
  11237. X|    expr1 | expr2; |expr
  11238. X\    expr \ i ; \x produces x if x is not null, otherwise fails
  11239. X?:=    s ?:= x
  11240. X?    s ? x; ?x produces a random element of x, failing if x is empty
  11241. XINFIX OPERATIONS
  11242. X+    n + m produces the sum of n and m; +n produces the numeric value of n
  11243. X-    n - m produces the difference of n and m; -n produces the negative of n
  11244. X*    n * m produces the product of n and m; *x produces the size of x
  11245. X/      n / m produces n divided by m; /x produces x if x is null, or else fails
  11246. X%    n % m    produces the remainder of n divided by m
  11247. X^    n ^ m produces n to the power of m; ^e produces a refreshed copy of e
  11248. X<    n < m produces m if n is less than m, else fails
  11249. X<=    n <= m produces m if n is less than or equal to m, else fails
  11250. X=    n = m produces m if n equals m, else fails; =s equiv. to tab(match(s))
  11251. X>=    n >= m produces m if n is greater than or equal to m, else fails
  11252. X>    n > m produces m if n is greater than m, else fails
  11253. X~=    n ~= m produces m if n is not equal to m, else fails
  11254. X++    c1 ++ c2 produces the cset union of c1 and c2
  11255. X--    c1 -- c2 produces the cset difference of c1 and c2
  11256. X**    c1 ** c2 produces the cset intersection of c1 and c2
  11257. X||    s1 || s2 produces a string consisting of s1 followed by s2
  11258. X<<    s1 << s2  produces s2 if s1 is lexically less than s2, else fails
  11259. X<<=    s1 <<= s2  produces s2 if s1 is lexically <= s2, else fails
  11260. X==    s1 == s2 produces s2 if s1 is lexically equal to s2, else fails
  11261. X>>=    s1 >>= s2 produces s2 if s1 is lexically >= s2, else fails
  11262. X>>    s1 >> s2 produces s2 if s1 is lexically greater than s2, else fails
  11263. X~==    s1 ~== s2 produces s2 if s2 isn't lexically equal to s2, else fails
  11264. X|||    a1 ||| a2 produces a list of the values of a1 followed by those of a2
  11265. X@    x @ e activates e and transmits x to it; @e produces the outcome of activating e
  11266. X:=    x := y assigns the value of y to x, and produces the variable x
  11267. X<-    x <- y assigns y to x and produces x; reverses assignment if resumed
  11268. X:=:    x :=: y exchanges the values of x and y and produces the variable x
  11269. X<->    x <-> y exchanges x and y and produces x; reverses exchange if resumed
  11270. X===    x === y produces y if x and y have the same value, else fails
  11271. X~===    x ~=== y produces y if x and y don't have the same value, else fails
  11272. X&    x & y produces y; produces a variable if y is a variable
  11273. X.    x . y produces a variable for the y field of record x
  11274. X+:=    n +:= m assigns the sum of n and m to n and produces n
  11275. X-:=    n -:= m assigns the difference of n and m to n and produces n
  11276. X*:=    n *:= m assigns the product of n and m to n and produces n
  11277. X/:=    n /:= m assigns the difference of n and m to n and produces n
  11278. X%:=    n %:= m assigns the remainder of n divided by m to n and produces n
  11279. X^:=    n ^:= m assigns n raised to the power m to n and produces n
  11280. X<:=    n <:= m assigns m to n if n < m, else fails; produces n
  11281. X<=:=    n <=:= m assigns m to n if n <= m, else fails; produces n
  11282. X=:=    n =:= m assigns m to n if n = m, else fails; produces n
  11283. X>=:=    n >=:= m assigns m to n if n >= m, else fails; produces n
  11284. X>:=    n >:= m assigns m to n if n > m, else fails; produces n
  11285. X~=:=    n ~=:= m assigns m to n if n ~= m, else fails; produces n
  11286. X++:=    c1 ++:= c2 assigns the cset union of c1 and c2 to c1 and produces c1
  11287. X--:=    c1 --:= c2 assigns the cset difference of c1 and c2 to c1, producing c1
  11288. X**:=    c1 **:= c2 assigns the intersection of c1 and c2 to c1, producing c1
  11289. X||:=    s1 ||:= s2 assigns the string s1 || s2 to s1 and produces s1
  11290. X<<:=    s1 <:= s2 assigns s2 to s1 if s1 << s2, else fails; produces s1
  11291. X<<=:=    s1 <=:= s2 assigns s2 to s1 if s1 <<= s2, else fails; produces s1
  11292. X==:=    s1 =:= s2 assigns s2 to s1 if s1 == s2, else fails; produces s1
  11293. X>>=:=    s1 >=:= s2 assigns s2 to s1 if s1 >>= s2, else fails; produces s1
  11294. X>>:=    s1 >:= s2 assigns s2 to s1 if s1 >> s2, else fails; produces s1
  11295. X~==:=    s1 ~=:= s2 assigns s2 to s1 if s1 ~== s2, else fails; produces s1
  11296. X|||:=    a1 |||:= a2 assigns to a1 the concatenation of a1 and a2; produces a1
  11297. X@:=    x @:= e activates e with the value of x, and assigns the result to x
  11298. X===:=    x ===:= y assigns y to x if x === y, else fails; produces x
  11299. X~===:=    x ~===:= y assigns y to x if x ~=== y, else fails; produces x
  11300. X&:=    x &:= y assigns the value of y to x and produces x
  11301. XPREFIX OPERATIONS (some under infix instead)
  11302. X~    ~c produces the cset complement of c with respect to &cset
  11303. X!    !x generates the elements of x, failing if x is empty (x may be a file)
  11304. X.    .x produces the value of x
  11305. XKEYWORDS
  11306. X&ascii    produces a cset of the 128 ASCII characters
  11307. X&clock    produces a string consisting of the current time of day
  11308. X&collections    
  11309. X&cset    produces a cset consisting of all 256 characters
  11310. X¤t    
  11311. X&date    produces a string consisting of the current date
  11312. X&dateline    produces a string of the current date and time of day
  11313. X&digits
  11314. X&error
  11315. X&errornumber
  11316. X&errortext
  11317. X&errorvalue
  11318. X&errout    produces the standard error output file
  11319. X&fail    fails
  11320. X&features
  11321. X&file
  11322. X&host    produces a string that identifies the host computer
  11323. X&input    produces the standard input file
  11324. X&lcase    produces a cset consisting of the 26 lowercase letters
  11325. X&level    produces the integer level of the current procedure call
  11326. X&line
  11327. X&main    produces a co-expression for the initial call of main
  11328. X&null    produces the null value
  11329. X&output    produces the standard output file
  11330. X&pos    produces the integer position of scanning in &subject
  11331. X&random    produces the value of the seed for the psuedo-random sequence
  11332. X®ions
  11333. X&source    produces a co-expression for the activator of the current co-expression
  11334. X&storage    how much of each storage region is currently being used
  11335. X&subject    produces the variable whose value is the string being scanned
  11336. X&time    produces the integer number of msecs since beginning of execution
  11337. X&trace    produces a variable whose value controls procedure tracing
  11338. X&ucase    produces a cset consisting of the 26 uppercase characters
  11339. X&version    produces a string that identifies the version of Icon
  11340. !FaR!OuT!
  11341. exit
  11342.  
  11343. From icon-group-request@arizona.edu  Fri May 31 08:17:53 1991
  11344. Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Fri, 31 May 91 08:17:53 MST
  11345. Resent-From: icon-group-request@arizona.edu
  11346. Received: from Arizona.edu (Merlin.Telcom.Arizona.EDU) by optima.cs.arizona.edu (4.1/15)
  11347.     id AA15592; Fri, 31 May 91 08:17:51 MST
  11348. Received: from ucbvax.Berkeley.EDU by Arizona.edu with PMDF#10282; Fri, 31 May
  11349.  1991 08:17 MST
  11350. Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA29331; Fri, 31 May 91
  11351.  08:02:33 -0700
  11352. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  11353.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  11354.  usenet@ucbvax.Berkeley.EDU if you have questions)
  11355. Resent-Date: Fri, 31 May 1991 08:17 MST
  11356. Date: 31 May 91 14:38:15 GMT
  11357. From: cis.ohio-state.edu!pacific.mps.ohio-state.edu!linac!midway!ellis.uchicago.edu!goer@ucbvax.berkeley.edu (Richard L.
  11358.  Goerwitz)
  11359. Subject: RE: Records
  11360. Sender: icon-group-request@arizona.edu
  11361. Resent-To: icon-group@cs.arizona.edu
  11362. To: icon-group@arizona.edu
  11363. Resent-Message-Id: <A8669FE806C00FB6@Arizona.edu>
  11364. Message-Id: <1991May31.143815.4204@midway.uchicago.edu>
  11365. X-Envelope-To: icon-group@CS.Arizona.EDU
  11366. X-Vms-To: icon-group@Arizona.edu
  11367. Organization: University of Chicago
  11368. References: <31.May.91..11:, 23:12.bst..060024@EMAS-A>
  11369.  
  11370. In <31.May.91..11:23:12.bst..060024@EMAS-A> R.J.Hare@edinburgh.ac.uk writes:
  11371. >Next question - I am using records as the basis for a simple database
  11372. >program. Given that the program will be written in a tight enough way to
  11373. >ensure that it won't be possible to write a list with more elements than
  11374. >there are in a database entry, what is the advantage of using a record
  11375. >to store a database entry as opposed to a list?
  11376.  
  11377. Record field access is much faster than list subscripting.  You can also
  11378. get at the fields by name, and not worry about their order.  If you want,
  11379. though, you can subscript records (as long as you realize that doing so
  11380. erases most of their method of/speed of access advantages).
  11381.  
  11382. If you really want to be clever, use a record for all the fields you know
  11383. you'll be using, but make one member of the record into a list where you
  11384. can store optional or other fields.  You'll get the best of both worlds,
  11385. at the expense of some clarity and straightforwardness.
  11386.  
  11387. -- 
  11388.  
  11389.    -Richard L. Goerwitz              goer%sophist@uchicago.bitnet
  11390.    goer@sophist.uchicago.edu         rutgers!oddjob!gide!sophist!goer
  11391.  
  11392. From uunet!men2a!aquin!luvthang!talmage  Sat Jun  1 02:07:07 1991
  11393. Received: from univers.cs.arizona.edu by cheltenham.cs.arizona.edu; Sat, 1 Jun 91 02:07:07 MST
  11394. Received: from uunet.UUCP by univers.cs.arizona.edu; Sat, 1 Jun 91 02:07:06 MST
  11395. Received: from men2a.UUCP (LOCALHOST.UU.NET) by relay2.UU.NET with SMTP 
  11396.     (5.61/UUNET-internet-primary) id AA04543; Sat, 1 Jun 91 03:46:13 -0400
  11397. Received: from men2a.UUCP by uunet.uu.net with UUCP/RMAIL
  11398.     (queueing-rmail) id 034526.15947; Sat, 1 Jun 1991 03:45:26 EDT
  11399. Received: by men2a.ori-cal.com (smail2.5)
  11400.     id AA00353; 1 Jun 91 03:52:14 EDT (Sat)
  11401. Received: by aquin.ORI-CAL.COM (smail2.5)
  11402.     id AA01610; 1 Jun 91 03:37:12 EDT (Sat)
  11403. Received: by luvthang.UUCP (1.05D/Amiga)
  11404.     id AA02235; Fri, 31 May 91 17:17:07 EST
  11405. Date: Fri, 31 May 91 17:17:07 EST
  11406. Message-Id: <9105312217.AA02235@luvthang.UUCP>
  11407. From: uunet!luvthang!talmage (David W. Talmage)
  11408. To: uunet!icon-group
  11409. Subject: Idol gotcha:  mixing procedures and methods
  11410.  
  11411. Boy, do I feel dumb!  Here's a "gotcha" for those of us who work with
  11412. Idol, Clint Jeffery's neato object-oriented language derived from Icon.
  11413.  
  11414. In Idol, you can have both procedures and methods in a class
  11415. definition.  Procedures become part of the global name space while
  11416. methods stay local to the objects of their class.  Because procedures
  11417. are in the global space, they have no concept of the variable "self",
  11418. which all methods may use to access the instance variables of their
  11419. class.  Procedures which try to dereference self invoke a run-time
  11420. error: "record expected".
  11421.  
  11422. This sample should illustrate the problem:
  11423.  
  11424. class DoNuthin(theFrobotz, theZimZam)
  11425. method asString()
  11426.   return "theFrobotz= " || self.theFrobotz || " theZimZam= " || self.theZimZam 
  11427. end
  11428.  
  11429. procedure printThem()
  11430.   write( self.theFrobotz )
  11431.   write( self.theZimZam )
  11432. end
  11433.  
  11434. initially
  11435.   printThem()
  11436. end
  11437.  
  11438. procedure main()
  11439. local aDoNuthin
  11440.  
  11441.   aDoNuthin := DoNuthin( "David", "Talmage" )
  11442.   write( aDoNuthin$asString() )
  11443.  
  11444. end
  11445.  
  11446. I don't want to tell you how long it took me to figure that one out.
  11447.  
  11448. -----------------------------------------------------------------------------
  11449. David W. Talmage (talmage@luvthang.aquin.ori-cal.com)
  11450. "I need fifty dollars to make you hollar.  I get paid to run this luvthang."
  11451.  
  11452. From cjeffery  Mon Jun  3 12:17:05 1991
  11453. Date: Mon, 3 Jun 91 12:17:05 MST
  11454. From: "Clinton Jeffery" <cjeffery>
  11455. Message-Id: <9106031917.AA17352@cheltenham.cs.arizona.edu>
  11456. Received: by cheltenham.cs.arizona.edu; Mon, 3 Jun 91 12:17:05 MST
  11457. To: uunet!men2a!aquin!luvthang!talmage
  11458. Cc: icon-group
  11459. In-Reply-To: David W. Talmage's message of Fri, 31 May 91 17:17:07 EST <9105312217.AA02235@luvthang.UUCP>
  11460. Subject: Idol gotcha:  mixing procedures and methods
  11461.  
  11462. <<This is a reply to David Talmage's note on mixing procedures and methods
  11463.   in Idol.  Regular Icon readers will not miss anything if they skip it.>>
  11464.  
  11465. Procedures inside class declarations are regular Icon procedures and do not
  11466. have any implicit "self" object on which to operate.  Idol used to flag this
  11467. with an error to prevent the kind of confusion Mr. Talmage experienced.  But
  11468. it is quite useful to allow normal Icon code (such as helping procedures)
  11469. to be included within a class declaration.  Idol does not take the view
  11470. that every piece of code should be a method, any more than it views
  11471. every piece of data as an object.  Saying "procedure" when you mean
  11472. "method" will indeed cause the kind of problems Mr. Talmage described.
  11473.  
  11474. From uunet!men2a!aquin!luvthang!talmage  Wed Jun  5 14:36:06 1991
  11475. Received: from univers.cs.arizona.edu by cheltenham.cs.arizona.edu; Wed, 5 Jun 91 14:36:06 MST
  11476. Received: from uunet.UUCP by univers.cs.arizona.edu; Wed, 5 Jun 91 14:36:06 MST
  11477. Received: from uunet.uu.net (LOCALHOST.UU.NET) by relay1.UU.NET with SMTP 
  11478.     (5.61/UUNET-internet-primary) id AA11701; Wed, 5 Jun 91 14:26:09 -0400
  11479. Received: from men2a.UUCP by uunet.uu.net with UUCP/RMAIL
  11480.     (queueing-rmail) id 142547.9400; Wed, 5 Jun 1991 14:25:47 EDT
  11481. Received: by men2a.ori-cal.com (smail2.5)
  11482.     id AA24099; 5 Jun 91 14:34:43 EDT (Wed)
  11483. Received: by aquin.ORI-CAL.COM (smail2.5)
  11484.     id AA02705; 5 Jun 91 14:17:48 EDT (Wed)
  11485. Received: by luvthang.aquin.ori-cal.com (1.05D/Amiga)
  11486.     id AA02343; Wed, 5 Jun 91 08:50:51 EST
  11487. Date: Wed, 5 Jun 91 08:50:51 EST
  11488. Message-Id: <9106051350.AA02343@luvthang.aquin.ori-cal.com>
  11489. From: uunet!luvthang.aquin.ori-cal.com!talmage (David W. Talmage)
  11490. To: uunet!icon-group
  11491. Subject: sorting files larger than physical memory
  11492.  
  11493. Once upon a time, Richard Goerwitz posted some text indexing code he
  11494. called gettext().  I've been using it and trying to improve it.  One
  11495. thing I'm working on is sorting the keys in the index files so
  11496. searches for keys are faster.  This presents a problem when the keys
  11497. are too many to fit in available memory at one time.  I'm looking for
  11498. solutions to this problem.
  11499.  
  11500. My solution, for the time being, is to read the keys in batches that
  11501. fit in my limited memory, sorting each batch with the built-in
  11502. function sort().  Each sorted batch I write to a temporary file.  When
  11503. all batches are sorted, I merge the temporary files one record at a
  11504. time in much the same way as you'd merge piles of sorted index cards.
  11505.  
  11506. I welcome comments and code from anyone.
  11507.  
  11508. -----------------------------------------------------------------------------
  11509. David W. Talmage (talmage@luvthang.aquin.ori-cal.com)
  11510. "I need fifty dollars to make you hollar.  I get paid to run this luvthang."
  11511.  
  11512. From @um.cc.umich.edu:Paul_Abrahams@MTS.cc.Wayne.edu  Wed Jun  5 15:53:57 1991
  11513. Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Wed, 5 Jun 91 15:53:57 MST
  11514. Received: from umich.edu by optima.cs.arizona.edu (4.1/15)
  11515.     id AA26204; Wed, 5 Jun 91 15:53:54 MST
  11516. Received: from um.cc.umich.edu by umich.edu (5.61/1123-1.0)
  11517.     id AA18627; Wed, 5 Jun 91 18:53:50 -0400
  11518. Received: from MTS.cc.Wayne.edu by um.cc.umich.edu via MTS-Net; Wed, 5 Jun 91 18:47:45 EDT
  11519. Date: Wed, 5 Jun 91 18:47:34 EDT
  11520. From: Paul_Abrahams@mts.cc.wayne.edu
  11521. To: icon-group@cs.arizona.edu
  11522. Message-Id: <335121@MTS.cc.Wayne.edu>
  11523. Subject: Sorting index files
  11524.  
  11525.  
  11526. Dave Talmage inquired about sorting files that are too large to
  11527. fit in memory.   I had the same problem in my indexing program
  11528. for ``TeX for the Impatient''.  My solution was simple: two Icon
  11529. programs and a sort in between, using the sort program that comes
  11530. with your system.  This solution works equally well for Unix and
  11531. DOS, although the standard DOS sorting program is probably not
  11532. satisfactory; you'll have to shop around for a better one.  You
  11533. can also do it with a single Icon program and the `system'
  11534. function, or maybe even more elegantly with `system' and piped
  11535. files under Unix.  But the two-program solution ain't that bad.
  11536.  
  11537. A couple more details: the first pass analyzes each index entry
  11538. and attaches a sort key to it.  With appropriate use of the Icon
  11539. map function, you can handle the fine points of sorting uppercase
  11540. versus lowercase and handling index entries that begin with
  11541. special characters.  The second pass strips the sort keys and
  11542. collects the entries for a particular index heading.
  11543.  
  11544. By the way, the standard practice on ordering special characters
  11545. in an index is to use the ASCII collating sequence.  As far as
  11546. I'm concerned, that's a copout.  Indices are intended to be read
  11547. by people, not by machines.  How many of your buddies (male or
  11548. female, no sexism intended) remember the ASCII collating sequence
  11549. for the special characters?  A much better solution is to sort
  11550. the special characters by their English names, which you should
  11551. list for the reader so as to avoid any confusion (is it ``star''
  11552. or ``asterisk'', ``dash'' or ``minus'')?  A few twiddles are in
  11553. order: ``parenthesis, left'' rather than ``left parenthesis'',
  11554. etc. 
  11555.  
  11556. Paul Abrahams
  11557. Abrahams@mts.cc.wayne.edu
  11558.  
  11559.  
  11560.  
  11561. From TENAGLIA@mis.mcw.edu  Thu Jun  6 04:09:14 1991
  11562. Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Thu, 6 Jun 91 04:09:14 MST
  11563. Received: from MIS1.MIS.MCW.EDU by optima.cs.arizona.edu (4.1/15)
  11564.     id AA25230; Thu, 6 Jun 91 04:09:09 MST
  11565. Received: from mis.mcw.edu (MCWMI3) by MIS1.MIS.MCW.EDU with PMDF#10477; Thu, 6
  11566.  Jun 1991 06:09 CST
  11567. Date: Thu, 6 Jun 1991 06:09 CST
  11568. From: Chris Tenaglia - 257-8765 <TENAGLIA@mis.mcw.edu>
  11569. Subject: Re: Sorting index files
  11570. To: Paul_Abrahams@mts.cc.wayne.edu
  11571. Cc: icon-group@cs.arizona.edu
  11572. Message-Id: <4D82694060200B20@mis.mcw.edu>
  11573. X-Organization: Medical College of Wisconsin MIS Department (Milwaukee, WI)
  11574. X-Vms-To: IN%"Paul_Abrahams@mts.cc.wayne.edu"
  11575. X-Vms-Cc: IN%"icon-group@cs.arizona.edu"
  11576.  
  11577. Regarding:    Sorting index files
  11578.  
  11579. > Dave Talmage inquired about sorting files that are too large to
  11580. > fit in memory.   I had the same problem in my indexing program
  11581. > for ``TeX for the Impatient''.  My solution was simple: two Icon
  11582. > programs and a sort in between, using the sort program that comes
  11583. > with your system.  This solution works equally well for Unix and
  11584. > DOS, although the standard DOS sorting program is probably not
  11585. > satisfactory; you'll have to shop around for a better one.  You
  11586. > can also do it with a single Icon program and the `system'
  11587. > function, or maybe even more elegantly with `system' and piped
  11588. > files under Unix.  But the two-program solution ain't that bad.
  11589. >>..more.. 
  11590. > Paul Abrahams
  11591. > Abrahams@mts.cc.wayne.edu
  11592.  
  11593. I also have a report generator with the same problem. It loads, sorts,
  11594. outputs. Somewhere between 2000 and 5000 items is the limit of icon
  11595. sort() {under VMS} so once the list is loaded I test it's size. If
  11596. greater than the limit, I write it to a temporary file, sort with
  11597.              system("sort/key=(pos:5,size:12,ascending) file.tmp")
  11598. reload the file, output the report and cleanup temp files.
  11599.  
  11600. Although there are sometimes when the list goes to 20,000 to 50,000 items
  11601. and I can't even fit it. So I have a passed parameter (-file) when I know this
  11602. will happen to run everything with temp files. VMS, unlike unix does not
  11603. have piping (who | sort | mail tenaglia).
  11604.  
  11605. Chris Tenaglia (System Manager) | Medical College of Wisconsin
  11606. 8701 W. Watertown Plank Rd.     | Milwaukee, WI 53226
  11607. (414)257-8765                   | tenaglia@mis.mcw.edu, mcwmis!tenaglia
  11608.  
  11609.  
  11610. From icon-group-request@arizona.edu  Thu Jun  6 11:08:23 1991
  11611. Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Thu, 6 Jun 91 11:08:23 MST
  11612. Resent-From: icon-group-request@arizona.edu
  11613. Received: from Arizona.edu (Merlin.Telcom.Arizona.EDU) by optima.cs.arizona.edu (4.1/15)
  11614.     id AA09074; Thu, 6 Jun 91 11:08:20 MST
  11615. Received: from ucbvax.Berkeley.EDU by Arizona.edu with PMDF#10282; Thu, 6 Jun
  11616.  1991 10:56 MST
  11617. Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA17391; Thu, 6 Jun 91 10:48:02
  11618.  -0700
  11619. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  11620.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  11621.  usenet@ucbvax.Berkeley.EDU if you have questions)
  11622. Resent-Date: Thu, 6 Jun 1991 11:08 MST
  11623. Date: 6 Jun 91 17:30:10 GMT
  11624. From: agate!spool.mu.edu!sol.ctr.columbia.edu!ira.uka.de!i41s5!angelo@ucbvax.berkeley.edu (Angelo
  11625.  Schneider Betr.Prechelt)
  11626. Subject: WHAT Icon ?
  11627. Sender: icon-group-request@arizona.edu
  11628. Resent-To: icon-group@cs.arizona.edu
  11629. To: icon-group@arizona.edu
  11630. Resent-Message-Id: <7734F3E5A4C02B85@Arizona.edu>
  11631. Message-Id: <1991Jun6.173010.17650@ira.uka.de>
  11632. X-Envelope-To: icon-group@CS.Arizona.EDU
  11633. X-Vms-To: icon-group@Arizona.edu
  11634. Organization: University of Karlsruhe, FRG
  11635.  
  11636. Would anybody please mail me some information
  11637. about icon?
  11638.  
  11639. Can I get anywhere a compiler or at least a to C-Compiler?
  11640.  
  11641. thanx in advance 
  11642.  
  11643. angelo
  11644.  
  11645. From goer%sophist@gargoyle.uchicago.edu  Sun Jun  9 12:24:09 1991
  11646. Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Sun, 9 Jun 91 12:24:09 MST
  11647. Received: from gargoyle.uchicago.edu by optima.cs.arizona.edu (4.1/15)
  11648.     id AA20386; Sun, 9 Jun 91 12:24:07 MST
  11649. Received: by gargoyle.uchicago.edu from sophist (sophist.uchicago.edu) (4.0/1.14)
  11650.     id AA28884; Sun, 9 Jun 91 14:24:05 CDT
  11651. Return-Path: <goer@sophist.uchicago.edu>
  11652. Received:  by sophist (4.1/UofC3.1X)
  11653.     id AA07148; Sun, 9 Jun 91 14:25:08 CDT
  11654. Date: Sun, 9 Jun 91 14:25:08 CDT
  11655. From: Richard Goerwitz <goer%sophist@gargoyle.uchicago.edu>
  11656. Message-Id: <9106091925.AA07148@sophist>
  11657. To: icon-group@cs.arizona.edu
  11658. Subject: ansi routines
  11659.  
  11660. Is anyone using the IPL ansi.icn library?  If so, I have a set of
  11661. compatible routines I'm trying to test out that will run under a
  11662. wider variety of platforms.  Anyone who wants to try them out, pleas
  11663. drop me a line.
  11664.  
  11665.  
  11666.    -Richard L. Goerwitz              goer%sophist@uchicago.bitnet
  11667.    goer@sophist.uchicago.edu         rutgers!oddjob!gide!sophist!goer
  11668.  
  11669. From shafto@eos.arc.nasa.gov  Mon Jun 10 12:42:17 1991
  11670. Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Mon, 10 Jun 91 12:42:17 MST
  11671. Received: from eos.arc.nasa.gov by optima.cs.arizona.edu (4.1/15)
  11672.     id AA08664; Mon, 10 Jun 91 12:42:15 MST
  11673. Received: Mon, 10 Jun 91 12:42:05 -0700 by eos.arc.nasa.gov (5.65/1.2)
  11674. Date: Mon, 10 Jun 91 12:42:05 -0700
  11675. From: Michael Shafto <shafto@eos.arc.nasa.gov>
  11676. Message-Id: <9106101942.AA02715@eos.arc.nasa.gov>
  11677. To: goer%sophist@gargoyle.uchicago.edu, icon-group@cs.arizona.edu
  11678. Subject: Re:  ansi routines
  11679. Cc: shafto@eos.arc.nasa.gov
  11680.  
  11681. Richard --
  11682.  
  11683. Yes, and I would be interested in testing your new improved version.
  11684.  
  11685. Mike
  11686.  
  11687. From icon-group-request@arizona.edu  Mon Jun 10 14:50:07 1991
  11688. Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Mon, 10 Jun 91 14:50:07 MST
  11689. Resent-From: icon-group-request@arizona.edu
  11690. Received: from Arizona.edu (Merlin.Telcom.Arizona.EDU) by optima.cs.arizona.edu (4.1/15)
  11691.     id AA19481; Mon, 10 Jun 91 14:49:55 MST
  11692. Received: from ucbvax.Berkeley.EDU by Arizona.edu with PMDF#10282; Mon, 10 Jun
  11693.  1991 14:49 MST
  11694. Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA03491; Mon, 10 Jun 91
  11695.  14:30:50 -0700
  11696. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  11697.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  11698.  usenet@ucbvax.Berkeley.EDU if you have questions)
  11699. Resent-Date: Mon, 10 Jun 1991 14:49 MST
  11700. Date: 10 Jun 91 21:11:45 GMT
  11701. From: cis.ohio-state.edu!zaphod.mps.ohio-state.edu!sdd.hp.com!news.cs.indiana.edu!ux1.cso.uiuc.edu!midway!ellis.uchicago.edu!goer@ucbvax.berkeley.edu (Richard L.
  11702.  Goerwitz)
  11703. Subject: RE:  ansi routines
  11704. Sender: icon-group-request@arizona.edu
  11705. Resent-To: icon-group@cs.arizona.edu
  11706. To: icon-group@arizona.edu
  11707. Resent-Message-Id: <BACF26FE2CC02640@Arizona.edu>
  11708. Message-Id: <1991Jun10.211145.23543@midway.uchicago.edu>
  11709. X-Envelope-To: icon-group@CS.Arizona.EDU
  11710. X-Vms-To: icon-group@Arizona.edu
  11711. Organization: University of Chicago
  11712. References: <9106101942.AA02715@eos.arc.nasa.gov>
  11713.  
  11714. shafto@EOS.ARC.NASA.GOV (Michael Shafto) writes:
  11715. >
  11716. >Yes, and I would be interested in testing your new improved version.
  11717.  
  11718. I wasn't clear enough:  My version is expanded (in the sense that
  11719. the ANSI interface can be applied to non-ANSI terminals).  I'm not
  11720. sure that it really constitutes an improvement.  Anyway, I haven't
  11721. had enough requests to consider posting, so I reiterate the offer
  11722. of sending them to anyone who wants to use them.
  11723.  
  11724. It's really a good idea to used generalized I/O for any programs
  11725. written in Icon, since Icon runs on so many platforms.  These new
  11726. ANSI routines have the advantage of working as-is on DOS platforms
  11727. with the ansi.sys driver installed.  The escape codes are hard-
  11728. coded in.  If, however, you want to run a program written with
  11729. them on, say, a UNIX box, the routines are structured so that you
  11730. can just link in the Icon termlib-type routines I posted some time
  11731. ago here (and which I have copies of I'll gladly pass on; I use
  11732. them constantly, and can't seem to stop revising them).  There is
  11733. also a library of high-level routines I wrote for use in conjunc-
  11734. tion with the termlib-type library.  These can also be linked in
  11735. with the revised ANSI screen control library.  The routines in
  11736. the revised library sense what it is you've linked in, and make
  11737. use of whatever you've made available (if in fact they need any
  11738. additional help - which they don't in DOS environments).
  11739.  
  11740. The idea is to have a generalized library of screen functions
  11741. that DOS users can blindly use, which take up minimal space, are
  11742. fairly fast, and which can be augmented for Unix without having
  11743. to change a single line of code (and without requiring the user
  11744. to have to do worry about setting up any sort of database).  Ad-
  11745. mittedly, these routines are a bit more spartan than the iolib
  11746. routines I posted a while back.  They are a lot more hassle-free,
  11747. though, and they cover pretty much all the basic functions that
  11748. people doing visually oriented programs would need.
  11749.  
  11750. You know, speaking of screen control, I wrote a set of Icon-based
  11751. windowing routines some time ago.  They let you open up virtual
  11752. screens, move them around, create borders, overlap them, write to
  11753. any screen (aka window), and have the portion showing on the stan-
  11754. dard screen be correctly updated (if in fact any was showing).
  11755.  
  11756. The reason I didn't post them is quite simple:  Although they were
  11757. fast enough for most purposes, they ate up way, way too much mem-
  11758. ory.  I implemented the concept of a displayable area with the
  11759. Icon equivalent of a 2d array (a list of lists), and then tried
  11760. various ways of representing squares in that array (integers, rec-
  11761. ords, etc.).  The trouble was that I wanted them to be pointers
  11762. to window structures created by the user.  Not having this facility,
  11763. I had to use records, which used up just too much space.
  11764.  
  11765. It *almost* worked.  :-(  I guess I wish that Icon had some sort
  11766. of explicit pointer data type.
  11767.  
  11768. -- 
  11769.  
  11770.    -Richard L. Goerwitz              goer%sophist@uchicago.bitnet
  11771.    goer@sophist.uchicago.edu         rutgers!oddjob!gide!sophist!goer
  11772.  
  11773. From icon-group-request@arizona.edu  Tue Jun 11 16:39:17 1991
  11774. Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Tue, 11 Jun 91 16:39:17 MST
  11775. Resent-From: icon-group-request@arizona.edu
  11776. Received: from Arizona.edu (Merlin.Telcom.Arizona.EDU) by optima.cs.arizona.edu (4.1/15)
  11777.     id AA20908; Tue, 11 Jun 91 16:39:12 MST
  11778. Received: from ucbvax.Berkeley.EDU by Arizona.edu with PMDF#10282; Tue, 11 Jun
  11779.  1991 16:38 MST
  11780. Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA17305; Tue, 11 Jun 91
  11781.  16:30:41 -0700
  11782. Received: from USENET by ucbvax.Berkeley.EDU with netnews for
  11783.  icon-group@arizona.edu (icon-group@arizona.edu) (contact
  11784.  usenet@ucbvax.Berkeley.EDU if you have questions)
  11785. Resent-Date: Tue, 11 Jun 1991 16:38 MST
  11786. Date: 11 Jun 91 22:45:29 GMT
  11787. From: acf5!mitsolid@nyu.edu (Thanasis Mitsolides)
  11788. Subject: ALLOY: Parallel, higher level, and flexible. V2.0
  11789. Sender: icon-group-request@arizona.edu
  11790. Resent-To: icon-group@cs.arizona.edu
  11791. To: icon-group@arizona.edu
  11792. Resent-Message-Id: <933F0BC460C03614@Arizona.edu>
  11793. Message-Id: <1624@acf5.NYU.EDU>
  11794. X-Envelope-To: icon-group@CS.Arizona.EDU
  11795. X-Vms-To: icon-group@Arizona.edu
  11796. Organization: New York University
  11797.  
  11798. This, announces the availability of the interpreter, manual,
  11799.  examples, and thesis for the programming language ALLOY v2.0.
  11800. ALLOY now completely unifies its functional and object oriented aspects.
  11801.  Also, its supports a much richer library.
  11802.  
  11803. ALLOY is high level, parallel, flexible and efficient.
  11804. ALLOY combines serial/parallel ev., eager/lazy ev., single/multiple solutions
  11805.  and parallel object oriented programming in a remarkably simple framework.
  11806.  
  11807. Example programs ready for execution include:
  11808.  1) factorial, partition sort, FP             (highly parallel)
  11809.  2) fibonacci sequence, prime numbers             (eager or lazy)
  11810.  3) systolic sort, hamming network            (clear flow of data)
  11811.  4) list member, tree leave, list permutation, n queens (multiple solutions)
  11812.  5) queue, stack, faa, semaphores, dinning philosophers    (objects)
  11813.  6) prolog package, prolog/parlog programming styles     (flexibility)
  11814.  
  11815. Part of ALLOY is explained in:
  11816. [MH90]    Thanasis  Mitsolides  and  Malcolm  Harrison.   Generators  and  the
  11817.           replicator control  structure in the parallel  environment of ALLOY.
  11818.           In ACM  SIGPLAN '90  Conference on  Programming Language  Design and
  11819.           Implementation, pages 189--196, White Plains, New York, June 1990.
  11820.  
  11821. The abstract of the ALLOY manual is appended at the end of this message.
  11822. The sources, manual, example programs, benchmarks, and thesis of ALLOY
  11823. are available for anonymous FTP from cs.nyu.edu (128.122.140.24)
  11824.  
  11825. I hope you will find ALLOY interesting.
  11826. I will be glad to answer your comments!
  11827. Thank you,
  11828.  
  11829. Thanasis
  11830.  
  11831.  
  11832. ===============================================================================
  11833.                 ABSTRACT
  11834.  
  11835.        ALLOY is a higher level parallel  programming language appropriate
  11836.      for programming  massively parallel computing systems.   It is based
  11837.      on  a combination  of  ideas from  functional,  object oriented  and
  11838.      logic programming languages.
  11839.        The  result  is  a  language that can  directly support functional,
  11840.      object  oriented  and logic  programming  styles  in a  unified  and
  11841.      controlled framework.   Evaluating modes support serial  or parallel
  11842.      execution,  eager or  lazy evaluation,  non-determinism or  multiple
  11843.      solutions etc.   ALLOY is  simple as it only requires  29 primitives
  11844.      in all (half of which for Object Oriented Programming support).
  11845.        This article, starts with  a formal definition of the  small ALLOY
  11846.      kernel  proceeds with the  definition of  some useful libraries  and
  11847.      concludes  with examples  which demonstrate  its expressiveness  and
  11848.      clarity.
  11849.        Programming language ALLOY is located  on system spunky.cs.nyu.edu
  11850.      directory  ~mitsolid/alloy.   This article can  be found in dvi  and
  11851.      ascii  form  on subdirectory  doc,  The  examples presented  can  be
  11852.      found  in subdirectory progs.   The  interpreter is executable  file
  11853.      alloy.   All the above and the sources of the  ALLOY interpreter are
  11854.      available   for   anonymous  ftp  on  system  cs.nyu.edu   directory 
  11855.      pub/local/alloy.
  11856.  
  11857. -------------------------------------------------------------------------------
  11858. Internet: mitsolid@cs.nyu.edu                 (mitsolid%cs.nyu.edu@relay.cs.net)
  11859. UUCP    : ...!uunet!cmcl2!cs!mitsolid
  11860. -------------------------------------------------------------------------------
  11861.  
  11862.  
  11863. -- 
  11864. -------------------------------------------------------------------------------
  11865. Internet: mitsolid@cs.nyu.edu                 (mitsolid%cs.nyu.edu@relay.cs.net)
  11866. UUCP    : ...!uunet!cmcl2!cs!mitsolid
  11867. -------------------------------------------------------------------------------
  11868.  
  11869. From uunet!men2a!aquin!luvthang!talmage  Thu Jun 13 10:11:25 1991
  11870. Received: from univers.cs.arizona.edu by cheltenham.cs.arizona.edu; Thu, 13 Jun 91 10:11:25 MST
  11871. Received: from uunet.UUCP by univers.cs.arizona.edu; Thu, 13 Jun 91 10:11:24 MST
  11872. Received: from uunet.uu.net (via LOCALHOST.UU.NET) by relay1.UU.NET with SMTP 
  11873.     (5.61/UUNET-internet-primary) id AA00621; Thu, 13 Jun 91 08:22:21 -0400
  11874. Received: from men2a.UUCP by uunet.uu.net with UUCP/RMAIL
  11875.     (queueing-rmail) id 082208.20608; Thu, 13 Jun 1991 08:22:08 EDT
  11876. Received: by men2a.ori-cal.com (smail2.5)
  11877.     id AA12884; 13 Jun 91 08:19:53 EDT (Thu)
  11878. Received: by aquin.ORI-CAL.COM (smail2.5)
  11879.     id AA05816; 13 Jun 91 07:34:44 EDT (Thu)
  11880. Received: by luvthang.aquin.ori-cal.com (1.05D/Amiga)
  11881.     id AA02419; Tue, 11 Jun 91 10:25:31 EST
  11882. Date: Tue, 11 Jun 91 10:25:31 EST
  11883. Message-Id: <9106111525.AA02419@luvthang.aquin.ori-cal.com>
  11884. From: uunet!luvthang.aquin.ori-cal.com!talmage (David W. Talmage)
  11885. To: uunet!icon-group
  11886. Subject: Increasing the number of concurrently open files
  11887.  
  11888. How many open files can an Icon program have at one time?  How can I
  11889. change this?  I'm encountering a limit of about 20 with Amiga Icon
  11890. version 8.0, February 14, 1990.  It looks like I can open 17 files of
  11891. my own choosing.  The remaining three must be &input, &output, and
  11892. &errout. 
  11893.  
  11894. The documentation tells me of an icont option -SFnnnn where nnnn is
  11895. the number of files.  Is there anything else I must do?  I've tried
  11896. -SF50, for example, with no change.
  11897.  
  11898. Enclosed, for the curious, is a program that determines how many open
  11899. files you can have at one time.
  11900.  
  11901. David Talmage
  11902. uunet!luvthang!talmage
  11903.  
  11904. ----- Begin included text -----
  11905. # File: OpenFileTest.icn
  11906. # Author: David W. Talmage
  11907. #
  11908. # Usage: iconx OpenFileTest [numfiles]
  11909. #
  11910. # OpenFileTest attempts to open numfiles files and keep them all open
  11911. # at the same time.  If it cannot open one of the files, OpenFileTest
  11912. # reports the name and number of the file.
  11913. #
  11914. # OpenFileTest removes all of the files it creates.
  11915. #
  11916. # By default, numfiles is 15.
  11917. #
  11918. record fileRec( theFilePointer, theFileName )
  11919.  
  11920. procedure main( argv )
  11921. local aFileRec
  11922. local fileName
  11923. local fRecList
  11924. local numFRecs
  11925. local openFileCount
  11926. local j
  11927.  
  11928.   openFileCount := 0
  11929.   numFRecs := integer( argv[1] ) | 15
  11930.   fRecList := list()
  11931.  
  11932. #
  11933. # CHANGE THE BASE NAME OF THE TEMPORARY FILE TO ONE FITTING YOUR SYSTEM.
  11934. #
  11935.   every fileName := (tempname("t:xxOFT." ) \ numFRecs) do {
  11936.  
  11937.  
  11938.     aFileRec := fileRec( open( fileName, "w" ), fileName ) | break( 
  11939.         write( "OpenFileTest: Can't open ", fileName,
  11940.         ", file #", openFileCount + 1 ) ) 
  11941.  
  11942.     openFileCount +:= 1
  11943.     put( fRecList, aFileRec )
  11944.  
  11945.   }
  11946.  
  11947.   write( "OpenFileTest: opened ", openFileCount, " concurrently." )
  11948.  
  11949.   #
  11950.   # Clean up after ourselves.  Close and delete each temporary file.
  11951.   #
  11952.   every j := 1 to openFileCount do {
  11953.  
  11954.     close( fRecList[ j ].theFilePointer ) 
  11955.     remove( fRecList[ j ].theFileName )
  11956.  
  11957.   }
  11958. end
  11959.  
  11960.  
  11961. # This is a version of Ronald Florence's (ron@mlfarm.com) tempname
  11962. # generator from post.icn of January 8, 1991.  That procedure was
  11963. # based on Richard Goerwitz's tempname generator, probably the one
  11964. # named get_dos_tempname in gdl.icn version 1.2.
  11965. #
  11966. # tempname() generates a sequence of unique temporary file names with
  11967. # some common base name.
  11968. #
  11969.  
  11970. procedure tempname(basename)
  11971. local temp_name
  11972.     
  11973.   every temp_name := basename || right(1 to 999,3,"0") do {
  11974.     close(open(temp_name)) & next
  11975.     suspend \temp_name
  11976.   }
  11977. end
  11978.  
  11979.  
  11980.  
  11981.