From ralph Tue Oct 9 08:37:22 1990 Received: from cheltenham.cs.arizona.edu by megaron.cs.arizona.edu (5.61/15) via SMTP id AA05206; Tue, 9 Oct 90 08:37:22 -0700 Date: Tue, 9 Oct 90 08:37:20 MST From: "Ralph Griswold" Message-Id: <9010091537.AA11439@cheltenham.cs.arizona.edu> Received: by cheltenham.cs.arizona.edu; Tue, 9 Oct 90 08:37:20 MST To: icon-group Subject: large messages Please remember that large e-mail messages cause some gateways, especially PCs, to crash. If you're sending something over 20K or so characters, please break it up into separate messages. If it's something like a program, take care to identify the parts clearly. Ralph Griswold / Dept of Computer Science / Univ of Arizona / Tucson, AZ 85721 +1 602 621 6609 ralph@cs.arizona.edu uunet!arizona!ralph From tenaglia@mis.mcw.edu Tue Oct 9 14:34:25 1990 Received: from rutgers.edu by megaron.cs.arizona.edu (5.61/15) via SMTP id AA03729; Tue, 9 Oct 90 14:34:25 -0700 Received: from uwm.UUCP by rutgers.edu (5.59/SMI4.0/RU1.4/3.08) with UUCP id AA21071; Tue, 9 Oct 90 17:18:44 EDT Received: by uwm.edu; id AA12064; Tue, 9 Oct 90 15:49:36 -0500 Received: from mcwmis by fps.mcw.edu (DECUS UUCP ///1.2a/2.5/); Tue, 9 Oct 90 15:16:51 CDT Received: by mis.mcw.edu (DECUS UUCP ///1.2a/2.5/); Tue, 9 Oct 90 15:15:31 CDT Date: Tue, 9 Oct 90 15:15:31 CDT Message-Id: <0093DF0203306BA0.2040083E@mis.mcw.edu> From: "Chris Tenaglia - 257-8765" Subject: Time and Date Routines To: icon-group@cs.arizona.edu Perhaps I didn't look close enough at the IPL, but I am interested in time and date manipulation routines. One the outside it sounds simple. Here're the specs. procedure dow(d) : Day of week. Should return either 1 through 7 or Sunday through Saturday. procedure difdate(d1,d2,uom) : Subtracts date d1 from date d2. uom is the unit of measure for the result as seconds, minutes, hours, days, weeks, months, years. procedure future(d1,d2,uom) : Adds duration d2 to date d1, yielding answer. duration in unit of measure uom, being either seconds, minutes, hours, days, weeks, months, years. Date formats => YYYY-MMM-DD:HH:MM:SS Month Day, Year HH:MM:SS The routines should be smart enough to handle leap years, and be able to make due with partial specs. 1990-oct-04 would default with 00:00:00. oct-04 would also assume the current year. Examples... difdate("oct-04","oct-16","day") returns 12 future("oct-02",6,"month") returns "1991-apr-02:00:00:00" dow("oct-9") returns 3 or Tuesday I think these might make a good addition to the IPL. Perhaps others have better ideas. Is date manipulation of interest to anyone else? I haven't developed the bodies of the procedures yet, but wonder if someone else has already? Chris Tenaglia (System Manager) Medical College of Wisconsin 8701 W. Watertown Plank Rd. Milwaukee, WI 53226 (414)257-8765 tenaglia@mis.mcw.edu, mcwmis!tenaglia From goer%sophist@gargoyle.uchicago.edu Tue Oct 9 21:41:04 1990 Resent-From: goer%sophist@gargoyle.uchicago.edu Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP id AA26047; Tue, 9 Oct 90 21:41:04 -0700 Return-Path: goer@sophist.uchicago.edu Received: from gargoyle.uchicago.edu by Arizona.edu; Tue, 9 Oct 90 21:40 MST Received: by gargoyle.uchicago.edu from sophist.uchicago.edu (5.59/1.14) id AA15188; Tue, 9 Oct 90 23:40:27 199 Received: by sophist (4.1/UofC3.1X) id AA21196; Tue, 9 Oct 90 23:44:23 CDT Resent-Date: Tue, 9 Oct 90 21:40 MST Date: Tue, 9 Oct 90 23:44:23 CDT From: Richard Goerwitz Subject: parsing natural languages Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: <20C82A039A47201ECF@Arizona.edu> Message-Id: <9010100444.AA21196@sophist> X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.EDU I'm just curious what sort of work is being done in natural languages using Icon. Naturally, I know of my own work in phonology and phonologi- cal databases. I wonder, though, whether anyone out there has done very much with the syntax of natural languages. A while back, I was working on several different approaches to bottom-up parsing in Icon, but got a bit sidetracked. I also tried implementing DFSA's in Icon, but found it difficult to get them to run quickly, with reasonable memory require- ments. Anyway, you can't parse natural languages with a DFSA. I'd ap- preciate it very much if anyone who has worked in such areas - in Icon - would drop me a line (or post a followup). -Richard From goer%sophist@gargoyle.uchicago.edu Tue Oct 9 22:27:56 1990 Resent-From: goer%sophist@gargoyle.uchicago.edu Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP id AA27111; Tue, 9 Oct 90 22:27:56 -0700 Return-Path: goer@sophist.uchicago.edu Received: from gargoyle.uchicago.edu by Arizona.edu; Tue, 9 Oct 90 22:27 MST Received: by gargoyle.uchicago.edu from sophist.uchicago.edu (5.59/1.14) id AA15801; Wed, 10 Oct 90 00:27:19 199 Received: by sophist (4.1/UofC3.1X) id AA21302; Wed, 10 Oct 90 00:31:14 CDT Resent-Date: Tue, 9 Oct 90 22:27 MST Date: Wed, 10 Oct 90 00:31:14 CDT From: Richard Goerwitz Subject: coaxing makes to handle Icon programs Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: <20C19B5B464720263C@Arizona.edu> Message-Id: <9010100531.AA21302@sophist> X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.EDU I often find that I can't coax make programs to handle Icon programs. Since I send out a lot of code over this newsgroup, I have a vested interest in making sure my makefiles work. Below is a shar archive of a test program. If anyone is feeling adventurous, I'd appreciate it very much if they would direct their adventursomeness in the fol- lowing way: Un-shar the following archive, then make. Write me if it doesn't work. Write me if it does work. Tell me your OS, and your make program. Note that the following shar archive can be "made" using gnu make. I can't get it to work on my Xenix (SysVR3-based) system using the stock make program. Nor can I get it to work using the stock Sun make here on sophist. It "should" work, though. The fact that it doesn't explains the ponderousness of the makefiles I distribute with my programs. -Richard ---- Cut Here and feed the following to sh ---- #!/bin/sh # This is a shell archive (produced by shar 3.49) # To extract the files from this archive, save it to a file, remove # everything above the "!/bin/sh" line above, and type "sh file_name". # if test -r _shar_seq_.tmp; then echo 'Must unpack archives in sequence!' echo Please unpack part `cat _shar_seq_.tmp` next exit 1 fi # ============= Makefile ============== if test -f 'Makefile' -a X"$1" != X"-c"; then echo 'x - skipping Makefile (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp echo 'x - extracting Makefile (Text)' sed 's/^X//' << 'SHAR_EOF' > 'Makefile' && X.SUFFIXES: .u2 .icn .icn~ X X.icn.u2: X icont -c $*.icn X.u2: X icont -o $* $*.u1 $*.u2 X @/bin/rm $*.u? X Xall: tmp SHAR_EOF true || echo 'restore of Makefile failed' rm -f _shar_wnt_.tmp fi # ============= s.tmp.icn ============== if test -f 's.tmp.icn' -a X"$1" != X"-c"; then echo 'x - skipping s.tmp.icn (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp echo 'x - extracting s.tmp.icn (Text)' sed 's/^X//' << 'SHAR_EOF' > 's.tmp.icn' && Xh11144 Xs 00003/00000/00000 Xd D 1.1 90/10/10 00:09:09 richard 1 0 Xc date and time created 90/10/10 00:09:09 by richard Xe Xu XU Xt XT XI 1 Xprocedure main() Xwrite("hello") Xend XE 1 SHAR_EOF true || echo 'restore of s.tmp.icn failed' rm -f _shar_wnt_.tmp fi exit 0 From nickerso@SPUNKY.CS.NYU.EDU Wed Oct 10 16:41:20 1990 Received: from SPUNKY.CS.NYU.EDU by megaron.cs.arizona.edu (5.61/15) via SMTP id AA22368; Wed, 10 Oct 90 16:41:20 -0700 Received: by SPUNKY.CS.NYU.EDU (5.61/1.34) id AA12133; Wed, 10 Oct 90 19:41:37 -0400 Date: Wed, 10 Oct 90 19:41:37 -0400 From: nickerso@SPUNKY.CS.NYU.EDU (Jeff Nickerson) Message-Id: <9010102341.AA12133@SPUNKY.CS.NYU.EDU> To: icon-group@cs.arizona.edu Subject: desubscribe Please desubscribe me from your electronic mailing list. From icon-group-request@arizona.edu Fri Oct 12 07:11:29 1990 Resent-From: icon-group-request@arizona.edu Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP id AA29291; Fri, 12 Oct 90 07:11:29 -0700 Received: from ucbvax.Berkeley.EDU by Arizona.edu; Fri, 12 Oct 90 07:10 MST Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA23854; Fri, 12 Oct 90 06:59:01 -0700 Received: from USENET by ucbvax.Berkeley.EDU with netnews for icon-group@arizona.edu (icon-group@arizona.edu) (contact usenet@ucbvax.Berkeley.EDU if you have questions) Resent-Date: Fri, 12 Oct 90 07:11 MST Date: 10 Oct 90 20:57:37 GMT From: eru!hagbard!sunic!mcsun!ukc!warwick!nott-cs!christopher-robin.cs.bham.ac.uk!lxg@bloom-beacon.mit.edu Subject: An introduction to Icon? Sender: icon-group-request@arizona.edu Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: <1EE6281A5AE7203E3F@Arizona.edu> Message-Id: <1004@christopher-robin.cs.bham.ac.uk> Organization: Birmingham University, England X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.EDU I have just picked up version 8 of Icon and would like to explore it further. Does anyone know if there is a tutorial on it floating around and accessible by ftp? Cheers Griff, University of Birmingham. ------------------------------------------------------------- ------------------------------------------------------------- From icon-group-request@arizona.edu Thu Oct 18 17:14:05 1990 Resent-From: icon-group-request@arizona.edu Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP id AA16109; Thu, 18 Oct 90 17:14:05 -0700 Received: from ucbvax.Berkeley.EDU by Arizona.edu; Thu, 18 Oct 90 17:13 MST Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA22642; Thu, 18 Oct 90 17:04:45 -0700 Received: from USENET by ucbvax.Berkeley.EDU with netnews for icon-group@arizona.edu (icon-group@arizona.edu) (contact usenet@ucbvax.Berkeley.EDU if you have questions) Resent-Date: Thu, 18 Oct 90 17:13 MST Date: 17 Oct 90 23:35:34 GMT From: bsu-cs!bsu-ucs!earlham!johnb@iuvax.cs.indiana.edu Subject: Icon and Oracle. A great mix Sender: icon-group-request@arizona.edu Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: <19DAF65F7A0B206CB7@Arizona.edu> Message-Id: <3145@yang.earlham.edu> Organization: Earlham College, Richmond, Indiana X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.EDU For anyone who is interested..... At Earlham College (Heard of it?) we undertook a project of intergrating Icon with the Oralce Relational Database. We are finished now, and the project seems to have alot of potential. Our interface is a new built in function called 'oracle' which accepts any SQL statement (Not SQL*PLUS). The information is returned through the list data type. All DMLs, DDL, and queries supported as well as a new built in &OracleError code. We chose Icon because it is such a strong language for use with strings and text. Our intergration, called OraConIt allows for sophisticated manipulation of the information returned. It could be used as a SQL front end, or as a report writer, or for DBAs be able to intergote the Data Dictionary and be able to process the data in a high-level laguage. Samples of code written in PRO*C and OraCon are very interesting to compare. (Of course OraCon takes less code.) We have developed only a VAX/VMS version, but conversion to any other platform should be painless. One needs the Oracle C run time library and the source code for that version of Icon. If you are interested by this little bit of info, (there is alot more) drop me a 'line' here. I would love to get some feedback on it. Thank you, The OraCon Group John Benjamin Johnb@yang.Earlham.Edu From kwalker Thu Oct 18 17:35:57 1990 Received: from gacham.cs.arizona.edu by megaron.cs.arizona.edu (5.61/15) via SMTP id AA16751; Thu, 18 Oct 90 17:35:57 -0700 Date: Thu, 18 Oct 90 17:35:55 MST From: "Kenneth Walker" Message-Id: <9010190035.AA02399@gacham.cs.arizona.edu> Received: by gacham.cs.arizona.edu; Thu, 18 Oct 90 17:35:55 MST To: icon-group Subject: Re: Icon and Oracle. A great mix Date: 17 Oct 90 23:35:34 GMT From: bsu-cs!bsu-ucs!earlham!johnb@iuvax.cs.indiana.edu At Earlham College (Heard of it?) we undertook a project of intergrating Icon with the Oralce Relational Database. We are finished now, and the project seems to have alot of potential. Our interface is a new built in function called 'oracle' which accepts any SQL statement (Not SQL*PLUS). The information is returned through the list data type. Neat! I was wondering if there is information that would be reasonable to "generate" rather than return in a list (I don't know much about Oracle or SQL, or data bases in general). Generating results is a more "Iconish" approach to returning multiple homogenous results than using a data structure. The programmer can then put them in a list if desired. Ken Walker / Computer Science Dept / Univ of Arizona / Tucson, AZ 85721 +1 602 621-4252 kwalker@cs.arizona.edu {uunet|allegra|noao}!arizona!kwalker From nowlin@iwtqg.att.com Fri Oct 19 05:17:25 1990 Resent-From: nowlin@iwtqg.att.com Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP id AA11455; Fri, 19 Oct 90 05:17:25 -0700 Received: from att.att.com by Arizona.edu; Fri, 19 Oct 90 05:16 MST Resent-Date: Fri, 19 Oct 90 05:17 MST Date: Fri, 19 Oct 90 06:51 CDT From: nowlin@iwtqg.att.com Subject: RE: Icon and Oracle (SQL) Resent-To: icon-group@cs.arizona.edu To: att!arizona.edu!icon-group@cs.arizona.edu Resent-Message-Id: <1975EF2F382B2077AF@Arizona.edu> Message-Id: <1975F7C2F5958016D3@Arizona.edu> Original-From: iwtqg!nowlin (Jerry D Nowlin +1 312 979 7268) X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: att!arizona.edu!icon-group@cs.Arizona.edu We've prototyped an interface to Informix that contains a single function called sql(). This function is a generator that's passed an SQL statement. It either fails or generates results. If the SQL statement passed is a "select" statement the sql() procedure generates a series of Icon tables that correspond to the records selected. The keys to the tables are the field names selected and the values are the corresponding values from the database. If the SQL statement passed isn't a "select" statement the result generated is the integer number of records in the database affected by the SQL statement. For example, a "delete" statement with a where clause that deleted 12 records from a database table would generate the single integer 12 before failing. Right now this Informix interface is implemented as an Icon procedure that calls a C program written with ESQL. We plan to eventually implement it as a built-in function using a pi. It would certainly be possible to use Oracle or most any database that supports SQL the same way. There's a definite advantage to being able to manipulate the results of a database query with Icon instead of C. Jerry Nowlin (...!att!iwtqg!nowlin) From @mirsa.inria.fr:ol@cerisi.cerisi.Fr Fri Oct 19 13:47:52 1990 Resent-From: @mirsa.inria.fr:ol@cerisi.cerisi.Fr Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP id AA06197; Fri, 19 Oct 90 13:47:52 -0700 Received: from mirsa.inria.fr by Arizona.edu; Fri, 19 Oct 90 13:47 MST Received: from cerisi.cerisi.fr by mirsa.inria.fr with SMTP (5.61+++/IDA-1.2.8) id AA11424; Fri, 19 Oct 90 21:48:49 +0100 Resent-Date: Fri, 19 Oct 90 13:47 MST Date: Fri, 19 Oct 90 21:45:28 -0100 From: Lecarme Olivier Subject: Icon and X-windows Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: <192E9AD0116B207EB8@Arizona.edu> Message-Id: <9010192048.AA11424@mirsa.inria.fr> Posted-Date: Fri, 19 Oct 90 21:45:28 -0100 X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.EDU I have the project of using the variant translator capability of Icon, as well as the personalized interpreter, in order to define an extension to Icon interfaced with X-windows. The idea would be to have a very powerful and flexible language for prototyping interactive graphic environments. Has anybody already attempted something similar? Has anybody any interesting idea about this matter? Olivier Lecarme From cjeffery Fri Oct 19 14:51:13 1990 Resent-From: "Clinton Jeffery" Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP id AA09356; Fri, 19 Oct 90 14:51:13 -0700 Received: from megaron.cs.Arizona.EDU by Arizona.edu; Fri, 19 Oct 90 14:50 MST Received: from caslon.cs.arizona.edu by megaron.cs.arizona.edu (5.61/15) via SMTP id AA09319; Fri, 19 Oct 90 14:50:33 -0700 Received: by caslon.cs.arizona.edu; Fri, 19 Oct 90 14:50:30 -0700 Resent-Date: Fri, 19 Oct 90 14:50 MST Date: Fri, 19 Oct 90 14:50:30 -0700 From: Clinton Jeffery Subject: Icon and X-windows Resent-To: icon-group@cs.arizona.edu To: ol@cerisi.cerisi.Fr Cc: icon-group@arizona.edu Resent-Message-Id: <1925C158F62B2075CA@Arizona.edu> Message-Id: <9010192150.AA06946@caslon.cs.arizona.edu> In-Reply-To: Lecarme Olivier's message of Fri, 19 Oct 90 21:45:28 -0100 <9010192048.AA11424@mirsa.inria.fr> X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: ol@cerisi.cerisi.Fr X-Vms-Cc: icon-group@Arizona.EDU We are using an Icon X Windows interface internally here in our program visualization research. There is a 15 page reference document describing it, Icon Project Document 150. The interface is built on top of Xlib. There is no public distribution that includes the X Windows interface at this time. Interested persons may obtain more information from me by electronic mail. I would also enjoy hearing from persons who are working on Icon interfaces to other window systems. Clint Jeffery, U. of Arizona Dept. of Computer Science cjeffery@cs.arizona.edu -or- {noao allegra}!arizona!cjeffery From goer@midway.uchicago.edu Sat Oct 20 23:52:57 1990 Resent-From: goer@midway.uchicago.edu Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP id AA03592; Sat, 20 Oct 90 23:52:57 -0700 Received: from midway.uchicago.edu by Arizona.edu; Sat, 20 Oct 90 23:52 MST Received: from quads.uchicago.edu (quads.uchicago.edu) by midway.uchicago.edu Sun, 21 Oct 90 01:52:24 CDT Resent-Date: Sat, 20 Oct 90 23:52 MST Date: Sun, 21 Oct 90 01:52:24 CDT From: "Richard L. Goerwitz" Subject: test posting of dir lister Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: <1810E919AC6B20793F@Arizona.edu> Message-Id: <9010210652.AA08963@midway.uchicago.edu> X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.EDU It's hard to get directory listings from within Icon. Here are some routines that do this in a generic way. The idea of doing things generically is to avoid OS-specificity, at least on the level on which these routines are called (not, in other words, in the actual mechanics of how to get the listing, which are very OS-specific). Anyway, I hope someone finds these routines useful. -Richard ############################################################################ # # Name: gdl.icn # # Title: Get directory list # # Author: Richard L. Goerwitz # # Version: 1.2 # ############################################################################ # # Gdl returns a list containing everything in a directory (whose name # must be passed as an argument to gdl). Nothing fancy. I use this file # as a template, modifying the procedures according to the needs of the # program in which they are used. # ############################################################################ # # Requires: UNIX or MS-DOS # ############################################################################ procedure gdl(dir) getdir := set_getdir_by_os() return getdir(dir) end procedure set_getdir_by_os() # Decide how to get a directory, based on whether we are running # under Unix or MS-DOS. if find("UNIX", &features) then return unix_get_dir else if find("MS-DOS", &features) then return msdos_get_dir else stop("Your operating system is not (yet) supported.") end procedure msdos_get_dir(dir) # Returns a sorted list of all filenames (full paths included) in # directory "dir." The list is sorted. Fails on invalid or empty # directory. Aborts if temp file cannot be opened. # # Temp files can be directed to one or another directory either by # manually setting the variable temp_dir below, or by setting the # value of the environment variable TEMPDIR to an appropriate # directory name. local in_dir, filename_list, line static temp_dir initial { temp_dir := (trim(map(getenv("TEMPDIR"), "/", "\\"), '\\') || "\\") | ".\\" } # Get name of tempfile to be used. temp_name := get_dos_tempname(temp_dir) | stop("No more available tempfile names!") # Make sure we have an unambiguous directory name, with backslashes # instead of Unix-like forward slashes. dir := trim(map(dir, "/", "\\"), '\\') || "\\" # Put dir listing into a temp file. system("dir "||dir||" > "||temp_name) # Put tempfile entries into a list, removing blank- and # space-initial lines. Exclude directories (i.e. return file # names only). in_dir := open(temp_name,"r") | stop("Can't open temp file in directory ",temp_dir,".") filename_list := list() every filename := ("" ~== !in_dir) do { match(" ",filename) | find(" ", filename) & next # Exclude our own tempfiles (may not always be appropriate). filename ?:= trim(trim(tab(10)) || "." || tab(13), '. ') put(filename_list, map(dir || filename)) } # Clean up. close(in_dir) & remove(temp_name) # Check to be sure we actually managed to read some files. if *filename_list = 0 then fail else return sort(filename_list) end procedure get_dos_tempname(dir) # Don't clobber existing files. Get a unique temp file name for # use as a temporary storage site. every temp_name := dir || "icondir." || right(string(1 to 999),3,"0") do { temp_file := open(temp_name,"r") | break close(temp_file) } return \temp_name end procedure unix_get_dir(dir) dir := trim(dir, '/') || "/" filename_list := list() in_dir := open("/bin/ls -F "||dir, "pr") every filename := ("" ~== !in_dir) do { match("/",filename,*filename) & next put(filename_list, trim(dir || filename, '*')) } close(in_dir) if *filename_list = 0 then fail else return filename_list end From ralph Tue Oct 23 05:38:12 1990 Received: from cheltenham.cs.arizona.edu by megaron.cs.arizona.edu (5.61/15) via SMTP id AA26192; Tue, 23 Oct 90 05:38:12 -0700 Date: Tue, 23 Oct 90 05:38:08 MST From: "Ralph Griswold" Message-Id: <9010231238.AA23237@cheltenham.cs.arizona.edu> Received: by cheltenham.cs.arizona.edu; Tue, 23 Oct 90 05:38:08 MST To: icon-group Subject: Message forwarded by request For anyone who is interested..... At Earlham College (Heard of it?) we undertook a project of intergrating Icon with the Oralce Relational Database. We are finished now, and the project seems to have alot of potential. Our interface is a new built in function called 'oracle' which accepts any SQL statement (Not SQL*PLUS). The information is returned through the list data type. All DMLs, DDL, and queries supported as well as a new built in &OracleError code. We chose Icon because it is such a strong language for use with strings and text. Our intergration, called OraConIt allows for sophisticated manipulation of the information returned. It could be used as a SQL front end, or as a report writer, or for DBAs be able to intergote the Data Dictionary and be able to process the data in a high-level laguage. Samples of code written in PRO*C and OraCon are very interesting to compare. (Of course OraCon takes less code.) We have developed only a VAX/VMS version, but conversion to any other platform should be painless. One needs the Oracle C run time library and the source code for that version of Icon. If you are interested by this little bit of info, (there is alot more) drop me a 'line' here. I would love to get some feedback on it. Thank you, The OraCon Group John Benjamin Johnb@yang.Earlham.Edu From goer%sophist@gargoyle.uchicago.edu Tue Oct 23 18:56:58 1990 Resent-From: goer%sophist@gargoyle.uchicago.edu Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP id AA03478; Tue, 23 Oct 90 18:56:58 -0700 Return-Path: goer@sophist.uchicago.edu Received: from gargoyle.uchicago.edu by Arizona.edu; Tue, 23 Oct 90 18:56 MST Received: by gargoyle.uchicago.edu from sophist.uchicago.edu (5.59/1.14) id AA16775; Tue, 23 Oct 90 20:56:22 199 Received: by sophist (4.1/UofC3.1X) id AA07035; Tue, 23 Oct 90 21:00:05 CDT Resent-Date: Tue, 23 Oct 90 18:56 MST Date: Tue, 23 Oct 90 21:00:05 CDT From: Richard Goerwitz Subject: BCD Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: <15DEC3453B0B209EA7@Arizona.edu> Message-Id: <9010240200.AA07035@sophist> X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.EDU I recall someone posting some nice little routines that turned integers into binary coded decimal strings. I remember looking at them and thinking they looked useful. I wonder if these are still around somewhere. -Richard (goer@sophist.uchicago.edu) From tenaglia@mis.mcw.edu Wed Oct 24 11:35:43 1990 Received: from rutgers.edu by megaron.cs.arizona.edu (5.61/15) via SMTP id AA08895; Wed, 24 Oct 90 11:35:43 -0700 Received: from uwm.UUCP by rutgers.edu (5.59/SMI4.0/RU1.4/3.08) with UUCP id AA24606; Wed, 24 Oct 90 14:21:50 EDT Received: by uwm.edu; id AA22598; Wed, 24 Oct 90 13:02:18 -0500 Received: from mcwmis by fps.mcw.edu (DECUS UUCP ///1.2a/2.5/); Wed, 24 Oct 90 11:59:16 CDT Received: by mis.mcw.edu (DECUS UUCP ///1.2a/2.5/); Wed, 24 Oct 90 08:15:25 CDT Date: Wed, 24 Oct 90 08:15:25 CDT Message-Id: <0093EA90CFB67D60.20400660@mis.mcw.edu> From: "Chris Tenaglia - 257-8765" Subject: Packed Decimal Procedures To: icon-group@cs.arizona.edu Here are the procedures pack() and unpack(). They are part of my personal IPL. Most of my icon programs have so much in common that this 10 module library I use as a program starter. I 'include' the file into the editor, chop out from 2 to 7 modules, and begin coding while line := read(in) do { HERE } which is pretty good in regards to 'reusable modules' or 'software chips', the chief goal of ADA and OOPS. I wonder if anyone else has developed their own 'software chips' or 'program starter'? Chris Tenaglia (System Manager) | Medical College of Wisconsin 8701 W. Watertown Plank Rd. | Milwaukee, WI 53226 (414)257-8765 | tenaglia@mis.mcw.edu, mcwmis!tenaglia ################################################################## # # # THIS PROCEDURE PACKS AN INTEGER IN TO PACKED DECIMAL STRING. # # # ################################################################## procedure pack(num,width) local int,sign,prep,packed,i,word (int := integer(num)) | fail if int < 0 then sign := "=" else sign := "<" prep := int || sign packed := "" if (*prep % 2) ~= 0 then prep := "0" || prep every i := 1 to *prep by 2 do { word := prep[i+:2] if word[-1] == ("=" | "<") then { packed ||:= char(word[1]*16 + ord(word[2])-48) next } packed ||:= char(word[1]*16 + word[2]) } /width := *packed return right(packed,width,"\0") end ################################################################## # # # THIS PROCEDURE UNPACKS A VALUE INTO AN INTEGER. USING THIS # # CODE SEGMENT REQUIRES LINKING WITH RADCON FROM THE IPL. # # # ################################################################## procedure unpack(val,width) local tmp,number,tens,ones,sign tmp := "" sign := 1 every number := ord(!val) do tmp ||:= right(map(radcon(number,10,16),&lcase,&ucase),2,"0") if tmp[-1] == ("B" | "D") then sign := -1 tmp[-1] := "" tmp *:= sign /width := *tmp return right(tmp,width) end From sboisen@BBN.COM Wed Oct 24 13:06:05 1990 Message-Id: <9010242006.AA03609@megaron.cs.arizona.edu> Received: from SLANG.BBN.COM by megaron.cs.arizona.edu (5.61/15) via SMTP id AA03609; Wed, 24 Oct 90 13:06:05 -0700 To: tenaglia@mis.mcw.edu Cc: icon-group@cs.arizona.edu In-Reply-To: Chris Tenaglia - 257-8765's message of Wed, 24 Oct 90 08:15:25 CDT <0093EA90CFB67D60.20400660@mis.mcw.edu> Subject: Packed Decimal Procedures From: Sean Boisen Sender: sboisen@BBN.COM Reply-To: sboisen@BBN.COM Date: Wed, 24 Oct 90 16:02:47 EDT > I wonder if anyone else has developed > their own 'software chips' or 'program starter'? > > Chris Tenaglia (System Manager) | Medical College of Wisconsin > 8701 W. Watertown Plank Rd. | Milwaukee, WI 53226 > (414)257-8765 | tenaglia@mis.mcw.edu, mcwmis!tenaglia Since most of the Icon code i write is for small Unix-like utilities, i frequently care about setting up handling for command line arguments. My basic template therefore looks like this (i believe i got this from one of the newsletters): ---------------------------------------------------------------------- # procedure main(cmdline) local switch while switch := get(cmdline) do { case switch of { "-t": tswitch := 1 "-l": limit := integer(get(cmdline)) | Usage() default: Usage() } } end # stop, informing of incorrect usage # procedure Usage() stop("usage for : [-t] [-l n]") end ---------------------------------------------------------------------- This gives me two examples of command line switches, one with and one without args, and an helpful message if i get the args wrong. Typically the first thing i do is edit the args and usage message, and then start working on the guts of the thing. ........................................ Sean Boisen -- sboisen@bbn.com BBN Systems and Technologies, Cambridge MA From icon-group-request@arizona.edu Thu Oct 25 11:49:31 1990 Resent-From: icon-group-request@arizona.edu Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP id AA17695; Thu, 25 Oct 90 11:49:31 -0700 Received: from ucbvax.Berkeley.EDU by Arizona.edu; Thu, 25 Oct 90 11:48 MST Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA09800; Thu, 25 Oct 90 11:37:45 -0700 Received: from USENET by ucbvax.Berkeley.EDU with netnews for icon-group@arizona.edu (icon-group@arizona.edu) (contact usenet@ucbvax.Berkeley.EDU if you have questions) Resent-Date: Thu, 25 Oct 90 11:48 MST Date: 25 Oct 90 01:32:31 GMT From: att!linac!midway!quads.uchicago.edu!goer@ucbvax.Berkeley.EDU Subject: RE: Packed Decimal Procedures Sender: icon-group-request@arizona.edu Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: <14882FAEA41520A50F@Arizona.edu> Message-Id: <1990Oct25.013231.21009@midway.uchicago.edu> Organization: University of Chicago X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.EDU References: <0093EA90CFB67D60.20400660@mis.mcw.edu> Tenaglia@mis.mcw.edu ("Chris Tenaglia - 257-8765") writes: > >Here are the procedures pack() and unpack(). They are part of my >personal IPL. I couldn't resist toying with the (un)pack routines just posted. There's no reason I can see for storing the sign if the int is positive, so I cut that part out. I also added another unpack routine, which runs a bit faster, and behaves somewhat differently than the one Chris wrote. Oh, I should perhaps add that the thing has been redone in IPL format, and I've eliminated most automatic type conversions. They automatic type conversion thing is just a pet peeve of mine. I hope no one holds it against me :-). -Richard ############################################################################ # # Name: packunpk.icn # # Title: Pack and unpack packed-decimal strings # # Author: Chris Tenaglia (modified by Richard L. Goerwitz) # # Version: 1.1 # ############################################################################ # # Integers written directly as strings occupy much more space # than they need to. One easy way to shrink them a bit is to "pack" # them, i.e. convert each decimal digit into a four-byte binary # code, and pack these four-bit chunks into eight-bit characters, # which can be written to a file. # # Interestingly, packing decimal strings in this manner lends # itself to unpacking by treating each character as a base-10 # integer, and then converting it to base-16. Say we have an input # string "99." Pack() would convert it to an internal representation # of char(16*9 + 9), i.e. char(153). Unpack would treat this # char(153) representation as a base-10 integer, and convert it to # base 16 (i.e. 10r153 -> 16r99). The 99 is, of course, what we # started with. # # Note that two unpack routines are provided here: The first, by # Tanaglia, utilizes radcon.icn from the IPL. The second, by # Goerwitz, does not. They utilize very different methods, but both # amount to basically the same thing. Goerwitz's routine returns an # integer, though, and has no "width" argument. # ############################################################################ # # Links: radcon.icn # ############################################################################ # link radcon.icn procedure pack(num,width) # THIS PROCEDURE PACKS AN INTEGER INTO A PACKED DECIMAL STRING. local int, sign, prep, packed, word int := integer(num) | fail # There's really no need to store the sign if it's positive. if int < 0 then sign := "=" else sign := "" prep := string(abs(int)) || sign packed := "" if (*prep % 2) ~= 0 then prep := "0" || prep prep ? { while word := move(2) do { if pos(0) then packed ||:= char(integer(word[1])*16 + ord(word[2])-48) else packed ||:= char(integer(word[1])*16 + integer(word[2])) } } /width := *packed return right(packed, width, "\0") end procedure unpack(val,width) # THIS PROCEDURE UNPACKS A VALUE INTO A STRING-INTEGER. USING THIS # CODE SEGMENT REQUIRES LINKING WITH RADCON FROM THE IPL. local tmp, number, tens, ones, sign tmp := "" sign := 1 every number := ord(!val) do tmp ||:= right(map(radcon(number,10,16),&lcase,&ucase),2,"0") if tmp[-1] == ("B" | "D") then { sign := -1 tmp[-1] := "" } tmp *:= sign /width := *string(tmp) return right(string(tmp), width) end procedure unpack2(val) # THIS PROCEDURE UNPACKS A VALUE INTO AN STRING-INTEGER. local unpacked, int unpacked := "" val ? { while int := ord(move(1)) do { unpacked ||:= string(iand(2r11110000,int) / 16) if pos(0) then { if iand(2r00001111,int) = 13 then { unpacked := "-" || unpacked break } } unpacked ||:= string(iand(2r00001111,int)) } } return integer(unpacked) end From tenaglia@mis.mcw.edu Sat Oct 27 08:23:20 1990 Received: from rutgers.edu by megaron.cs.arizona.edu (5.61/15) via SMTP id AA09782; Sat, 27 Oct 90 08:23:20 -0700 Received: from uwm.UUCP by rutgers.edu (5.59/SMI4.0/RU1.4/3.08) with UUCP id AA07803; Sat, 27 Oct 90 11:16:11 EDT Received: by uwm.edu; id AA12078; Sat, 27 Oct 90 09:51:02 -0500 Received: from mcwmis by fps.mcw.edu (DECUS UUCP ///1.2a/2.5/); Sat, 27 Oct 90 08:59:29 CDT Received: by mis.mcw.edu (DECUS UUCP ///1.2a/2.5/); Sat, 27 Oct 90 08:29:55 CDT Date: Sat, 27 Oct 90 08:29:55 CDT Message-Id: <0093ECEE55262040.20400CCB@mis.mcw.edu> From: "Chris Tenaglia - 257-8765" Subject: pack and unpack routines To: icon-group@cs.arizona.edu regarding : suggested enhancements to the pack & unpack routines > >Tenaglia@mis.mcw.edu ("Chris Tenaglia - 257-8765") writes: >> >>Here are the procedures pack() and unpack(). They are part of my >>personal IPL. > >I couldn't resist toying with the (un)pack routines just posted. >There's no reason I can see for storing the sign if the int is >positive, so I cut that part out. I also added another unpack >routine, which runs a bit faster, and behaves somewhat differently >than the one Chris wrote. > >Oh, I should perhaps add that the thing has been redone in IPL >format, and I've eliminated most automatic type conversions. >They automatic type conversion thing is just a pet peeve of mine. >I hope no one holds it against me :-). > >-Richard MORE,... The reason I handled the sign in the manner I did was that DEC and IBM computers actually handle numbers in that format in some modes of operation. Other language programs (COBOL, BASIC, FORTRAN, etc,..) may still need access to those numbers for some reason, thus I maintained the sign, even though it cost me 4 bits. Your versions are fine so long as icon programs using this are the only accessors to the data. Chris Tenaglia (System Manager) Medical College of Wisconsin 8701 W. Watertown Plank Rd. Milwaukee, WI 53226 (414)257-8765 tenaglia@mis.mcw.edu, mcwmis!tenaglia From cary@hpcllak.cup.hp.com Wed Oct 31 16:10:31 1990 Received: from relay.hp.com (hp-sde.sde.hp.com) by megaron.cs.arizona.edu (5.61/15) via SMTP id AA13689; Wed, 31 Oct 90 16:10:31 -0700 Received: from hpcllak.cup.hp.com by relay.hp.com with SMTP (16.5/15.5+IOS 3.13) id AA29399; Wed, 31 Oct 90 15:10:27 -0800 Message-Id: <9010312310.AA29399@relay.hp.com> Received: by hpcllak; Wed, 31 Oct 90 15:09:41 pst Date: Wed, 31 Oct 90 15:09:41 pst From: Cary Coutant To: icon-group@cs.arizona.edu Subject: date arithmetic > Perhaps I didn't look close enough at the IPL, but I am interested in time > and date manipulation routines. Well, it doesn't quite meet your specs, but I have here a set of Icon procedures that convert dates to and from Julian day numbers. Given the Julian day numbers, you can do all of the arithmetic you like and the convert back. These routines are as correct as I can establish from a several sources, the most helpful ones being the _Astronomical_Calendar_ (annual) and _Astronomical_Companion_, both by Guy Ottewell (great books, both!). I got the trick for converting month number to days-in-year-so-far from some well-known published calculator algorithms floating around the net. -Cary Coutant, Hewlett-Packard Computer Language Laboratory # This is a shell archive. Remove anything before this line, # then unpack it by saving it in a file and typing "sh file". # # Wrapped by Cary Coutant on Wed Oct 31 15:04:41 1990 # # This archive contains: # jdate.icn # LANG=""; export LANG PATH=/bin:/usr/bin:$PATH; export PATH echo x - jdate.icn cat >jdate.icn <<'@EOF' # Note: "Julian day" is named after the father of the astronomer who # invented the Julian day numbering system. It is unrelated to the # "Julian calendar", which was the one established by Julius Caesar, # and introduced the concept of a leap year every fourth year. The # Gregorian calendar, established by Pope Gregory the somethingorother, # corrected the Julian calendar by eliminating three leap years out of # every four hundred years, bringing the average year to a length of # 365 + 1/4 - 3/100 = 365.22 days. # By the way, to astronomers (and to this program), the year 1 B.C. # is year 0, 2 B.C. is -1, etc. global cutover # julian day number of cutover from Julian to # Gregorian calendar (should be the first day # skipped). procedure main(args) cutover := julian(9, 3, 1752) # England and the Colonies if !args == "-c" then cutover := julian(10, 5, 1582) # Catholic countries convert() return end procedure convert() local g while read() ? { month := integer(tab(many('0123456789'))) tab(many(' /')) day := integer(tab(many('0123456789'))) tab(many(' /')) year := integer(tab(many('-0123456789'))) g := gregorian(month, day, year) write(datestring(g), " = ", g) } return end ## gregorian(m,d,y) - Return the Julian day number for 12:00 noon # on the given m/d/y, using the Gregorian calendar. procedure gregorian(month, day, year) local g g := julian(month, day, year) if g >= cutover then { if month < 3 then year -:= 1 g +:= 2 - floor(year/100.0) + floor(year/400.0) } return g end ## julian(m,d,y) - Return the Julian day number for 12:00 noon # on the given m/d/y, using the Julian calendar. procedure julian(month, day, year) month -:= 3 if month < 0 then { month +:= 12 year -:= 1 } return 1721117 + floor(year*365.25) + (month*153+2)/5 + day end ## datestring() - produces a formatted date string for a julian day number. procedure datestring(g) local dow, mdy, m, d, y dow := dayofweek(g) mdy := tomdy(g) m := mdy[1] d := mdy[2] y := mdy[3] return left(dow, 10) || right(m, 2, "0") || "/" || right(d, 2, "0") || "/" || (right(0= cutover then { qc := floor(day/146097.0) c := floor((day-qc*146097)/36525.0) day +:= c + qc*3 - 2 } year := floor((day*4+3)/1461.0) day -:= floor(year*1461/4.0) month := (day*5+2)/153 day := day - (month*153+2)/5 + 1 month +:= 3 if month > 12 then { month -:= 12 year +:= 1 } return [month, day, year] end ## floor() - rounds to an integer towards negative infinity. procedure floor(f) local i i := integer(f) if i > f then i -:= 1 return i end ## test() - Tests the date conversion routines by brute force, # by stepping through day by day through the years 1601 to 2000. # # procedure test() # local g, year, month, day, mdy # # g := julian(1, 1, 1601) # every year := 1601 to 2000 do { # every month := 1 to 12 do { # every day := 1 to ndays(year, month) do { # if year = 1752 & month = 9 & 2 < day < 14 then next # g1 := gregorian(month, day, year) # if g ~= g1 then # write("gregorian(", month, "/", day, "/", year, ") is ", # g1, ", should be ", g) # mdy := tomdy(g) # if mdy[1] ~= month | mdy[2] ~= day | mdy[3] ~= year then # write("tomdy(", g, ") is ", # mdy[1], "/", mdy[2], "/", mdy[3], # ", should be ", # month, "/", day, "/", year) # g +:= 1 # } # } # if year % 25 = 0 then write(year) # } # return # end # # procedure ndays(year, month) # local mdays # static stdyear, leapyear # # initial { # stdyear := [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] # leapyear := [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] # } # # mdays := stdyear # if year % 4 = 0 then mdays := leapyear # if (1752 < year) % 400 = (100|200|300) then mdays := stdyear # return .mdays[month] # end @EOF chmod 664 jdate.icn exit 0 From @um.cc.umich.edu:Paul_Abrahams@Wayne-MTS Fri Nov 2 14:13:59 1990 Received: from umich.edu by megaron.cs.arizona.edu (5.61/15) via SMTP id AA27706; Fri, 2 Nov 90 14:13:59 -0700 Received: from um.cc.umich.edu by umich.edu (5.61/1123-1.0) id AA04865; Fri, 2 Nov 90 16:13:55 -0500 Received: from Wayne-MTS by um.cc.umich.edu via MTS-Net; Fri, 2 Nov 90 16:09:19 EST Date: Fri, 2 Nov 90 14:33:12 EST From: Paul_Abrahams%Wayne-MTS@um.cc.umich.edu To: icon-group@cs.arizona.edu Message-Id: <266508@Wayne-MTS> Subject: Generating variables The Icon operator ! generates a sequence of variables when it's applied to a list, string, or record. My question is: is there any way that a user-defined procedure can generate variables (other than using the "variable" function)? Here is my attempt at it; it didn't work. Paul Abrahams abrahams%wayne-mts@um.cc.umich.edu procedure main () l := [1,2,3,4] every writes(!l, " ") write() # writes 1 2 3 4 every !l := 9 every writes(!l, " ") write() # writes 9 9 9 9 every !p1(l) := 7 # produces an error; can't assign 7 to "9" every writes(!l, " ") write() end procedure p1(z) suspend !z end From cary@hpcllak.cup.hp.com Fri Nov 2 16:04:49 1990 Received: from relay.hp.com ([15.255.152.2]) by megaron.cs.arizona.edu (5.61/15) via SMTP id AA01495; Fri, 2 Nov 90 16:04:49 -0700 Received: from hpcllak.cup.hp.com by relay.hp.com with SMTP (16.5/15.5+IOS 3.13) id AA26865; Fri, 2 Nov 90 15:03:48 -0800 Message-Id: <9011022303.AA26865@relay.hp.com> Received: by hpcllak; Fri, 2 Nov 90 15:03:02 pst Date: Fri, 2 Nov 90 15:03:02 pst From: Cary Coutant To: icon-group@cs.arizona.edu Subject: Generating variables The program would have worked but for a double bang -- you applied the bang operator within the procedure, and on the procedure call. Removing the latter yields a program that does what you were expecting. -Cary Coutant, HP Computer Language Lab procedure main () l := [1,2,3,4] every writes(!l, " ") write() # writes 1 2 3 4 every !l := 9 every writes(!l, " ") write() # writes 9 9 9 9 every p1(l) := 7 # no extra bang operator here every writes(!l, " ") write() end procedure p1(z) suspend !z end From @um.cc.umich.edu:Paul_Abrahams@Wayne-MTS Sat Nov 3 02:13:57 1990 Received: from umich.edu by megaron.cs.arizona.edu (5.61/15) via SMTP id AA14051; Sat, 3 Nov 90 02:13:57 -0700 Received: from um.cc.umich.edu by umich.edu (5.61/1123-1.0) id AA01640; Sat, 3 Nov 90 04:13:51 -0500 Received: from Wayne-MTS by um.cc.umich.edu via MTS-Net; Sat, 3 Nov 90 04:10:13 EST Date: Fri, 2 Nov 90 22:52:16 EST From: Paul_Abrahams%Wayne-MTS@um.cc.umich.edu To: icon-group@cs.arizona.edu Message-Id: <266657@Wayne-MTS> Subject: Dereferencing Yes, Beth was absolutely right about the way to fix my example of a generator that returns variables. I find it interesting that Icon attempts to preserve the "variable"-ness of a returned entity, dereferencing it only if it has to. But I can't think of a way of moving a variable in the other direction: from caller to callee. Not only does Icon have call-by-value---there doesn't seem to be any way to circumvent it. Or is there------? Paul Paul Abrahams abrahams%wayne-mts@um.cc.umich.edu From icon-group-request@arizona.edu Fri Nov 9 02:27:38 1990 Resent-From: icon-group-request@arizona.edu Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP id AA14768; Fri, 9 Nov 90 02:27:38 -0700 Received: from ucbvax.Berkeley.EDU by Arizona.edu; Fri, 9 Nov 90 02:27 MST Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA19952; Fri, 9 Nov 90 01:17:06 -0800 Received: from USENET by ucbvax.Berkeley.EDU with netnews for icon-group@arizona.edu (icon-group@arizona.edu) (contact usenet@ucbvax.Berkeley.EDU if you have questions) Resent-Date: Fri, 9 Nov 90 02:27 MST Date: 8 Nov 90 19:35:41 GMT From: wuarchive!cs.utexas.edu!news-server.csri.toronto.edu!clyde.concordia.ca!NSTN.NS.CA!cs.dal.ca!dal1!06davis@decwrl.dec.com Subject: What are ICONS? Sender: icon-group-request@arizona.edu Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: <090D2BD08B19A041D2@Arizona.edu> Message-Id: <2219@ac.dal.ca> X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.EDU Please forgive me, all those who are knowledgeable, but what are icons as applied to computers. I know that they are in plain 'ol English, but what are they and what kind of system do they run on? No flames please, I might just go and slit my wrists. Davis B. From icon-group-request@arizona.edu Fri Nov 9 09:58:12 1990 Resent-From: icon-group-request@arizona.edu Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP id AA06160; Fri, 9 Nov 90 09:58:12 -0700 Received: from ucbvax.Berkeley.EDU by Arizona.edu; Fri, 9 Nov 90 09:57 MST Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA28203; Fri, 9 Nov 90 08:55:35 -0800 Received: from USENET by ucbvax.Berkeley.EDU with netnews for icon-group@arizona.edu (icon-group@arizona.edu) (contact usenet@ucbvax.Berkeley.EDU if you have questions) Resent-Date: Fri, 9 Nov 90 09:57 MST Date: 9 Nov 90 16:42:27 GMT From: cme!cam!koontz@uunet.uu.net Subject: RE: What are ICONS? Sender: icon-group-request@arizona.edu Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: <08CE390FA6B9A046CE@Arizona.edu> Message-Id: <5726@alpha.cam.nist.gov> Organization: National Institute of Standards & Technology, Gaithersburg, MD X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.EDU References: <2219@ac.dal.ca> Icon has two meanings in the computer context, neither having anything to do with the Black Virgin of Kiev. 1) In the context of this newsgroup it is a programming language called Icon. Icon is a descendent of SNOBOL, but emphasizes the succeed/fail attribute of programming language statements in SNOBOL, rather than the pattern matching application per se. 2) More generally, an icon is a representation of a file or process in certain graphics-based user interfaces. You click on the icon with your mouse to get a menu of things that you can do to the file or with the application. For example, suppose that you are conducting a terminal session in a window. You can reduce the window to an icon (perhaps a picture of a terminal), and stick it in the corner of your screen while you do something else. Later you can click on the icon to get a menu that includes the option of converting the icon back into a window in which there is a terminal session. From goer%sophist@gargoyle.uchicago.edu Fri Nov 9 10:28:38 1990 Resent-From: goer%sophist@gargoyle.uchicago.edu Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP id AA08389; Fri, 9 Nov 90 10:28:38 -0700 Return-Path: goer@sophist.uchicago.edu Received: from gargoyle.uchicago.edu by Arizona.edu; Fri, 9 Nov 90 10:28 MST Received: by gargoyle.uchicago.edu from sophist.uchicago.edu (5.59/1.14) id AA07751; Fri, 9 Nov 90 11:27:56 199 Received: by sophist (4.1/UofC3.1X) id AA19459; Fri, 9 Nov 90 11:31:24 CST Resent-Date: Fri, 9 Nov 90 10:28 MST Date: Fri, 9 Nov 90 11:31:24 CST From: Richard Goerwitz Subject: what are icons Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: <08C9F83D3F79A045C3@Arizona.edu> Message-Id: <9011091731.AA19459@sophist> X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.EDU Please forgive me, all those who are knowledgeable, but what are icons as applied to computers. I know that they are in plain 'ol English, but what are they and what kind of system do they run on? No flames please, I might just go and slit my wrists. Before you do that, make sure to donate some blood to your local hospital, where it is probably badly needed. Seriously, though, here's an brief answer to your question: Icons, as used in relatively recent computer lingo, refer to symbols on your computer screen that, when activated in one way or another, function in a way that bears some analogy to their form. For instance, what do you think activating a picture of a trash can does? Sure: It trashes something. Anyway, you have just posted to the Icon group, a mailing list dedicated to discussion of the Icon programming language. It's got nothing to do with those cute pictures on your computer screen (if, that is, you are working with a windowing system that has them). Icon is the successor to Snobol4, and is used by people for general programming tasks, especially those in- volving heuristic "algorithms," symbol manipulation, and anything to do with language and text. It's especially popular among people involved in nonnumeric computing (in my case, the study of ancient languages). I hope you don't find this response cause to slit your wrists, by the way. (Maybe you need to develop a bit thicker skin....) -Richard From nowlin@iwtqg.att.com Fri Nov 9 15:42:56 1990 Message-Id: <9011092242.AA24842@megaron.cs.arizona.edu> Received: from att.att.com by megaron.cs.arizona.edu (5.61/15) via SMTP id AA24842; Fri, 9 Nov 90 15:42:56 -0700 From: nowlin@iwtqg.att.com Date: Fri, 9 Nov 90 15:22 CST Original-From: iwtqg!nowlin (Jerry D Nowlin +1 312 979 7268) To: att!cs.arizona.edu!icon-group Subject: MS-DOS Problem Here's a message I'm passing along for a friend. He's having a problem with Icon on MS-DOS and it doesn't have anything to do with memory this time! Any help would be appreciated. =========================================================================== I think I've tripped on an honest to goodness bug in MS-DOS Icon for Version 8. I've been wrong on things like this before but here's what I found last night. I am reading in a PC-FILE database and processing it with V8 of Icon on an AT&T 6300+ MS-DOS compatible computer. The file is not too long - about 5000 bytes. I start by reading in a number of fixed length (32 byte) header records until I get to a record that starts with a newline character. Normally it would read 20-30 such 32-byte records. But with V8 it read the first and then the next: line := reads(fd,32) returns not 32 characters but just 16 and a subsequent read attempt fails. I presume with EOF. A dump of the database file shows that the 49th character is an octal 032 which is the DOS CONTROL-Z or end-of-file marker. What appears to be happening is that V8 is stopping when it sees that CTL-Z. V7 did not do this! The open was like: fd := open("TESTOFF.DBF","ru") | stop("DBF open failed") and the open succeeds. Joe T. Hall (att!ihlpf!pax) From pax@pax7300.att.com Fri Nov 9 18:10:49 1990 Date: Fri, 9 Nov 90 18:10:49 -0700 From: pax@pax7300.att.com Message-Id: <9011100110.AA00524@megaron.cs.arizona.edu> Received: from att.UUCP by megaron.cs.arizona.edu (5.61/15) via UUCP id AA00524; Fri, 9 Nov 90 18:10:49 -0700 To: att!cs.arizona.edu!icon-group Subject: MSDOS V8 reads Cc: pax@ihlpf.att.com, nowlin@iwtqg.att.com Icon Trekkies! Is it possible that Version 8 of Icon on MS-DOS will not read past an octal 32 with reads??? procedure main() fd := open("TESTOFF.DBF","ru") | stop("DBF open failed") while line := reads(fd,32) do { write("*line=",*line) } end TESTOFF.DBF happens to have an octal 032 in position 49 of the file. The above program on MS-DOS returns: *line=32 *line-16 The above program on my UNIX-pc reads continuous 32 byte lines until it reaches the real end-of-file. It appears to me that Version 8 of Icon for MS-DOS will not read past this CTL-Z (octal 032) character. Joe Hall From sbw@turing.cse.nau.edu Fri Nov 9 18:52:47 1990 Received: from turing.cse.nau.edu ([134.114.64.4]) by megaron.cs.arizona.edu (5.61/15) via SMTP id AA00115; Fri, 9 Nov 90 18:52:47 -0700 Received: by turing.cse.nau.edu (5.64/1.34) id AA02657; Fri, 9 Nov 90 17:53:05 -0700 Message-Id: <9011100053.AA02657@turing.cse.nau.edu> From: sbw@turing.cse.nau.edu (Steve Wampler) Date: Fri, 9 Nov 1990 17:53:04 MST X-Mailer: Mail User's Shell (7.2.0 10/31/90) To: icon-group@cs.arizona.edu Subject: example of function tracing... A recent Icon Newsletter showed a neat way to trace a builtin function. The following little package shows how this might be used conveniently. Briefly, the procedure 'trace_option()' is passed the argument list to 'main'. The argument '-trace' turns on general tracing. Arguments of the form '-Ffunction' turn on tracing of the builtin function 'function', if possible. I think the comments explain everything else. Right now, the package only traces functions that I frequently want to trace, though it is easy to add tracing of others. ---- snip 'traceset.icn' ---- procedure trace_options(args) local nextarg, arg # # Check arguments for tracing parameters # # can trace some builtin functions, e.g.: # # -Ftab # # will trace tab() # every arg := !args do { if map(arg) == "-trace" then &trace := -1 else if match("-F",arg) then { # trace a built-in function set_trace(arg[3:0]) } } return end procedure set_trace(vf) local traceset, vp # # trace the builtin function 'vf', if possible # if not find("Version 8",&version) then { write(&errout,"You are running ",&version,", which doesn't support") write(&errout," this package. You need version 8.") stop() } # so far, can only trace these (easy to add more) traceset := set(["any","bal","copy","find","many","move","tab","upto"]) if member(traceset,vf) then { &trace := -1 # have to also trace all procedures! vp := vf vp[1] := map(vp[1],&lcase,&ucase) variable(vp) :=: variable(vf) write(&errout, "Calls of '",vf,"' will be traced as calls of '",vp,"'") } else write(&errout, vf, " is not a function that can be traced!") return end procedure Any(cs,s,i,j) return Any(cs,s,i,j) end procedure Bal(cs,cl,cr,s,i,j) suspend Bal(cs,cl,cr,s,i,j) end procedure Copy(cs) return Copy(cs) end procedure Find(s1,s,i,j) suspend Find(s1,s,i,j) end procedure Many(cs,s,i,j) return Many(cs,s,i,j) end procedure Match(s1,s,i,j) return Match(s1,s,i,j) end procedure Move(cs) suspend Move(cs) end procedure Tab(i) suspend Tab(i) end procedure Upto(cs,s,i,j) suspend Upto(cs) end ---- snip 'traceset.icn' end ---- -- Steve Wampler {....!arizona!naucse!sbw} {sbw@turing.cse.nau.edu} From icon-group-request@arizona.edu Fri Nov 9 19:01:38 1990 Resent-From: icon-group-request@arizona.edu Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP id AA00530; Fri, 9 Nov 90 19:01:38 -0700 Received: from ucbvax.Berkeley.EDU by Arizona.edu; Fri, 9 Nov 90 17:11 MST Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA03261; Fri, 9 Nov 90 16:05:33 -0800 Received: from USENET by ucbvax.Berkeley.EDU with netnews for icon-group@arizona.edu (icon-group@arizona.edu) (contact usenet@ucbvax.Berkeley.EDU if you have questions) Resent-Date: Fri, 9 Nov 90 17:12 MST Date: 9 Nov 90 22:39:30 GMT From: julius.cs.uiuc.edu!zaphod.mps.ohio-state.edu!unix.cis.pitt.edu!dsinc!netnews.upenn.edu!msuinfo!midway!iitmax!ed@apple.com Subject: RE: What are ICONS? Sender: icon-group-request@arizona.edu Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: <089190666E99A04A34@Arizona.edu> Message-Id: <4495@iitmax.IIT.EDU> Organization: Illinois Institute of Technology X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.edu References: <2219@ac.dal.ca>, <5726@alpha.cam.nist.gov> In article <5726@alpha.cam.nist.gov> koontz@cam.nist.gov (John E. Koontz X5180) writes: > [what does Icon mean?] >1) In the context of this newsgroup it is a programming language called > Icon. Icon is a descendent of SNOBOL, but emphasizes the succeed/fail > attribute of programming language statements in SNOBOL, rather than > the pattern matching application per se. One thing I've been wondering, and I've not seen it in the forward to the Icon book, is WHY is the language named "Icon"?? By the way, as long as I'm asking, does anyone know how SNOBOL and SPITBOL get thier names... You know, almost _every_ FORTRAN book mentions that its name comes from FORmula TRANslation, or BASIC is Beginners All-purpose Symbolic Instruction Code (or whatever) :-) -- //==========================================================================\\ || Ed Federmeyer || Internet: ed@iitMax.iit.edu || || "Unauthorized access is || Bitnet: sysed@iitVax || || strictly unauthorized." || Office: (312) 567-5981 || \\==========================================================================// From sbw@turing.cse.nau.edu Sun Nov 11 10:50:19 1990 Received: from turing.cse.nau.edu by megaron.cs.arizona.edu (5.61/15) via SMTP id AA08540; Sun, 11 Nov 90 10:50:19 -0700 Received: by turing.cse.nau.edu (5.64/1.34) id AA04852; Sun, 11 Nov 90 10:49:56 -0700 Message-Id: <9011111749.AA04852@turing.cse.nau.edu> From: sbw@turing.cse.nau.edu (Steve Wampler) Date: Sun, 11 Nov 1990 10:49:56 MST X-Mailer: Mail User's Shell (7.2.0 10/31/90) To: icon-group@cs.arizona.edu Subject: Oops, wrong publication... The description for simple builtin function tracing came from the Icon Analyst, not the Icon Newsletter. (If you're only getting the Newsletter, you might look into the Analyst - it has some neat things in it.) -- Steve Wampler {....!arizona!naucse!sbw} {sbw@turing.cse.nau.edu} From @s.ms.uky.edu:mtbb83@ms.uky.edu Sun Nov 11 12:22:11 1990 Resent-From: @s.ms.uky.edu:mtbb83@ms.uky.edu Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP id AA10366; Sun, 11 Nov 90 12:22:11 -0700 Received: from e.ms.uky.edu by Arizona.edu; Sun, 11 Nov 90 12:21 MST Received: from s.ms.uky.edu by g.ms.uky.edu id aa26311; 11 Nov 90 14:16 EST Resent-Date: Sun, 11 Nov 90 12:21 MST Date: Sun, 11 Nov 90 14:16:24 EST From: Dr Jerome Krumpelman Subject: Remove name Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: <0727C1C63859A05510@Arizona.edu> Message-Id: <9011111416.aa25042@s.s.ms.uky.edu> X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.edu I have enjoyed and learned from receiving the Icon traffic on *.edu net. However, please remove my name from the list, for now. Please do not re-send this message over the net, and do not purge me from the mailed material ( ICON news...). Thanx -- jk -- Jerome Krumpelman mtbb83@ms.uky.edu {rutgers,uunet}!ukma!ms!mtbb83 CompuServe 70441,2760 From icon-group-request@arizona.edu Mon Nov 12 12:01:41 1990 Resent-From: icon-group-request@arizona.edu Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP id AA28358; Mon, 12 Nov 90 12:01:41 -0700 Received: from ucbvax.Berkeley.EDU by Arizona.edu; Mon, 12 Nov 90 12:01 MST Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA07849; Mon, 12 Nov 90 10:57:19 -0800 Received: from USENET by ucbvax.Berkeley.EDU with netnews for icon-group@arizona.edu (icon-group@arizona.edu) (contact usenet@ucbvax.Berkeley.EDU if you have questions) Resent-Date: Mon, 12 Nov 90 12:01 MST Date: 12 Nov 90 07:19:43 GMT From: castor.ucdavis.edu!f140026@ucdavis.ucdavis.edu Subject: p/d icon wanted for Macintosh Sender: icon-group-request@arizona.edu Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: <0661772D616780041E@Arizona.edu> Message-Id: <9266@aggie.ucdavis.edu> Organization: University of California, Davis X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.edu Hi, I'm looking for an anonymously ftp-able version of Icon that will run on the Macintosh SE. The back of my Icon book says the University of Arizona to Tucson has it -- does anyone know if it's ftp-able? Thanks! f140026@castor.ucdavis.edu From MYankowski.BSPO@DOCKMASTER.NCSC.MIL Mon Nov 12 15:31:51 1990 Received: from DOCKMASTER.NCSC.MIL by megaron.cs.arizona.edu (5.61/15) via SMTP id AA05913; Mon, 12 Nov 90 15:31:51 -0700 Date: Mon, 12 Nov 90 17:27 EST From: MYankowski@DOCKMASTER.NCSC.MIL Subject: Icon Analyst To: icon-group@cs.arizona.edu Message-Id: <901112222754.543046@DOCKMASTER.NCSC.MIL> Could someone please provide more information on the ICON Analyst? Mike DOCKMASTER From ralph Mon Nov 12 16:02:27 1990 Received: from cheltenham.cs.arizona.edu by megaron.cs.arizona.edu (5.61/15) via SMTP id AA07058; Mon, 12 Nov 90 16:02:27 -0700 Date: Mon, 12 Nov 90 16:02:20 MST From: "Ralph Griswold" Message-Id: <9011122302.AA04186@cheltenham.cs.arizona.edu> Received: by cheltenham.cs.arizona.edu; Mon, 12 Nov 90 16:02:20 MST To: MYankowski@DOCKMASTER.NCSC.MIL Subject: Re: Icon Analyst Cc: icon-group The Icon Analyst is a technical newsletter published 6 times a year by the Icon Project. It is 12 pages, 8.5x11". It covers various aspects of the Icon programming language, mostly related to programming. The editors are Ralph E. Griswold and Madge T. Griswold, the same as for the Icon Newsletter, which features less tehcnical material of a more topical interest. The first issue of the Analyst was published in August, 1990. The third issue is presently being prepared for mailing. Articles so far have covered "getting started", memory monitoring, benchmarking expressions, expression evaluation, syntactic pitfalls, program readability, writing portable programs, string scanning, generators, and so forth. There's also a regular "programming tips" feature. A subscription to the Icon Analyst is $25 per year, which includes first-class postage in the United States, Canada, and Mexico. There is an additional charge of $10 per year for overseas subscriptions, which are sent by first-class airmail. Persons wishing to subscribe should make checks payable to The University of Arizona and send them to Icon Project Department of Computer Science The University of Arizona Tucson, AZ 85721 U.S.A. Mastercard and Visa also are acceptable. Ralph Griswold / Dept of Computer Science / Univ of Arizona / Tucson, AZ 85721 +1 602 621 6609 ralph@cs.arizona.edu uunet!arizona!ralph From icon-group-request@arizona.edu Tue Nov 13 14:01:54 1990 Resent-From: icon-group-request@arizona.edu Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP id AA28621; Tue, 13 Nov 90 14:01:54 -0700 Received: from ucbvax.Berkeley.EDU by Arizona.edu; Tue, 13 Nov 90 14:01 MST Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA03231; Tue, 13 Nov 90 13:00:49 -0800 Received: from USENET by ucbvax.Berkeley.EDU with netnews for icon-group@arizona.edu (icon-group@arizona.edu) (contact usenet@ucbvax.Berkeley.EDU if you have questions) Resent-Date: Tue, 13 Nov 90 14:01 MST Date: 12 Nov 90 21:28:19 GMT From: hpcc05!col!hpldola!hp-lsd!egul@hplabs.hpl.hp.com Subject: RE: What are ICONS? Sender: icon-group-request@arizona.edu Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: <058780800407800E43@Arizona.edu> Message-Id: <10110001@hp-lsd.COS.HP.COM> Organization: HP Logic Systems Division - ColoSpgs, CO X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.edu References: <2219@ac.dal.ca> an icon is a bitmap, created by either you or by the application shell, that pictorally represents an application, process, login, ...... whatever, to which you can jump from the current window. This is usually done via a mouse. "Clicking" the icon will usually start a script which otherwise you would have to run or key in manually. A picture (icon) is worth a thousand words, get it? From ralph Wed Nov 14 10:34:41 1990 Received: from cheltenham.cs.arizona.edu by megaron.cs.arizona.edu (5.61/15) via SMTP id AA17349; Wed, 14 Nov 90 10:34:41 -0700 Date: Wed, 14 Nov 90 10:34:39 MST From: "Ralph Griswold" Message-Id: <9011141734.AA01002@cheltenham.cs.arizona.edu> Received: by cheltenham.cs.arizona.edu; Wed, 14 Nov 90 10:34:39 MST To: icon-group Subject: Bug in MS-DOS Version 8 Icon As noted in recent icon-group mail, there is a bug in the first release of Version 8 Icon for MS-DOS. The bug is that the "untranslated" mode of input/output doesn't work -- input/output always is in the translated mode. This means that if you're reading a "binary" file carriage-return/line-feed combintations get turned into line-feeds on input and conversely on output. That's not so bad, as long as you're not examining or changing the file inside an Icon program. Much worse is that a control-Z character (hex 1A) terminates input. Note that this is a problem only if you're doing input/output on binary files. It does not affect input/output on text files. We corrected this problem a couple of months ago and diskettes distributed after mid-September have the correction. If you got Version 8 MS-DOS Icon diskettes from us, check the date on ICON.ARC on the second diskette. If it's before September 16, 1990, it has the bug. We've only recently updated our FTP and RBBS files for MS-DOS Icon, so if you got MS-DOS Icon from us electronically, you probably have a version with the error. If this bug is likely to bother you, you can download the corrected version. If you purchased MS-DOS Icon diskettes from us, send back the second diskette (DE.2) and we'll send you a free replacement. Ralph Griswold / Dept of Computer Science / Univ of Arizona / Tucson, AZ 85721 +1 602 621 6609 ralph@cs.arizona.edu uunet!arizona!ralph From icon-group-request@arizona.edu Wed Nov 14 13:08:29 1990 Resent-From: icon-group-request@arizona.edu Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP id AA25496; Wed, 14 Nov 90 13:08:29 -0700 Received: from ucbvax.Berkeley.EDU by Arizona.edu; Wed, 14 Nov 90 13:07 MST Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA04770; Wed, 14 Nov 90 12:08:00 -0800 Received: from USENET by ucbvax.Berkeley.EDU with netnews for icon-group@arizona.edu (icon-group@arizona.edu) (contact usenet@ucbvax.Berkeley.EDU if you have questions) Resent-Date: Wed, 14 Nov 90 13:08 MST Date: 14 Nov 90 02:11:45 GMT From: usc!zaphod.mps.ohio-state.edu!unix.cis.pitt.edu!dsinc!netnews.upenn.edu!vax1.cc.lehigh.edu!lehigh.bitnet!GB03@ucsd.edu Subject: RE:RE: WHAT ARE ICONS Sender: icon-group-request@arizona.edu Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: <04C5CDEDB927801349@Arizona.edu> Message-Id: <13119021:11:45GB03@lehigh.bitnet> X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.edu @bitnet@lehigh@gb03 It might interest most people to know that BASIC was originally BASIC. Kemeny and Kurtz got tired of telling people it was only BASIC. No one believed the inventors. They finally came up with Beginners All Purpose Simplified Code Ain't history wunderful!? From ralph Wed Nov 14 14:57:24 1990 Received: from cheltenham.cs.arizona.edu by megaron.cs.arizona.edu (5.61/15) via SMTP id AA01067; Wed, 14 Nov 90 14:57:24 -0700 Date: Wed, 14 Nov 90 14:57:22 MST From: "Ralph Griswold" Message-Id: <9011142157.AA08332@cheltenham.cs.arizona.edu> Received: by cheltenham.cs.arizona.edu; Wed, 14 Nov 90 14:57:22 MST To: icon-group Subject: Language names To dispel any misconceptions, the name "Icon" for the Icon programming language is not an acronym nor does it stand for anything. It's just a name. It seemed appropriate (at the time) -- I recall mentioning that the language design was somewhat iconoclastic. Regrettably, we couldn't see the future and the use of the word "icon" for pictograms to identify functions and objects on computer screens. This has caused some confusion and misunderstanding -- some folks see the word "Icon" and expect a programming language for manipulating Icons. The fact that our selection of the word came first doesn't help a lot. Someone asked about the origin of the name SNOBOL4 for an earlier programming language. SNOBOL4 is an acronmyn (of sorts) for StriNg Oriented symBOic Language. We were intending to poke fun at the way acronyms for programming languages were derived. But no one thought it was funny. Ralph Griswold / Dept of Computer Science / Univ of Arizona / Tucson, AZ 85721 +1 602 621 6609 ralph@cs.arizona.edu uunet!arizona!ralph From icon-group-request@arizona.edu Wed Nov 14 16:26:46 1990 Resent-From: icon-group-request@arizona.edu Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP id AA05411; Wed, 14 Nov 90 16:26:46 -0700 Received: from ucbvax.Berkeley.EDU by Arizona.edu; Wed, 14 Nov 90 16:26 MST Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA10416; Wed, 14 Nov 90 15:18:20 -0800 Received: from USENET by ucbvax.Berkeley.EDU with netnews for icon-group@arizona.edu (icon-group@arizona.edu) (contact usenet@ucbvax.Berkeley.EDU if you have questions) Resent-Date: Wed, 14 Nov 90 16:26 MST Date: 14 Nov 90 22:36:09 GMT From: usc!elroy.jpl.nasa.gov!suned1!zaft@ucsd.edu Subject: RE: p/d icon wanted for Macintosh Sender: icon-group-request@arizona.edu Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: <04AA1C182A27801BD1@Arizona.edu> Message-Id: <6070@suned1.Nswses.Navy.MIL> Organization: NSWSES, Port Hueneme, CA X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.edu References: <9266@aggie.ucdavis.edu> In article <9266@aggie.ucdavis.edu> f140026@castor.ucdavis.edu () writes: >Hi, I'm looking for an anonymously ftp-able version of Icon that will >run on the Macintosh SE. The back of my Icon book says the University >of Arizona to Tucson has it -- does anyone know if it's ftp-able? >Thanks! Well, you can FTP to cs.arizona.edu to try to find it; but to the best of my knowledge (correct me if I'm wrong!) the only version of Icon available for the Mac is ProIcon, which is NOT shareware, but is supposed to be inexpensive and very spiffy. Anyone else have more info? [Arizona slaughters ASU 11/24! Nine will be fine ! :-)] -- + Gordon Zaft | zaft@suned1.nswses.navy.mil + + NSWSES, Code 4Y33 | suned1!zaft@elroy.jpl.nasa.gov + + Port Hueneme, CA 93043-5007 | Phone: (805) 982-0684 FAX: 982-8768 + ++++ Ubi caritas et amor, Deus ibi est.++++ From ralph Wed Nov 14 16:44:02 1990 Received: from cheltenham.cs.arizona.edu by megaron.cs.arizona.edu (5.61/15) via SMTP id AA06158; Wed, 14 Nov 90 16:44:02 -0700 Date: Wed, 14 Nov 90 16:44:00 MST From: "Ralph Griswold" Message-Id: <9011142344.AA11247@cheltenham.cs.arizona.edu> Received: by cheltenham.cs.arizona.edu; Wed, 14 Nov 90 16:44:00 MST To: icon-group Subject: Icon for the Macintosh To clarify the situation, there is a public-domain version of Icon available from the Icon Project, but it is not a stand-alone application and requires the MPW to run. MPW is a subsystem for the Macintosh that vaguely resembles UNIX. Running Icon under MPW is similar to running Icon under UNIX -- a command-line environment without the usual graphical interface. ProIcon is a standard Macintosh application that has an integrated environment with an editor that allows you to write and debug Icon programs without leaving the application. ProIcon also has several extensions to Icon, including some capabilities for manipulating windows and handling dialogs from within a ProIcon program. Version 2.0 of ProIcon, which is scheduled for release later this month, also has an interface to HyperCard XCMDs and XFCNs. For information about ProIcon, contact: Catspaw, Inc. P.O. Box 1123 Salida, CO 81201-1123 719-539-3884 Ralph Griswold / Dept of Computer Science / Univ of Arizona / Tucson, AZ 85721 +1 602 621 6609 ralph@cs.arizona.edu uunet!arizona!ralph From icon-group-request@arizona.edu Fri Nov 16 11:25:59 1990 Resent-From: icon-group-request@arizona.edu Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP id AA21839; Fri, 16 Nov 90 11:25:59 -0700 Received: from ucbvax.Berkeley.EDU by Arizona.edu; Fri, 16 Nov 90 11:25 MST Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA07705; Fri, 16 Nov 90 10:19:51 -0800 Received: from USENET by ucbvax.Berkeley.EDU with netnews for icon-group@arizona.edu (icon-group@arizona.edu) (contact usenet@ucbvax.Berkeley.EDU if you have questions) Resent-Date: Fri, 16 Nov 90 11:25 MST Date: 12 Nov 90 18:10:25 GMT From: zodiac!tsommers@rutgers.edu Subject: RE: MSDOS V8 reads Sender: icon-group-request@arizona.edu Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: <0341CD3AFAE7A00526@Arizona.edu> Message-Id: <201.273ee591@zodiac.rutgers.edu> Organization: Rutgers University - Computing Services X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.edu References: <9011100110.AA00524@megaron.cs.arizona.edu> In article <9011100110.AA00524@megaron.cs.arizona.edu>, pax@pax7300.att.com writes: > Is it possible that Version 8 of Icon on MS-DOS will not read past > an octal 32 with reads??? > > procedure main() > fd := open("TESTOFF.DBF","ru") | stop("DBF open failed") > while line := reads(fd,32) do { > write("*line=",*line) > } > end > > TESTOFF.DBF happens to have an octal 032 in position 49 of the file. > > The above program on MS-DOS returns: > > *line=32 > *line-16 My guess would be that Icon is opening the file in text mode, and that the particular C compiler used to make Icon treats Control-Z as EOF in text mode. If Icon just passes the mode string unaltered to the C fopen (or whatever), then perhaps all that is required is to use the appropriate binary mode mode string when opening the file. From @um.cc.umich.edu:Paul_Abrahams@Wayne-MTS Fri Nov 16 20:27:37 1990 Received: from umich.edu by megaron.cs.arizona.edu (5.61/15) via SMTP id AA12222; Fri, 16 Nov 90 20:27:37 -0700 Received: from um.cc.umich.edu by umich.edu (5.61/1123-1.0) id AA26271; Fri, 16 Nov 90 22:27:34 -0500 Received: from Wayne-MTS by um.cc.umich.edu via MTS-Net; Fri, 16 Nov 90 22:22:54 EST Date: Fri, 16 Nov 90 20:47:38 EST From: Paul_Abrahams%Wayne-MTS@um.cc.umich.edu To: icon-group@cs.arizona.edu Message-Id: <270675@Wayne-MTS> Subject: Uses of dynamic typing As I mentioned in an earlier posting, I'm working on the design of SPLASH, a Systems Programming Language for Software Hackers. A question came up about how people use Icon's dynamic typing. In Icon the type of a variable isn't determined until you assign something to it, and even then it can change. That's in contrast with other languages of the Algol/Pascal/Ada/C sort, in which every variable has a declared type. My question is: how important is this flexibility for Icon programming, and how do people utilize it? There's one place where it clearly pays off: the possibility of writing a procedure that prints its argument no matter what the type of the argument. The fact that you can't write the C printf function in standard C shows why you want this. But aside from printing arguments and writing out their storage, I haven't been able to think of other operations that use the flexibility. Interestingly, sorting isn't one of those examples, since not all data types have a natural ordering relation and even for those that do, you use different operators in Icon (`<' for numbers, `<<' for strings.) Examples, anyone--particularly from programs that do something rather than just prove something? Paul Abrahams abrahams%wayne-mts@um.cc.umich.edu From gmt Fri Nov 16 21:50:19 1990 Received: from owl.cs.arizona.edu by megaron.cs.arizona.edu (5.61/15) via SMTP id AA14316; Fri, 16 Nov 90 21:50:19 -0700 Date: Fri, 16 Nov 90 21:50:18 MST From: "Gregg Townsend" Message-Id: <9011170450.AA03673@owl.cs.arizona.edu> Received: by owl.cs.arizona.edu; Fri, 16 Nov 90 21:50:18 MST To: icon-group Subject: Re: Uses of dynamic typing I've used Icon's type flexibility a few times to implement traps in subroutine packages. The paradigm works like this: (1) call enable() passing an arbitrary procedure p and other object x along with whatever is necessary to specify the trap conditions. (2) when the trap condition occurs -- for example, on every 60th call to an output routine -- p(x) is called using p and x from the enable() call. Because x can be any type including a list or record, any desired amount of data can be passed to p. This is clumsier in C because instead of an arbitrary object x one must pass a *pointer* to x, with an appropriate cast, and then access the data indirectly. To pick a nit, printf actually can be written in standard C, because the format specifies the expected types of the remaining arguments and there are standard routines for retrieving them. There are other problems such as a danger that getc() has been replaced, but they're irrelevant to this discussion. Gregg Townsend / Computer Science Dept / Univ of Arizona / Tucson, AZ 85721 +1 602 621 4325 gmt@cs.arizona.edu 110 57 16 W / 32 13 45 N / +758m From gudeman Sat Nov 17 01:01:50 1990 Date: Sat, 17 Nov 90 01:01:50 -0700 From: "David Gudeman" Message-Id: <9011170801.AA19991@megaron.cs.arizona.edu> Received: by megaron.cs.arizona.edu (5.61/15) id AA19991; Sat, 17 Nov 90 01:01:50 -0700 To: Paul_Abrahams%Wayne-MTS@um.cc.umich.edu Cc: icon-group@cs.arizona.edu In-Reply-To: Paul_Abrahams%Wayne-MTS@um.cc.umich.edu's message of Fri, 16 Nov 90 20:47:38 EST <270675@Wayne-MTS> Subject: Uses of dynamic typing One important use of dynamic typing is that the type itself gives some information. I write functions all the time where I _usually_ want a return value of a certain type, but on exceptional conditions I want something different. For example # factorial(i) return the factorial of i if i > = 0, # otherwise return &null. You can get much the same effect with exception handlers, but it has a different flavor. Another use is in program developement. The ability to assign different types to variables lets you try things out with fewer changes to a program. At least I think so. Two other features that help in this are polymorphism and automatic type conversions. Since Icon has all three, it is hard to say exactly which feature or set of features is most involved in this. Incidentally, there is no reason that run-time typing and static typing can't peacefully coexist in the same language. I can see two different ways of doing this: the first way is to say that all variables are untyped. This dynamically typed language also has type declarations that restrict the types that can be assigned to a given variable _at run time_. However, a given implementation _may_ give errors at compile time if a given path might lead to a type conflict. Furthermore, the implementation may optimize variables that always have a known type. The other way is to say that the language is statically typed, but that there are union types that carry type information around as a part of the union value. Also, all operators are overloaded so that they operate on the union types by checking the type at run time and doing the right operation. There is a specially named union type "any" that is a union of all other types. One might define that the default type of a variable is "any". Both of these paradigms allow the expressiveness of dynamic typing and the security and efficiency of static typing. In such a language, you can do developement with dynamic types and then "optimize" the program by declaring the types of most of the variables. From ralph Sat Nov 17 06:36:19 1990 Received: from cheltenham.cs.arizona.edu by megaron.cs.arizona.edu (5.61/15) via SMTP id AA00227; Sat, 17 Nov 90 06:36:19 -0700 Date: Sat, 17 Nov 90 06:36:15 MST From: "Ralph Griswold" Message-Id: <9011171336.AA22105@cheltenham.cs.arizona.edu> Received: by cheltenham.cs.arizona.edu; Sat, 17 Nov 90 06:36:15 MST To: Paul_Abrahams%Wayne-MTS@um.cc.umich.edu Subject: Re: Uses of dynamic typing Cc: icon-group I disagree with your characterization of types and variables in Icon. It's not that a variable doesn't have a type until an assignment is made to it, but rather that variables are not typed, but values are. Note that every variable has the null value initially. I realize this distinction may seem a bit strange to persons who are used to languages like Pascal, but if you look at the implementation of Icon, you'll see that's exactly what's going on. A variable is simply a place to store a value, all variables are the same size, as are all values. All values carry an identifying type. As to the usefulness of non-types variables, in my experience, it's mostly in heterogeneous structures. The elements of a list, for example, are variables. They can have different types in the same list. Heterogeneous structures occur frequently in Icon programs. I believe the second edition of the Icon Programming Language points out examples. Ralph Griswold / Dept of Computer Science / Univ of Arizona / Tucson, AZ 85721 +1 602 621 6609 ralph@cs.arizona.edu uunet!arizona!ralph From @um.cc.umich.edu:Paul_Abrahams@Wayne-MTS Sat Nov 17 14:08:43 1990 Received: from umich.edu by megaron.cs.arizona.edu (5.61/15) via SMTP id AA12907; Sat, 17 Nov 90 14:08:43 -0700 Received: from um.cc.umich.edu by umich.edu (5.61/1123-1.0) id AA25821; Sat, 17 Nov 90 16:08:38 -0500 Received: from Wayne-MTS by um.cc.umich.edu via MTS-Net; Sat, 17 Nov 90 16:03:27 EST Date: Sat, 17 Nov 90 15:45:32 EST From: Paul_Abrahams%Wayne-MTS@um.cc.umich.edu To: icon-group@cs.arizona.edu Message-Id: <270830@Wayne-MTS> Subject: Dynamic typing revisited Thanks to all for your replies to my query on this subject. Re Ralph's comment: yes, I was being sloppy in saying that the type of a variable can change. Viewing variables as untyped containers of arbitrary values is both cleaner and and the correct depiction of reality. Yes, you can use Icon's flexible typing structure to construct heterogeneous lists. But what isn't clear to me is what such lists are good for, particu- larly when they contain values of truly arbitrary types rather than of related types. In SPLASH I have a `box' type that can designate variables of any type. That provides an escape from strong typing---the second approach that Dave Gudeman suggested. I'm still wrestling with the semantics of boxes, though. What prompted my query was wondering what operations you might want on a box in addition to the image operation (in the sense of the Icon `image' procedure). In particular, the image operation would suffice for the trapping that Gregg gave as an example. You might think that an obvious operation on boxes would be to get a string giving the type of the box. But that turns out to be remarkably difficult in the presence of recursive types. That problem doesn't come up in Icon because Icon doesn't have recursive types---with dynamic typing, you don't need them. To clarify: in Pascalish languages you can have something like: type t is record v: integer; link: ref t end How then would you display the definition of t in a form that id independent of the name you give the type? In Icon the type would simply be `t' (which actually isn't very revealing if you don't have the definition of `t' handy). By the way, Modula-3 has a `refany' type which provides an escape from strong typing in that language. But you can only dereference a `refany' value using a `typecase' construction, which forces you to enumerate all the possibilities. That's less general than being able to apply `image' without knowing the type. Paul abrahams%wayne-mts@um.cc.umich.edu From nowlin@iwtqg.att.com Sat Nov 17 15:02:49 1990 Message-Id: <9011172202.AA14204@megaron.cs.arizona.edu> Received: from att.att.com by megaron.cs.arizona.edu (5.61/15) via SMTP id AA14204; Sat, 17 Nov 90 15:02:49 -0700 From: nowlin@iwtqg.att.com Date: Sat, 17 Nov 90 15:39 CST Original-From: iwtqg!nowlin (Jerry D Nowlin +1 312 979 7268) To: att!cs.arizona.edu!icon-group Subject: Re: Uses of dynamic typing > than just prove something? I have three specific examples. The first is the use of the types "null" and "file" in programs that can read input from files or from standard input. The same expressions can be used for input if the variable used as a file is set to &null when reading from standard input. I've used this many times. The same kind of scheme can be used for output. The second example is a set of procedures that does regular expression matching. It uses a list of records. Each record contains a pair of values; a procedure and an argument to be passed to the procedure. Sometimes the argument is a string, sometimes it's a cset, and sometimes it's &null. Icon doesn't care which I store as the second value in the record. The third use is a set of procedures I wrote for a friend. These procedures allow a series of global variables to be dumped into a file. A complementary set of procedures can read the dump file and reconstruct the global variables with the same values as the program that dumped them. These procedures are used to chain together a series of programs. This would require a whole series of different variables if Icon didn't allow me to use the same variable over and over with different types each time. Very handy. As a side note we've just recently achieved a breakthrough at work (AT&T) and we're now allowed to use Icon for "real" projects. It's great. Our methodology calls for code inspections and those of us who are familiar with Icon initially thought Icon would be much easier to code inspect than C++ or C. WRONGO! The tie in to this subject is that dynamic typing may contribute to the problem. It just seems counter intuitive that Icon would be harder to inspect but after our initial session that was definitely my impression. I'll try to figure out why on my own but if anyone has any ideas throw them out. Jerry Nowlin (iwtqg!nowlin) From nowlin@iwtqg.att.com Sat Nov 17 15:02:53 1990 Message-Id: <9011172202.AA14215@megaron.cs.arizona.edu> Received: from att.att.com by megaron.cs.arizona.edu (5.61/15) via SMTP id AA14215; Sat, 17 Nov 90 15:02:53 -0700 From: nowlin@iwtqg.att.com Date: Sat, 17 Nov 90 15:51 CST Original-From: iwtqg!nowlin (Jerry D Nowlin +1 312 979 7268) To: att!cs.arizona.edu!icon-group Subject: Re: Dynamic typing revisited > ... > How then would you display the definition of t in a form that is > independent of the name you give the type? In Icon the type would > simply be `t' (which actually isn't very revealing if you don't have > the definition of `t' handy). > ... > > Paul In fact, type 't' from Icon isn't that bad for some applications. You can get the fact that type 't' is a record by looking at the image() and then you can just treat values of 't' like lists and generate the members or directly subscript them. I don't know how you'd find the specific member names but you can get at the member values and that's more important in most cases. Jerry Nowlin (iwtqg!nowlin) From att!arizona!wgg@cs.washington.edu Sat Nov 17 15:37:18 1990 Received: from att.UUCP by megaron.cs.arizona.edu (5.61/15) via UUCP id AA15114; Sat, 17 Nov 90 15:37:18 -0700 Received: from june.cs.washington.edu by megaron.cs.arizona.edu (5.61/15) via SMTP id AA14976; Sat, 17 Nov 90 15:30:40 -0700 Received: by june.cs.washington.edu (5.64/7.0jh) id AA16599; Sat, 17 Nov 90 14:30:35 -0800 Date: Sat, 17 Nov 90 14:30:35 -0800 From: wgg@cs.washington.edu (William Griswold) Return-Path: Message-Id: <9011172230.AA16599@june.cs.washington.edu> To: att!cs.arizona.edu!icon-group, nowlin@iwtqg.att.com Subject: Re: Uses of dynamic typing Re: Jerry Nowlin's message >As a side note we've just recently achieved a breakthrough at work (AT&T) >and we're now allowed to use Icon for "real" projects. It's great. Our >methodology calls for code inspections and those of us who are familiar >with Icon initially thought Icon would be much easier to code inspect than >C++ or C. WRONGO! The tie in to this subject is that dynamic typing may >contribute to the problem. It just seems counter intuitive that Icon would >be harder to inspect but after our initial session that was definitely my >impression. I'll try to figure out why on my own but if anyone has any >ideas throw them out. > To me this suggests that a language in which you could add typing information during later phases of a project would be valuable. Having a tool to infer the types and insert them for you would be great, and could be revealing in itself. In the presence of tools like Ken Walker's Icon compiler, this doesn't sound impractical. This type information serves as constructive comments in the code. Not only does it tell a new programmer what is going on, but type violations created by the programmer's changes to the code will signal that the changes are outside the intents of the original implementation. bill From fps!mis.mcw.edu!mis.mcw.edu!TENAGLIA@uwm.edu Sun Nov 18 16:36:41 1990 Received: from uwm.edu by megaron.cs.arizona.edu (5.61/15) via SMTP id AA03210; Sun, 18 Nov 90 16:36:41 -0700 Received: by uwm.edu; id AA23452; Sun, 18 Nov 90 09:06:31 -0600 Received: from mis.mcw.edu by fps.mcw.edu (DECUS UUCP ///1.2a/2.5/); Sun, 18 Nov 90 08:01:12 CDT Received: by mis.mcw.edu with UUCP/PMDF (DECUS UUCP); Sun, 18 Nov 1990 07:13 CDT Date: Sun, 18 Nov 1990 07:13 CDT From: Chris Tenaglia - 257-8765 Subject: Re: Uses of dynamic typing To: icon-group@cs.arizona.edu Cc: icon-group@cs.arizona.edu Message-Id: <2D4AF1A400600126@mis.mcw.edu> X-Organization: Medical College of Wisconsin MIS Department (Milwaukee, WI) X-Envelope-To: icon-group@cs.arizona.edu, Paul_Abrahams%Wayne-MTS@um.cc.umich.edu X-Vms-To: IN%"Paul_Abrahams%Wayne-MTS@um.cc.umich.edu" X-Vms-Cc: IN%"icon-group@cs.arizona.edu" Regarding: Uses of dynamic typing > ... text ... > My question is: how important is this flexibility for Icon programming, and > how do people utilize it? > > ... text ... > > Examples, anyone--particularly from programs that do something rather than > just prove something? > > Paul Abrahams > abrahams%wayne-mts@um.cc.umich.edu Some things are implicitly utilized. Dynamic typing, in my opinion, causes some things. 1. Reduces lines of code, since many variable type declarations become un-necessary. 2. Reduces code clutter from having to cast this type to that in expressions. Although I still find it necessary for floating point calculations. 3. I suppose I'm just a lazy programmer, and when programming in Icon, I'm not fighting the datatypes. I just code away, much like I did when BASIC was my native computer language. 4. No need for separate sets of procedure libraries. Well, I suppose if well designed, C & Pascal can have smart procedures that adapt to the type of data passed. Chris Tenaglia (System Manager) | Medical College of Wisconsin 8701 W. Watertown Plank Rd. | Milwaukee, WI 53226 (414)257-8765 | tenaglia@mis.mcw.edu, mcwmis!tenaglia From fps!mis.mcw.edu!mis.mcw.edu!TENAGLIA@uwm.edu Mon Nov 19 06:27:14 1990 Received: from uwm.edu by megaron.cs.arizona.edu (5.61/15) via SMTP id AA00165; Mon, 19 Nov 90 06:27:14 -0700 Received: by uwm.edu; id AA09863; Mon, 19 Nov 90 07:27:02 -0600 Received: from mis.mcw.edu by fps.mcw.edu (DECUS UUCP ///1.2a/2.5/); Mon, 19 Nov 90 06:55:13 CDT Received: by mis.mcw.edu with UUCP/PMDF (DECUS UUCP); Mon, 19 Nov 1990 06:19 CDT Date: Mon, 19 Nov 1990 06:19 CDT From: Chris Tenaglia - 257-8765 Subject: Card game algorythms To: icon-group@cs.arizona.edu Message-Id: X-Organization: Medical College of Wisconsin MIS Department (Milwaukee, WI) X-Envelope-To: icon-group@cs.arizona.edu X-Vms-To: IN%"icon-group@cs.arizona.edu" I've been thinking about card game algorythms. It seems to me that cards belong in a set rather than a list. Each hand would also be a set. Since order in a set is arbitrary, I become a little confused as to shuffling the deck. And even if one were to use lists, shuffling is an operational remnant of our physical world. In a computer, virtual shuffling could just consist of dealing cards from random deck positions. Is there one basic shuffling concept, or are there several approaches? Chris Tenaglia (System Manager) | Medical College of Wisconsin 8701 W. Watertown Plank Rd. | Milwaukee, WI 53226 (414)257-8765 | tenaglia@mis.mcw.edu, mcwmis!tenaglia From @um.cc.umich.edu:Paul_Abrahams@Wayne-MTS Mon Nov 19 08:21:57 1990 Received: from umich.edu by megaron.cs.arizona.edu (5.61/15) via SMTP id AA03820; Mon, 19 Nov 90 08:21:57 -0700 Received: from um.cc.umich.edu by umich.edu (5.61/1123-1.0) id AA09475; Mon, 19 Nov 90 10:21:49 -0500 Received: from Wayne-MTS by um.cc.umich.edu via MTS-Net; Mon, 19 Nov 90 10:17:21 EST Date: Sun, 18 Nov 90 22:36:28 EST From: Paul_Abrahams%Wayne-MTS@um.cc.umich.edu To: icon-group@cs.arizona.edu Message-Id: <270978@Wayne-MTS> Subject: Dynamic typing (more) To respond to various points: (1) Finding a representation of dynamic types is more difficult when (a) the types involve mutual recursions, not just one, and (b) your language has structural equivalence rather than name equivalence (like Modula-3). Structurally equivalent types should have the same representation even if their declarations use different names. In fact, it's an interesting job for an Icon program (given, say, a textual representation of a collection of Modula-3 type declarations). (2) Of Jerry Nowlin's three examples, the one I find most interesting is the third, in which global variables of arbitrary types are dumped to a file and read back in again by another program (or another execution of the same program, I gather). The first two could be done with variant records, subclasses, or what have you since there are only a small, finite number of choices. The third one involved a kind of inverse of `image' that transforms an image into a value for almost any type at all (but not for procedures, I'd guess). (3) My box type in SPLASH isn't overloaded in the sense that x+y adds x and y even if x and y are boxes containing numbers. It will probably have an extraction operator that extracts the variable or value contained in a box, but I haven't figured out how to do this because I only want to permit the extraction in a context where the type of the box's contents has been proclaimed (using something like the Modula-3 TYPECASE statement). But TYPECASE doesn't work well when you have complex nested types. (4) There isn't a necessary connection between compile-time typing and operator overloading, but languages with dynamic typing generally don't seem to have operator overloading except in the weak sense of things like overloading + to work both on integers and reals. In fact, Icon probably could have been designed to use overloading more extensively and even to make it available to users, with type declarations used in parameter lists solely for the purpose of overload resolution. Then you wouldn't have different operators for lexical versus numerical comparison. I won't try to argue very strongly that it would be better that way, but it's an interesting possibility that as far as I know no language designers have considered. (5) I probably should reiterate that a lot of the design of SPLASH was inspired by Icon, and SPLASH has a lot of Icon features in it (especially the central notions of generators and of failure as a possible outcome of expression evaluation). The current state of it is that the definition is about 50 pages long and, I'd estimate, about 60% complete (which doesn't imply that the final version will be 80 pages long). Paul abrahams%wayne-mts@um.cc.umich.edu From gudeman Tue Nov 20 13:09:12 1990 Date: Tue, 20 Nov 90 13:09:12 -0700 From: "David Gudeman" Message-Id: <9011202009.AA14193@megaron.cs.arizona.edu> Received: by megaron.cs.arizona.edu (5.61/15) id AA14193; Tue, 20 Nov 90 13:09:12 -0700 To: icon-group@cs.arizona.edu In-Reply-To: Paul_Abrahams%Wayne-MTS@um.cc.umich.edu's message of Sun, 18 Nov 90 22:36:28 EST <270978@Wayne-MTS> Subject: Dynamic typing (more) >Date: Sun, 18 Nov 90 22:36:28 EST >From: Paul_Abrahams%Wayne-MTS@um.cc.umich.edu >Structurally equivalent types should have the same representation even if >their declarations use different names. Hmm, that really isn't obvious to me. If I declare two structurally equivalent types with different names, then I probably have some reason for wanting to distinguish them. In this case I would rather have the representations include the names explicitely. Of course, if type equivalence isn't the same as representation equivalence then I would also want a predicate on representations to tell me when two representations denote the same type. >...The first two could be done with variant records, >subclasses, or what have you since there are only a small, finite number of >choices... But what "could be done" isn't the issue. Obviously you can do anything in Pascal that you can do in Icon, the issue is how easy it is to do and how easy it is to understand. Typing in a list of different things to do for different types is more cumbersome than letting the language figure it out. Strict static typing in this sense violates one of my cardinal rules of language design: "Make the computer do any work that it can. The programmer should only be required to do what the computer can't." >(3) My box type in SPLASH isn't overloaded in the sense that x+y adds x and >y even if x and y are boxes containing numbers. In this case, I would say that the box type does not give you the advantages of dynamic typing at all. It is just an abbreviation for a union of everything. Incidentally, in the union approach to dynamic typing (that is, unions-with-type-information and universal overloading) the operators should be overloaded on all unions. For example if union int_or_string {int, string} declares a new type "int_or_string", and I declare variables "x" and "y" of this type, then the expression "x + y" should be understood to do the correct thing based on the dynamic types of "x" and "y". In other words, there is no reason to limit this overloading to unions of everything. >(4) There isn't a necessary connection between compile-time typing and >operator overloading, but languages with dynamic typing generally don't seem >to have operator overloading except in the weak sense of things like >overloading + to work both on integers and reals... Icon has two ways in which an operator can work on different types: automatic conversion and overloading. There is actually quite a bit of overloading, look at unary "!" and "?", subscripting, sectioning, general comparisons ("===" and friends), member(), sort(), and copy(). The comparison operators could not be overloaded without losing some functionality. They are currently defined to do automatic type conversions, which has different uses. From icon-group-request@arizona.edu Thu Nov 22 06:25:36 1990 Resent-From: icon-group-request@arizona.edu Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP id AA11121; Thu, 22 Nov 90 06:25:36 -0700 Received: from ucbvax.Berkeley.EDU by Arizona.edu; Thu, 22 Nov 90 06:25 MST Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA00781; Thu, 22 Nov 90 05:25:07 -0800 Received: from USENET by ucbvax.Berkeley.EDU with netnews for icon-group@arizona.edu (icon-group@arizona.edu) (contact usenet@ucbvax.Berkeley.EDU if you have questions) Resent-Date: Thu, 22 Nov 90 06:25 MST Date: 20 Nov 90 06:25:31 GMT From: news@psuvax1.cs.psu.edu Subject: RE: Card game algorythms Sender: icon-group-request@arizona.edu Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: Message-Id: Organization: Penn State Computer Science X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.edu References: Each hand is a set, but the deck itself is a list. If you consider solitaire games, then the various piles, the talon, and the stock are all lists. I've wanted a generalized solitaire language for a while.. -- Felix Lee flee@cs.psu.edu From icon-group-request@arizona.edu Thu Nov 22 08:41:49 1990 Resent-From: icon-group-request@arizona.edu Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP id AA16629; Thu, 22 Nov 90 08:41:49 -0700 Received: from ucbvax.Berkeley.EDU by Arizona.edu; Thu, 22 Nov 90 08:41 MST Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA06651; Thu, 22 Nov 90 07:28:01 -0800 Received: from USENET by ucbvax.Berkeley.EDU with netnews for icon-group@arizona.edu (icon-group@arizona.edu) (contact usenet@ucbvax.Berkeley.EDU if you have questions) Resent-Date: Thu, 22 Nov 90 08:41 MST Date: 21 Nov 90 02:43:46 GMT From: iris!hildum@ucdavis.ucdavis.edu Subject: Icon I/O system and X Windows/Motif Sender: icon-group-request@arizona.edu Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: Message-Id: <7999@ucdavis.ucdavis.edu> Organization: U.C. Davis - Department of Electrical Engineering and Computer Science X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.edu I have been looking at some articles on the X window system recently, and am curious about the Icon communities' thoughts on how an X Window/Motif based graphical interface would most naturally be incorporated. I realize that the intent of Icon is the development of high level language constructs and semantics; however, with the growing importance of graphical interfaces, the current simple I/O system Icon supports seems inadequate. In particular, I am interested in the the effects of language constructs and semantics such as coexpressions, suspend and resume, generators, and failure in combination with the asynchronous model of the X protocol. Any comments on how such an interface might be built and what form it should take? dehildum@ucdavis.ucdavis.edu (Internet) dehildum@ucdavis.bitnet (BITNET) ucbvax!ucdavis!dehildum (uucp) From icon-group-request@arizona.edu Fri Nov 23 18:29:56 1990 Resent-From: icon-group-request@arizona.edu Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP id AA13934; Fri, 23 Nov 90 18:29:56 -0700 Received: from ucbvax.Berkeley.EDU by Arizona.edu; Fri, 23 Nov 90 18:29 MST Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA13064; Fri, 23 Nov 90 17:24:52 -0800 Received: from USENET by ucbvax.Berkeley.EDU with netnews for icon-group@arizona.edu (icon-group@arizona.edu) (contact usenet@ucbvax.Berkeley.EDU if you have questions) Resent-Date: Fri, 23 Nov 90 18:29 MST Date: 23 Nov 90 20:54:07 GMT From: usc!bbn.com!nic!chaos.cs.brandeis.edu!iad@rutgers.edu Subject: Help/hint needed Sender: icon-group-request@arizona.edu Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: Message-Id: <1990Nov23.205407.4570@chaos.cs.brandeis.edu> Organization: Brandeis University Computer Science Dept X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.edu SOS! I've been only using Icon for about four weeks, and I'm enjoying it more than I can tell. However, today I ran into the following problem: I was trying to write a procedure that takes a list of coexpressions (its length must be allowed to vary) and suspends lists of the corresponding values of the arguments. For example, the call f ([create 1 to 3, create "Q" | "Z"]) would produce the result sequence { [1,"Q"], [1,"Z"], [2,"Q"], [2,"Z"], [3,"Q"], [3,"Z"] }. I thought is should be easy (given the overall power of Icon), but somehow I can't think of any way of doing it without recursion. Can anyone give me a hint? Thanks, Ivan A. Derzhanski P.S. My apologies if it turns out to be actually very simple. -- Ivan A. Derzhanski iad@chaos.brandeis.edu MB 1766 Brandeis University P.O.Box 9110 Waltham, MA 02254-9110 From fps!mis.mcw.edu!mis.mcw.edu!TENAGLIA@uwm.edu Mon Nov 26 08:50:06 1990 Received: from uwm.edu by megaron.cs.arizona.edu (5.61/15) via SMTP id AA02332; Mon, 26 Nov 90 08:50:06 -0700 Received: by uwm.edu; id AA20516; Mon, 26 Nov 90 09:49:54 -0600 Received: from mis.mcw.edu by fps.mcw.edu (DECUS UUCP ///1.2a/2.5/); Mon, 26 Nov 90 09:34:07 CDT Received: by mis.mcw.edu with UUCP/PMDF (DECUS UUCP); Mon, 26 Nov 1990 08:55 CDT Date: Mon, 26 Nov 1990 08:54 CDT From: Chris Tenaglia - 257-8765 Subject: Icon in Windowing environments To: icon-group@cs.arizona.edu Message-Id: <84CC7215C06007E3@mis.mcw.edu> X-Organization: Medical College of Wisconsin MIS Department (Milwaukee, WI) X-Envelope-To: icon-group@cs.arizona.edu X-Vms-To: IN%"icon-group@cs.arizona.edu" Icon seems to be designed around the data stream concept of the unix shell (character cell) environment. It's not not fast enough with image processing. I've tried it. Still, here is some thinking from the keyboard. I won't mention any new language constructs that may be needed to support it. I'm just going over the most external look and feel of what an X-Window/Motif Icon environment might look like ... Obviously, with a windowing interface the term 'icon' becomes overloaded. To preserve the 'Icon' language we'd call the pictures objects or pix to keep the names straight. These objects will have a file name squeezed into them, and a user editable pictogram to make it more recognizable. Each file type, should have special distinguishing features to make them instantly recognizable. icont may be another object to which source and ucode is fed, and new icode objects generated. Files : (Source) These contain icon source code. Clicking on a source object brings them up in an editor window of choice. (Ucode) These contain the intermediate ucode. An IPATH window contains ones that one may want to link with. (Icode exec) Under unix these can be made self-starting. I'm not sure what to do about other operating systems. This graphical object would have input and output sockets (stdin & stdout always by default, others declared in the program). Data files have only a stdin/stdout socket pair, where icode files can have many sockets. These sockets should have 'gender' and allow one to construct applications much like LEGO blocks. (Data files (pipes)) These are data files or other shell filters. The icon environment would give them each a stdin/stdout socket pair. If the object is a textual data file, clicking on it should pop it into an editor window just like source code. These are just some food for thought. I come from a VAX VMS VT100 style shop with a few PCs and MACs laying around, so my vision may be clouded by ignorance. Chris Tenaglia (System Manager) | Medical College of Wisconsin 8701 W. Watertown Plank Rd. | Milwaukee, WI 53226 (414)257-8765 | tenaglia@mis.mcw.edu, mcwmis!tenaglia From fps!mis.mcw.edu!mis.mcw.edu!TENAGLIA@uwm.edu Mon Nov 26 08:50:21 1990 Received: from uwm.edu by megaron.cs.arizona.edu (5.61/15) via SMTP id AA02366; Mon, 26 Nov 90 08:50:21 -0700 Received: by uwm.edu; id AA20522; Mon, 26 Nov 90 09:50:09 -0600 Received: from mis.mcw.edu by fps.mcw.edu (DECUS UUCP ///1.2a/2.5/); Mon, 26 Nov 90 09:34:22 CDT Received: by mis.mcw.edu with UUCP/PMDF (DECUS UUCP); Mon, 26 Nov 1990 09:18 CDT Date: Mon, 26 Nov 1990 09:17 CDT From: Chris Tenaglia - 257-8765 Subject: final language construct To: icon-group@cs.arizona.edu Message-Id: <87FEAFB0806007E3@mis.mcw.edu> X-Organization: Medical College of Wisconsin MIS Department (Milwaukee, WI) X-Envelope-To: icon-group@cs.arizona.edu X-Vms-To: IN%"icon-group@cs.arizona.edu" Icon is a pretty nifty programming language. I like and use the 'initial' construct. But sometimes I wished I had a 'final' construct. This may be a crummy example, but it illustrates the concept of the final pass through a procedure. Perhaps this isn't even implementable? Any comments on it's usefullness or implementation problems? procedure print(fo,line) static ff, pageno, line_count initial { ff := "" pageno := 0 line_count := 0 } if (line_count -:= 1) < 0 then { write(fo,ff,"title line ",(pageno +:= 1)) line_count := 55 ff := "\f" } write(fo,format(line)) final { output_summary() } end Chris Tenaglia (System Manager) | Medical College of Wisconsin 8701 W. Watertown Plank Rd. | Milwaukee, WI 53226 (414)257-8765 | tenaglia@mis.mcw.edu, mcwmis!tenaglia From goer%sophist@gargoyle.uchicago.edu Mon Nov 26 13:03:38 1990 Resent-From: goer%sophist@gargoyle.uchicago.edu Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP id AA14510; Mon, 26 Nov 90 13:03:38 -0700 Return-Path: goer@sophist.uchicago.edu Received: from gargoyle.uchicago.edu by Arizona.edu; Mon, 26 Nov 90 13:02 MST Received: by gargoyle.uchicago.edu from sophist (sophist.uchicago.edu) (4.0/1.14) id AA25249; Mon, 26 Nov 90 14:02:47 CST Received: by sophist (4.1/UofC3.1X) id AA29090; Mon, 26 Nov 90 14:06:04 CST Resent-Date: Mon, 26 Nov 90 13:03 MST Date: Mon, 26 Nov 90 14:06:04 CST From: Richard Goerwitz Subject: final, initial Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: Message-Id: <9011262006.AA29090@sophist> X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.edu In additions to initial clauses, I've often wanted to use second clauses, thirds, fourths, as well as finals. I guess it could go on forever. With "finals" the real problem seems to be how the interpreter is supposed to know that a given call is really the last one. I don't see how it can know this sort of thing. -Richard (goer@sophist.uchicago.edu) From icon-group-request@arizona.edu Mon Nov 26 22:47:58 1990 Resent-From: icon-group-request@arizona.edu Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP id AA06914; Mon, 26 Nov 90 22:47:58 -0700 Received: from UCBVAX.Berkeley.EDU by Arizona.edu; Mon, 26 Nov 90 22:47 MST Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA02485; Mon, 26 Nov 90 21:44:23 -0800 Received: from USENET by ucbvax.Berkeley.EDU with netnews for icon-group@arizona.edu (icon-group@arizona.edu) (contact usenet@ucbvax.Berkeley.EDU if you have questions) Resent-Date: Mon, 26 Nov 90 22:47 MST Date: 27 Nov 90 05:30:22 GMT From: iris!hildum@ucdavis.ucdavis.edu Subject: RE: final, initial Sender: icon-group-request@arizona.edu Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: Message-Id: <8008@ucdavis.ucdavis.edu> Organization: U.C. Davis - Department of Electrical Engineering and Computer Science X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.edu References: <9011262006.AA29090@sophist> Two cents worth: probably the only way to do this is to have the interpreter invoke the final clauses as part of the program termination. This leads to the following issues: 1. Error termination - are final clauses executed? 2. What order are multiple final clauses executed - the order in which the procedures were first invoked? Of course, all this can be handled by placing the appropriate calls at the "end" of the program, so I am not sure this really helps (other than grouping code...) If you are actually trying to execute the code as part of the final call, I suspect that it cannot be done. It looks suspicously like a halting problem to me... Eric dehildum@ucdavis.ucdavis.edu (Internet) dehildum@ucdavis.bitnet (BITNET) ucbvax!ucdavis!dehildum (uucp) From nowlin@iwtqg.att.com Tue Nov 27 08:49:45 1990 Message-Id: <9011271549.AA28956@megaron.cs.arizona.edu> Received: from att.att.com by megaron.cs.arizona.edu (5.61/15) via SMTP id AA28956; Tue, 27 Nov 90 08:49:45 -0700 From: nowlin@iwtqg.att.com Date: Tue, 27 Nov 90 08:05 CST Original-From: iwtqg!nowlin (Jerry D Nowlin +1 312 979 7268) To: icon-group@cs.arizona.edu Subject: Re: help/hint needed > Date: 23 Nov 90 20:54:07 GMT > From: usc!bbn.com!nic!chaos.cs.brandeis.edu!iad@rutgers.edu > Subject: Help/hint needed > > SOS! > > I've been only using Icon for about four weeks, and I'm enjoying it > more than I can tell. However, today I ran into the following problem: > > I was trying to write a procedure that takes a list of coexpressions > (its length must be allowed to vary) and suspends lists of the > corresponding values of the arguments. For example, the call > > f ([create 1 to 3, create "Q" | "Z"]) > > would produce the result sequence > > { [1,"Q"], [1,"Z"], [2,"Q"], [2,"Z"], [3,"Q"], [3,"Z"] }. > > I thought is should be easy (given the overall power of Icon), but > somehow I can't think of any way of doing it without recursion. Can > anyone give me a hint? > > Thanks, > > Ivan A. Derzhanski > > P.S. My apologies if it turns out to be actually very simple. > -- > Ivan A. Derzhanski iad@chaos.brandeis.edu > MB 1766 Brandeis University P.O.Box 9110 Waltham, MA 02254-9110 Admittedly coexpressions are not a piece of Icon I use much. I can't think of a way to do this with coexpressions without recursing either. But I stopped and asked my self why should I use coexpressions if what I want is all the possible combinations of a list of generators? Maybe the example you used was oversimplifying your problem but the following program generates the sequences you asked for without even requiring a procedure: procedure main() every l := [1 to 3, "Q" | "Z"] do { writes("[ ") every writes(!l," ") write("]") } end This isn't the normal coding style I'd use but it isolates the piece of code that's pertinent to the original question. To make this more general you can use a procedure but it's a simple procedure. The following is the same basic program but with a procedure call. The key is to use a list of generators instead of a list of coexpressions. I just prefer to simplify. procedure main() every l := f( [1 to 3, "Q" | "Z"] ) do { writes("[ ") every writes(!l," ") write("]") } end procedure f(lg) suspend lg end This seems almost too easy so if I've really missed the point please let me know. Otherwise, isn't Icon great! Jerry Nowlin (att!iwtqg!nowlin) From nowlin@iwtqg.att.com Tue Nov 27 08:49:53 1990 Message-Id: <9011271549.AA28965@megaron.cs.arizona.edu> Received: from att.att.com by megaron.cs.arizona.edu (5.61/15) via SMTP id AA28965; Tue, 27 Nov 90 08:49:53 -0700 From: nowlin@iwtqg.att.com Date: Tue, 27 Nov 90 08:59 CST Original-From: iwtqg!nowlin (Jerry D Nowlin +1 312 979 7268) To: icon-group@cs.arizona.edu Subject: Re: hints... > procedure main() > > every l := > > [1 to 3, "Q" | "Z"] > > do { > writes("[ ") > every writes(!l," ") > write("]") > } > > end > ... > > This seems almost too easy so if I've really missed the point please let > me know. Otherwise, isn't Icon great! Forget the procedure example (not shown). In fact, forget the whole solution unless you can use constant lists of generators as above. Rule #1 - When something seems too easy to be true, it is. The generation that makes this work is driven by goal directed evaluation in the context of the every. It works the way I thought it did almost but requires a constant list of generators in that context. If you assign a list of generators to a variable and use the variable in this construct it won't generate the result sequence wanted. This requires more thought. Too bad I have real work to do! Jerry From icon-group-request@arizona.edu Tue Nov 27 14:33:40 1990 Resent-From: icon-group-request@arizona.edu Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP id AA15180; Tue, 27 Nov 90 14:33:40 -0700 Received: from UCBVAX.Berkeley.EDU by Arizona.edu; Tue, 27 Nov 90 14:32 MST Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA21614; Tue, 27 Nov 90 13:21:42 -0800 Received: from USENET by ucbvax.Berkeley.EDU with netnews for icon-group@arizona.edu (icon-group@arizona.edu) (contact usenet@ucbvax.Berkeley.EDU if you have questions) Resent-Date: Tue, 27 Nov 90 14:32 MST Date: 27 Nov 90 17:25:25 GMT From: ingr!@uunet.uu.net Subject: RE: WHAT ARE ICONS Sender: icon-group-request@arizona.edu Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: Message-Id: <1805@b15.INGR.COM> Organization: Intergraph Huntsville X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.edu References: <13119021:11:45GB03@lehigh.bitnet> In <13119021:11:45GB03@lehigh.bitnet> GB03@Lehigh writes: :It might interest most people to know that BASIC was originally BASIC. :Kemeny and Kurtz got tired of telling people it was only BASIC. No one :believed the inventors. They finally came up with Beginners All :Purpose Simplified Code The American Heritage Dictionary (2nd College Edition, 1985) says: Beginner's All-purpose Symbolic Instruction Code From nowlin@iwtqg.att.com Tue Nov 27 20:46:12 1990 Message-Id: <9011280346.AA29841@megaron.cs.arizona.edu> Received: from att.att.com by megaron.cs.arizona.edu (5.61/15) via SMTP id AA29841; Tue, 27 Nov 90 20:46:12 -0700 From: nowlin@iwtqg.att.com Date: Tue, 27 Nov 90 17:16 CST Original-From: iwtqg!nowlin (Jerry D Nowlin +1 312 979 7268) To: icon-group@cs.arizona.edu Subject: Re: final clause > Icon is a pretty nifty programming language. I like and use the 'initial' > construct. But sometimes I wished I had a 'final' construct. This may be > a crummy example, but it illustrates the concept of the final pass through > a procedure. Perhaps this isn't even implementable? Any comments on it's > usefulness or implementation problems? I don't see anyway to implement a final clause. You might have the interpreter go through all the declared procedures when it's told to terminate and execute the final clauses. Even then how do you know that the order of execution of final clauses isn't significant? How would you handle run time errors or external interrupts? If that won't work, how could the interpreter possibly know that a procedure won't be executed again? I don't think procedures ever go out of scope in Icon so that's not a valid criteria. What happens when you declare a variable with the same name as a procedure? What happens when a procedure is assigned to a variable? I don't see any way to do this. Is this an attempt to get construction and destruction type constructs for procedures? > procedure print(fo,line) > static ff, pageno, line_count > initial > { > ff := "" > pageno := 0 > line_count := 0 > } > if (line_count -:= 1) < 0 then > { > write(fo,ff,"title line ",(pageno +:= 1)) > line_count := 55 > ff := "\f" > } > write(fo,format(line)) > final > { > output_summary() > } > end The example above has some problems since the output_summary() procedure is called as part of the final clause but it isn't passed the parameters that were initialized in the initial clause. I get the idea though. This could be handled by making the 'fo' and 'line' parameters optional. If they're missing invoke the equivalent of the final clause. I use optional parameters frequently although not usually for this kind of thing. Jerry Nowlin (...!att!iwtqg!nowlin) From djbailey@skyler.mavd.honeywell.com Wed Nov 28 09:51:09 1990 Message-Id: <9011281651.AA25093@megaron.cs.arizona.edu> Received: from skyler.mavd.honeywell.com by megaron.cs.arizona.edu (5.61/15) via SMTP id AA25093; Wed, 28 Nov 90 09:51:09 -0700 Date: 28 Nov 90 10:49:00 CDT From: "BAILEY, DON" Subject: Re: final clause To: "icon-group" Has anyone else suggested the simple brute force solution to implementing a "final" clause? Just push your program down a level in the calling sequence. For example, procedure main(args) # my_real_program(args,final_parameter_list) do_final_work(final_parameter_list) end The real program can have an initial clause if it really needs it. Whenever it finishes, "do_final_work" will be called. At worst, you have to make some extra data global and deal with the success or failure of your program. This approach lets you invoke different final processing, by adding an "if", depending on success or failure or a state variable you pass back up. -- Don J. Bailey (djbailey@skyler.mavd.honeywell.com) From fps!mis.mcw.edu!mis.mcw.edu!TENAGLIA@uwm.edu Wed Nov 28 13:17:15 1990 Received: from uwm.edu by megaron.cs.arizona.edu (5.61/15) via SMTP id AA04749; Wed, 28 Nov 90 13:17:15 -0700 Received: by uwm.edu; id AA10695; Wed, 28 Nov 90 14:16:58 -0600 Received: from mis.mcw.edu by fps.mcw.edu (DECUS UUCP ///1.2a/2.5/); Wed, 28 Nov 90 14:00:48 CDT Received: by mis.mcw.edu with UUCP/PMDF (DECUS UUCP); Wed, 28 Nov 1990 13:00 CDT Date: Wed, 28 Nov 1990 13:00 CDT From: Chris Tenaglia - 257-8765 Subject: The Final Clause To: icon-group@cs.arizona.edu Message-Id: <396C1E3A80400B3F@mis.mcw.edu> X-Organization: Medical College of Wisconsin MIS Department (Milwaukee, WI) X-Envelope-To: icon-group@cs.arizona.edu X-Vms-To: IN%"icon-group@cs.arizona.edu" Regarding : The Final Clause I've seen a lot of interesting replies on this problem. Some say it's not possible because it's 'decidable'. Someone else mentioned the 'halting problem', which I assume refers to Turing machines. How does a procedure 'know' when it's finally called? Also the example I furnished wasn't very good, but I can't seem to think of another at the moment. I didn't think it would have been such a big deal. After all, how does program know when it's reached the end of file or pipe? (The operating system tells it). I also thought that since Icon is a virtual machine, that its extensibility would allow something like the Variant Translator or Personal Interpreter to handle it. Practically, though, the method I envisioned was that Icon would do a silent run, recording activity to a journal (much like MEMMON). Upon exit, the final clause(s) would be inserted into the journal stream, and then the whole mess flushed (kind of like a database commit). I thought about that a bit, and I guessed it would gobble tons of memory/disk and cause everything to run slow. I also dreaded permutations with 'final's getting tied up in recursive infinite loops. I also considered limiting it to one 'final' per program, or allowing only in main(), but that really did not seem too useful. I guess the best approach is to use a procedure final() called near the end of main() using passed or global variables. Thanx for all the ideas. Chris Tenaglia (System Manager) | Medical College of Wisconsin 8701 W. Watertown Plank Rd. | Milwaukee, WI 53226 (414)257-8765 | tenaglia@mis.mcw.edu, mcwmis!tenaglia From fps!mis.mcw.edu!mis.mcw.edu!TENAGLIA@uwm.edu Sat Dec 1 11:47:20 1990 Received: from uwm.edu by megaron.cs.arizona.edu (5.61/15) via SMTP id AA25239; Sat, 1 Dec 90 11:47:20 -0700 Received: by uwm.edu; id AA18340; Sat, 1 Dec 90 12:46:59 -0600 Received: from mis.mcw.edu by fps.mcw.edu (DECUS UUCP ///1.2a/2.5/); Sat, 1 Dec 90 12:22:02 CDT Received: by mis.mcw.edu with UUCP/PMDF (DECUS UUCP); Sat, 1 Dec 1990 08:48 CDT Date: Sat, 1 Dec 1990 08:48 CDT From: Chris Tenaglia - 257-8765 Subject: A more useful concept To: icon-group@cs.arizona.edu Message-Id: <71AFB0BFE0401C1A@mis.mcw.edu> X-Organization: Medical College of Wisconsin MIS Department (Milwaukee, WI) X-Envelope-To: icon-group@cs.arizona.edu X-Vms-To: IN%"icon-group@cs.arizona.edu" In the past icon has been getting better and better. For example there's now a remove(filespec) procedure to delete files which is better than system("rm "||filespec) and I think there's also a rename(ofile,nfile) instead of system("mv "||ofile||" "||nfile) I think it would be nice to have a few more file management primitives. Oh oh, maybe they already exist, and I should just read the manual? cpfile(oldfile,newfile) # copy files appfile(oldfile,existingfile) # append files together listvar := dir(path) # generate a list of file names (directory) freedisk:= df(dspec) # returns number of blocks of free disk like unix df or vms show dev/mount ---- Also there are the environmental variables that are accessible with getenv(), and known as logicals to VMS people. Is it possible to capture aliases (symbols to vms people)? Or doesn't that sound like a useful enough feature? From icon-group-request@arizona.edu Tue Dec 4 14:36:50 1990 Resent-From: icon-group-request@arizona.edu Received: from HOPEY.TELCOM.ARIZONA.EDU by megaron.cs.arizona.edu (5.61/15) via SMTP id AA06044; Tue, 4 Dec 90 14:36:50 -0700 Received: from ucbvax.Berkeley.EDU by Arizona.edu with PMDF#10282; Tue, 4 Dec 1990 14:36 MST Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA00435; Tue, 4 Dec 90 13:24:37 -0800 Received: from USENET by ucbvax.Berkeley.EDU with netnews for icon-group@arizona.edu (icon-group@arizona.edu) (contact usenet@ucbvax.Berkeley.EDU if you have questions) Resent-Date: Tue, 4 Dec 1990 14:36 MST Date: 4 Dec 90 19:26:00 GMT From: timbuk!cs.umn.edu!mmm.serc.3m.com!us269574@uunet.uu.net (Darryn J. Kozak) Subject: Is ICON the successor to SNOBOL? Sender: icon-group-request@arizona.edu Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: Message-Id: <1990Dec4.192600.16430@mmm.serc.3m.com> X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.edu Organization: 3M - St. Paul, MN 55144-1000 US Is ICON the successor to SNOBOL? Darryn Kozak 3M Center 260-4A-08 St. Paul, MN 55144 phone: 612-733-3271 email: us269574@mmm.3m.com or kozak@umn-cs.edu FAX: 612-737-3213 From goer%sophist@gargoyle.uchicago.edu Wed Dec 5 10:05:04 1990 Resent-From: goer%sophist@gargoyle.uchicago.edu Received: from HOPEY.TELCOM.ARIZONA.EDU by megaron.cs.arizona.edu (5.61/15) via SMTP id AA21479; Wed, 5 Dec 90 10:05:04 -0700 Return-Path: goer@sophist.uchicago.edu Received: from gargoyle.uchicago.edu by Arizona.edu with PMDF#10282; Wed, 5 Dec 1990 10:03 MST Received: by gargoyle.uchicago.edu from sophist (sophist.uchicago.edu) (4.0/1.14) id AA13345; Wed, 5 Dec 90 11:03:29 CST Received: by sophist (4.1/UofC3.1X) id AA05261; Wed, 5 Dec 90 11:06:47 CST Resent-Date: Wed, 5 Dec 1990 10:04 MST Date: Wed, 5 Dec 90 11:06:47 CST From: Richard Goerwitz Subject: Snobol -> Icon Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: Message-Id: <9012051706.AA05261@sophist> X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.edu (I didn't see anyone else respond, and it seems worthwhile, I'll try to answer this question. Note that I am not part of the Icon Project, and that some of what I say may not be entirely accurate :-)). Re: Is ICON the successor to SNOBOL? Sure. They started working on SL5, but suddenly felt inspired with the knowledge that the backtracking mechanisms found in string scan- ning could be superimposed on a consistent, general-purpose program- ming language with a modern, procedurally oriented program struc- ture. Icon is, at once, like Snobol string processing gone wild, and at the same time like languages such as C and Pascal. I've also heard it described as an Algolish Prolog as well, because it essentially im- plements a backtracking mechanism somewhat like that of Prolog in terms of control structures we all know and "love." It is not really quite a *successor* to Snobol, but it is certainly a logical step forward. I don't believe SL5 (which *would* have been the successor to SNOBOL4) was ever released. If you know Snobol, don't expect the conversion to be immediate. You can write a 3-line Arb() procedure, if you like. But it's not built in. Icon offers low-level tools with which to construct your own matching functions. It is very flexible, but what I'm trying to say is that, at first, Snobol programmers often feel a bit lost. Perhaps some former Snobol-ers can comment on this statement. Icon is nice in the sense that it runs on almost all small and mid-range machines, and on many high-end ones. It's very portable, and is pretty much free. -Richard From icon-group-request@arizona.edu Wed Dec 5 23:33:53 1990 Resent-From: icon-group-request@arizona.edu Received: from HOPEY.TELCOM.ARIZONA.EDU by megaron.cs.arizona.edu (5.61/15) via SMTP id AA10370; Wed, 5 Dec 90 23:33:53 -0700 Received: from ucbvax.Berkeley.EDU by Arizona.edu with PMDF#10282; Wed, 5 Dec 1990 23:33 MST Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA11733; Wed, 5 Dec 90 22:18:49 -0800 Received: from USENET by ucbvax.Berkeley.EDU with netnews for icon-group@arizona.edu (icon-group@arizona.edu) (contact usenet@ucbvax.Berkeley.EDU if you have questions) Resent-Date: Wed, 5 Dec 1990 23:33 MST Date: 6 Dec 90 02:03:04 GMT From: att!linac!pacific.mps.ohio-state.edu!zaphod.mps.ohio-state.edu!van-bc!ubc-cs!alberta!herald.usask.ca!skorpio!gulati@ucbvax.Berkeley.EDU (Neeraj Gulati) Subject: Just a test ... Sender: icon-group-request@arizona.edu Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: <120BE8FBBC4010BB@Arizona.edu> Message-Id: <1990Dec6.020304.18013@herald.usask.ca> X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.edu Organization: University of Saskatchewan Please ignore !! From icon-group-request@arizona.edu Thu Dec 6 07:34:40 1990 Resent-From: icon-group-request@arizona.edu Received: from HOPEY.TELCOM.ARIZONA.EDU by megaron.cs.arizona.edu (5.61/15) via SMTP id AA26318; Thu, 6 Dec 90 07:34:40 -0700 Received: from ucbvax.Berkeley.EDU by Arizona.edu with PMDF#10282; Thu, 6 Dec 1990 07:34 MST Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA19462; Thu, 6 Dec 90 06:21:58 -0800 Received: from USENET by ucbvax.Berkeley.EDU with netnews for icon-group@arizona.edu (icon-group@arizona.edu) (contact usenet@ucbvax.Berkeley.EDU if you have questions) Resent-Date: Thu, 6 Dec 1990 07:34 MST Date: 6 Dec 90 12:33:55 GMT From: eru!hagbard!sunic!mcsun!cernvax!chx400!hslrswi!naz@bloom-beacon.mit.edu (Norman H. Azadian) Subject: Klondike card game, version 1.41. part 1/4 Sender: icon-group-request@arizona.edu Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: <553247FFCC4022BE@Arizona.edu> Message-Id: <1687@hslrswi.UUCP> X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.edu Organization: Hasler AG This is a new version of the solitaire card game that I posted some months ago. This one improved ICONisms, an improved user interface, and a much better chance of actually running on any ANSI terminal. There is even a man page, klondike.man, included in this message. The source is now split into three files: klondike.icn main program, top-level user-interface routines kloncon.icn console I/O subroutines klonsub.icn assorted other subroutines To execute from scratch, I believe the following suffices: icont -c kloncon klonsub icont klondike iconx klondike <> Should you wish to peruse the source, use a tab interval of 4, not 8. NHA --- PAPER: Norman Azadian; Ascom AG; Belpstrasse 23; 3000 Berne 14; Switzerland X.400: naz@hslrswi.hasler UUCP: ...{uunet,ukc,mcvax,...}!cernvax!hslrswi!naz VOICE: +41 31 63 2178 BITNET: naz%hslrswi.UUCP@cernvax.BITNET --------------- cut here -------------------- cut here --------------------- NAME klondike -- one of the many versions of solitaire SYNOPSIS klondike -[ACD] [-B gameCount] [-R randomSeed] DESCRIPTION This is actually a popular variation on the Klondike version of Solitaire (or Patience) as described on page 181 of my 1963 version of "Hoyle's Rules of Games". The difference is that here we go through the deck (stock) 3 cards at a time instead of one-by-one, and we allow it any number of times. It should run on any ANSI-compatible terminal, but it looks best on a PC, preferably color. OPTIONS Options may be either upper or lower case. They may be given in any order. Parameters follow their options with whitespace inbetween. Each option must be given as a separate argument. -A disables automatically putting uncovered Ace cards on the appropriate pile. Note that, in any case, it is not allowed to put an Ace onto a stack, as this could lead to building stacks which are too big to display with 25 lines. -B count Batch mode. The requested number of games is played and the average number of cards promoted to the ace piles is written to the standard output. No other I/O is performed. -C disable the "click" for silent games -D enable special debugging commands which, among other things, allow one to cheat -R seed set the random seed to the designated value COMMANDS H or ? display a Help screen ^L (control-L) redraws the screen A Automatic mode. Plays the game until nothing useful remains to be done, or until any key is struck. B Boss key. The screen is blanked and the current position is saved. When the game is started again in the usual way, this saved game will be automatically restored and the save file deleted. C Continuous mode. The computer plays games automatically until a key is struck. Two statistics are displayed: the number of games already played, and the total number of aces which have been promoted to the ace piles. M Move a card from the deck or a stack to a stack or an ace pile. Q Quit this game, with the opportunity to play another. S Suggest a possible move. Hitting this key multiple times results in multiple suggestions being displayed. When there is nothing interesting left to do, it will suggest "Thumb". T Thumb. Remove the top 3 cards from the face-down deck and lay them face-up on the face-up deck. U Undo. This can be used all the way back to the start of the current game. Z Debug. This is only enabled when the -D option has been given on the command line. There is a sub-menu of commands available, including a (very brief) Help summary. The Move command takes two parameters: source and destination. Possible sources are: D for the Deck of face-up cards; and a number from 1 to 7 inclusive, meaning the corresponding stack. Possible destinations are the stacks (1-7) and A for the appropriate ace pile. For instance, to move the visible card from the face-up deck to stack 4, one types the three characters: "MD4". Actually, the "M" character itself is optional, which explains why the "debug" command isn't invoked with a "D". BUGS Slow. Doesn't use termcap for maximum portability. The program's play is simplistic, with no concept of strategy. FILES klondike.sav Position is checkpointed here when the Boss key is used. klondike.sv? Position checkpointed here with the "S" debug command. "?" can be any (upper-case) character legal in your filesystem. ACKNOWLEDGEMENT The inspiration, name, and user interface were lifted wholesale from a game copyrighted in 1985 by Allyn Wade. VERSION 1.41 -- 26 November, 1990 AUTHOR Norman H. Azadian naz@hslrswi -- PAPER: Norman Azadian; Ascom AG; Belpstrasse 23; 3000 Berne 14; Switzerland X.400: naz@hslrswi.hasler UUCP: ...{uunet,ukc,mcvax,...}!cernvax!hslrswi!naz VOICE: +41 31 63 2178 BITNET: naz%hslrswi.UUCP@cernvax.BITNET From icon-group-request@arizona.edu Thu Dec 6 07:35:40 1990 Resent-From: icon-group-request@arizona.edu Received: from HOPEY.TELCOM.ARIZONA.EDU by megaron.cs.arizona.edu (5.61/15) via SMTP id AA26388; Thu, 6 Dec 90 07:35:40 -0700 Received: from ucbvax.Berkeley.EDU by Arizona.edu with PMDF#10282; Thu, 6 Dec 1990 07:34 MST Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA19656; Thu, 6 Dec 90 06:32:50 -0800 Received: from USENET by ucbvax.Berkeley.EDU with netnews for icon-group@arizona.edu (icon-group@arizona.edu) (contact usenet@ucbvax.Berkeley.EDU if you have questions) Resent-Date: Thu, 6 Dec 1990 07:34 MST Date: 6 Dec 90 12:43:12 GMT From: eru!hagbard!sunic!mcsun!cernvax!chx400!hslrswi!naz@bloom-beacon.mit.edu (Norman H. Azadian) Subject: klondike, version 1.41. part 3/4 Sender: icon-group-request@arizona.edu Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: <55429BAFCC401D40@Arizona.edu> Message-Id: <1689@hslrswi.UUCP> X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.edu Organization: Hasler AG #kloncon.icn 901029 NHA # Console interface routines for Klondike # Requires ANSI.SYS (or NANSI.SYS) screen driver and a 25-line display. # # TO FIX: # # # TO DO: # # - termcap for portability ?? # - click for each card moved in a stack ? # # constants global suitID #suit identification chars global isDOS # 1 when running under DOS global monochrome # 1 when running Black&White # Video control strings (ANSI.SYS) global ESC global Vnormal, Vreverse, Vblink, Vbold, VclearAll, VclearEOL, Vbell global color #list of suit color strings # i n i t C o n s t a n t s # Initialize the program "constants". These are actually variables that # are set just once at the beginning of the world. procedure initConstants () local i local Vred, Vblack #suit color strings if \invisible then return #ensure that we are dealing with an ANSI-compatible screen writes ("\33[6n") #request cursor position report #NOTE that the first character to match should be an ESCape. #Unfortunately, reads() seems to eat that character match ("[", reads (&input, 8)) | stop ("Klondike: requires ANSI.SYS screen driver") isDOS := find("MS-DOS", &host) if \isDOS then { i := ord (Peek([16r40, 16r49])) #BIOS display mode byte case i of { 2 : monochrome := 1 3 : monochrome := &null #living color 7 : monochrome := 1 default : stop ("Klondike: unknown display mode ", i) } } else monochrome := 1 ESC := "\33" #escape character VclearAll := "\33[2J" #also homes cursor VclearEOL := "\33[K" Vnormal := "\33[0m" Vbold := "\33[1m" Vblink := "\33[5m" Vreverse := "\33[7m" Vbell := "\^G" if \monochrome then { Vred := Vnormal Vblack := Vreverse } else { Vred := "\33[0;47;31m" # "extra" 0 seems to be necessary Vblack := "\33[0;47;30m" } # Suits are: 1=Hearts, 2=Diamonds, 3=Clubs, 4=Spades suitID := if \isDOS then "\3\4\5\6" else "HDCS" color := [Vred, Vred, Vblack, Vblack] end #initConstants # i n i t S c r e e n # Initialize output and write the fixed parts of the screen. # initConstants() must have been called earlier. procedure initScreen () local i static vertical initial { vertical := if \isDOS then "\272" else "|" } if \invisible then return if \monochrome then writes ("\33[=2h") #25x80 B&W text mode else writes ("\33[=3h") #25x80 color text mode writes (VclearAll, "\33[=7l") #clear screen, prevent wrap every i := 1 to 7 do writeStackNumber (i, Vnormal) every i := 2 to 25 do writes ("\33[",i,";64H", vertical) if \isDOS then writes ("\33[2;64H\311\315\315\315\315SOLITAIRE\315\315\315\315") else writes ("\33[2;64H=====SOLITAIRE====") end #initScreen # w r i t e S t a c k N u m b e r # Write the indicated stack number with the specified video attribute. # Cursor position is preserved -- WARNING: THIS IS NOT NESTABLE. procedure writeStackNumber (num, attr) if \invisible then return writes (ESC, "[s") #save cursor position writeCursor (1, [2,11,20,29,38,47,56][num]) writes (attr, num, Vnormal) writes (ESC, "[u") #restore cursor position end #writeStackNumber # w r i t e C u r s o r # Position the cursor to row,col. # Screen origin (top left corner) is row=1 and col=1. procedure writeCursor (row, col) if /invisible then writes ("\33[", row, ";", col, "H") end #writeCursor # w r i t e F r o n t # Displays an image of the specified card fronts at the specified spot. # WARNING: this eats the list that you provide -- pass a copy() if you care!! # Top left corner of the first card will be placed at the specified position. # Successive cards are displayed two rows higher (lower position on the screen). # Cursor need not be in any particular position before this, and is left # in a random position afterwards. Video is always left normal (not reversed). # Cards are 7 columns wide by 5 rows tall. # With 25 rows, we can put 12 cards in a stack (assuming we start in row 2). # But if there are 11 in the stack we can only display 4 rows of the top card. # If there are 12 cards, we can only display 2 rows of the topmost card. ##We can only write a row at a time due to a problem with ANSI col 80 handling. procedure writeFront (cardlist, row, col) local suit, rank, card static vertical, topHorizontal, bottomHorizontal initial { if \isDOS then { vertical := "\263" topHorizontal := "\332\304\304\304\304\304\277" bottomHorizontal := "\300\304\304\304\304\304\331" } else { vertical := "|" topHorizontal := "-------" bottomHorizontal := "-------" } } while card := get(cardlist) do { #first 2 rows of card writeCursor (row+0, col); writes (Vreverse, topHorizontal) writeCursor (row+1, col); writes (vertical, color[card.suit], "A23456789TJQK"[card.rank], suitID[card.suit], Vreverse, " ", vertical) if (*cardlist = 0) & (row < 24) then { #next 2 rows of top card unless it's the 12th card on the stack writeCursor (row+2, col); writes (Vreverse, vertical, " ", vertical) writeCursor (row+3, col); writes (vertical, " ",color[card.suit],"A23456789TJQK"[card.rank], suitID[card.suit], Vreverse, vertical) if row < 22 then { #last row of card unless it's the 11th on the stack writeCursor (row+4, col); writes (bottomHorizontal) } } row +:= 2 } writes (Vnormal) end #writeFront # w r i t e B a c k # Puts an image of the back of a card at the specified spot on the screen. procedure writeBack (row, col) static backLine initial { backLine := repl (if \isDOS then "\260" else "#", 7) } if \invisible then return writeCursor (row+0, col); writes (backLine) writeCursor (row+1, col); writes (backLine) writeCursor (row+2, col); writes (backLine) writeCursor (row+3, col); writes (backLine) writeCursor (row+4, col); writes (backLine) end #writeBack # w r i t e B l a n k # Blanks a card-sized area at the specified spot on the screen. procedure writeBlank (row, col) static blankLine initial { blankLine := repl (" ", 7) } if \invisible then return writeCursor (row+0, col); writes (blankLine) writeCursor (row+1, col); writes (blankLine) writeCursor (row+2, col); writes (blankLine) writeCursor (row+3, col); writes (blankLine) writeCursor (row+4, col); writes (blankLine) end #writeBlank # w r i t e S t a c k # Display the specified stack. Left end is bottom of stackUp, top of stackDown. # Stacks start in row 2, column1; with 2 columns between stacks. # last[] holds, for each stack, the total number of visible cards # on that stack as of the last time writeStack() was called. This allows # us to simply draw (or erase) the cards that have been added (or subtracted). # By special arrangement, this routine can be called with a negative stack # number! This is a hint that our idea of what is on the display is actually # wrong, and therefore the entire stack needs to be re-displayed. This can # happen in two situations: 1) in refreshScreen(), the entire screen is cleared # before calling writeStack(); 2) in undo() when undoing a move between # stacks, the bottom card needs to be changed, although the normal algorithm # would consider that it is already correctly displayed. Note that in neither # case is the stack shrinking, therefore we don't need to worry about erasing # any cards that were displayed last time. procedure writeStack (n) local row, col, s static last, blankLine, firstRow, lastRow initial { last := [0,0,0,0,0,0,0] blankLine := repl (" ", 7) firstRow := [2,4,6,8,10,12,14,16,18,20,22,24] #first row of a card lastRow := [6,8,10,12,14,16,18,20,22,24,25,25] #last row of a card } if \invisible then return if n < 0 then { n := -n last[n] := 0 #force complete re-write } col := 1 + ((n -1) * 9) #leftmost column for this stack if *stackUp[n] <= last[n] then { #the stack just got smaller (or stayed the same) #blank out two rows for each card that has been removed row := lastRow[last[n]] #last row used by top card while *stackUp[n] < last[n] do { writeCursor (row-0, col); writes (blankLine) writeCursor (row-1, col); writes (blankLine) row -:= 2 last[n] -:= 1 #count and update simultaneously } dieIf (*stackUp[n] ~= last[n], last[n]) #re-write new top card if *stackUp[n] = 0 then if *stackDown[n] = 0 then writeBlank (2, col) else writeBack (2, col) else writeFront ([stackUp[n][-1]], firstRow[last[n]], col) } else { #the stack just got bigger -- display new cards s := stackUp[n][last[n]-(*stackUp[n]):0] #list of new cards writeFront (s, firstRow[last[n]+1], col) last[n] := *stackUp[n] #remember how much is displayed } writeCursor (2, (7 + col)) writes (" 123456???"[1+*stackDown[n]]) #display the number of hidden cards end #writeStack # w r i t e P i l e # Displays an image of the specified ace pile, face up (or blank if empty) procedure writePile (n) static pileRow, pileCol initial { pileRow := [3,3,9,9] pileCol := [66,74,66,74] } if \invisible then return if 0 = pile[n] then writeBlank (pileRow[n], pileCol[n]) else writeFront ([card(n,pile[n])], pileRow[n], pileCol[n]) end #writePile # w r i t e D e c k D o w n # Displays an image of deckDown (the face-down deck) in the proper spot. procedure writeDeckDown () if \invisible then return if 0 < *deckDown then writeBack (21, 74) else writeBlank (21, 74) writeCursor (20, 76) writes (right(*deckDown, 2)) end #writeDeckDown # w r i t e D e c k U p # Displays an image of deckUp (the face-up deck) in the proper spot. procedure writeDeckUp () if \invisible then return if 0 < *deckUp then writeFront ([deckUp[1]], 21, 66) else writeBlank (21, 66) writeCursor (20, 68) writes (right(*deckUp, 2)) end #writeDeckUp # w r i t e I n f o # Displays a new short string (up to 12 printing characters) in the # officially approved information area of the screen. # An empty string results in clearing the area and restoring normal attributes. procedure writeInfo (s) if \invisible then return writeCursor (16, 65) writes (Vnormal, VclearEOL) if *s ~= 0 then writes (s) end #writeInfo # c l i c k # Make a quick sound to accompany card transfers procedure click () local x if (\clicking) & (\isDOS) then { x := InPort (16r61) OutPort (16r61, 3) OutPort (16r61, x) } end #click # g e t C m d C h a r # Returns an upper-case command character, echoed to current cursor position. # Fails if character wasn't "normal" and complaint was made. # For ESC, abort information is written, and ESC is returned. # Normal calling sequence (from within a command procedure) is thus: # until (s := getCmdChar ()) # if s == ESC then fail procedure getCmdChar () local s s := getch () #get command character if s == "\0" then { #non-ASCII character getch () #discard keyboard scan code complain () fail } s := map (s, &lcase, &ucase) if s == ESC then writeInfo (Vbold || "Cmd Aborted.") else writes (s) #echo the command character return s end #getCmdChar # c o m p l a i n # Let the boob know he done something wrong # The short beep produced under isDOS is not as annoying as the normal beeeeep. procedure complain () local x writeInfo (Vbold || "INVALID") if \clicking then if \isDOS then { x := InPort (16r61) every 1 to 22 do OutPort (16r61, 3) OutPort (16r61, x) } else writes (Vbell) end #complain # r e f r e s h S c r e e n # Re-write entire screen. procedure refreshScreen () if \invisible then return initScreen () every writeStack (-1 to -7 by -1) every writePile (1 to 4) writeDeckDown () writeDeckUp () end #refreshScreen -- PAPER: Norman Azadian; Ascom AG; Belpstrasse 23; 3000 Berne 14; Switzerland X.400: naz@hslrswi.hasler UUCP: ...{uunet,ukc,mcvax,...}!cernvax!hslrswi!naz VOICE: +41 31 63 2178 BITNET: naz%hslrswi.UUCP@cernvax.BITNET From icon-group-request@arizona.edu Thu Dec 6 07:35:46 1990 Resent-From: icon-group-request@arizona.edu Received: from HOPEY.TELCOM.ARIZONA.EDU by megaron.cs.arizona.edu (5.61/15) via SMTP id AA26395; Thu, 6 Dec 90 07:35:46 -0700 Received: from ucbvax.Berkeley.EDU by Arizona.edu with PMDF#10282; Thu, 6 Dec 1990 07:34 MST Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA19678; Thu, 6 Dec 90 06:33:14 -0800 Received: from USENET by ucbvax.Berkeley.EDU with netnews for icon-group@arizona.edu (icon-group@arizona.edu) (contact usenet@ucbvax.Berkeley.EDU if you have questions) Resent-Date: Thu, 6 Dec 1990 07:35 MST Date: 6 Dec 90 12:44:22 GMT From: eru!hagbard!sunic!mcsun!cernvax!chx400!hslrswi!naz@bloom-beacon.mit.edu (Norman H. Azadian) Subject: klondike, version 1.41. part 4/4 Sender: icon-group-request@arizona.edu Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: <555A54FD6C4022C1@Arizona.edu> Message-Id: <1690@hslrswi.UUCP> X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.edu Organization: Hasler AG #klonsub.icn 901029 NHA #subroutines for Klondike # d i e I f # If the first argument succeeds, then write out the remaining args & die. # Note that the remaining arguments must succeed. procedure dieIf (failed, writeArgs[]) every writes (&output, !writeArgs) write (&output) display () every writes (&errout, !writeArgs) write (&errout) runerr (500) end #dieIf # f i t O n S t a c k # Given a card and a stack number, fail unless card can be added to the stack. # Note that we disallow putting an Ace on a stack, period. This prevents # ever building a stack with 13 cards, which we can't display in 25 rows. procedure fitOnStack (c, n) local top #top card on stack if *stackUp[n] = 0 then { dieIf (*stackDown[n] ~= 0, "Up empty, Down not") if c.rank ~= 13 then fail #only a king can go to empty stack } else { top := stackUp[n][-1] #copy of top card if (c.rank ~= (top.rank - 1)) then fail #wrong rank if (c.suit < 3) & (top.suit < 3) then fail #same color if (c.suit > 2) & (top.suit > 2) then fail #same color if c.rank = 1 then fail #no ace on stack dieIf (*stackUp[n] >= 12, "stack too big") } return #success end #fitOnStack # c h e c k 4 a c e # Only has an effect when global automaticAce is set! # Given a stack number, check for an ace as the top of stackUp[n]. # If present, move it over to it's ace pile, turn over the next card # from stackDown, and check again. # Must not be more than one up card in stack. # Returns a string of the operations performed. procedure check4ace (n) local c, op op := "" if \automaticAce then { dieIf (1 < *stackUp[n]) while 0 < *stackUp[n] do { c := stackUp[n][1] #copy of (top = bottom) up card if c.rank = 1 then { #it's an ace! pop (stackUp[n]) #remove it from the stack pile[c.suit] := 1 #move to ace pile op ||:= c.suit push (stackUp[n], get(stackDown[n])) #turn over card underneath writeStack (n) writePile (c.suit) click () } else break #not an ace } } return op end #check4ace # m o v e S t a c k # Move a stack to another stack, no questions asked. # Updates video and audio. # Returns any automatic ace operations that were done as a consequence. ##It would be nice to do this in a visually and audibly more satisfying way procedure moveStack (src, dst) while put (stackUp[dst], get(stackUp[src])) put (stackUp[src], get(stackDown[src])) writeStack (src) writeStack (dst) click () return check4ace (src) end #moveStack # m o v e # This is the internal move, taking a operation string. No Thumbs allowed. # Upon success it returns the (possibly modified) operation string. procedure move (op) local src, dst, c, moved dieIf (op[1] ~== "M", "op is ", op) src := op[2] dst := op[3] moved := 0 if src == "D" then { c := deckUp[1] if dst == "A" then { # Deck -> Ace if c.rank = (pile[c.suit] + 1) then { op[4] := c.suit # Deck -> Ace: fits - do it pile[c.suit] +:= 1 writePile (c.suit) moved := 1 } else fail # Deck -> Ace: doesn't fit } else { # Deck -> stack if fitOnStack (c, dst) then { put (stackUp[dst], c) # Deck -> stack: fits - do it writeStack (dst) moved := 1 } else fail # Deck -> stack: doesn't fit } while moved ~= 0 do { pop (deckUp) writeDeckUp () # Deck -> somewhere, with success click () moved := 0 if \automaticAce then { if (c := deckUp[1]).rank = 1 then { #automatic Ace handling pile[c.suit] := 1 op ||:= c.suit writePile (c.suit) moved := 1 } } } } else { if dst == "A" then { # stack -> Ace c := stackUp[src][-1] #copy of card on top of stack if c.rank = (pile[c.suit] + 1) then { op[4] := c.suit # stack -> Ace: fits - do it pile[c.suit] +:= 1 pull (stackUp[src]) writeStack (src) click () writePile (c.suit) if *stackUp[src] = 0 then { op[4] +:= 4 #mark this case for undo() put (stackUp[src], get(stackDown[src])) #turn over a card writeStack (src) click () op ||:= check4ace (src) } } else { fail # stack -> Ace: doesn't fit } } else { # stack -> stack if fitOnStack (stackUp[src][1], dst) then { # stack -> stack: fits - do it op[4] := "123456789abcdef"[*stackUp[src]] op ||:= moveStack (src, dst) } else fail # stack -> stack: doesn't fit } } return op #success end #move # t h u m b # Move to next spot in deckDown # Returns the operation performed (usually just "T3"), or fail if none possible. procedure thumb () local c, op, moved if *deckDown = *deckUp = 0 then return complain() #no cards left in the deck if *deckDown = 0 then while push (deckDown, pop(deckUp)) op := "T" || if *deckDown < 3 then *deckDown else 3 push (deckUp, pop(deckDown)) push (deckUp, pop(deckDown)) push (deckUp, pop(deckDown)) writeDeckDown () moved := 1 while moved ~= 0 do { writeDeckUp () click () moved := 0 if \automaticAce then { if deckUp[1].rank = 1 then { c := pop (deckUp) pile[c.suit] := 1 op ||:= c.suit writePile (c.suit) moved := 1 } } } return op end #thumb # u n d o # backup one move, including any automatic ace moves procedure undo () local op, suit writes ("ndo") if op := pop (ops) then { writeInfo (op) # op looks like: Msdixxx # where x is an [optional] number 1..4 of an ace pile # and s is either a stack number or "D" # and d is either "A" or a number 1..7 of a stack # and i is an extra piece of info which may be valid case op[1] of { "M" : { dieIf ((*op < 4) | ((/automaticAce) & (4 < *op)), op) if op[2] == "D" then { #Move cards from Ace piles to deck, starting at end while 4 < *op do { suit := op[-1] pile[suit] := 0 writePile (suit) push (deckUp, card(suit,1)) writeDeckUp () click () op[-1] := "" } if op[3] == "A" then { # unMove Deck to Ace op[4] suit := op[4] push (deckUp, card(suit,pile[suit])) pile[suit] -:= 1 writePile (suit) } else { # unMove Deck to stack op[3] push (deckUp, pull(stackUp[op[3]])) writeStack (op[3]) } writeDeckUp () } else { #Move cards from Ace piles to stack, starting at end while 4 < *op do { suit := op[-1] pile[suit] := 0 writePile (suit) dieIf (1 < *stackUp[op[2]]) push (stackDown[op[2]], pull(stackUp[op[2]])) push (stackUp[op[2]], card(suit,1)) writeStack (op[2]) click () op[-1] := "" } if op[3] == "A" then { # unMove stack op[2] to Ace pile op[4] suit := op[4] if 4 < suit then { suit -:= 4 #ace pile card was last on stack dieIf (1 < *stackUp[op[2]]) push (stackDown[op[2]], pull(stackUp[op[2]])) } put (stackUp[op[2]], card(suit,pile[suit])) pile[suit] -:= 1 writePile (suit) writeStack (op[2]) } else { # unMove top op[4] cards on stack op[2] # to stack op[3] dieIf (1 < *stackUp[op[2]]) push (stackDown[op[2]], pull(stackUp[op[2]])) every 1 to ("16r" || op[4]) do push (stackUp[op[2]], pull(stackUp[op[3]])) writeStack (op[3]) writeStack (-op[2]) } } } "T" : { dieIf ((/automaticAce) & (*op ~= 2)) ### op looks like: Tcxx ### where c is the number of cards thumbed (usually 3) ### and x is an optional number 1..4 of an ace pile ### There can be 0,1,2, or 3 of these x's. # move cards from Ace piles to deck, starting at end while 2 < *op do { suit := op[-1] pile[suit] := 0 writePile (suit) push (deckUp, card(suit,1)) writeDeckUp () click () op[-1] := "" } # then undo the Thumb operation itself dieIf (*deckUp = 0) every 1 to op[2] do push (deckDown, pop(deckUp)) if *deckUp = 0 then while push (deckUp, pop(deckDown)) writeDeckUp () writeDeckDown () } default : stop ("Klondike: unknown operation `", op, "' in ops[]") } click () } else { ## Admittedly this is a bit of a kluge, but better than nothing ? if *deckDown = 0 then while push (deckDown, pop(deckUp)) writeDeckUp () writeDeckDown () writeInfo ("Stack Empty") } end #undo # s h o w L i s t # Display a list of cards at the current cursor position. # Intended for debugging only . procedure showList (lst) local c every c := !lst do writes (color[c.suit], "A23456789TJQK"[c.rank], suitID[c.suit], Vnormal, " "); end #showList # c a r d 2 s t r # Given a list of card records, returns a string representation. # Even an empty list results in a non-zero string length. procedure card2str (lst) local c, s s := "$" every c := !lst do s ||:= string(c.suit) || "123456789abcd"[c.rank] return s end #card2str # s t r 2 c a r d # Given a string [as generated by card2str()], # return corresponding list of card records. # Fails if the string is invalid. procedure str2card (s) local cc, i if s[i:=1] ~== "$" then fail cc := [] while put (cc, card(s[i+:=1], integer("14r"||s[i+:=1]))) return cc end #str2card # s a v e S t a t e # Saves the current state in the named file, which is created/overwritten # as necessary. # Fails if the state was not successfully saved. procedure saveState (filename) local f, i (f := open (filename, "c")) | fail write (f, &dateline) write (f, if \automaticAce then 1 else 0) write (f, if \clicking then 1 else 0) write (f, firstSeed) write (f, lastSeed) write (f, &random) every write (f, !pile) every write (f, card2str(!stackUp)) every write (f, card2str(!stackDown)) write (f, card2str(deckUp)) write (f, card2str(deckDown)) write (f, totalGames) write (f, totalAces) every write (f, !ops) return close (f) end #saveState # r e s t o r e S t a t e # Restore game from the named file. # Fails if the file isn't there, isn't readable, or isn't correct format. # Otherwise returns date the file was last written. # Note that we do not update the screen here !! procedure restoreState (filename) local f, date if not (f := open (filename, "r")) then fail if (not (date := read(f))) | (*date = 0) then fail automaticAce := if read (f) == "0" then &null else 1 clicking := if read (f) == "0" then &null else 1 firstSeed := read (f) lastSeed := read (f) &random := read (f) every ((!pile) := read(f)) every ((!stackUp) := str2card (read(f))) every ((!stackDown) := str2card (read(f))) deckUp := str2card (read(f)) deckDown := str2card (read(f)) totalGames := read (f) totalAces := read (f) ops := [] while push (ops, read (f)) dieIf (not close (f), "can't close") return date end #restoreState # n e w G a m e # Set up all the global variables for a new game. # Returns the seed used to generate this game. procedure newGame () local i, j, s, seed initScreen () #initialize deck, stacks, piles ops := [] #no operations done yet deckUp := [] #deck in hand, face-up deckDown := [] #deck in hand, face-down stackUp := list(7, 0) #columns on table, face up stackDown := list(7, 0) #columns on table, face down pile := list(4, 0) #aces - only top rank stored every i := 1 to 4 do every j := 1 to 13 do put (deckDown, card(i, j)) #take cards out of the box seed := &random if not \invisible then #Vblink not defined in Batch mode writeInfo (Vblink || "Shuffling") every 1 to 100 do ?deckDown :=: ?deckDown writeInfo ("") every !stackUp := [] every !stackDown := [] every i := 1 to 7 do { push (stackUp[i], get(deckDown)) writeStack (-i) click () every j := (i+1) to 7 do { push (stackDown[j], get(deckDown)) writeStack (-j) click () } ### writeStack (-i) ### this replaces 2 calls above } writeDeckDown() #handle any Aces which are showing every i := 1 to 7 do if *(s := check4ace (i)) ~= 0 then push (ops, "M" || string(i) || "A" || string(integer(s) + 4)) return seed end #newGame -- PAPER: Norman Azadian; Ascom AG; Belpstrasse 23; 3000 Berne 14; Switzerland X.400: naz@hslrswi.hasler UUCP: ...{uunet,ukc,mcvax,...}!cernvax!hslrswi!naz VOICE: +41 31 63 2178 BITNET: naz%hslrswi.UUCP@cernvax.BITNET From icon-group-request@arizona.edu Thu Dec 6 07:36:54 1990 Resent-From: icon-group-request@arizona.edu Received: from HOPEY.TELCOM.ARIZONA.EDU by megaron.cs.arizona.edu (5.61/15) via SMTP id AA26473; Thu, 6 Dec 90 07:36:54 -0700 Received: from ucbvax.Berkeley.EDU by Arizona.edu with PMDF#10282; Thu, 6 Dec 1990 07:35 MST Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA19641; Thu, 6 Dec 90 06:32:04 -0800 Received: from USENET by ucbvax.Berkeley.EDU with netnews for icon-group@arizona.edu (icon-group@arizona.edu) (contact usenet@ucbvax.Berkeley.EDU if you have questions) Resent-Date: Thu, 6 Dec 1990 07:36 MST Date: 6 Dec 90 12:42:14 GMT From: eru!hagbard!sunic!mcsun!cernvax!chx400!hslrswi!naz@bloom-beacon.mit.edu (Norman H. Azadian) Subject: klondike, version 1.41. part 2/4 Sender: icon-group-request@arizona.edu Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: <5580B0A18C401FC4@Arizona.edu> Message-Id: <1688@hslrswi.UUCP> X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.edu Organization: Hasler AG #klondike.icn 900720 NHA #The Klondike version of Solitaire. # Requires ANSI.SYS (or NANSI.SYS) screen driver and a 25-line display. # # TO FIX: # # # # TO DO: # # - Use space to step to next non-thumb move, and enter to do it ??? # - Implement an heuristic to discover optimal play strategy. # link kloncon #console I/O link klonsub #general subroutines record card(suit, rank) #suit is 1..4, rank is 1..13 # variables global deckUp, deckDown, stackUp, stackDown #collections of card global pile #ace piles - top rank only global ops #list of all operations done global debugging, automaticAce #command-line flags global invisible, clicking #visual, audible feedback global firstSeed, lastSeed #&random remembered global totalGames, totalAces #ace pile statistics # a u t o m a t i c 1 # Do 1 move, thumbing as necessary to achieve it. # Fails if there is nothing useful left to do. # This is an internal routine that doesn't worry at all about the user. procedure automatic1 () local s, thumbCount thumbCount := 0 while thumbCount <= ((*deckUp + *deckDown + 2) / 3) do { if s := suggest() then { push (ops, move ("M" || s || "0")) thumbCount := 0 return; } else { #no good move found -- thumb if (*deckUp = 0) & (*deckDown = 0) then fail #no cards left to thumb through push (ops, s := thumb()) if 2 < *s then return #must have turned up an Ace thumbCount +:= 1 } } end #automatic1 # a u t o m a t i c # Run the game, as far as possible, untouched by human hands # This is an internal routine that only worries a little about the user. # Returns when either there is nothing useful left to do or a key is struck. procedure automatic () local s, thumbCount thumbCount := 0 repeat { if kbhit () then return #stopped by human intervention if pile[1] = pile[2] = pile[3] = pile[4] = 13 then return #victory automatic1 () | return } end #automatic # u a u t o m a t i c # Play this hand automatically, untouched by human hands. # This is the fuction that interacts with the user. procedure uautomatic () writes ("utomatic") automatic() if kbhit() then if getch() == "\0" then getch() end #uautomatic # u c o n t i n u o u s # Plays automatic games -- forever (or until any keystroke) procedure ucontinuous() writes ("ontinuous") repeat { writeInfo (string(totalGames) || " " || string(totalAces)) automatic() if kbhit() then { if getch() == "\0" then #eat stopping char(s) getch() return } else totalAces +:= pile[1] + pile[2] + pile[3] + pile[4] totalGames +:= 1 lastSeed := newGame() } end #ucontinuous # u h e l p # Provide command summary for user, plus statistics to date, if any. procedure uhelp () write (VclearAll, Vnormal) write ("Klondike version 1.41 901126 NHA\t\t", &version) write ("\n\nThe following commands are available:\n") write ("\t", Vbold, "^L\tre-draw", Vnormal, " screen") write ("\t", Vbold, "A\tAutomatic", Vnormal, " mode -- plays 1 game by itself until any key is hit") write ("\t", Vbold, "B\tBoss", Vnormal, " key for when you-know-who visits") write ("\t", Vbold, "C\tContinuous", Vnormal, " mode -- plays games continuously until any key hit") write ("\t", Vbold, "H,?\tHelp", Vnormal, ", this help screen") write ("\t", Vbold, "M\tMove", Vnormal, " card (or stack) from Deck/Stack to Stack/Ace pile") write ("\t", Vbold, "Q\tQuit", Vnormal, " this game") write ("\t", Vbold, "S\tSuggest", Vnormal, " (another) possible move") write ("\t", Vbold, "T\tThumb", Vnormal, " through the deck") write ("\t", Vbold, "U\tUndo", Vnormal, " -- back up one move") if \debugging then write ("\t", Vbold, "Z\tDebug", Vnormal) write ("\t", Vbold, "ESC\tEscape", Vnormal, " -- abort current command") if totalGames ~= 0 then write ("\n\ntotalGames = ", totalGames, " totalAces = ", totalAces, " average = ", real(totalAces) / real(totalGames)) write ("\n\n", Vblink, "Press any key to resume game", Vnormal) if getch() == "\0" then getch() refreshScreen () end #uhelp # u m o v e # Move a card from deck to stack, or from stack to ace pile, # or move a stack to another stack. # Parameter is the source [1-7 or D] or &null to indicate that "M" was used # and therefore source should be gathered from the keyboard. # Fails if indicated move is not possible # This is the routine that interacts with the user. procedure umove (src) local dst, c, op, moved if \src then writes ("\bMove ", Vbold, src) else { writes ("ove " || Vbold); until (src := getCmdChar ()) if src == ESC then return } if src == "D" then { if *deckUp = 0 then fail } else { if not any ('1234567', src) then fail if *stackUp[src] = 0 then fail writeStackNumber (src, Vblink) } writes (Vnormal || " to " || Vbold) until (dst := getCmdChar ()) if src ~== "D" then writeStackNumber (src, Vnormal) if dst == ESC then return if not any ('A1234567', dst) then fail if dst == src then fail return push (ops, move("M" || src || dst || "0")) end #umove # s u g g e s t # Find a (reasonable) possible move in this situation # This is the internal routine. procedure suggest () local i, j, k, c #look at deckUp to see if the top card fits on a pile if c := deckUp[1] then if c.rank = (pile[c.suit] + 1) then suspend "DA" #look at deckUp to see if the top card fits on a stack if c := deckUp[1] then every i := 1 to 7 do if fitOnStack (c, i) then suspend "D" || string(i) #look at each stack to see if top card can be put on ace pile every i := 1 to 7 do if c := stackUp[i][-1] then #top card if c.rank = (pile[c.suit] + 1) then suspend string(i) || "A" #look at each stack to see if something can be (reasonably) moved every i := 7 to 1 by -1 do every j := 1 to 7 do if fitOnStack (stackUp[i][1], j) then { if (0 < *stackDown[i]) then suspend string(i) || string(j) else { # possibility, but since there are no cards hidden under # this pile, we reject it UNLESS there are no empty slots # AND one of the following is true: # 1) deckUp[1].rank = 13 # 2) there is a king with cards hidden beneath it c := 0 #number of empty stacks every k := 1 to 7 do if *stackUp[k] = 0 then c +:= 1 if c = 0 then if (deckUp[1].rank = 13) | (every k := 1 to 7 do if (stackUp[k][1].rank = 13) & (0 < *stackDown[k]) then break #success ) then suspend string(i) || string(j) } } #punt fail end #suggest # u s u g g e s t # Suggest a (reasonable) possible move in this situation. # Repeated invocations produce successive possibilities, until the # only thing left to do is Thumb. After this, it cycles around to the start. procedure usuggest (another) static suggestions, i local s, ss writes ("uggest") if another = 0 then { suggestions := [] #generate a new list of suggestions every put (suggestions, suggest()) i := 0 } if ss := suggestions[i+:=1] then { s := "Move " || if ss[1] == "A" then "Ace" else if ss[1] == "D" then "Deck" else ss[1] s ||:= " to " || if ss[2] == "A" then "Ace" else ss[2] writeInfo (s) } else { writeInfo ("Thumb") i := 0 } end #usuggest # u t e r m i n a t e # Parameter should be non-zero if termination is due to complete success. # Returns success to quit this game and start another. # Returns failure to just continue this game. # If program termination is wished, that is done right here. procedure uterminate (victory) local s if \victory then { totalAces +:= 52 pile[1] := pile[2] := pile[3] := pile[4] := 0 #prevent victory loops writeCursor (12, 22) writes (Vbold, Vblink, "Congratulations -- You've WON !!!", Vnormal) } else writes ("uit") writeInfo (Vbold || "Another game? ") until (s := getCmdChar ()) if s == ESC then fail() #didn't really want to quit anyway if s == "Y" then return #please start a new game if s ~== "N" then return complain () #program termination requested writes ("\33[=7h", Vnormal) #set cursor wrap mode, normal attr totalGames +:= 1 if /victory then totalAces +:= pile[1] + pile[2] + pile[3] + pile[4] write (VclearAll, "In ", totalGames, " games, you put ", totalAces, " cards on the ace piles") write ("average = ", real(totalAces) / real(totalGames), " per game") exit () end #uterminate # u d e b u g # Additional commands to support the implementer. procedure udebug () local s, d, c, name if not \debugging then return complain() writes ("\bDebug ") until (s := getCmdChar ()) case s of { ESC : fail "A" : { writes ("gain") &random := lastSeed writeCursor (23, 1) write (Vbold, "&random set. Quit to play this game again.", Vnormal, VclearEOL) } "D" : display() "H"|"?" : { writes (if s == "?" then "\bhelp" else "elp") writeCursor (23, 1) write (Vbold, "Again, Dump, Options, Move, Peek{1-7UD}, Restore, Save, Toggle{ACT}.", Vnormal, VclearEOL) } "M" : { writes ("ove ") until (s := getCmdChar ()) #Source if s == ESC then fail if s == "A" then fail until (d := getCmdChar ()) #Destination if d == ESC then fail if d == s then fail if not any('1234567', d) then fail if s == "D" then { if *deckUp = 0 then fail put (stackUp[d], get(deckUp)) writeDeckUp () writeStack (d) push (ops, "MD" || d || "0") } else { c := "123456789abcdef"[*stackUp[s]] moveStack (s, d) push (ops, "M" || s || d || c) } } "O" : { writes ("ptions") writeCursor (23, 1) write (Vbold, if \automaticAce then "AutomaticAce " else " ", if \clicking then "Clicking " else " ", " &trace=", &trace, " seeds=", firstSeed, ",", lastSeed, Vnormal, VclearEOL) } "P" : { writes ("eek ") until (s := getCmdChar ()) if s == ESC then fail writeCursor (23, 1) writes (VclearEOL, Vnormal) if any('1234567', s) then showList (stackDown[s]) else if s == "D" then showList (deckDown) else if s == "U" then showList (deckUp) else complain () } "R" : { writes ("estore") until (s := getCmdChar ()) if s == ESC then fail name := "klondike.sv" || s if (d := restoreState(name)) then { refreshScreen() writeCursor (23, 1) write (Vbold, "Restored position from file ", name, " of ", d, Vnormal, VclearEOL) } else { writeCursor (23, 1) write (Vblink, "Can't restore from file ", name, ".", Vnormal, VclearEOL) } } "S" : { writes ("ave ") until (s := getCmdChar ()) if s == ESC then fail name := "klondike.sv" || s writeCursor (23, 1) if saveState (name) then write (Vbold, "Position saved in file ",name, Vnormal, VclearEOL) else write (Vblink, "Can't save in file ", name, ".", Vnormal, VclearEOL) } "T" : { writes ("oggle ") until (s := getCmdChar ()) if s == ESC then fail case s of { "A" : automaticAce := if \automaticAce then &null else 1 "C" : clicking := if \clicking then &null else 1 "T" : &trace := if &trace = 0 then -1 else 0 default : complain () } #case for Toggle } default : complain () } #case for Debug command end #udebug # u b o s s # Cheese it, the Fuzz. # Quick -- clear the screen and save the state in a file. procedure uboss () writes ("oss") writes ("\33[=7h", VclearAll, "C>") #set cursor-wrap mode, look innocent saveState ("klondike.sav") exit () end #uboss # m a i n procedure main (av) local s, prevsCmd, maxGames # set defaults automaticAce := 1 # automatic ace handling clicking := 1 # give audible feedback debugging := &null # no debugging allowed invisible := &null # let's see the action maxGames := &null # interactive mode &random := map (&clock, ":", "0") # randomize the seed # deal with command-line parameters while s := get (av) do case map (s, &lcase, &ucase) of { "-A" : automaticAce := &null #disable automatic ace handling "-B" : maxGames := get (av) #batch mode, this many games "-C" : clicking := &null #run silent "-D" : debugging := 1 #grant all sorts of perqs "-R" : &random := get (av) #unrandomize default : {write ("klondike [-ACD] [-B gameCount] [-R randomSeed]") stop("klondike: bogus option ", s) } } totalGames := totalAces := 0 if \maxGames then { # In Batch mode there is absolutely no console I/O. # The requested number of games is played # and the average result is printed on the standard output. invisible := 1 clicking := &null totalGames := maxGames while 0 <= (maxGames -:= 1) do { newGame () while automatic1 () #don't allow user to interrupt totalAces +:= pile[1] + pile[2] + pile[3] + pile[4] } write (real(totalAces) / real(totalGames)) exit () } initConstants() #for console I/O firstSeed := &random #initial seed lastSeed := newGame () #if last game terminated via the Boss key, then restore it now if restoreState ("klondike.sav") then { refreshScreen () writeInfo ("Game restored") close (open ("klondike.sav", "c")) #truncate boss save file } repeat { #game loop prevsCmd := "x" #anything but "S"uggest #respond to user input repeat { #command loop writeCursor (18, 65) writes (VclearEOL || Vnormal || "> ") #clear command line if pile[1] = pile[2] = pile[3] = pile[4] = 13 then if uterminate (1) then break # VICTORY! s := getCmdChar () writeInfo ("") #clear info line writeCursor (18, 68) case s of { "?"|"H" : uhelp() "1"|"2"|"3"|"4"|"5"|"6"|"7"|"D" : if not umove(s) then complain() "A" : uautomatic() #look Ma, no hands! "B" : uboss() #bail out -- quick "C" : ucontinuous() #no hands, forever "M" : if not umove(&null) then complain() "Q" : if uterminate(&null) then break #new game "S" : usuggest (if s == prevsCmd then 1 else 0) "T" : { writes("humb"); push(ops, thumb()) } "U" : undo() "Z" : udebug() "\^L" : refreshScreen() ESC : s #do nothing here default : complain() } #case prevsCmd := s } #repeat command totalAces +:= pile[1] + pile[2] + pile[3] + pile[4] totalGames +:= 1 lastSeed := newGame () } #repeat game end #main -- PAPER: Norman Azadian; Ascom AG; Belpstrasse 23; 3000 Berne 14; Switzerland X.400: naz@hslrswi.hasler UUCP: ...{uunet,ukc,mcvax,...}!cernvax!hslrswi!naz VOICE: +41 31 63 2178 BITNET: naz%hslrswi.UUCP@cernvax.BITNET From goer%sophist@gargoyle.uchicago.edu Thu Dec 6 14:22:17 1990 Resent-From: goer%sophist@gargoyle.uchicago.edu Received: from MERLIN.TELCOM.ARIZONA.EDU by megaron.cs.arizona.edu (5.61/15) via SMTP id AA15356; Thu, 6 Dec 90 14:22:17 -0700 Return-Path: goer@sophist.uchicago.edu Received: from gargoyle.uchicago.edu by Arizona.edu with PMDF#10282; Thu, 6 Dec 1990 14:21 MST Received: by gargoyle.uchicago.edu from sophist (sophist.uchicago.edu) (4.0/1.14) id AA24137; Thu, 6 Dec 90 15:21:01 CST Received: by sophist (4.1/UofC3.1X) id AA07162; Thu, 6 Dec 90 15:24:20 CST Resent-Date: Thu, 6 Dec 1990 14:21 MST Date: Thu, 6 Dec 90 15:24:20 CST From: Richard Goerwitz Subject: klondike Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: <8E234DAE5C402A2E@Arizona.edu> Message-Id: <9012062124.AA07162@sophist> X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.edu I just thought I'd mention that Norman Azadian's klondike game is a pretty nicely done piece of software. My son hasn't stopped playing it since I compiled it this afternoon. He's running it under a DOS emulator on our Xenix box. So far, no luck compiling it under Xenix. I'll try to figure out the problem, and perhaps re-post a Unix version some time in the near future. It's probably the best game I've seen done in Icon. And, con- sidering all the screen processing, it runs pretty fast, too. -Richard From icon-group-request@arizona.edu Thu Dec 6 16:49:46 1990 Resent-From: icon-group-request@arizona.edu Received: from MERLIN.TELCOM.ARIZONA.EDU by megaron.cs.arizona.edu (5.61/15) via SMTP id AA19847; Thu, 6 Dec 90 16:49:46 -0700 Received: from ucbvax.Berkeley.EDU by Arizona.edu with PMDF#10282; Thu, 6 Dec 1990 16:49 MST Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA17065; Thu, 6 Dec 90 15:42:43 -0800 Received: from USENET by ucbvax.Berkeley.EDU with netnews for icon-group@arizona.edu (icon-group@arizona.edu) (contact usenet@ucbvax.Berkeley.EDU if you have questions) Resent-Date: Thu, 6 Dec 1990 16:49 MST Date: 6 Dec 90 22:46:19 GMT From: midway!quads.uchicago.edu!goer@handies.ucar.edu (Richard L. Goerwitz) Subject: sgml stripping Sender: icon-group-request@arizona.edu Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: Message-Id: <1990Dec6.224619.22998@midway.uchicago.edu> X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.edu Organization: University of Chicago Mad as this sounds, I occasionally find it expedient simply to strip out <>-style tags from a SGML-encoded file. Here's a very simple program to do this. I dunno, but I'd expect that it would work with the perverted variant of SGML mandated in the U of Chi- cago guide to electronic manuscripts. I posted this elsewhere, but since it's Icon code, I figured someone might here might want to take a look at it. -Richard ---- Cut Here and feed the following to sh ---- #!/bin/sh # This is a shell archive (produced by shar 3.49) # To extract the files from this archive, save it to a file, remove # everything above the "!/bin/sh" line above, and type "sh file_name". # # made 12/06/1990 07:11 UTC by goer@sophist.uchicago.edu # Source directory /u/richard/Stripsgml # # existing files will NOT be overwritten unless -c is specified # This format requires very little intelligence at unshar time. # "if test", "cat", "rm", "echo", "true", and "sed" may be needed. # # This shar contains: # length mode name # ------ ---------- ------------------------------------------ # 3170 -r--r--r-- stripsgml.icn # 2615 -r--r--r-- stripunb.icn # 1915 -r--r--r-- readtbl.icn # 2084 -r--r--r-- slashbal.icn # 981 -rw-r--r-- README # 659 -rw-r--r-- Makefile.dist # if test -r _shar_seq_.tmp; then echo 'Must unpack archives in sequence!' echo Please unpack part `cat _shar_seq_.tmp` next exit 1 fi # ============= stripsgml.icn ============== if test -f 'stripsgml.icn' -a X"$1" != X"-c"; then echo 'x - skipping stripsgml.icn (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp echo 'x - extracting stripsgml.icn (Text)' sed 's/^X//' << 'SHAR_EOF' > 'stripsgml.icn' && X############################################################################ X# X# Name: stripsgml.icn X# X# Title: Strip (or translate) simple SGML tags from a file X# X# Author: Richard L. Goerwitz X# X# Version: 1.7 X# X############################################################################ X# X# This program, stripsgml, may be used either to strip SGML tags X# from a file, or to translate them into some other format (or perhaps X# some combination of the two). Note that it only handles very X# simple SGML codes, either stripping or translating set strings. X# This is a VERY simple program, merely intended to satisfy a need X# many have expressed for being able to remove, or perform simple X# manipulations on, files containing <>-style tags. X# X# In its basic mode, you would simply have stripsgml read the X# standard input (an SGML-marked file). Stripsgml would then write X# an SGML-free text on the standard output. Used in this way, X# stripsgml is just a simple stripping program. X# X# If you want some or all of the SGML codes translated into another set X# of codes, simply create a file in which each line has 1) the name of X# the SGML code, and then 2) the way you want that code translated on X# both initialization and completion. The completion specification is X# optional. Put succinctly, the format is: X# X# code initialization completion X# X# A tab or colon separates the fields. If you want to use a tab or colon X# as part of the text (and not as a separator), place a backslash before X# it. The completion field is optional. There is not currently any way X# of specifying a completion field without an initialization field. X# X# In its translation mode, stripsgml is invoked with one argument (the X# name of the file containing the translation information). As before, X# the standard input is expected to contain an SGML encoded file: X# X# stripsgml translation_file < SGML-file X# X# To the standard output is written a SGML-free text. X# X# Note that, if you are translating SGML code into font change or escape X# sequences, you may get unexpected results. This isn't stripsgml's X# fault. It's just a matter of how your terminal or WP operate. Some X# need to be "reminded" at the beginning of each line what mode or font X# is being used. Note also that stripsgml assumes < and > as delimiters. X# If you want to put a greater-than or less-than sign into your text, X# put a backslash before it. This will effectively "escape" the spe- X# cial meaning of those symbols. There is currently no way to change X# the default delimiters. X# X############################################################################ X# X# Links: slashbal.icn ./stripunb.icn ./readtbl.icn X# X############################################################################ X X Xprocedure main(a) X X usage := "usage: stripsgml [map-file]" X *a > 1 & stop(usage) X X map_file := open(a[1]) & t := readtbl(map_file) X X every line := !&input do X write(stripunb('<','>',line,&null,&null,t)) X X # last_k is the stack used in stripunb.icn X if *\last_k ~= 0 then X stop("Unexpected EOF encountered. Expecting ", pop(last_k), ".") X Xend SHAR_EOF true || echo 'restore of stripsgml.icn failed' rm -f _shar_wnt_.tmp fi # ============= stripunb.icn ============== if test -f 'stripunb.icn' -a X"$1" != X"-c"; then echo 'x - skipping stripunb.icn (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp echo 'x - extracting stripunb.icn (Text)' sed 's/^X//' << 'SHAR_EOF' > 'stripunb.icn' && X############################################################################ X# X# Name: stripunb.icn X# X# Title: Strip unbalanced material X# X# Author: Richard L. Goerwitz X# X# Version: 1.3 X# X############################################################################ X# X# This routine strips material from a line which is unbalanced with X# respect to the characters defined in arguments 1 and 2 (unbalanced X# being defined as bal() defines it, except that characters preceded X# by a backslash are counted as regular characters, and are not taken X# into account by the balancing algorithm). X# X# One little bit of weirdness I added in is a table argument. Put X# simply, if you call stripunb() as follows, X# X# stripunb('<','>',s,&null,&null,t) X# X# and if t is a table having the form, X# X# key: "bold" value: outstr("\e[2m", "\e1m") X# key: "underline" value: outstr("\e[4m", "\e1m") X# etc. X# X# then every instance of "" in string s will be mapped to X# "\e2m," and every instance of "" will be mapped to "\e[1m." X# Values in table t must be records of type output(on, off). When X# "" is encountered, stripunb will output the .off value for the X# preceding .on string encountered. X# X############################################################################ X# X# Links: slashbal.icn X# X############################################################################ X Xglobal last_k Xrecord outstr(on, off) X X Xprocedure stripunb(c1,c2,s,i,j,t) X X # NB: Stripunb() returns a string - not an integer (like find, X # upto). X X local lookinfor, bothcs, s2, k X #global last_k X initial last_k := list() X X /c1 := '<' X /c2 := '>' X bothcs := c1 ++ c2 X lookinfor := c1 ++ '\\' X c := &cset -- c1 -- c2 X X /s := \&subject | stop("stripunb: No string argument.") X /i := \&pos | 1 X /j := *s + 1 X X s2 := "" X s ? { X tab(i) | fail X while s2 ||:= tab(upto(lookinfor)) do { X if ="\\" & any(bothcs) then { X &pos+1 > j & (return s2) X s2 ||:= move(1) X next X } X else { X &pos > j & (return s2) X any(c1) | X stop("stripunb: Unbalanced string, pos(",&pos,").\n",s) X k := tab(slashbal(c,c1,c2,&null,&null,&null,1)) | tab(0) X if \t then { X k ?:= 2(="<", tab(find(">")), =">", pos(0)) X if k ?:= (="/", tab(0)) then { X compl := pop(last_k) | stop("Unclosed <>, ",&subject) X if k == "" X then k := compl X else k == compl | stop("Incorrectly paired <>, .") X s2 ||:= \(\t[k]).off X } X else { X s2 ||:= \(\t[k]).on X push(last_k, k) X } X } X } X } X s2 ||:= tab(0) X } X X return s2 X Xend SHAR_EOF true || echo 'restore of stripunb.icn failed' rm -f _shar_wnt_.tmp fi # ============= readtbl.icn ============== if test -f 'readtbl.icn' -a X"$1" != X"-c"; then echo 'x - skipping readtbl.icn (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp echo 'x - extracting readtbl.icn (Text)' sed 's/^X//' << 'SHAR_EOF' > 'readtbl.icn' && X############################################################################ X# X# Name: readtbl.icn X# X# Title: Read user-created stripsgml table X# X# Author: Richard L. Goerwitz X# X# Version: 1.1 X# X############################################################################ X# X# This file is part of the stripsgml package. It does the job of read- X# ing option user-created mapping information from a file. The purpose X# of this file is to specify how each code in a given input text should X# be translated. Each line has the form: X# X# SGML-designator start_code end_code X# X# where the SGML designator is something like "quote" (without the quota- X# tion marks), and the start and end codes are the way in which you want X# the beginning and end of a ...<\quote> sequence to be transla- X# ted. Presumably, in this instance, your codes would indicate some set X# level of indentation, and perhaps a font change. If you don't have an X# end code for a particular SGML designator, just leave it blank. X# X############################################################################ X# X# Links: stripsgml.icn X# X############################################################################ X X Xprocedure readtbl(f) X X local t, line, k, on_sequence, off_sequence X X /f & stop("readtbl: Arg must be a valid open file.") X X t := table() X X every line := trim(!f,'\t ') do { X line ? { X k := tabslashupto('\t:') & X tab(many('\t:')) & X on_sequence := tabslashupto('\t:') | tab(0) X tab(many('\t:')) X off_sequence := tab(0) X } | stop("readtbl: Bad map file format.") X insert(t, k, outstr(on_sequence, off_sequence)) X } X X return t X Xend X X X Xprocedure tabslashupto(c,s) X X POS := &pos X X while tab(upto('\\' ++ c)) do { X if ="\\" then { X move(1) X next X } X else { X if any(c) then { X suspend &subject[POS:.&pos] X } X } X } X X &pos := POS X fail X Xend SHAR_EOF true || echo 'restore of readtbl.icn failed' rm -f _shar_wnt_.tmp fi # ============= slashbal.icn ============== if test -f 'slashbal.icn' -a X"$1" != X"-c"; then echo 'x - skipping slashbal.icn (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp echo 'x - extracting slashbal.icn (Text)' sed 's/^X//' << 'SHAR_EOF' > 'slashbal.icn' && X############################################################################ X# X# Name: slashbal.icn X# X# Title: Bal() with backslash escaping X# X# Author: Richard L. Goerwitz X# X# Version: 1.4 X# X############################################################################ X# X# I am often frustrated at bal()'s inability to deal elegantly with X# the common \backslash escaping convention (a way of telling Unix X# Bourne and C shells, for instance, not to interpret a given X# character as a "metacharacter"). I recognize that bal()'s generic X# behavior is a must, and so I wrote slashbal() to fill the gap. X# X# Slashbal behaves like bal, except that it ignores, for purposes of X# balancing, any c2/c3 char which is preceded by a backslash. Note X# that we are talking about internally represented backslashes, and X# not necessarily the backslashes used in Icon string literals. If X# you have "\(" in your source code, the string produced will have no X# backslash. To get this effect, you would need to write "\\(." X# X# BUGS: Note that, like bal() (v8), slashbal() cannot correctly X# handle cases where c2 and c3 intersect. X# X############################################################################ X# X# Links: none X# X############################################################################ X Xprocedure slashbal(c1, c2, c3, s, i, j) X X local twocs, allcs, chr2, count X X /c1 := &cset X /c2 := '(' X /c3 := ')' X twocs := c2 ++ c3 X allcs := c1 ++ c2 ++ c3 ++ '\\' X X /s := \&subject | stop("slashbal: No string argument.") X /i := \&pos | 1 X /j := *s + 1 X X count := 0 X s ? { X tab(i) | fail X while tab(upto(allcs)) do { X chr := move(1) X if chr == "\\" & any(twocs) then { X chr2 := move(1) X &pos > j & fail X if any(c1, chr) & count = 0 then X suspend .&pos - 2 X if any(c1, chr2) & count = 0 then X suspend .&pos - 1 X } X else { X &pos > j & fail X if any(c1, chr) & count = 0 then X suspend .&pos - 1 X if any(c2, chr) then X count +:= 1 X else if any(c3, chr) then X count -:= 1 X } X } X } X Xend SHAR_EOF true || echo 'restore of slashbal.icn failed' rm -f _shar_wnt_.tmp fi # ============= README ============== if test -f 'README' -a X"$1" != X"-c"; then echo 'x - skipping README (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp echo 'x - extracting README (Text)' sed 's/^X//' << 'SHAR_EOF' > 'README' && XRe: stripsgml.icn & associated files X XThis program is documented in the various source files, most notably Xstripsgml.icn. Please look them over, even if you are not an Icon Xprogrammer. X XIn order to compile this program, you will need an Icon interpreter X(or compiler). If you do not have it, get it. It is free, and can Xbe obtained via ftp from cs.arizona.edu. If you do not have access Xto the internet, drop a line to the icon-project@arizona.edu, and Xthey will fill you in on what to do. X XIf you are working on a Unix system, you can simply mv Makefile.dist Xto Makefile, and then make. Users on other systems will need to Xtype: X X icont -o stripsgml readtbl.icn slashbal.icn stripsgml.icn stripunb.icn X XAs I said above, see the file stripsgml.icn for more information on how Xto use this program. This program is not fancy, and handles only the Xsimplest <>-style markup. It is in no way an attempt to handle the full Xmetalanguage! X X-Richard (goer@sophist.uchicago.edu) SHAR_EOF true || echo 'restore of README failed' rm -f _shar_wnt_.tmp fi # ============= Makefile.dist ============== if test -f 'Makefile.dist' -a X"$1" != X"-c"; then echo 'x - skipping Makefile.dist (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp echo 'x - extracting Makefile.dist (Text)' sed 's/^X//' << 'SHAR_EOF' > 'Makefile.dist' && XPROGNAME = stripsgml X X# Please edit these to reflect your local file structure & conventions. XDESTDIR = /usr/local/bin XOWNER = bin XGROUP = bin X XSRC = $(PROGNAME).icn stripunb.icn readtbl.icn slashbal.icn X X$(PROGNAME): $(SRC) X icont -o $(PROGNAME) $(SRC) X X# Pessimistic assumptions regarding the environment (in particular, X# I don't assume you have the BSD "install" shell script). Xinstall: $(PROGNAME) X @sh -c "test -d $(DESTDIR) || (mkdir $(DESTDIR) && chmod 755 $(DESTDIR))" X cp $(PROGNAME) $(DESTDIR)/ X chgrp $(GROUP) $(DESTDIR)/$(PROGNAME) X chown $(OWNER) $(DESTDIR)/$(PROGNAME) X @echo "\nInstallation done.\n" X Xclean: X -rm -f *~ .u? X -rm -f $(PROGNAME) SHAR_EOF true || echo 'restore of Makefile.dist failed' rm -f _shar_wnt_.tmp fi exit 0 From goer%sophist@gargoyle.uchicago.edu Thu Dec 6 22:48:10 1990 Resent-From: goer%sophist@gargoyle.uchicago.edu Received: from MERLIN.TELCOM.ARIZONA.EDU by megaron.cs.arizona.edu (5.61/15) via SMTP id AA28085; Thu, 6 Dec 90 22:48:10 -0700 Return-Path: goer@sophist.uchicago.edu Received: from gargoyle.uchicago.edu by Arizona.edu with PMDF#10282; Thu, 6 Dec 1990 22:47 MST Received: by gargoyle.uchicago.edu from sophist (sophist.uchicago.edu) (4.0/1.14) id AA05683; Thu, 6 Dec 90 23:47:26 CST Received: by sophist (4.1/UofC3.1X) id AA07496; Thu, 6 Dec 90 23:50:44 CST Resent-Date: Thu, 6 Dec 1990 22:47 MST Date: Thu, 6 Dec 90 23:50:44 CST From: Richard Goerwitz Subject: klondike Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: Message-Id: <9012070550.AA07496@sophist> X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.edu Richard Goerwitz writes [re Klondike]: > So far, no luck compiling it under Xenix. I'll try to figure > out the problem, and perhaps re-post a Unix version some time in > the near future. I hope you will. Icon needs a great, portable game. I've located the problems. Basically they are simply that klondike a) calls kbhit, which simply can't be done easily and portably from within Icon under Unix, b) that it calls getch(), c) that it uses the cursor report request to test for ANSI console conformancy, and d) that it mixes straight text with screen control codes. These problems are mainly pretty easy to get around. Kbhit() is called but once, as I recall. I wrote a getch() implementation for Unix that will cover (b). Under Unix, (c) isn't necessary (we'll just check the current environment). I still haven't figured an easy way to lift screen control codes out of write() functions outputting straight text, but even in a worst case scenario it will mean just spending some time doing searches and replaces. Klondike is indeed a nice game under DOS. Really nicely done. And this from a guy who claims to be a novice at Icon! Ron, you'll be the first I'll let know if I do in fact actually get a Unix version out, since I know you are running Xenix like me, and also (like me) have some of those blasted magic cookie terminals sitting around. -Richard From fps!mis.mcw.edu!mis.mcw.edu!TENAGLIA@uwm.edu Fri Dec 7 10:08:19 1990 Received: from uwm.edu by megaron.cs.arizona.edu (5.61/15) via SMTP id AA24517; Fri, 7 Dec 90 10:08:19 -0700 Received: by uwm.edu; id AA00863; Fri, 7 Dec 90 11:08:11 -0600 Received: from mis.mcw.edu by fps.mcw.edu (DECUS UUCP ///1.2a/2.5/); Fri, 7 Dec 90 08:23:04 CDT Received: by mis.mcw.edu with UUCP/PMDF (DECUS UUCP); Fri, 7 Dec 1990 08:10 CDT Date: Fri, 7 Dec 1990 08:09 CDT From: Chris Tenaglia - 257-8765 Subject: Klondike - Neato To: icon-group@cs.arizona.edu Message-Id: <23551171406002A9@mis.mcw.edu> X-Organization: Medical College of Wisconsin MIS Department (Milwaukee, WI) X-Envelope-To: icon-group@cs.arizona.edu X-Vms-To: IN%"icon-group@cs.arizona.edu" I liked both versions. I got the original PC one running quickly. I liked the colors. But my chief platform is VAX VMS with VT compatible terminals. So the ANSI version was welcome. I also took it one step further by using the ANSI line drawing. For example I replaced "|" with "\e(0x\e(B" and likewise for the tops and bottoms of cards. I also had to comment out a lot of getch() and kbhit() which isn't available from VMS, and add read() instead. Fortunately my wyse terminal also has a 25 line mode. These added escape sequences may slow things done a little, but the esthetics are worth it. My daughter loves it, although she gets lazy after a few minutes and shifts into automatic. Thanx for the nifty program. I'm interested in game playing heuristics. I'd like to post another one I use on my daughter. It's call Spelling test. I type the words into a file. This file is then redirected into the spelltest program which asks for words. It assumes that you have the words on another sheet as well from which the test is administered. The words can be given in any order. The masters and answers are then sorted and compared in parallel. It works almost like magic as long as the words are not too lexically similar and the student isn't too bad of a speller. Perhaps the parallel checking might have been done better with coexpressions, but I'm not skilled with them. # # SPELLTEST.ICN 11/26/90 BY TENAGLIA # # THIS SIMPLE PROGRAM ADMINISTERS A SPELLING TEST. THE WORDS SHOULD BE LISTED # ONE PER LINE IN AN ANSWER FILE. THE TEACHER CAN ISSUE THE WORDS IN ANY ORDER # AS THE TRIES AND ANSWERS ARE FINALY SORTED AND COMPARED IN PARALLEL. THIS # SORT OF IMPLIES THAT THE WORDS SHOULD NOT BE TOO LEXICALLY ALIKE. THE GOOF # UPS AND SCORES ARE OUTPUT AT THE END OF THE TEST. THE ANSWER FILE IS PIPED # INTO STDIN. USAGE : ICONX SPELLTEST Subject: klondike -> unix (preliminary) Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: Message-Id: <9012081053.AA08404@sophist> X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.edu OK, I hacked this together tonight for fun. It's not perfect. The saving mechanism isn't working quite right, and when com- piled under DOS the help screen needs work. I did this so that I could run the executable under Xenix at an ANSI console. It will probably work on any Unix variant that implements the -g option for stty, and which looks remotely USG. Who knows, it might work under BSD. Definitely not well tested, though. I kind of hoped that others who had wanted this thing up and run- ning under Unix would fix it up some more in the usual hand-me- down fashion.... Five-part shar follows in fairly small pieces. -Richard ---- Cut Here and feed the following to sh ---- #!/bin/sh # This is a shell archive (produced by shar 3.49) # To extract the files from this archive, save it to a file, remove # everything above the "!/bin/sh" line above, and type "sh file_name". # # made 12/08/1990 11:18 UTC by goer@sophist.uchicago.edu # Source directory /u/richard/Klondike # # existing files will NOT be overwritten unless -c is specified # This format requires very little intelligence at unshar time. # "if test", "cat", "rm", "echo", "true", and "sed" may be needed. # # This is part 1 of a multipart archive # do not concatenate these parts, unpack them in order with /bin/sh # # This shar contains: # length mode name # ------ ---------- ------------------------------------------ # 20981 -r--r--r-- klondike.icn # 17168 -r--r--r-- kloncon.icn # 15873 -r--r--r-- klonsub.icn # 12240 -r--r--r-- itlib.icn # 8538 -r--r--r-- getchlib.icn # 4418 -r--r--r-- iscreen.icn # 4513 -rw-r--r-- klondike.man # 477 -rw-r--r-- README # 707 -rw-r--r-- Makefile.dist # if test -r _shar_seq_.tmp; then echo 'Must unpack archives in sequence!' echo Please unpack part `cat _shar_seq_.tmp` next exit 1 fi # ============= klondike.icn ============== if test -f 'klondike.icn' -a X"$1" != X"-c"; then echo 'x - skipping klondike.icn (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp echo 'x - extracting klondike.icn (Text)' sed 's/^X//' << 'SHAR_EOF' > 'klondike.icn' && X############################################################################ X# X# Name: klondike.icn X# X# Title: klondike card game X# X# Author: Norman H. Azadian, ported to Unix by Richard Goerwitz X# X# Version: 1.5 (beta) X# X############################################################################ X# X# klondike.icn 900720 NHA X# The Klondike version of Solitaire. X# Requires ANSI.SYS (or NANSI.SYS) screen driver and a 25-line display. X# X# TO FIX: X# X# X# TO DO: X# X# - Use space to step to next non-thumb move, and enter to do it ??? X# - Implement an heuristic to discover optimal play strategy. X# X# UNIX VERSION: This Unix port of the MS-DOS game classifies as some- X# thing of a hack. It's what I could do in an evening. Don't bug me X# about it :-). -RLG X# X############################################################################ X# X# Links: X# X# See also: kloncon.icn, klonsub.icn X# X############################################################################ X Xlink kloncon #console I/O Xlink klonsub #general subroutines X Xrecord card(suit, rank) #suit is 1..4, rank is 1..13 X X# variables Xglobal deckUp, deckDown, stackUp, stackDown #collections of card Xglobal pile #ace piles - top rank only Xglobal ops #list of all operations done Xglobal debugging, automaticAce #command-line flags Xglobal invisible, clicking #visual, audible feedback Xglobal firstSeed, lastSeed #&random remembered Xglobal totalGames, totalAces #ace pile statistics X X X# a u t o m a t i c 1 X# Do 1 move, thumbing as necessary to achieve it. X# Fails if there is nothing useful left to do. X# This is an internal routine that doesn't worry at all about the user. Xprocedure automatic1 () Xlocal s, thumbCount X thumbCount := 0 X while thumbCount <= ((*deckUp + *deckDown + 2) / 3) do { X if s := suggest() then { X push (ops, _move ("M" || s || "0")) X thumbCount := 0 X return; X } else { #no good move found -- thumb X if (*deckUp = 0) & (*deckDown = 0) then X fail #no cards left to thumb through X push (ops, s := thumb()) X if 2 < *s then X return #must have turned up an Ace X thumbCount +:= 1 X } X } Xend #automatic1 X X X# a u t o m a t i c X# Run the game, as far as possible, untouched by human hands X# This is an internal routine that only worries a little about the user. X# Returns when either there is nothing useful left to do or a key is struck. Xprocedure automatic () Xlocal s, thumbCount X thumbCount := 0 X repeat { X if \isDOS then { X if kbhit () then X return #stopped by human intervention X } X if pile[1] = pile[2] = pile[3] = pile[4] = 13 then X return #victory X automatic1 () | return X } Xend #automatic X X X# u a u t o m a t i c X# Play this hand automatically, untouched by human hands. X# This is the fuction that interacts with the user. Xprocedure uautomatic () X writes ("utomatic") X automatic() X if \isDOS then { X if kbhit() then X if getch() == "\0" then getch() X } Xend #uautomatic X X X# u c o n t i n u o u s X# Plays automatic games -- forever (or until any keystroke) Xprocedure ucontinuous() X writes ("ontinuous") X repeat { X writeInfo (string(totalGames) || " " || string(totalAces)) X automatic() X if \isDOS & kbhit() then { X if getch() == "\0" then #eat stopping char(s) X getch() X return X } else X totalAces +:= pile[1] + pile[2] + pile[3] + pile[4] X totalGames +:= 1 X if \isUNIX then { X writeCursor (18, 65) X iputs(getval("ce")) X writes ("Continue? ") X until (s := getCmdChar ()) X map(s) == "n" | next X return X } X lastSeed := newGame() X } Xend #ucontinuous X X X# u h e l p X# Provide command summary for user, plus statistics to date, if any. Xprocedure uhelp () X if \isDOS then X write (VclearAll, Vnormal) X else if \isUNIX then { X normal (); clear () X } X writeCursor (2, 1) X writes ("Klondike version 1.5 901126 NHA", repl(" ",8), &version) X writeCursor (5, 1) X writes ("The following commands are available:") X writeCursor (8, 8) X bwrite ("^L\tre-draw", " screen") X writeCursor (9, 8) X if \isDOS then X bwrite ("A\tAutomatic", " mode -- plays 1 game by itself until any key is hit") X else if \isUNIX then X bwrite ("A\tAutomatic", " mode -- plays 1 game by itself.") X writeCursor (10, 8) X bwrite ("B\tBoss", " key for when you-know-who visits") X writeCursor (11, 8) X if \isDOS then X bwrite ("C\tContinuous", " mode -- plays games continuously until any key hit") X else if \isUNIX then X bwrite ("C\tContinuous", " mode -- plays games by itself") X writeCursor (12, 8) X bwrite ("H,?\tHelp", ", this help screen") X writeCursor (13, 8) X bwrite ("M\tMove", " card (or stack) from Deck/Stack to Stack/Ace pile") X writeCursor (14, 8) X bwrite ("Q\tQuit", " this game") X writeCursor (15, 8) X bwrite ("S\tSuggest", " (another) possible move") X writeCursor (16, 8) X bwrite ("T\tThumb", " through the deck") X writeCursor (17, 8) X bwrite ("U\tUndo", " -- back up one move") X writeCursor (18, 8) X bwrite ("ESC\tEscape", " -- abort current command") X writeCursor (19, 9) X if \debugging then X bwrite ("Z\tDebug") X X writeCursor (20, 1) X if totalGames ~= 0 then X writes ("totalGames = ", totalGames, " totalAces = ", totalAces, X " average = ", real(totalAces) / real(totalGames)) X writeCursor (23, 1) X bwrite ("", "Press any key to resume game") X writeCursor (24, 1) X if getch() == "\0" then getch() X refreshScreen () Xend #uhelp X X X# b w r i t e X# Boldface first arg in 1-4 string-arg procedure. Xprocedure bwrite(a, b[]) X if \isDOS then X writes (Vbold) X else if \isUNIX then X emphasize() X writes(a) X if \isDOS then X writes (Vnormal) X else if \isUNIX then X normal() X every writes(\!b) X return Xend X X X# u m o v e X# Move a card from deck to stack, or from stack to ace pile, X# or move a stack to another stack. X# Parameter is the source [1-7 or D] or &null to indicate that "M" was used X# and therefore source should be gathered from the keyboard. X# Fails if indicated move is not possible X# This is the routine that interacts with the user. Xprocedure umove (src) Xlocal dst, c, op, moved X if \src then { X if \isDOS then X writes ("\bMove ", Vbold, src) X else if \isUNIX then { X writes ("\bMove ") X emphasize () X writes (src) X } X } X else { X if \isDOS then X writes ("ove " || Vbold) X else if \isUNIX then { X writes ("ove ") X emphasize () X } X until (src := getCmdChar ()) X if src == ESC then return X } X if src == "D" then { X if *deckUp = 0 then fail X } else { X if not any ('1234567', src) then fail X if *stackUp[src] = 0 then fail X writeStackNumber (src, Vblink) X } X X if \isDOS then X writes (Vnormal || " to " || Vbold) X else if \isUNIX then { X normal () X writes (" to ") X emphasize () X } X until (dst := getCmdChar ()) X if src ~== "D" then writeStackNumber (src, Vnormal) X if dst == ESC then return X if not any ('A1234567', dst) then fail X if dst == src then fail X X return push (ops, _move("M" || src || dst || "0")) Xend #umove X X X# s u g g e s t X# Find a (reasonable) possible move in this situation X# This is the internal routine. Xprocedure suggest () Xlocal i, j, k, c X #look at deckUp to see if the top card fits on a pile X if c := deckUp[1] then X if c.rank = (pile[c.suit] + 1) then X suspend "DA" X #look at deckUp to see if the top card fits on a stack X if c := deckUp[1] then X every i := 1 to 7 do X if fitOnStack (c, i) then X suspend "D" || string(i) X #look at each stack to see if top card can be put on ace pile X every i := 1 to 7 do X if c := stackUp[i][-1] then #top card X if c.rank = (pile[c.suit] + 1) then X suspend string(i) || "A" X #look at each stack to see if something can be (reasonably) moved X every i := 7 to 1 by -1 do X every j := 1 to 7 do X if fitOnStack (stackUp[i][1], j) then { X if (0 < *stackDown[i]) then X suspend string(i) || string(j) X else { X # possibility, but since there are no cards hidden under X # this pile, we reject it UNLESS there are no empty slots X # AND one of the following is true: X # 1) deckUp[1].rank = 13 X # 2) there is a king with cards hidden beneath it X c := 0 #number of empty stacks X every k := 1 to 7 do X if *stackUp[k] = 0 then c +:= 1 X if c = 0 then X if (deckUp[1].rank = 13) | X (every k := 1 to 7 do X if (stackUp[k][1].rank = 13) & X (0 < *stackDown[k]) then X break #success X ) X then X suspend string(i) || string(j) X } X } X #punt X fail Xend #suggest X X X# u s u g g e s t X# Suggest a (reasonable) possible move in this situation. X# Repeated invocations produce successive possibilities, until the X# only thing left to do is Thumb. After this, it cycles around to the start. Xprocedure usuggest (another) Xstatic suggestions, i Xlocal s, ss X writes ("uggest") X if another = 0 then { X suggestions := [] #generate a new list of suggestions X every put (suggestions, suggest()) X i := 0 X } X if ss := suggestions[i+:=1] then { X s := "Move " || if ss[1] == "A" then "Ace" X else if ss[1] == "D" then "Deck" X else ss[1] X s ||:= " to " || if ss[2] == "A" then "Ace" else ss[2] X writeInfo (s) X } else { X writeInfo ("Thumb") X i := 0 X } Xend #usuggest X X X# u t e r m i n a t e X# Parameter should be non-zero if termination is due to complete success. X# Returns success to quit this game and start another. X# Returns failure to just continue this game. X# If program termination is wished, that is done right here. Xprocedure uterminate (victory) Xlocal s X if \victory then { X totalAces +:= 52 X pile[1] := pile[2] := pile[3] := pile[4] := 0 #prevent victory loops X writeCursor (12, 22) X if \isDOS then X writes (Vbold, Vblink, "Congratulations -- You've WON !!!", Vnormal) X else if \isUNIX then { X emphasize () X writes ("Congratulations -- You've WON !!!") X normal () X } X } else X writes ("uit") X if \isDOS then X writeInfo (Vbold || "Another game? ") X else if \isUNIX then X writeInfo ("Another game? ") X until (s := getCmdChar ()) X if s == ESC then fail() #didn't really want to quit anyway X if s == "Y" then return #please start a new game X if s ~== "N" then return complain () X X #program termination requested X if \isDOS then X writes ("\33[=7h", Vnormal) #set cursor wrap mode, normal attr X else if \isUNIX then X normal () & clear () X totalGames +:= 1 X if /victory then X totalAces +:= pile[1] + pile[2] + pile[3] + pile[4] X writeCursor (2, 1) X writes (VclearAll, "In ", totalGames, " games, you put ", totalAces, X " cards on the ace piles") X writeCursor (3, 1) X write ("average = ", real(totalAces) / real(totalGames), " per game") X writeCursor (5, 1) X if \isUNIX then reset_tty() X exit () Xend #uterminate X X X# u d e b u g X# Additional commands to support the implementer. Xprocedure udebug () Xlocal s, d, c, name X if not \debugging then return complain() X writes ("\bDebug ") X until (s := getCmdChar ()) X case s of { X ESC : fail X "A" : { X writes ("gain") X &random := lastSeed X writeCursor (23, 1) X write (Vbold, "&random set. Quit to play this game again.", X Vnormal, VclearEOL) X } X "D" : display() X "H"|"?" : { X writes (if s == "?" then "\bhelp" else "elp") X writeCursor (23, 1) X write (Vbold, X "Again, Dump, Options, Move, Peek{1-7UD}, Restore, Save, Toggle{ACT}.", X Vnormal, VclearEOL) X } X "M" : { X writes ("ove ") X until (s := getCmdChar ()) #Source X if s == ESC then fail X if s == "A" then fail X until (d := getCmdChar ()) #Destination X if d == ESC then fail X if d == s then fail X if not any('1234567', d) then fail X if s == "D" then { X if *deckUp = 0 then fail X put (stackUp[d], get(deckUp)) X writeDeckUp () X writeStack (d) X push (ops, "MD" || d || "0") X } else { X c := "123456789abcdef"[*stackUp[s]] X moveStack (s, d) X push (ops, "M" || s || d || c) X } X } X "O" : { X writes ("ptions") X writeCursor (23, 1) X write (Vbold, X if \automaticAce then "AutomaticAce " else " ", X if \clicking then "Clicking " else " ", X " &trace=", &trace, X " seeds=", firstSeed, ",", lastSeed, Vnormal, VclearEOL) X } X "P" : { X writes ("eek ") X until (s := getCmdChar ()) X if s == ESC then fail X writeCursor (23, 1) X writes (VclearEOL, Vnormal) X if any('1234567', s) then showList (stackDown[s]) X else if s == "D" then showList (deckDown) X else if s == "U" then showList (deckUp) X else complain () X } X "R" : { X writes ("estore") X until (s := getCmdChar ()) X if s == ESC then fail X name := "klondike.sv" || s X if (d := restoreState(name)) then { X refreshScreen() X writeCursor (23, 1) X write (Vbold, "Restored position from file ", name, X " of ", d, Vnormal, VclearEOL) X } else { X writeCursor (23, 1) X write (Vblink, "Can't restore from file ", name, ".", X Vnormal, VclearEOL) X } X } X "S" : { X writes ("ave ") X until (s := getCmdChar ()) X if s == ESC then fail X name := "klondike.sv" || s X writeCursor (23, 1) X if saveState (name) then X write (Vbold, "Position saved in file ",name, X Vnormal, VclearEOL) X else X write (Vblink, "Can't save in file ", name, ".", X Vnormal, VclearEOL) X } X "T" : { X writes ("oggle ") X until (s := getCmdChar ()) X if s == ESC then fail X case s of { X "A" : automaticAce := if \automaticAce then &null X else 1 X "C" : clicking := if \clicking then &null else 1 X "T" : &trace := if &trace = 0 then -1 else 0 X default : complain () X } #case for Toggle X } X default : complain () X } #case for Debug command Xend #udebug X X X# u b o s s X# Cheese it, the Fuzz. X# Quick -- clear the screen and save the state in a file. Xprocedure uboss () X writes ("oss") X if \isDOS then { X writes("\33[=7h", VclearAll, "C>") #set cursor-wrap mode, look innocent X saveState ("klondike.sav") X } X else if \isUNIX then { X normal() X clear() X saveState("~/.klondike.sav") X reset_tty() X } X exit () Xend #uboss X X X X# m a i n Xprocedure main (av) Xlocal s, prevsCmd, maxGames, f_nam X X # set defaults X automaticAce := 1 # automatic ace handling X clicking := 1 # give audible feedback X debugging := &null # no debugging allowed X invisible := &null # let's see the action X maxGames := &null # interactive mode X &random := map (&clock, ":", "0") # randomize the seed X X # deal with command-line parameters X while s := get (av) do X case map (s, &lcase, &ucase) of { X "-A" : automaticAce := &null #disable automatic ace handling X "-B" : maxGames := get (av) #batch mode, this many games SHAR_EOF true || echo 'restore of klondike.icn failed' fi echo 'End of part 1' echo 'File klondike.icn is continued in part 2' echo 2 > _shar_seq_.tmp exit 0 From goer%sophist@gargoyle.uchicago.edu Sat Dec 8 03:51:42 1990 Resent-From: goer%sophist@gargoyle.uchicago.edu Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP id AA02492; Sat, 8 Dec 90 03:51:42 -0700 Return-Path: goer@sophist.uchicago.edu Received: from gargoyle.uchicago.edu by Arizona.edu; Sat, 8 Dec 90 03:50 MST Received: by gargoyle.uchicago.edu from sophist (sophist.uchicago.edu) (4.0/1.14) id AA04503; Sat, 8 Dec 90 04:50:40 CST Received: by sophist (4.1/UofC3.1X) id AA08417; Sat, 8 Dec 90 04:53:59 CST Resent-Date: Sat, 8 Dec 90 03:51 MST Date: Sat, 8 Dec 90 04:53:59 CST From: Richard Goerwitz Subject: klondike, part 02 of 05 Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: Message-Id: <9012081053.AA08417@sophist> X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.edu ---- Cut Here and feed the following to sh ---- #!/bin/sh # this is klondike.02 (part 2 of a multipart archive) # do not concatenate these parts, unpack them in order with /bin/sh # file klondike.icn continued # if test ! -r _shar_seq_.tmp; then echo 'Please unpack part 1 first!' exit 1 fi (read Scheck if test "$Scheck" != 2; then echo Please unpack part "$Scheck" next! exit 1 else exit 0 fi ) < _shar_seq_.tmp || exit 1 if test ! -f _shar_wnt_.tmp; then echo 'x - still skipping klondike.icn' else echo 'x - continuing file klondike.icn' sed 's/^X//' << 'SHAR_EOF' >> 'klondike.icn' && X "-C" : clicking := &null #run silent X "-D" : debugging := 1 #grant all sorts of perqs X "-R" : &random := get (av) #unrandomize X default : {write ("klondike [-ACD] [-B gameCount] [-R randomSeed]") X if \isUNIX then reset_tty() X stop("klondike: bogus option ", s) } X } X X totalGames := totalAces := 0 X X if \maxGames then { X # In Batch mode there is absolutely no console I/O. X # The requested number of games is played X # and the average result is printed on the standard output. X invisible := 1 X clicking := &null X totalGames := maxGames X while 0 <= (maxGames -:= 1) do { X newGame () X while automatic1 () #don't allow user to interrupt X totalAces +:= pile[1] + pile[2] + pile[3] + pile[4] X } X write (real(totalAces) / real(totalGames)) X if \isUNIX then reset_tty() X exit () X } X X X initConstants() #for console I/O X firstSeed := &random #initial seed X X lastSeed := newGame () X #if last game terminated via the Boss key, then restore it now X if \isDOS then X f_nam := "klondike.sav" X else if \isUNIX then X f_nam := "~/.klondike.sav" X if restoreState (f_nam) then { X refreshScreen () X writeInfo ("Game restored") X close (open (f_nam, "c")) #truncate boss save file X } X X X repeat { #game loop X prevsCmd := "x" #anything but "S"uggest X X #respond to user input X repeat { #command loop X writeCursor (18, 65) X if \isDOS then X writes (VclearEOL || Vnormal || "> ") #clear command line X else if \isUNIX then { X iputs (getval("ce")) X normal () X writes ("> ") #clear command line X } X if pile[1] = pile[2] = pile[3] = pile[4] = 13 then X if uterminate (1) then break # VICTORY! X s := getCmdChar () X writeInfo ("") #clear info line X writeCursor (18, 68) X case s of { X "?"|"H" : uhelp() X "1"|"2"|"3"|"4"|"5"|"6"|"7"|"D" : X if not umove(s) then complain() X "A" : uautomatic() #look Ma, no hands! X "B" : uboss() #bail out -- quick X "C" : ucontinuous() #no hands, forever X "M" : if not umove(&null) then complain() X "Q" : if uterminate(&null) then break #new game X "S" : usuggest (if s == prevsCmd then 1 else 0) X "T" : { writes("humb"); push(ops, thumb()) } X "U" : undo() X "Z" : udebug() X "\^L" : refreshScreen() X ESC : s #do nothing here X default : complain() X } #case X prevsCmd := s X } #repeat command X totalAces +:= pile[1] + pile[2] + pile[3] + pile[4] X totalGames +:= 1 X lastSeed := newGame () X } #repeat game Xend #main SHAR_EOF echo 'File klondike.icn is complete' && true || echo 'restore of klondike.icn failed' rm -f _shar_wnt_.tmp fi # ============= kloncon.icn ============== if test -f 'kloncon.icn' -a X"$1" != X"-c"; then echo 'x - skipping kloncon.icn (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp echo 'x - extracting kloncon.icn (Text)' sed 's/^X//' << 'SHAR_EOF' > 'kloncon.icn' && X############################################################################ X# X# Name: kloncon.icn X# X# Title: klondike console interface routines X# X# Author: Norman H. Azadian X# X# Version: 1.3 X# X############################################################################ X# X# kloncon.icn 901029 NHA X# Console interface routines for Klondike X# Requires ANSI.SYS (or NANSI.SYS) screen driver and a 25-line display. X# X# TO FIX: X# X# X# TO DO: X# X# - termcap for portability ?? X# - click for each card moved in a stack ? X# X############################################################################ X# X# Links: X# X# See also: klondike.icn, klonsub.icn X# X############################################################################ X X X# constants Xglobal suitID #suit identification chars Xglobal isDOS # 1 when running under DOS Xglobal isUNIX # 1 when running under UNIX Xglobal isXENIXconsole # 1 if XENIX ansi console Xglobal monochrome # 1 when running Black&White X# Video control strings (ANSI.SYS) Xglobal ESC Xglobal Vnormal, Vreverse, Vblink, Vbold, VclearAll, VclearEOL, Vbell Xglobal color #list of suit color strings X X X# i n i t C o n s t a n t s X# Initialize the program "constants". These are actually variables that X# are set just once at the beginning of the world. Xprocedure initConstants () Xlocal i Xlocal Vred, Vblack #suit color strings X X if \invisible then return X X isUNIX := find("UNIX",&features) X isDOS := find("MS-DOS",&host) X isXENIXconsole := 1(find("XENIX",&host), find("ansi"|"li",getname())) X X if \isDOS then { X #ensure that we are dealing with an ANSI-compatible screen X writes ("\33[6n") #request cursor position report X #NOTE that the first character to match should be an ESCape. X #Unfortunately, reads() seems to eat that character X match ("[", reads (&input, 8)) | X stop ("Klondike: requires (N)ANSI.SYS screen driver") X X i := ord (Peek([16r40, 16r49])) #BIOS display mode byte X case i of { X 2 : monochrome := 1 X 3 : monochrome := &null #living color X 7 : monochrome := 1 X default : { X stop ("Klondike: unknown display mode ", i) X } X } X } else X monochrome := 1 X X if \isDOS then { X ESC := "\33" #escape character X VclearAll := "\33[2J" #also homes cursor X VclearEOL := "\33[K" X Vnormal := "\33[0m" X Vbold := "\33[1m" X Vblink := "\33[5m" X Vreverse := "\33[7m" X Vbell := "\^G" X if \monochrome then { X Vred := Vnormal X Vblack := Vreverse X } else { X Vred := "\33[0;47;31m" # "extra" 0 seems to be necessary X Vblack := "\33[0;47;30m" X } X } X else if \isUNIX then { X # Check terminal size. X 24 < getval("li") < 29 & 79 < getval("co") < 85 | X { reset_tty(); stop("klondike: terminal must be 80x25.") } X ESC := "\e" X VclearAll := getval("cl") X Vnormal := getval("se") || (getval("ue") | "") | X { reset_tty(); stop("klondike: terminal must have standout mode.") } X VclearEOL := Vnormal || getval("ce") X Vbold := getval("so") X Vblink := getval("us") X Vreverse := getval("so") X Vbell := "\^G" X# color not implemented for UNIX X# if \monochrome then { X Vred := Vnormal X Vblack := Vreverse X# } else { X# Vred := "\33[0;47;31m" # "extra" 0 seems to be necessary X# Vblack := "\33[0;47;30m" X# } X } X else X stop("Klondike: OS not supported.") X X # Suits are: 1=Hearts, 2=Diamonds, 3=Clubs, 4=Spades X suitID := if \isDOS then "\3\4\5\6" else "HDCS" X color := [Vred, Vred, Vblack, Vblack] Xend #initConstants X X X# i n i t S c r e e n X# Initialize output and write the fixed parts of the screen. X# initConstants() must have been called earlier. Xprocedure initScreen () Xlocal i Xstatic vertical Xinitial { X vertical := if \isDOS then "\272" else "|" X} X X if \invisible then return X if \isDOS then { X if \monochrome then writes ("\33[=2h") #25x80 B&W text mode X else writes ("\33[=3h") #25x80 color text mode X writes (VclearAll, "\33[=7l") #clear screen, prevent wrap X } X else if \isUNIX then { X iputs(getval("se")) X iputs(getval("ue")) X clear() X } X X every i := 1 to 7 do X writeStackNumber (i, Vnormal) X every i := 2 to 25 do { X if \isDOS then X writes ("\33[",i,";64H", vertical) X else if \isUNIX then { X iputs(igoto(getval("cm"), 64, i)) X writes (vertical) X } X } X if \isDOS then X writes ("\33[2;64H\311\315\315\315\315SOLITAIRE\315\315\315\315") X else if \isUNIX then { X iputs(igoto(getval("cm"), 64, 2)) X writes ("=====SOLITAIRE====") X } Xend #initScreen X X X# w r i t e S t a c k N u m b e r X# Write the indicated stack number with the specified video attribute. X# Cursor position is preserved -- WARNING: THIS IS NOT NESTABLE. Xprocedure writeStackNumber (num, attr) X if \invisible then return X if \isDOS then X writes (ESC, "[s") #save cursor position X writeCursor (1, [2,11,20,29,38,47,56][num]) X if \isDOS then { X writes (attr, num, Vnormal) X writes (ESC, "[u") #restore cursor position X } X else if \isUNIX then { X iputs(attr); writes(num); iputs(Vnormal) X writeCursor (18, 73) X } Xend #writeStackNumber X X X# w r i t e C u r s o r X# Position the cursor to row,col. X# Screen origin (top left corner) is row=1 and col=1. Xprocedure writeCursor (row, col) X if /invisible then { X if \isDOS then X writes ("\33[", row, ";", col, "H") X else if \isUNIX then X iputs(igoto(getval("cm"), col, row)) X } Xend #writeCursor X X X# w r i t e F r o n t X# Displays an image of the specified card fronts at the specified spot. X# WARNING: this eats the list that you provide -- pass a copy() if you care!! X# Top left corner of the first card will be placed at the specified position. X# Successive cards are displayed two rows higher (lower position on the screen). X# Cursor need not be in any particular position before this, and is left X# in a random position afterwards. Video is always left normal (not reversed). X# Cards are 7 columns wide by 5 rows tall. X# With 25 rows, we can put 12 cards in a stack (assuming we start in row 2). X# But if there are 11 in the stack we can only display 4 rows of the top card. X# If there are 12 cards, we can only display 2 rows of the topmost card. X##We can only write a row at a time due to a problem with ANSI col 80 handling. Xprocedure writeFront (cardlist, row, col) Xlocal suit, rank, card Xstatic vertical, topHorizontal, bottomHorizontal Xinitial { X if \isDOS then { X vertical := "\263" X topHorizontal := "\332\304\304\304\304\304\277" X bottomHorizontal := "\300\304\304\304\304\304\331" X } else { X vertical := "|" X topHorizontal := "-------" X bottomHorizontal := "-------" X } X} X if \isDOS then { X while card := get(cardlist) do { X #first 2 rows of card X writeCursor (row+0, col); X writes (Vreverse, topHorizontal) X writeCursor (row+1, col); X writes (vertical, color[card.suit], "A23456789TJQK"[card.rank], X suitID[card.suit], Vreverse, " ", vertical) X if (*cardlist = 0) & (row < 24) then { X #next 2 rows of top card unless it's the 12th card on the stack X writeCursor (row+2, col); X writes (Vreverse, vertical, " ", vertical) X writeCursor (row+3, col); X writes (vertical," ",color[card.suit],"A23456789TJQK"[card.rank], X suitID[card.suit], Vreverse, vertical) X if row < 22 then { X #last row of card unless it's the 11th on the stack X writeCursor (row+4, col); X writes (bottomHorizontal) X } X } X row +:= 2 X } X writes (Vnormal) X } X else if \isUNIX then { X if (row = 21, col > 65, getval("li") = 25, \getval("am")) then X row -:= 1 X while card := get(cardlist) do { X #first 2 rows of card X writeCursor (row+0, col); X emphasize (); writes (topHorizontal) X writeCursor (row+1, col); X writes (vertical, color[card.suit], "A23456789TJQK"[card.rank], X suitID[card.suit]); emphasize (); writes (" ", vertical) X if (*cardlist = 0) & (row < 24) then { X #next 2 rows of top card unless it's the 12th card on the stack X writeCursor (row+2, col); X emphasize (); writes (vertical, " ", vertical) X writeCursor (row+3, col); X writes (vertical," ",color[card.suit],"A23456789TJQK"[card.rank], X suitID[card.suit]); emphasize (); writes (vertical) X if row < 22 then { X #last row of card unless it's the 11th on the stack X writeCursor (row+4, col); X writes (bottomHorizontal) X } X } X row +:= 2 X } X normal () X } Xend #writeFront X X X# w r i t e B a c k X# Puts an image of the back of a card at the specified spot on the screen. Xprocedure writeBack (row, col) Xstatic backLine Xinitial { X backLine := repl (if \isDOS then "\260" else "#", 7) X} X if \invisible then return X if (row = 21, col > 65, \isUNIX, getval("li") = 25, \getval("am")) then X row -:= 1 X writeCursor (row+0, col); writes (backLine) X writeCursor (row+1, col); writes (backLine) X writeCursor (row+2, col); writes (backLine) X writeCursor (row+3, col); writes (backLine) X writeCursor (row+4, col); writes (backLine) Xend #writeBack X X X# w r i t e B l a n k X# Blanks a card-sized area at the specified spot on the screen. Xprocedure writeBlank (row, col) Xstatic blankLine Xinitial { X blankLine := repl (" ", 7) X} X if \invisible then return X if (row = 21, col > 65, \isUNIX, getval("li") = 25, \getval("am")) then X row -:= 1 X writeCursor (row+0, col); writes (blankLine) X writeCursor (row+1, col); writes (blankLine) X writeCursor (row+2, col); writes (blankLine) X writeCursor (row+3, col); writes (blankLine) X writeCursor (row+4, col); writes (blankLine) Xend #writeBlank X X X# w r i t e S t a c k X# Display the specified stack. Left end is bottom of stackUp, top of stackDown. X# Stacks start in row 2, column1; with 2 columns between stacks. X# last[] holds, for each stack, the total number of visible cards X# on that stack as of the last time writeStack() was called. This allows X# us to simply draw (or erase) the cards that have been added (or subtracted). X# By special arrangement, this routine can be called with a negative stack X# number! This is a hint that our idea of what is on the display is actually X# wrong, and therefore the entire stack needs to be re-displayed. This can X# happen in two situations: 1) in refreshScreen(), the entire screen is cleared X# before calling writeStack(); 2) in undo() when undoing a move between X# stacks, the bottom card needs to be changed, although the normal algorithm X# would consider that it is already correctly displayed. Note that in neither X# case is the stack shrinking, therefore we don't need to worry about erasing X# any cards that were displayed last time. Xprocedure writeStack (n) Xlocal row, col, s Xstatic last, blankLine, firstRow, lastRow Xinitial { X last := [0,0,0,0,0,0,0] X blankLine := repl (" ", 7) X firstRow := [2,4,6,8,10,12,14,16,18,20,22,24] #first row of a card X lastRow := [6,8,10,12,14,16,18,20,22,24,25,25] #last row of a card X} X if \invisible then return X if n < 0 then { X n := -n X last[n] := 0 #force complete re-write X } X X col := 1 + ((n -1) * 9) #leftmost column for this stack X X if *stackUp[n] <= last[n] then { X #the stack just got smaller (or stayed the same) X #blank out two rows for each card that has been removed X row := lastRow[last[n]] #last row used by top card X while *stackUp[n] < last[n] do { X writeCursor (row-0, col); writes (blankLine) X writeCursor (row-1, col); writes (blankLine) X row -:= 2 X last[n] -:= 1 #count and update simultaneously X } X dieIf (*stackUp[n] ~= last[n], last[n]) X #re-write new top card X if *stackUp[n] = 0 then X if *stackDown[n] = 0 then X writeBlank (2, col) X else X writeBack (2, col) X else X writeFront ([stackUp[n][-1]], firstRow[last[n]], col) X } else { X #the stack just got bigger -- display new cards X s := stackUp[n][last[n]-(*stackUp[n]):0] #list of new cards X writeFront (s, firstRow[last[n]+1], col) X last[n] := *stackUp[n] #remember how much is displayed X } X X writeCursor (2, (7 + col)) X writes (" 123456???"[1+*stackDown[n]]) #display the number of hidden cards Xend #writeStack X X X# w r i t e P i l e X# Displays an image of the specified ace pile, face up (or blank if empty) Xprocedure writePile (n) Xstatic pileRow, pileCol Xinitial { X pileRow := [3,3,9,9] X pileCol := [66,74,66,74] X} X if \invisible then return X if 0 = pile[n] then writeBlank (pileRow[n], pileCol[n]) X else writeFront ([card(n,pile[n])], pileRow[n], pileCol[n]) Xend #writePile X X X# w r i t e D e c k D o w n X# Displays an image of deckDown (the face-down deck) in the proper spot. Xprocedure writeDeckDown () X if \invisible then return X if 0 < *deckDown then X writeBack (21, 74) X else X writeBlank (21, 74) X if (\isUNIX, getval("li") = 25, \getval("am")) then X writeCursor (19, 76) X else X writeCursor (20, 76) X writes (right(*deckDown, 2)) Xend #writeDeckDown X X X# w r i t e D e c k U p X# Displays an image of deckUp (the face-up deck) in the proper spot. Xprocedure writeDeckUp () X if \invisible then return X if 0 < *deckUp then X writeFront ([deckUp[1]], 21, 66) X else X writeBlank (21, 66) X if (\isUNIX, getval("li") = 25, \getval("am")) then X writeCursor (19, 68) X else X writeCursor (20, 68) X writes (right(*deckUp, 2)) Xend #writeDeckUp X X X# w r i t e I n f o X# Displays a new short string (up to 12 printing characters) in the X# officially approved information area of the screen. X# An empty string results in clearing the area and restoring normal attributes. Xprocedure writeInfo (s) SHAR_EOF true || echo 'restore of kloncon.icn failed' fi echo 'End of part 2' echo 'File kloncon.icn is continued in part 3' echo 3 > _shar_seq_.tmp exit 0 From goer%sophist@gargoyle.uchicago.edu Sat Dec 8 03:52:25 1990 Resent-From: goer%sophist@gargoyle.uchicago.edu Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP id AA02517; Sat, 8 Dec 90 03:52:25 -0700 Return-Path: goer@sophist.uchicago.edu Received: from gargoyle.uchicago.edu by Arizona.edu; Sat, 8 Dec 90 03:51 MST Received: by gargoyle.uchicago.edu from sophist (sophist.uchicago.edu) (4.0/1.14) id AA04506; Sat, 8 Dec 90 04:51:08 CST Received: by sophist (4.1/UofC3.1X) id AA08425; Sat, 8 Dec 90 04:54:27 CST Resent-Date: Sat, 8 Dec 90 03:51 MST Date: Sat, 8 Dec 90 04:54:27 CST From: Richard Goerwitz Subject: klondike, part 03 of 05 Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: Message-Id: <9012081054.AA08425@sophist> X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.edu ---- Cut Here and feed the following to sh ---- #!/bin/sh # this is klondike.03 (part 3 of a multipart archive) # do not concatenate these parts, unpack them in order with /bin/sh # file kloncon.icn continued # if test ! -r _shar_seq_.tmp; then echo 'Please unpack part 1 first!' exit 1 fi (read Scheck if test "$Scheck" != 3; then echo Please unpack part "$Scheck" next! exit 1 else exit 0 fi ) < _shar_seq_.tmp || exit 1 if test ! -f _shar_wnt_.tmp; then echo 'x - still skipping kloncon.icn' else echo 'x - continuing file kloncon.icn' sed 's/^X//' << 'SHAR_EOF' >> 'kloncon.icn' && X if \invisible then return X writeCursor (16, 65) X if \isDOS then X writes (Vnormal, VclearEOL) X else if \isUNIX then X normal () & iputs (VclearEOL) X if *s ~= 0 then writes (s) Xend #writeInfo X X X# c l i c k X# Make a quick sound to accompany card transfers Xprocedure click () Xlocal x X if (\clicking) & (\isDOS) then { X x := InPort (16r61) X OutPort (16r61, 3) X OutPort (16r61, x) X } Xend #click X X X# g e t C m d C h a r X# Returns an upper-case command character, echoed to current cursor position. X# Fails if character wasn't "normal" and complaint was made. X# For ESC, abort information is written, and ESC is returned. X# Normal calling sequence (from within a command procedure) is thus: X# until (s := getCmdChar ()) X# if s == ESC then fail Xprocedure getCmdChar () Xlocal s X s := getch () #get command character X if s == "\0" then { #non-ASCII character X getch () #discard keyboard scan code X complain () X fail X } X s := map (s, &lcase, &ucase) X if s == ESC then { X if \isDOS then X writeInfo (Vbold || "Cmd Aborted.") X else if \isUNIX then X writeInfo ("Cmd aborted.") X } X else X writes (s) #echo the command character X return s Xend #getCmdChar X X X# c o m p l a i n X# Let the boob know he done something wrong X# The short beep produced under isDOS is not as annoying as the normal beeeeep. Xprocedure complain () Xlocal x X if \isDOS then X writeInfo (Vbold || "INVALID") X else if \isUNIX then X writeInfo ("INVALID") X if \clicking then X if \isDOS then { X x := InPort (16r61) X every 1 to 22 do X OutPort (16r61, 3) X OutPort (16r61, x) X } else X writes (Vbell) Xend #complain X X X# r e f r e s h S c r e e n X# Re-write entire screen. Xprocedure refreshScreen () X if \invisible then return X initScreen () X every writeStack (-1 to -7 by -1) X every writePile (1 to 4) X writeDeckDown () X writeDeckUp () Xend #refreshScreen SHAR_EOF echo 'File kloncon.icn is complete' && true || echo 'restore of kloncon.icn failed' rm -f _shar_wnt_.tmp fi # ============= klonsub.icn ============== if test -f 'klonsub.icn' -a X"$1" != X"-c"; then echo 'x - skipping klonsub.icn (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp echo 'x - extracting klonsub.icn (Text)' sed 's/^X//' << 'SHAR_EOF' > 'klonsub.icn' && X############################################################################ X# X# Name: klonsub.icn X# X# Title: subroutines for klondike X# X# Author: Norman H. Azadian X# X# Version: 1.2 X# X############################################################################ X# X# Links: X# X# See also: klondike.icn X# X############################################################################ X X X#klonsub.icn 901029 NHA X#subroutines for Klondike X X# d i e I f X# If the first argument succeeds, then write out the remaining args & die. X# Note that the remaining arguments must succeed. Xprocedure dieIf (failed, writeArgs[]) X every writes (&output, !writeArgs) X write (&output) X display () X every writes (&errout, !writeArgs) X write (&errout) X runerr (500) Xend #dieIf X X X# f i t O n S t a c k X# Given a card and a stack number, fail unless card can be added to the stack. X# Note that we disallow putting an Ace on a stack, period. This prevents X# ever building a stack with 13 cards, which we can't display in 25 rows. Xprocedure fitOnStack (c, n) Xlocal top #top card on stack X if *stackUp[n] = 0 then { X dieIf (*stackDown[n] ~= 0, "Up empty, Down not") X if c.rank ~= 13 then fail #only a king can go to empty stack X } else { X top := stackUp[n][-1] #copy of top card X if (c.rank ~= (top.rank - 1)) then fail #wrong rank X if (c.suit < 3) & (top.suit < 3) then fail #same color X if (c.suit > 2) & (top.suit > 2) then fail #same color X if c.rank = 1 then fail #no ace on stack X dieIf (*stackUp[n] >= 12, "stack too big") X } X return #success Xend #fitOnStack X X X# c h e c k 4 a c e X# Only has an effect when global automaticAce is set! X# Given a stack number, check for an ace as the top of stackUp[n]. X# If present, move it over to it's ace pile, turn over the next card X# from stackDown, and check again. X# Must not be more than one up card in stack. X# Returns a string of the operations performed. Xprocedure check4ace (n) Xlocal c, op X op := "" X if \automaticAce then { X dieIf (1 < *stackUp[n]) X while 0 < *stackUp[n] do { X c := stackUp[n][1] #copy of (top = bottom) up card X if c.rank = 1 then { #it's an ace! X pop (stackUp[n]) #remove it from the stack X pile[c.suit] := 1 #move to ace pile X op ||:= c.suit X push (stackUp[n], get(stackDown[n])) #turn over card underneath X writeStack (n) X writePile (c.suit) X click () X } else X break #not an ace X } X } X return op Xend #check4ace X X X# m o v e S t a c k X# Move a stack to another stack, no questions asked. X# Updates video and audio. X# Returns any automatic ace operations that were done as a consequence. X##It would be nice to do this in a visually and audibly more satisfying way Xprocedure moveStack (src, dst) X while put (stackUp[dst], get(stackUp[src])) X put (stackUp[src], get(stackDown[src])) X writeStack (src) X writeStack (dst) X click () X return check4ace (src) Xend #moveStack X X X# _ m o v e X# This is the internal move, taking a operation string. No Thumbs allowed. X# Upon success it returns the (possibly modified) operation string. Xprocedure _move (op) Xlocal src, dst, c, moved X dieIf (op[1] ~== "M", "op is ", op) X src := op[2] X dst := op[3] X moved := 0 X if src == "D" then { X c := deckUp[1] X if dst == "A" then { # Deck -> Ace X if c.rank = (pile[c.suit] + 1) then { X op[4] := c.suit # Deck -> Ace: fits - do it X pile[c.suit] +:= 1 X writePile (c.suit) X moved := 1 X } else X fail # Deck -> Ace: doesn't fit X } else { # Deck -> stack X if fitOnStack (c, dst) then { X put (stackUp[dst], c) # Deck -> stack: fits - do it X writeStack (dst) X moved := 1 X } else X fail # Deck -> stack: doesn't fit X } X while moved ~= 0 do { X pop (deckUp) X writeDeckUp () # Deck -> somewhere, with success X click () X moved := 0 X if \automaticAce then { X if (c := deckUp[1]).rank = 1 then { #automatic Ace handling X pile[c.suit] := 1 X op ||:= c.suit X writePile (c.suit) X moved := 1 X } X } X } X } else { X if dst == "A" then { # stack -> Ace X c := stackUp[src][-1] #copy of card on top of stack X if c.rank = (pile[c.suit] + 1) then { X op[4] := c.suit # stack -> Ace: fits - do it X pile[c.suit] +:= 1 X pull (stackUp[src]) X writeStack (src) X click () X writePile (c.suit) X if *stackUp[src] = 0 then { X op[4] +:= 4 #mark this case for undo() X put (stackUp[src], get(stackDown[src])) #turn over a card X writeStack (src) X click () X op ||:= check4ace (src) X } X } else { X fail # stack -> Ace: doesn't fit X } X } else { # stack -> stack X if fitOnStack (stackUp[src][1], dst) then { X # stack -> stack: fits - do it X op[4] := "123456789abcdef"[*stackUp[src]] X op ||:= moveStack (src, dst) X } else X fail # stack -> stack: doesn't fit X } X } X return op #success Xend #move X X X# t h u m b X# Move to next spot in deckDown X# Returns the operation performed (usually just "T3"), or fail if none possible. Xprocedure thumb () Xlocal c, op, moved X if *deckDown = *deckUp = 0 then X return complain() #no cards left in the deck X if *deckDown = 0 then X while push (deckDown, pop(deckUp)) X op := "T" || if *deckDown < 3 then *deckDown else 3 X push (deckUp, pop(deckDown)) X push (deckUp, pop(deckDown)) X push (deckUp, pop(deckDown)) X writeDeckDown () X moved := 1 X while moved ~= 0 do { X writeDeckUp () X click () X moved := 0 X if \automaticAce then { X if deckUp[1].rank = 1 then { X c := pop (deckUp) X pile[c.suit] := 1 X op ||:= c.suit X writePile (c.suit) X moved := 1 X } X } X } X return op Xend #thumb X X X# u n d o X# backup one move, including any automatic ace moves Xprocedure undo () Xlocal op, suit X writes ("ndo") X if op := pop (ops) then { X writeInfo (op) X # op looks like: Msdixxx X # where x is an [optional] number 1..4 of an ace pile X # and s is either a stack number or "D" X # and d is either "A" or a number 1..7 of a stack X # and i is an extra piece of info which may be valid X case op[1] of { X "M" : { X dieIf ((*op < 4) | ((/automaticAce) & (4 < *op)), op) X if op[2] == "D" then { X #Move cards from Ace piles to deck, starting at end X while 4 < *op do { X suit := op[-1] X pile[suit] := 0 X writePile (suit) X push (deckUp, card(suit,1)) X writeDeckUp () X click () X op[-1] := "" X } X if op[3] == "A" then { X # unMove Deck to Ace op[4] X suit := op[4] X push (deckUp, card(suit,pile[suit])) X pile[suit] -:= 1 X writePile (suit) X } else { X # unMove Deck to stack op[3] X push (deckUp, pull(stackUp[op[3]])) X writeStack (op[3]) X } X writeDeckUp () X } else { X #Move cards from Ace piles to stack, starting at end X while 4 < *op do { X suit := op[-1] X pile[suit] := 0 X writePile (suit) X dieIf (1 < *stackUp[op[2]]) X push (stackDown[op[2]], pull(stackUp[op[2]])) X push (stackUp[op[2]], card(suit,1)) X writeStack (op[2]) X click () X op[-1] := "" X } X if op[3] == "A" then { X # unMove stack op[2] to Ace pile op[4] X suit := op[4] X if 4 < suit then { X suit -:= 4 #ace pile card was last on stack X dieIf (1 < *stackUp[op[2]]) X push (stackDown[op[2]], pull(stackUp[op[2]])) X } X put (stackUp[op[2]], card(suit,pile[suit])) X pile[suit] -:= 1 X writePile (suit) X writeStack (op[2]) X } else { X # unMove top op[4] cards on stack op[2] X # to stack op[3] X dieIf (1 < *stackUp[op[2]]) X push (stackDown[op[2]], pull(stackUp[op[2]])) X every 1 to ("16r" || op[4]) do X push (stackUp[op[2]], pull(stackUp[op[3]])) X writeStack (op[3]) X writeStack (-op[2]) X } X } X } X "T" : { X dieIf ((/automaticAce) & (*op ~= 2)) X ### op looks like: Tcxx X ### where c is the number of cards thumbed (usually 3) X ### and x is an optional number 1..4 of an ace pile X ### There can be 0,1,2, or 3 of these x's. X # move cards from Ace piles to deck, starting at end X while 2 < *op do { X suit := op[-1] X pile[suit] := 0 X writePile (suit) X push (deckUp, card(suit,1)) X writeDeckUp () X click () X op[-1] := "" X } X # then undo the Thumb operation itself X dieIf (*deckUp = 0) X every 1 to op[2] do X push (deckDown, pop(deckUp)) X if *deckUp = 0 then X while push (deckUp, pop(deckDown)) X writeDeckUp () X writeDeckDown () X } X default : { X if \isUNIX then reset_tty() X stop ("Klondike: unknown operation `", op, "' in ops[]") X } X } X click () X } else { X ## Admittedly this is a bit of a kluge, but better than nothing ? X if *deckDown = 0 then X while push (deckDown, pop(deckUp)) X writeDeckUp () X writeDeckDown () X writeInfo ("Stack Empty") X } X Xend #undo X X X# s h o w L i s t X# Display a list of cards at the current cursor position. X# Intended for debugging only . Xprocedure showList (lst) Xlocal c X every c := !lst do { X if \isDOS then X writes (color[c.suit], "A23456789TJQK"[c.rank], suitID[c.suit], X Vnormal, " ") X else if \isUNIX then { X writes (color[c.suit], "A23456789TJQK"[c.rank], suitID[c.suit]) X normal (); writes(" ") X } X } Xend #showList X X X# c a r d 2 s t r X# Given a list of card records, returns a string representation. X# Even an empty list results in a non-zero string length. Xprocedure card2str (lst) Xlocal c, s X s := "$" X every c := !lst do X s ||:= string(c.suit) || "123456789abcd"[c.rank] X return s Xend #card2str X X X# s t r 2 c a r d X# Given a string [as generated by card2str()], X# return corresponding list of card records. X# Fails if the string is invalid. Xprocedure str2card (s) Xlocal cc, i X if s[i:=1] ~== "$" then fail X cc := [] X while put (cc, card(s[i+:=1], integer("14r"||s[i+:=1]))) X return cc Xend #str2card X X X# s a v e S t a t e X# Saves the current state in the named file, which is created/overwritten X# as necessary. X# Fails if the state was not successfully saved. Xprocedure saveState (filename) Xlocal f, i X (f := open (filename, "c")) | fail X write (f, &dateline) X write (f, if \automaticAce then 1 else 0) X write (f, if \clicking then 1 else 0) X write (f, firstSeed) X write (f, lastSeed) X write (f, &random) X every write (f, !pile) X every write (f, card2str(!stackUp)) X every write (f, card2str(!stackDown)) X write (f, card2str(deckUp)) X write (f, card2str(deckDown)) X write (f, totalGames) X write (f, totalAces) X every write (f, !ops) X return close (f) Xend #saveState X X X# r e s t o r e S t a t e X# Restore game from the named file. X# Fails if the file isn't there, isn't readable, or isn't correct format. X# Otherwise returns date the file was last written. X# Note that we do not update the screen here !! Xprocedure restoreState (filename) Xlocal f, date X if not (f := open (filename, "r")) then fail X if (not (date := read(f))) | (*date = 0) then fail X automaticAce := if read (f) == "0" then &null else 1 X clicking := if read (f) == "0" then &null else 1 X firstSeed := read (f) X lastSeed := read (f) X &random := read (f) X every ((!pile) := read(f)) X every ((!stackUp) := str2card (read(f))) X every ((!stackDown) := str2card (read(f))) X deckUp := str2card (read(f)) X deckDown := str2card (read(f)) X totalGames := read (f) X totalAces := read (f) X ops := [] X while push (ops, read (f)) X dieIf (not close (f), "can't close") X return date Xend #restoreState X X X# n e w G a m e X# Set up all the global variables for a new game. X# Returns the seed used to generate this game. Xprocedure newGame () Xlocal i, j, s, seed X initScreen () X X #initialize deck, stacks, piles X ops := [] #no operations done yet X deckUp := [] #deck in hand, face-up X deckDown := [] #deck in hand, face-down X stackUp := list(7, 0) #columns on table, face up X stackDown := list(7, 0) #columns on table, face down X pile := list(4, 0) #aces - only top rank stored X every i := 1 to 4 do X every j := 1 to 13 do X put (deckDown, card(i, j)) #take cards out of the box X X seed := &random X if not \invisible then { #Vblink not defined in Batch mode X if \isDOS then X writeInfo (Vblink || "Shuffling") X else if \isUNIX then X writeInfo ("Shuffling") X } X every 1 to 100 do X ?deckDown :=: ?deckDown X writeInfo ("") X X every !stackUp := [] X every !stackDown := [] X every i := 1 to 7 do { X push (stackUp[i], get(deckDown)) X writeStack (-i) X click () X every j := (i+1) to 7 do { X push (stackDown[j], get(deckDown)) X writeStack (-j) X click () X } X### writeStack (-i) ### this replaces 2 calls above X } X writeDeckDown() X X #handle any Aces which are showing X every i := 1 to 7 do X if *(s := check4ace (i)) ~= 0 then X push (ops, "M" || string(i) || "A" || string(integer(s) + 4)) X return seed Xend #newGame SHAR_EOF true || echo 'restore of klonsub.icn failed' rm -f _shar_wnt_.tmp fi # ============= itlib.icn ============== if test -f 'itlib.icn' -a X"$1" != X"-c"; then echo 'x - skipping itlib.icn (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp echo 'x - extracting itlib.icn (Text)' sed 's/^X//' << 'SHAR_EOF' > 'itlib.icn' && X######################################################################## SHAR_EOF true || echo 'restore of itlib.icn failed' fi echo 'End of part 3' echo 'File itlib.icn is continued in part 4' echo 4 > _shar_seq_.tmp exit 0 From goer%sophist@gargoyle.uchicago.edu Sat Dec 8 03:53:06 1990 Resent-From: goer%sophist@gargoyle.uchicago.edu Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP id AA02536; Sat, 8 Dec 90 03:53:06 -0700 Return-Path: goer@sophist.uchicago.edu Received: from gargoyle.uchicago.edu by Arizona.edu; Sat, 8 Dec 90 03:51 MST Received: by gargoyle.uchicago.edu from sophist (sophist.uchicago.edu) (4.0/1.14) id AA04509; Sat, 8 Dec 90 04:51:37 CST Received: by sophist (4.1/UofC3.1X) id AA08433; Sat, 8 Dec 90 04:54:56 CST Resent-Date: Sat, 8 Dec 90 03:52 MST Date: Sat, 8 Dec 90 04:54:56 CST From: Richard Goerwitz Subject: klondike, part 04 of 05 Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: Message-Id: <9012081054.AA08433@sophist> X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.edu ---- Cut Here and feed the following to sh ---- #!/bin/sh # this is klondike.04 (part 4 of a multipart archive) # do not concatenate these parts, unpack them in order with /bin/sh # file itlib.icn continued # if test ! -r _shar_seq_.tmp; then echo 'Please unpack part 1 first!' exit 1 fi (read Scheck if test "$Scheck" != 4; then echo Please unpack part "$Scheck" next! exit 1 else exit 0 fi ) < _shar_seq_.tmp || exit 1 if test ! -f _shar_wnt_.tmp; then echo 'x - still skipping itlib.icn' else echo 'x - continuing file itlib.icn' sed 's/^X//' << 'SHAR_EOF' >> 'itlib.icn' && X# X# Name: itlib.icn X# X# Title: Icon termlib-type tools X# X# Author: Richard L. Goerwitz X# X# Version: 1.23 X# X######################################################################### X# X# I place this and future versions of itlib in the public domain - RLG X# X######################################################################### X# X# The following library represents a series of rough functional X# equivalents to the standard Unix low-level termcap routines. They X# are not meant as exact termlib clones. Nor are they enhanced to X# take care of magic cookie terminals, terminals that use \D in their X# termcap entries, or, in short, anything I felt would not affect my X# normal, day-to-day work with ANSI and vt100 terminals. X# X# Requires: A unix platform & co-expressions. There is an MS-DOS X# version, itlibdos.icn. X# X# setname(term) X# Use only if you wish to initialize itermlib for a terminal X# other than what your current environment specifies. "Term" is the X# name of the termcap entry to use. Normally this initialization is X# done automatically, and need not concern the user. X# X# getval(id) X# Works something like tgetnum, tgetflag, and tgetstr. In the X# spirit of Icon, all three have been collapsed into one routine. X# Integer valued caps are returned as integers, strings as strings, X# and flags as records (if a flag is set, then type(flag) will return X# "true"). Absence of a given capability is signalled by procedure X# failure. X# X# igoto(cm,destcol,destline) - NB: default 1 offset (*not* zero)! X# Analogous to tgoto. "Cm" is the cursor movement command for X# the current terminal, as obtained via getval("cm"). Igoto() X# returns a string which, when output via iputs, will cause the X# cursor to move to column "destcol" and line "destline." Column and X# line are always calculated using a *one* offset. This is far more X# Iconish than the normal zero offset used by tgoto. If you want to X# go to the first square on your screen, then include in your program X# "iputs(igoto(getval("cm"),1,1))." X# X# iputs(cp,affcnt) X# Equivalent to tputs. "Cp" is a string obtained via getval(), X# or, in the case of "cm," via igoto(getval("cm"),x,y). Affcnt is a X# count of affected lines. It is only relevant for terminals which X# specify proportional (starred) delays in their termcap entries. X# X# Bugs: I have not tested these routines on terminals that require X# padding. These routines WILL NOT WORK if your machines stty com- X# mand has no -g option (tisk, tisk). This includes NeXT worksta- X# tions, and some others that I haven't had time to pinpoint. X# X########################################################################## X# X# Requires: UNIX, co-expressions X# X# See also: iscreen.icn (a set of companion utilities) X# X########################################################################## X X Xglobal tc_table, tty_speed Xrecord true() X X Xprocedure check_features() X X local in_params, line X # global tty_speed X X initial { X find("unix",map(&features)) | X er("check_features","unix system required",1) X find("o-expres",&features) | X er("check_features","co-expressions not implemented - &$#!",1) X system("/bin/stty tabs") | X er("check_features","can't set tabs option",1) X } X X # clumsy, clumsy, clumsy, and probably won't work on all systems X tty_speed := getspeed() X return "term characteristics reset; features check out" X Xend X X X Xprocedure setname(name) X X # Sets current terminal type to "name" and builds a new termcap X # capability database (residing in tc_table). Fails if unable to X # find a termcap entry for terminal type "name." If you want it X # to terminate with an error message under these circumstances, X # comment out "| fail" below, and uncomment the er() line. X X #tc_table is global X X check_features() X X tc_table := table() X tc_table := maketc_table(getentry(name)) | fail X # er("setname","no termcap entry found for "||name,3) X return "successfully reset for terminal " || name X Xend X X X Xprocedure getname() X X # Getname() first checks to be sure we're running under Unix, and, X # if so, tries to figure out what the current terminal type is, X # checking successively the value of the environment variable X # TERM, and then the output of "tset -". Terminates with an error X # message if the terminal type cannot be ascertained. X X local term, tset_output X X check_features() X X if not (term := getenv("TERM")) then { X tset_output := open("/bin/tset -","pr") | X er("getname","can't find tset command",1) X term := !tset_output X close(tset_output) X } X return \term | X er("getname","can't seem to determine your terminal type",1) X Xend X X X Xprocedure er(func,msg,errnum) X X # short error processing utility X write(&errout,func,": ",msg) X exit(errnum) X Xend X X X Xprocedure getentry(name, termcap_string) X X # "Name" designates the current terminal type. Getentry() scans X # the current environment for the variable TERMCAP. If the X # TERMCAP string represents a termcap entry for a terminal of type X # "name," then getentry() returns the TERMCAP string. Otherwise, X # getentry() will check to see if TERMCAP is a file name. If so, X # getentry() will scan that file for an entry corresponding to X # "name." If the TERMCAP string does not designate a filename, X # getentry() will scan /etc/termcap for the correct entry. X # Whatever the input file, if an entry for terminal "name" is X # found, getentry() returns that entry. Otherwise, getentry() X # fails. X X local f, getline, line, nm, ent1, ent2 X X # You can force getentry() to use a specific termcap file by cal- X # ling it with a second argument - the name of the termcap file X # to use instead of the regular one, or the one specified in the X # termcap environment variable. X /termcap_string := getenv("TERMCAP") X X if \termcap_string ? (not match("/"), pos(0) | tab(find("|")+1), =name) X then return termcap_string X else { X X # The logic here probably isn't clear. The idea is to try to use X # the termcap environment variable successively as 1) a termcap en- X # try and then 2) as a termcap file. If neither works, 3) go to X # the /etc/termcap file. The else clause here does 2 and, if ne- X # cessary, 3. The "\termcap_string ? (not match..." expression X # handles 1. X X if find("/",\termcap_string) X then f := open(termcap_string) X /f := open("/etc/termcap") | X er("getentry","I can't access your /etc/termcap file",1) X X getline := create read_file(f) X X while line := @getline do { X if line ? (pos(1) | tab(find("|")+1), =name, any(':|')) then { X entry := "" X while (\line | @getline) ? { X if entry ||:= 1(tab(find(":")+1), pos(0)) X then { X close(f) X # if entry ends in tc= then add in the named tc entry X entry ?:= tab(find("tc=")) || X # recursively fetch the new termcap entry X (move(3), getentry(tab(find(":"))) ? X # remove the name field from the new entry X (tab(find(":")+1), tab(0))) X return entry X } X else { X \line := &null # must precede the next line X entry ||:= trim(trim(tab(0),'\\'),':') X } X } X } X } X } X X close(f) X er("getentry","can't find and/or process your termcap entry",3) X Xend X X X Xprocedure read_file(f) X X # Suspends all non #-initial lines in the file f. X # Removes leading tabs and spaces from lines before suspending X # them. X X local line X X \f | er("read_tcap_file","no valid termcap file found",3) X while line := read(f) do { X match("#",line) & next X line ?:= (tab(many('\t ')) | &null, tab(0)) X suspend line X } X X fail X Xend X X X Xprocedure maketc_table(entry) X X # Maketc_table(s) (where s is a valid termcap entry for some X # terminal-type): Returns a table in which the keys are termcap X # capability designators, and the values are the entries in X # "entry" for those designators. X X local k, v X X /entry & er("maketc_table","no entry given",8) X if entry[-1] ~== ":" then entry ||:= ":" X X /tc_table := table() X X entry ? { X X tab(find(":")+1) # tab past initial (name) field X X while tab((find(":")+1) \ 1) ? { X &subject == "" & next X if k := 1(move(2), ="=") X then tc_table[k] := Decode(tab(find(":"))) X else if k := 1(move(2), ="#") X then tc_table[k] := integer(tab(find(":"))) X else if k := 1(tab(find(":")), pos(-1)) X then tc_table[k] := true() X else er("maketc_table", "your termcap file has a bad entry",3) X } X } X X return tc_table X Xend X X X Xprocedure getval(id) X X /tc_table := maketc_table(getentry(getname())) | X er("getval","can't make a table for your terminal",4) X X return \tc_table[id] | fail X # er("getval","the current terminal doesn't support "||id,7) X Xend X X X Xprocedure Decode(s) X X # Does things like turn ^ plus a letter into a genuine control X # character. X X new_s := "" X X s ? { X X while new_s ||:= tab(upto('\\^')) do { X chr := move(1) X if chr == "\\" then { X new_s ||:= { X case chr2 := move(1) of { X "\\" : "\\" X "^" : "^" X "E" : "\e" X "b" : "\b" X "f" : "\f" X "n" : "\n" X "r" : "\r" X "t" : "\t" X default : { X if any(&digits,chr2) then { X char(integer("8r"||chr2||move(2 to 0 by -1))) | X er("Decode","bad termcap entry",3) X } X else chr2 X } X } X } X } X else new_s ||:= char(ord(map(move(1),&lcase,&ucase)) - 64) X } X new_s ||:= tab(0) X } X X return new_s X Xend X X X Xprocedure igoto(cm,col,line) X X local colline, range, increment, str, outstr, chr, x, y X X if col > (tc_table["co"]) | line > (tc_table["li"]) then { X colline := string(\col) || "," || string(\line) | string(\col|line) X range := "(" || tc_table["co"]-1 || "," || tc_table["li"]-1 || ")" X er("igoto",colline || " out of range " || (\range|""),9) X } X X # Use the Iconish 1;1 upper left corner & not the C-ish 0 offsets X increment := -1 X outstr := "" X X cm ? { X while outstr ||:= tab(find("%")) do { X tab(match("%")) X chr := move(1) X if case chr of { X "." : outstr ||:= char(line + increment) X "+" : outstr ||:= char(line + ord(move(1)) + increment) X "d" : { X str := string(line + increment) X outstr ||:= right(str, integer(tab(any('23'))), "0") | str X } X } X then line :=: col X else { X case chr of { X "n" : line := ixor(line,96) & col := ixor(col,96) X "i" : increment := 0 X "r" : line :=: col X "%" : outstr ||:= "%" X "B" : line := ior(ishift(line / 10, 4), line % 10) X ">" : { X x := move(1); y := move(1) X line > ord(x) & line +:= ord(y) X &null X } X } | er("goto","bad termcap entry",5) X } X } X return outstr || tab(0) X } X Xend X X X Xprocedure iputs(cp, affcnt) X X local baud_rates, char_rates, i, delay, PC X static num_chars, char_times X # global tty_speed X X initial { X num_chars := &digits ++ '.' X char_times := table() X # Baud rates in decimal, not octal (as in termio.h) X baud_rates := [0,7,8,9,10,11,12,13,14,15] X char_rates := [0,333,166,83,55,41,20,10,10,10] X every i := 1 to *baud_rates do { X char_times[baud_rates[i]] := char_rates[i] X } X } X X type(cp) == "string" | X er("iputs","you can't iputs() a non-string value!",10) X X cp ? { X delay := tab(many(num_chars)) X if ="*" then { X delay *:= \affcnt | X er("iputs","affected line count missing",6) X } X writes(tab(0)) X } X X if (\delay, tty_speed ~= 0) then { X PC := tc_table["pc"] | "\000" X char_time := char_times[tty_speed] | (return "speed error") X delay := (delay * char_time) + (char_time / 2) X every 1 to delay by 10 X do writes(PC) X } X X return X Xend X X X Xprocedure getspeed() X X local stty_g, stty_output, c_cflag, o_speed X X stty_g := open("/bin/stty -g 2>&1","pr") | X er("getspeed","Can't access your stty command.",4) X stty_output := !stty_g X close(stty_g) X X \stty_output ? { X # tab to the third field of the output of the stty -g cmd X tab(find(":")+1) & tab(find(":")+1) & X c_cflag := integer("16r"||tab(find(":"))) X } | er("getspeed","Unable to unwind your stty -g output.",4) X X o_speed := iand(15,c_cflag) X return o_speed X Xend SHAR_EOF echo 'File itlib.icn is complete' && true || echo 'restore of itlib.icn failed' rm -f _shar_wnt_.tmp fi # ============= getchlib.icn ============== if test -f 'getchlib.icn' -a X"$1" != X"-c"; then echo 'x - skipping getchlib.icn (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp echo 'x - extracting getchlib.icn (Text)' sed 's/^X//' << 'SHAR_EOF' > 'getchlib.icn' && X############################################################################ X# X# Name: getchlib.icn X# X# Title: Implementation of getch() for Unix (and more) X# X# Author: Richard L. Goerwitz X# X# Version: 1.11 X# X############################################################################ X# X# I place this and future versions of getchlib in the public domain - RLG X# X############################################################################ X# X# Implementing getch() is a much, much more complex affair under Unix X# than it is under, say, MS-DOS. This library represents one, X# solution to the problem - one which can be run as a library, and X# need not be compiled into the run-time system. X# X# Four basic utilities are included here: X# X# getch() - waits until a keystroke is available & X# returns it without displaying it on the screen X# getche() - same as getch() only with echo X# getse(s) - like getche() only for strings. The optional X# argument s gives getse() something to start with. Use this X# if, say, you want to read single characters in cbreak mode, X# but get more input if the character read is the first part X# of a longer command. If the user backspaces over everything X# that has been input, getse() fails. Returns on \r or \n. X# reset_tty() - absolutely vital routine for putting the cur- X# rent tty line back into cooked mode; call it before exiting X# or you will find yourself with a locked-up terminal; use it X# also if you must temporarily restore the terminal to cooked X# mode X# X# Note that getse() *must* be used in place of read(&input) if you X# are planning on using getch() or getche(), since read(&input) X# assumes a tty with "sane" settings. X# X# Warning: The routines below do not do any sophisticated output X# processing. As noted above, they also put your tty line in raw X# mode. I know, I know: "Raw is overkill - use cbreak." But in X# a world that includes SysV, one must pick a lowest common denomi- X# nator. And no, icanon != cbreak. X# X# Bugs: These routines will not work on systems that do not imple- X# ment the -g option for the stty command. The NeXT workstation is X# an example of such a system. Tisk, tisk. X# X############################################################################ X# X# Example program: X# X# The following program is a simple file viewer. To run, it X# needs to be linked with itlib.icn, iscreen.icn, and this file X# (getchlib.icn). X# X# procedure main(a) X# X# # Simple pager/file searcher for Unix systems. Must be linked X# # with itlib.icn and iscreen.icn. X# X# local intext, c, s X# X# # Open input file X# intext := open(a[1],"r") | { X# write(&errout,"Can't open input file.") X# exit(1) X# } X# X# # Initialize screen X# clear() X# print_screen(intext) | exit(0) X# X# # Prompt & read input X# repeat { X# iputs(igoto(getval("cm"), 1, getval("li"))) X# emphasize() X# writes("More? (y/n or /search):") X# write_ce(" ") X# case c := getche() of { X# "y" : print_screen(intext) | break X# " " : print_screen(intext) | break X# "n" : break X# "q" : break X# "/" : { X# iputs(igoto(getval("cm"), 1, getval("li"))) X# emphasize() X# writes("Enter search string:") X# write_ce(" ") X# pattern := GetMoreInput() X# /pattern | "" == pattern & next X# # For more complex patterns, use findre() (IPL findre.icn) X# if not find(pattern, s := !intext) then { X# iputs(igoto(getval("cm"), 1, getval("li"))) X# emphasize() X# write_ce("String not found.") X# break X# } X# else print_screen(intext, s) | break X# } X# } X# } X# X# reset_tty() X# write() X# exit(0) X# X# end X# X# procedure GetMoreInput(c) X# X# local input_string X# static BS X# initial BS := getval("bc") | "\b" X# X# /c := "" X# if any('\n\r', chr := getch()) X# then return c X# else { X# chr == BS & fail X# writes(chr) X# input_string := getse(c || chr) | fail X# if any('\n\r', input_string) X# then fail else (return input_string) X# } X# X# end X# X# procedure print_screen(f,s) X# X# if /s then X# begin := 1 X# # Print top line, if one is supplied X# else { X# iputs(igoto(getval("cm"), 1, 1)) X# write_ce(s ? tab(getval("co") | 0)) X# begin := 2 X# } X# X# # Fill the screen with lines from f; clear and fail on EOF. X# every i := begin to getval("li") - 1 do { X# iputs(igoto(getval("cm"), 1, i)) X# if not write_ce(read(f) ? tab(getval("co") | 0)) then { X# # Clear remaining lines on the screen. X# every j := i to getval("li") do { X# iputs(igoto(getval("cm"), 1, j)) X# iputs(getval("ce")) X# } X# iputs(igoto(getval("cm"), 1, i)) X# fail X# } X# } X# return X# X# end X# X# procedure write_ce(s) X# X# normal() X# iputs(getval("ce")) | X# writes(repl(" ",getval("co") - *s)) X# writes(s) X# return X# X# end X# X############################################################################ X# X# Requires: UNIX X# X# Links: itlib.icn X# X############################################################################ X X Xglobal c_cc, current_mode # what mode are we in, raw or cooked? Xrecord termio_struct(vintr,vquit,verase,vkill) X Xprocedure getse(s) X X # getse() - like getche, only for strings instead of single chars X # X # This procedure *must* be used instead of read(&input) if getch X # and/or getche are to be used, since these put the current tty X # line in raw mode. X # X # Note that the buffer can be initialized by calling getse with a X # string argument. Note also that, as getse now stands, it will X # fail if the user backspaces over everything that has been input. X # This change does not coincide with its behavior in previous ver- X # sions. It can be changed by commenting out the line "if *s < 1 SHAR_EOF true || echo 'restore of getchlib.icn failed' fi echo 'End of part 4' echo 'File getchlib.icn is continued in part 5' echo 5 > _shar_seq_.tmp exit 0 From goer%sophist@gargoyle.uchicago.edu Sat Dec 8 03:53:23 1990 Resent-From: goer%sophist@gargoyle.uchicago.edu Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP id AA02554; Sat, 8 Dec 90 03:53:23 -0700 Return-Path: goer@sophist.uchicago.edu Received: from gargoyle.uchicago.edu by Arizona.edu; Sat, 8 Dec 90 03:52 MST Received: by gargoyle.uchicago.edu from sophist (sophist.uchicago.edu) (4.0/1.14) id AA04514; Sat, 8 Dec 90 04:52:01 CST Received: by sophist (4.1/UofC3.1X) id AA08441; Sat, 8 Dec 90 04:55:20 CST Resent-Date: Sat, 8 Dec 90 03:52 MST Date: Sat, 8 Dec 90 04:55:20 CST From: Richard Goerwitz Subject: klondike, part 05 of 05 Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: Message-Id: <9012081055.AA08441@sophist> X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.edu ---- Cut Here and feed the following to sh ---- #!/bin/sh # this is klondike.05 (part 5 of a multipart archive) # do not concatenate these parts, unpack them in order with /bin/sh # file getchlib.icn continued # if test ! -r _shar_seq_.tmp; then echo 'Please unpack part 1 first!' exit 1 fi (read Scheck if test "$Scheck" != 5; then echo Please unpack part "$Scheck" next! exit 1 else exit 0 fi ) < _shar_seq_.tmp || exit 1 if test ! -f _shar_wnt_.tmp; then echo 'x - still skipping getchlib.icn' else echo 'x - continuing file getchlib.icn' sed 's/^X//' << 'SHAR_EOF' >> 'getchlib.icn' && X # then fail" below, and uncommenting the line "if *s < 1 then X # next." X X local chr X static BS X initial { X BS := getval("bc") | "\b" X if not getval("bs") then { X reset_tty() X stop("Your terminal can't backspace!") X } X } X X /s := "" X repeat { X case chr := getch() | fail of { X "\r"|"\n" : return s X c_cc.vkill : { X if *s < 1 then next X every 1 to *s do writes(BS) X s := "" X } X c_cc.verase : { X # if *s < 1 then next X writes(BS) & s := s[1:-1] X if *s < 1 then fail X } X default: writes(chr) & s ||:= chr X } X } X Xend X X X Xprocedure setup_tty() X change_tty_mode("setup") X return Xend X X X Xprocedure reset_tty() X X # Reset (global) mode switch to &null to show we're in cooked mode. X current_mode := &null X change_tty_mode("reset") X return X Xend X X X Xprocedure getch() X X local chr X X # If the global variable current_mode is null, then we have to X # reset the terminal to raw mode. X if /current_mode := 1 then X setup_tty() X X chr := reads(&input) X case chr of { X c_cc.vintr : reset_tty() & stop() # shouldn't hard code this in X c_cc.vquit : reset_tty() & stop() X default : return chr X } X Xend X X X Xprocedure getche() X X local chr X X # If the global variable current_mode is null, then we have to X # reset the terminal to raw mode. X if /current_mode := 1 then X setup_tty() X X chr := reads(&input) X case chr of { X c_cc.vintr : reset_tty() & stop() X c_cc.vquit : reset_tty() & stop() X default : writes(chr) & return chr X } X Xend X X X Xprocedure change_tty_mode(switch) X X # global c_cc (global record containing values for kill, etc. chars) X local get_term_params, i X static reset_string X initial { X getval("li") # check to be sure itlib is set up X find("unix",map(&features)) | X stop("change_tty_mode: These routines must run under Unix.") X get_term_params := open("/bin/stty -g 2>&1","pr") X reset_string := !get_term_params X close(get_term_params) X reset_string ? { X # tab upto the fifth field of the output of the stty -g cmd X # fields of stty -g seem to be the same as those of the X # termio struct, except that the c_line field is missing X every 1 to 4 do tab(find(":")+1) X c_cc := termio_struct("\x03","\x1C","\x08","\x15") X every i := 1 to 3 do { X c_cc[i] := char(integer("16r"||tab(find(":")))) X move(1) X } X c_cc[i+1] := char(integer("16r"||tab(0))) X } X } X X if switch == "setup" X then system("/bin/stty -echo raw") X else system("/bin/stty "||reset_string) X X return X Xend SHAR_EOF echo 'File getchlib.icn is complete' && true || echo 'restore of getchlib.icn failed' rm -f _shar_wnt_.tmp fi # ============= iscreen.icn ============== if test -f 'iscreen.icn' -a X"$1" != X"-c"; then echo 'x - skipping iscreen.icn (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp echo 'x - extracting iscreen.icn (Text)' sed 's/^X//' << 'SHAR_EOF' > 'iscreen.icn' && X############################################################################ X# X# Name: iscreen.icn X# X# Title: Icon screen functions X# X# Author: Richard L. Goerwitz X# X# Version: 1.12 X# X############################################################################ X# X# This and future version of iscreen are placed in the public domain - RLG X# X############################################################################ X# X# This file contains some rudimentary screen functions for use with X# itlib.icn (termlib-like routines for Icon). X# X# clear() - clears the screen (tries several methods) X# emphasize() - initiates emphasized mode X# normal(mode) - resets to normal mode; if mode is null, X# or "b," normal() assumes you were in emphasize mode, X# otherwise you are assumed to have been in underline mode X# message(s) - displays message s on 2nd-to-last line X# underline() - initiates underline mode X# status_line(s,s2,p) - draws status line s on the 3rd-to-last X# screen line; if s is too short for the terminal, s2 is used; X# if p is nonnull then it either centers, left-, or right-justi- X# fies, depending on the value, "c," "l," or "r." X# X############################################################################ X# X# Requires: UNIX X# X# Links: itlib.icn (or your OS-specific port of itlib) X# X# See also: boldface.icn X# X############################################################################ X X Xprocedure clear() X X # Clears the screen. Tries several methods. X X if not iputs(getval("cl")) X then iputs(igoto(getval("cm"),1,1)) X if not iputs(getval("cd")) X then { X every i := 1 to getval("li") do { X iputs(igoto(getval("cm"),1,i)) X iputs(getval("ce")) X } X iputs(igoto(getval("cm"),1,1)) X } X return X Xend X X X Xprocedure emphasize() X X static bold_str, cookie_str X initial { X if bold_str := getval("so") X then cookie_str := repl(getval("bc") | "\b", getval("sg")) X else { X if bold_str := getval("us") X then cookie_str := repl(getval("bc") | "\b", getval("ug")) X } X } X X iputs(\bold_str) X iputs(\cookie_str) X return X Xend X X X Xprocedure underline() X X static underline_str, cookie_str X initial { X if underline_str := getval("us") X then cookie_str := repl(getval("bc") | "\b", getval("sg")) X } X X iputs(\underline_str) X iputs(\cookie_str) X return X Xend X X X Xprocedure normal(mode) X X static UN_bold_str, bold_cookie_str, X UN_underline_str, underline_cookie_str X initial { X X if UN_bold_str := getval("se") then X bold_cookie_str := repl(getval("bc") | "\b", getval("sg")) X else { X UN_bold_str := getval("ue") X bold_cookie_str := repl(getval("bc")|"\b", getval("ug")) X } X if UN_underline_str := getval("ue") then X underline_cookie_str := repl(getval("bc")|"\b", getval("ug")) X } X X if /mode | (mode == "b") then { X iputs(\UN_bold_str) X iputs(\bold_cookie_str) X return X } X X iputs(\UN_underline_str) X iputs(\underline_cookie_str) X return X Xend X X X Xprocedure status_line(s,s2,p) X X # Writes a status line on the terminal's third-to-last line X # The only necessary argument is s. S2 (optional) is used X # for extra narrow screens. In other words, by specifying X # s2 you give status_line an alternate, shorter status string X # to display, in case the terminal isn't wide enough to sup- X # port s. If p is nonnull, then the status line is either X # centered (if equal to "c"), left justified ("l"), or right X # justified ("r"). X X local width X X /s := "" X width := getval("co") X if *s > width then { X (*s2 < width, s := \s2) | X er("status_line","Your terminal is too narrow.",4) X } X case \p of { X "c" : s := center(s,width-1) X "l" : s := left(s,width-1) X "r" : s := right(s,width-1) X default: stop("status_line: Unknown option "||string(p),4) X } X X iputs(igoto(getval("cm"), 1, getval("li")-2)) X emphasize(); writes(s); iputs(getval("ce")) X normal() X return X Xend X X X Xprocedure message(s) X X # Display prompt s on the second-to-last line of the screen. X # I hate to use the last line, due to all the problems with X # automatic scrolling. X X /s := "" X normal() X iputs(igoto(getval("cm"), 1, getval("li")-1)) X writes(s[1:getval("co")] | s) X iputs(getval("ce")) X return X Xend SHAR_EOF true || echo 'restore of iscreen.icn failed' rm -f _shar_wnt_.tmp fi # ============= klondike.man ============== if test -f 'klondike.man' -a X"$1" != X"-c"; then echo 'x - skipping klondike.man (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp echo 'x - extracting klondike.man (Text)' sed 's/^X//' << 'SHAR_EOF' > 'klondike.man' && X X X - 1 - X X XKLONDIKE(6) KLONDIKE(6) X X X X NAME X klondike -- one of the many versions of solitaire X X SYNOPSIS X klondike -[ACD] [-B gameCount] [-R randomSeed] X X DESCRIPTION X This is actually a popular variation on the Klondike version of X Solitaire (or Patience) as described on page 181 of my 1963 X version of "Hoyle's Rules of Games". The difference is that X here we go through the deck (stock) 3 cards at a time instead X of one-by-one, and we allow it any number of times. X X It should run on any ANSI-compatible terminal, but it looks X best on a PC, preferably color. X X OPTIONS X Options may be either upper or lower case. They may be given X in any order. Parameters follow their options with whitespace X inbetween. Each option must be given as a separate argument. X X -A disables automatically putting uncovered Ace cards X on the appropriate pile. Note that, in any case, it is X not allowed to put an Ace onto a stack, as this could lead X to building stacks which are too big to display with 25 lines. X X -B count X Batch mode. The requested number of games is played and X the average number of cards promoted to the ace piles is X written to the standard output. No other I/O is performed. X X -C disable the "click" for silent games X X -D enable special debugging commands which, among other things, X allow one to cheat X X -R seed X set the random seed to the designated value X X COMMANDS X H or ? display a Help screen X X ^L (control-L) redraws the screen X X A Automatic mode. Plays the game until nothing useful X remains to be done, or until any key is struck. X X B Boss key. The screen is blanked and the current position X is saved. When the game is started again in the usual X way, this saved game will be automatically restored and X the save file deleted. X X C Continuous mode. The computer plays games automatically X until a key is struck. Two statistics are displayed: X the number of games already played, and the total number X of aces which have been promoted to the ace piles. X X M Move a card from the deck or a stack to a stack or an X ace pile. X X Q Quit this game, with the opportunity to play another. X X S Suggest a possible move. Hitting this key multiple times X results in multiple suggestions being displayed. When X there is nothing interesting left to do, it will suggest X "Thumb". X X T Thumb. Remove the top 3 cards from the face-down deck X and lay them face-up on the face-up deck. X X U Undo. This can be used all the way back to the start X of the current game. X X Z Debug. This is only enabled when the -D option has X been given on the command line. There is a sub-menu X of commands available, including a (very brief) Help X summary. X X The Move command takes two parameters: source and destination. X Possible sources are: D for the Deck of face-up cards; and a X number from 1 to 7 inclusive, meaning the corresponding stack. X Possible destinations are the stacks (1-7) and A for the X appropriate ace pile. For instance, to move the visible card X from the face-up deck to stack 4, one types the three characters: X "MD4". Actually, the "M" character itself is optional, which X explains why the "debug" command isn't invoked with a "D". X X BUGS X Slow. X Doesn't use termcap for maximum portability. X The program's play is simplistic, with no concept of strategy. X X X FILES X klondike.sav Position is checkpointed here when the Boss key is used. X klondike.sv? Position checkpointed here with the "S" debug command. X "?" can be any (upper-case) character legal in your X filesystem. X X ACKNOWLEDGEMENT X The inspiration, name, and user interface were lifted X wholesale from a game copyrighted in 1985 by Allyn Wade. X X VERSION X 1.41 -- 26 November, 1990 X X AUTHOR X Norman H. Azadian X naz@hslrswi X SHAR_EOF true || echo 'restore of klondike.man failed' rm -f _shar_wnt_.tmp fi # ============= README ============== if test -f 'README' -a X"$1" != X"-c"; then echo 'x - skipping README (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp echo 'x - extracting README (Text)' sed 's/^X//' << 'SHAR_EOF' > 'README' && XThis package is the Unix port of Norman H. Azadian's DOS klondike Xprogram. To test, just mv Makefile.dist to Makefile, and make. XTo install, su root, and then make install. Needs a 25-line term Xwith at least 80 cols. WILL NOT WORK ON SYSTEMS THAT DO NOT IM- XPLEMENT THE STTY -G OPTION (TSK, TSK). UNLESS YOU LIKE HAVING A XLOCKED UP KEYBOARD, DON'T EVEN THINK OF TRYING KLONDIKE ON SUCH A XSYSTEM. X XIt's a nice card game, but a pretty rough hack for Unix. X X-Richard Goerwitz SHAR_EOF true || echo 'restore of README failed' rm -f _shar_wnt_.tmp fi # ============= Makefile.dist ============== if test -f 'Makefile.dist' -a X"$1" != X"-c"; then echo 'x - skipping Makefile.dist (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp echo 'x - extracting Makefile.dist (Text)' sed 's/^X//' << 'SHAR_EOF' > 'Makefile.dist' && XPROGNAME = klondike X X# Please edit these to reflect your local file structure & conventions. XDESTDIR = /usr/local/bin XOWNER = bin XGROUP = bin X XMAN = klondike.man XSRC = klondike.icn kloncon.icn klonsub.icn XLIB = itlib.icn getchlib.icn iscreen.icn X XSHELL = /bin/sh X X$(PROGNAME): $(SRC) $(LIB) X icont -Si 1000 -Sn 2000 -o $(PROGNAME) $(SRC) $(LIB) X X# Pessimistic assumptions regarding the environment (in particular, X# I don't assume you have the BSD "install" shell script). Xinstall: $(PROGNAME) X @sh -c "test -d $(DESTDIR) || (mkdir $(DESTDIR) && chmod 755 $(DESTDIR))" X cp $(PROGNAME) $(DESTDIR)/ X chgrp $(GROUP) $(DESTDIR)/$(PROGNAME) X chown $(OWNER) $(DESTDIR)/$(PROGNAME) X @echo "\nInstallation done.\n" SHAR_EOF true || echo 'restore of Makefile.dist failed' rm -f _shar_wnt_.tmp fi rm -f _shar_seq_.tmp echo You have unpacked the last part exit 0 From icon-group-request@arizona.edu Mon Dec 10 22:09:27 1990 Resent-From: icon-group-request@arizona.edu Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP id AA23425; Mon, 10 Dec 90 22:09:27 -0700 Received: from ucbvax.Berkeley.EDU by Arizona.edu; Mon, 10 Dec 90 22:08 MST Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA11002; Mon, 10 Dec 90 21:02:50 -0800 Received: from USENET by ucbvax.Berkeley.EDU with netnews for icon-group@arizona.edu (icon-group@arizona.edu) (contact usenet@ucbvax.Berkeley.EDU if you have questions) Resent-Date: Mon, 10 Dec 90 22:09 MST Date: 11 Dec 90 03:15:50 GMT From: midway!ellis.uchicago.edu!goer@handies.ucar.edu Subject: continuation of the code orgy Sender: icon-group-request@arizona.edu Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: Message-Id: <1990Dec11.031550.9454@midway.uchicago.edu> Organization: University of Chicago X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.edu I get annoyed when software requires that I be in this or that directory, and refuses to poke around a bit, looking for files. To help remedy the deficiency, I wrote the procedure appended below. Right now I've only tested it under Unix and MS-DOS. I'd love it if someone would repost with additions to make it work under other operating systems. -Richard (goer@sophist.uchicago.edu) ############################################################################ # # Name: getpaths.icn # # Title: suspend elements in path environment variable # # Author: Richard L. Goerwitz # # Version: 1.3 # ############################################################################ # # Suspends, in turn, the paths supplied as args to getpaths(), # then all paths in the PATH environment variable. A typical # invocation might look like: # # open(getpaths("/usr/local/lib/icon/procs") || filename) # # Note that getpaths() will be resumed in the above context until # open succeeds in finding an existing, readable file. Getpaths() # can take any number of arguments. # ############################################################################ # # Requires: UNIX or MS-DOS # ############################################################################ procedure getpaths(base_paths[]) local paths, p static sep, trailer, trimmer initial { if find("UNIX", &features) then { sep := ":" trailer := "/" trimmer := cset(trailer || " ") } else if find("MS-DOS", &features) then { sep := ";" trailer := "\\" trimmer := cset(trailer || " ") } else stop("getpaths: OS not supported.") } suspend !base_paths paths := getenv("PATH") \paths ? { tab(match(sep)) while p := 1(tab(find(sep)), move(1)) do suspend ("" ~== trim(p,trimmer)) || trailer return ("" ~== trim(tab(0),trimmer)) || trailer } end From icon-group-request@arizona.edu Tue Dec 11 02:07:46 1990 Resent-From: icon-group-request@arizona.edu Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP id AA29311; Tue, 11 Dec 90 02:07:46 -0700 Received: from ucbvax.Berkeley.EDU by Arizona.edu; Tue, 11 Dec 90 02:07 MST Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA15203; Tue, 11 Dec 90 00:54:35 -0800 Received: from USENET by ucbvax.Berkeley.EDU with netnews for icon-group@arizona.edu (icon-group@arizona.edu) (contact usenet@ucbvax.Berkeley.EDU if you have questions) Resent-Date: Tue, 11 Dec 90 02:07 MST Date: 11 Dec 90 08:50:41 GMT From: zaphod.mps.ohio-state.edu!usc!samsung!munnari.oz.au!goanna!ok@tut.cis.ohio-state.edu Subject: RE: continuation of the code orgy Sender: icon-group-request@arizona.edu Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: Message-Id: <4482@goanna.cs.rmit.oz.au> Organization: Comp Sci, RMIT, Melbourne, Australia X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.edu References: <1990Dec11.031550.9454@midway.uchicago.edu> In article <1990Dec11.031550.9454@midway.uchicago.edu>, goer@ellis.uchicago.edu (Richard L. Goerwitz) writes: > paths := getenv("PATH") $PATH is for *programs*. Data files do not belong there. A better approach would be to allow $env substitution in the argument to getpaths, e.g. getpaths("$HOME/lib/foo:$PROJECT/lib", file) -- The Marxists have merely _interpreted_ Marxism in various ways; the point, however, is to _change_ it. -- R. Hochhuth. From goer%sophist@gargoyle.uchicago.edu Tue Dec 11 07:23:38 1990 Resent-From: goer%sophist@gargoyle.uchicago.edu Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP id AA09506; Tue, 11 Dec 90 07:23:38 -0700 Return-Path: goer@sophist.uchicago.edu Received: from gargoyle.uchicago.edu by Arizona.edu; Tue, 11 Dec 90 07:23 MST Received: by gargoyle.uchicago.edu from sophist (sophist.uchicago.edu) (4.0/1.14) id AA23936; Tue, 11 Dec 90 08:22:41 CST Received: by sophist (4.1/UofC3.1X) id AA09758; Tue, 11 Dec 90 08:26:00 CST Resent-Date: Tue, 11 Dec 90 07:23 MST Date: Tue, 11 Dec 90 08:26:00 CST From: Richard Goerwitz Subject: RE: continuation of the code orgy Resent-To: icon-group@cs.arizona.edu To: zaphod.mps.ohio-state.edu!usc!samsung!munnari.oz.au!goanna!ok@tut.cis.ohio-state.edu Cc: icon-group@arizona.edu Resent-Message-Id: Message-Id: <9012111426.AA09758@sophist> X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: zaphod.mps.ohio-state.edu!usc!samsung!munnari.oz.au!goanna!ok@tut.cis.ohio-state.edu X-Vms-Cc: icon-group@Arizona.edu $PATH is for *programs*. Data files do not belong there. A relevant consideration. BUT: Icon programs are often unpacked into user directories, and people aren't as careful about separating files into lib/src/bin as you might suppose (nor should they necessesarily be). A better approach would be to allow $env substitution in the argument to getpaths, e.g. getpaths("$HOME/lib/foo:$PROJECT/lib", file) I utilized the PATH environment variable because Unix and MS-DOS happen to share this feature. It would be easy enough to change the particular environment variable used, according to the OS, but when you start put- ting $STRINGS into the arguments, you are not going to be able to run the program under anything but Unix. What I'd really like to see at this point is some revisions to the code along the lines you suggested. Can this be done in a way that will make the program broadly useful? -Richard (goer@sophist.uchicago.edu) From icon-group-request@arizona.edu Tue Dec 11 14:54:42 1990 Resent-From: icon-group-request@arizona.edu Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP id AA27425; Tue, 11 Dec 90 14:54:42 -0700 Received: from ucbvax.Berkeley.EDU by Arizona.edu; Tue, 11 Dec 90 14:54 MST Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA01894; Tue, 11 Dec 90 13:47:05 -0800 Received: from USENET by ucbvax.Berkeley.EDU with netnews for icon-group@arizona.edu (icon-group@arizona.edu) (contact usenet@ucbvax.Berkeley.EDU if you have questions) Resent-Date: Tue, 11 Dec 90 14:54 MST Date: 11 Dec 90 21:42:51 GMT From: news@psuvax1.cs.psu.edu Subject: iconx.hdr size on a Sun-4. Sender: icon-group-request@arizona.edu Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: Message-Id: Organization: Penn State Computer Science X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.edu 12.8k is a little large. The changes below will reduce the size to 2.6k. Apply the patch below to src/icont/ixhdr.c, and add the following to config/unix/sun4/define.h: #define MaxHdr 2688 #define UseFakeFunctionsInHdr UseFakeFunctionsInHdr will replace some standard C library functions with smaller and simpler versions in ixhdr.c. This may have benefit for systems other than Sun-4s; I haven't tried. The real trick is to reduce the header to 20 bytes. -- Felix Lee flee@cs.psu.edu *** /tmp/,RCSt1a04604 Tue Dec 11 16:30:01 1990 --- ixhdr.c Tue Sep 11 19:22:57 1990 *************** *** 30,35 **** --- 30,61 ---- #define Iconx IconxPath #endif /* Iconx */ + #ifdef UseFakeFunctionsInHdr + /* fake functions to reduce executable size. */ + novalue exit(x) int x; { _exit(x); } + + /* small, inefficient strcpy(). */ + char * strcpy(a, b) register char * a; register char * b; + { + while (*a++ = *b++) ; + return a; /* note! this is incompatible with real strcpy */ + } + /* small, inefficient strlen(). */ + int strlen(s) char * s; + { + register char * p; + while (*p++) ; + return p - s; + } + /* small, inefficient strcat(). */ + char * strcat(a, b) register char * a; register char * b; + { + while (*a++) ; + while (*a++ = *b++) ; + return a; /* note! this is incompatible with real strcat */ + } + #endif UseFakeFunctionsInHdr + novalue main(argc, argv) int argc; char **argv; From icon-group-request@arizona.edu Thu Dec 13 05:27:38 1990 Resent-From: icon-group-request@arizona.edu Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP id AA13790; Thu, 13 Dec 90 05:27:38 -0700 Received: from ucbvax.Berkeley.EDU by Arizona.edu; Thu, 13 Dec 90 05:27 MST Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA17639; Thu, 13 Dec 90 04:18:03 -0800 Received: from USENET by ucbvax.Berkeley.EDU with netnews for icon-group@arizona.edu (icon-group@arizona.edu) (contact usenet@ucbvax.Berkeley.EDU if you have questions) Resent-Date: Thu, 13 Dec 90 05:27 MST Date: 12 Dec 90 13:37:46 GMT From: jvb@cs.duke.edu Subject: public domain/free version Sender: icon-group-request@arizona.edu Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: Message-Id: <661009065@helios.cs.duke.edu> Organization: Duke University Computer Science Dept.; Durham, N.C. X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.edu I will be teaching a programming languages course this Spring and am looking to teach a string manipulation language. ICON is one natural choice. However, I have a zero budget. This leaves me with awk as my only choice. I don't think it is bad choice, but ICON would be better. Is there a free ICON interpretter out there? Jack From icon-group-request@arizona.edu Thu Dec 13 06:30:54 1990 Resent-From: icon-group-request@arizona.edu Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP id AA15025; Thu, 13 Dec 90 06:30:54 -0700 Received: from ucbvax.Berkeley.EDU by Arizona.edu; Thu, 13 Dec 90 06:30 MST Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA20514; Thu, 13 Dec 90 05:25:11 -0800 Received: from USENET by ucbvax.Berkeley.EDU with netnews for icon-group@arizona.edu (icon-group@arizona.edu) (contact usenet@ucbvax.Berkeley.EDU if you have questions) Resent-Date: Thu, 13 Dec 90 06:30 MST Date: 12 Dec 90 17:01:31 GMT From: hub.ucsb.edu!anywhere!aks@ucsd.edu Subject: RE: public domain/free version Sender: icon-group-request@arizona.edu Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: Message-Id: <7794@hub.ucsb.edu> Organization: CCSE, Univ. of CA, Santa Barbara X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.edu References: <661009065@helios.cs.duke.edu> In <661009065@helios.cs.duke.edu> jvb@duke.cs.duke.edu (Jack V. Briner, Jr.) writes: >I will be teaching a programming languages course this Spring and am >looking to teach a string manipulation language. ICON is one natural >choice. However, I have a zero budget. This leaves me with awk as >my only choice. I don't think it is bad choice, but ICON would be better. >Is there a free ICON interpretter out there? For the benefit of others, here's Griswold's original posting announcing Version 8: From +comp.lang.icon Wed Dec 12 08:56:24 1990 From: ralph@CS.ARIZONA.EDU ("Ralph Griswold") Newsgroups: comp.lang.icon Subject: Version 8 of Icon for UNIX Message-ID: <9003311250.AA18283@megaron.cs.arizona.edu> Date: 31 Mar 90 12:50:35 GMT Distribution: inet Organization: The Internet Lines: 37 Version 8 of Icon for UNIX systems is now available. This implementation can be configured for a wide variety of UNIX systems. Configuration information is provided for 56 different systems, including the Sun Sparcstation, the DecStation, the NeXT, the DG AViiON, and the Cray-2. Configurations for new systems can be added with relative ease. The UNIX distribution includes source code, configuration files, documentation, the Icon program library (new in Version 8), and several auxiliary components of Icon. Version 8 of Icon for UNIX systems can be obtained by anonymous FTP to cs.arizona.edu. After connecting, cd /icon/v8. Get READ.ME there for more information. If you do not have FTP access or prefer to obtain a magnetic tape and printed documentation, Version 8 of Icon for UNIX can be ordered ~from: Icon Project Department of Computer Science Gould-Simpson Building The University of Arizona Tucson, AZ 85721 602 621-2018 (voice) 602 621-4246 (FAX) The price is $30, payable in US dollars with a check written on a bank in the United States. Orders also can be charged to MasterCard or Visa. This price includes shipping by parcel post in the United States, Canada, and Mexico. Add $10 for air mail delivery to other countries. Please direct any questions to me, not to icon-project or icon-group. Ralph Griswold / Dept of Computer Science / Univ of Arizona / Tucson, AZ 85721 +1 602 621 6609 ralph@cs.arizona.edu uunet!arizona!ralph -- Alan Stebbens From goer%sophist@gargoyle.uchicago.edu Thu Dec 13 15:50:14 1990 Resent-From: goer%sophist@gargoyle.uchicago.edu Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP id AA07464; Thu, 13 Dec 90 15:50:14 -0700 Return-Path: goer@sophist.uchicago.edu Received: from gargoyle.uchicago.edu by Arizona.edu; Thu, 13 Dec 90 15:49 MST Received: by gargoyle.uchicago.edu from sophist (sophist.uchicago.edu) (4.0/1.14) id AA11262; Thu, 13 Dec 90 16:49:36 CST Received: by sophist (4.1/UofC3.1X) id AA02207; Thu, 13 Dec 90 16:52:40 CST Resent-Date: Thu, 13 Dec 90 15:49 MST Date: Thu, 13 Dec 90 16:52:40 CST From: Richard Goerwitz Subject: Iconish b-trees Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: Message-Id: <9012132252.AA02207@sophist> X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.edu Has anyone worked on b-tree algorithms for use in Icon - i.e. on b-trees which use hash tables or other built-in Iconish data struc- tures, as part of their implementation. I'm just curious whether I need to think this stuff through from scratch. -Richard From goer%sophist@gargoyle.uchicago.edu Thu Dec 13 18:05:50 1990 Resent-From: goer%sophist@gargoyle.uchicago.edu Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP id AA10873; Thu, 13 Dec 90 18:05:50 -0700 Return-Path: goer@sophist.uchicago.edu Received: from gargoyle.uchicago.edu by Arizona.edu; Thu, 13 Dec 90 18:05 MST Received: by gargoyle.uchicago.edu from sophist (sophist.uchicago.edu) (4.0/1.14) id AA14286; Thu, 13 Dec 90 19:05:13 CST Received: by sophist (4.1/UofC3.1X) id AA02487; Thu, 13 Dec 90 19:08:17 CST Resent-Date: Thu, 13 Dec 90 18:05 MST Date: Thu, 13 Dec 90 19:08:17 CST From: Richard Goerwitz Subject: Iconish b-trees Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: Message-Id: <9012140108.AA02487@sophist> X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.edu Blasted noisy lines. I'll try again. Has anyone given any thought to the question of how b-trees might best be implemented in Icon, taking advantage data structures like tables and sets? -Richard (goer@sophist.uchicago.edu) From fps!mis.mcw.edu!mis.mcw.edu!TENAGLIA@uwm.edu Sat Dec 15 10:36:39 1990 Received: from uwm.edu by megaron.cs.arizona.edu (5.61/15) via SMTP id AA24856; Sat, 15 Dec 90 10:36:39 -0700 Received: by uwm.edu; id AA04923; Sat, 15 Dec 90 11:36:30 -0600 Received: from mis.mcw.edu by fps.mcw.edu (DECUS UUCP ///1.2a/2.5/); Sat, 15 Dec 90 10:55:06 CDT Received: by mis.mcw.edu with UUCP/PMDF (DECUS UUCP); Sat, 15 Dec 1990 07:36 CDT Date: Sat, 15 Dec 1990 07:36 CDT From: Chris Tenaglia - 257-8765 Subject: Draw Poker Game To: icon-group@cs.arizona.edu Message-Id: <67EEF267C0600950@mis.mcw.edu> X-Organization: Medical College of Wisconsin MIS Department (Milwaukee, WI) X-Envelope-To: icon-group@cs.arizona.edu X-Vms-To: IN%"icon-group@cs.arizona.edu" Since the submission of the solitaire game, I felt it might be nice if I could contribute one. Here's a draw poker game. I use ICON on VAX/VMS 5.2 with VT terminals, so I do everything with ANSI escape sequences. I also realize that I could have done some of the table manipulations more efficiently, but I thought in this case, tab["key"] := something, helped the readability of the code. Invoke it with ICONX DRAW [credits]. The parameter is how much virtual money you want to start with. 3 is default. Have fun! Chris Tenaglia (System Manager) | Medical College of Wisconsin 8701 W. Watertown Plank Rd. | Milwaukee, WI 53226 (414)257-8765 | tenaglia@mis.mcw.edu, mcwmis!tenaglia ######################################################### # # # DRAW.ICN 12/15/90 BY TENAGLIA # # # # SIMPLE BUT FUN DRAW POKER GAME. WORKS ON ANSI SCREEN. # # USAGE : ICONX DRAW [starting credits] # # # ######################################################### global money, message procedure main(param) money := integer(param[1]) | 3 write("\e[2J\e[2H \e#3\e[1;7mDRAW : Nothing Wild\e[m") write(" \e#4\e[1;7mDRAW : Nothing Wild\e[m") repeat { deck := shuffle() message := "" hand := [] every 1 to 5 do put(hand,pop(deck)) display(hand,1,4) repeat { keep := obtain("\e[12;1fKeep which ones (1 2 3 4 5):\e[J") if map(input("\e[12;50fAre you sure y/n :\e[K"))[1] == "y" then break } all := set() ; every i := 1 to 5 do insert(all,i) every delete(all,integer(!keep)) every hand[!all] := pop(deck) money +:= evaluate(hand) display(hand,1,15) if map(input("\e[23;1fAnother game? y/n :\e[K"))[1] ~== "y" then break } write("\e[2J\e[H") end # # THIS SECTION OBTAINS THE VALIDATES INPUT # procedure obtain(prompt) bad := 0 repeat { nums := parse(input(prompt),' \t,') every num := !nums do { integer(num) | { input(num || " not a number. Press ") ; bad := 1 ; next } (integer(num) > 0) | { input(num || " must be between 1 and 5. Press ") ; bad := 1 ; next } (integer(num) < 6) | { input(num || " must be between 1 and 5. Press ") ; bad := 1 ; next } } (bad = 1) | return nums } end # # THIS ROUTINE DISPLAYS THE CURRENT HAND AT THE GIVEN X,Y COORDINATES # procedure display(cards,x,y) all := [] every card := !cards do { j := y if find(card[2],"CS") then card := "\e[1;7m" || card || "\e[m" shape := ["\e["||(j+:=1)||";"||x||"f\e(0lqqqqqqqk\e(B"] put(shape,"\e["||(j+:=1)||";"||x||"f\e(0x " || card || " x\e(B") put(shape,"\e["||(j+:=1)||";"||x||"f\e(0x x\e(B") put(shape,"\e["||(j+:=1)||";"||x||"f\e(0x x\e(B") put(shape,"\e["||(j+:=1)||";"||x||"f\e(0x x\e(B") put(shape,"\e["||(j+:=1)||";"||x||"f\e(0x " || card || " x\e(B") put(shape,"\e["||(j+:=1)||";"||x||"f\e(0mqqqqqqqj\e(B") put(all,shape) x +:= 14 } while shape := pop(all) do every writes(!shape) writes(message,"\e[",y+2,";",x-3,"fCredits\e[K") writes("\e[",y+3,";",x-5,"f \e[1m",right(money,7),"\e[m\e[K") end # # THIS ROUTINE SHUFFLES THE CARD DECK # procedure shuffle() static faces, suits local cards initial { &random := map(&clock,":","7") # initial on multiple shuffles faces := ["2","3","4","5","6","7","8","9","T","J","Q","K","A"] suits := ["D","H","C","S"] } cards := [] every put(cards,!faces || !suits) swaps := 52 + ?12 every 1 to swaps do cards[?52] :=: cards[?52] return cards end # # THIS SECTION EVALUATES THE FINAL HAND, TALLIES WINNINGS OR LOOSINGS # procedure evaluate(cards) static hash1,hash2 initial { hash1 := "23456789TJQKA" hash2 := "CSHD" } temp := table(0) ; suit := table(0) ; result := table(0) four := 0 ; three := 0 ; twopair := 0 ; job := 0 ; points := -1 flush := 0 ; full := 0 ; royal := 0 ; straight:= 0 ; pair:= 0 every card := !cards do temp[card[1]] +:= 1 every tmp := key(temp) do case temp[tmp] of { 4 : { result["four"] := 1 ; result["job"] := 1 } 3 : { result["three"] := 1 ; result["job"] := 1 } 2 : { result["pair"] +:= 1 ; result["job"] := if find(tmp,hash1) > 9 then 1 } } if result["pair"] = 2 then { result["twopair"] := 1 ; result["job"] := 1 } every card := !cards do suit[card[2]] +:= 1 every tmp := key(suit) do if suit[tmp] = 5 then { result["flush"] := 1 ; result["job"] := 1 } tmp := sort(cards) ; test := "" every card := !tmp do test ||:= card[1] if (result["three"] = 1) & (result["pair"] = 1) then { result["full"] := 1 ; result["job"] := 1 } if find(test,hash1) then { result["straight"] := 1 result["job"] := 1 if test[1] == "T" then result["royal"] := 1 } if result["job"] = 1 then points +:= 1 if result["twopair"] = 1 then points +:= 1 if result["three"] = 1 then points +:= 5 if result["full"] = 1 then points +:= 10 if result["flush"] = 1 then points +:= 10 if result["straight"]= 1 then points +:= 10 if result["four"] = 1 then points +:= 100 if result["royal"] = 1 then points +:= 500 message := "\e[14;1fHand Evaluation -> " every thing := key(result) do message ||:= thing || ", " return points end # # THIS ROUTINE PARSES A STRING WITH RESPECT TO SOME DELIMITER # procedure parse(line,delims) static chars chars := &cset -- delims tokens := [] line ? while tab(upto(chars)) do put(tokens,tab(many(chars))) return tokens end # # THIS ROUTINE PROMPTS FOR INPUT AND RETURNS A STRING # procedure input(prompt) writes(prompt) return read() end From icon-group-request@arizona.edu Sun Dec 16 11:10:25 1990 Resent-From: icon-group-request@arizona.edu Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP id AA28760; Sun, 16 Dec 90 11:10:25 -0700 Received: from ucbvax.Berkeley.EDU by Arizona.edu; Sun, 16 Dec 90 11:10 MST Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA03555; Sun, 16 Dec 90 09:50:35 -0800 Received: from USENET by ucbvax.Berkeley.EDU with netnews for icon-group@arizona.edu (icon-group@arizona.edu) (contact usenet@ucbvax.Berkeley.EDU if you have questions) Resent-Date: Sun, 16 Dec 90 11:10 MST Date: 15 Dec 90 02:04:05 GMT From: snorkelwacker.mit.edu!usc!zaphod.mps.ohio-state.edu!mips!daver!kcdev!obrien@bloom-beacon.mit.edu Subject: klondike Sender: icon-group-request@arizona.edu Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: Message-Id: <1259@kcdev.UUCP> Organization: AT&T Kansas City, MO. X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.edu Would some kind person send me sector 5 of the unix version of klondike. I can not seem to get the one I captured to download to my machine. Please send to obrien@spam because this feed appears to be about gone. -- | John D. O'Brien AT&T Communications Kansas City, MO 64106 | | Ph(816)654-4085 Home(816)229-7648 | | Email: obrien@kcdev.UUCP ATTMail: attmail!kc1sur!jdobrien | | $include {std_disclaimer.h} "Please don't drink and drive" | From icon-group-request@arizona.edu Sun Dec 16 12:04:55 1990 Resent-From: icon-group-request@arizona.edu Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP id AA29965; Sun, 16 Dec 90 12:04:55 -0700 Received: from ucbvax.Berkeley.EDU by Arizona.edu; Sun, 16 Dec 90 12:04 MST Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA06641; Sun, 16 Dec 90 10:56:14 -0800 Received: from USENET by ucbvax.Berkeley.EDU with netnews for icon-group@arizona.edu (icon-group@arizona.edu) (contact usenet@ucbvax.Berkeley.EDU if you have questions) Resent-Date: Sun, 16 Dec 90 12:04 MST Date: 15 Dec 90 19:21:20 GMT From: midway!quads.uchicago.edu!goer@uunet.uu.net Subject: RE: Draw Poker Game Sender: icon-group-request@arizona.edu Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: Message-Id: <1990Dec15.192120.1009@midway.uchicago.edu> Organization: University of Chicago X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.edu References: <67EEF267C0600950@mis.mcw.edu> In article <67EEF267C0600950@mis.mcw.edu> TENAGLIA@mis.mcw.edu (Chris Tenaglia - 257-8765) writes: >global money, message >procedure main(param) > money := integer(param[1]) | 3 > write("\e[2J\e[2H \e#3\e[1;7mDRAW : Nothing Wild\e[m") ^^^^^^^^^^ ^^^^^^^^^^^^ ^^^^^ I love to try to port people's things to Unix, but it's sometimes pretty hard. The code above is part of a really neat game, and I like it a lot. But unless a person happens to know ANSI escape se- quences like the back of his or her hand, it's kinda hard to know what is going on. It's also a fact that most ANSI terminals don't really implement the full, exact ANSI standard, and in general peo- ple (at least here at the U of Chicago) are using Wyse, Televideo, or VT-100 terminals (or emulators). It's hard to say this, especially when the code is otherwise so clear and clean, but my own personal observation is that code which assumes hard-coded screen control 1) is hard to read, 2) is harder to main- tain, and 3) is very tedious to port. One solution (the one used in the klondike game) is to make all the screen control sequences into global variables, and put them together in one place, so they can easily be altered. If the global variables are mnemonic, this solves 1 and 2, but leaves 3 still up in the air. (I've written a lot of code that has all three problems, so don't take this as a flame.) The workability of the "klondike" solution is evinced by the fact that I was able to port it to Unix in a very short period of time and repost. I admit that the repost was something of a hack. When the next klondike version comes out I'll do a more serious job. The mnemonic global variables really helped. Another solution is to isolate screen control sequences in a single procedure, which would be called mnemonically. This solution is not perfect, because it is not always as easy to read as the "klondike" solution. But is does make maintenance a snap, and leaves would-be port-ers with very little work to do. I'll give a little example below that will show how things can be done this way, and yet kept readable: > write("\e[2J\e[2H \e#3\e[1;7mDRAW : Nothing Wild\e[m") output("clear") output("goto",1,2) writes(" ") output(whatever \e#3 does) output("bold-reverse") # or output("bold"); output("reverse") ??? write("DRAW : Nothing Wild") output("normal") By doing things this way, even someone who doesn't know the least bit about ANSI screen codes will be able to understand what is going on. What is more, no changes will be required if, say, some escape sequence needs to be changed. In fact, one could insert codes for a _whole dif- ferent terminal_ and it wouldn't require changing a single scratch of the above code. All changes would be isolated within the output pro- cedure. I admit that things are more bulky this way. But you don't have to have your ANSI chart out while programming. And in fact, you don't even have to think about what sort of terminal you're using. Nor does anyone else who reads your code. The sequence output("clear") is infinitely more clear, portable, and maintainable than "\e[2J"! One more bit that might be useful to inject here: Most terminals can han- dle 24 lines of text. Not all can handle 25. To hit the majority of users, keep screen I/O within a range of 24 lines. I hope that this will help, and not seem like a gratuitous flame! -Richard From mlfarm!ron@hsi.hsi.com Mon Dec 17 05:48:21 1990 Received: from hsi.hsi.com by megaron.cs.arizona.edu (5.61/15) via SMTP id AA29256; Mon, 17 Dec 90 05:48:21 -0700 Received: by hsi.hsi.com (5.61+++/1.34) id AA29734; Mon, 17 Dec 90 07:46:30 -0500 Received: by mlfarm.com (smail2.5) id AA09251; 17 Dec 90 06:16:37 EST (Mon) To: icon-group@cs.arizona.edu In-Reply-To: goer@quads.uchicago.edu's message of Dec 15 19:21:20 GMT Subject: RE: Draw Poker Game Message-Id: <9012170616.AA09251@mlfarm.com> Date: 17 Dec 90 06:16:37 EST (Mon) From: mlfarm!ron@hsi.hsi.com (Ronald Florence) I'd like to add a strong second to Richard Goerwitz's comments on code portability. One of the most welcome features of Icon is the implementation independence of the code. With few exceptions, Icon code works on a broad range of machines. How depressing, then, to discover valuable utilites and clever games which require hours of porting with an editor because of hard-coded screen-control escape sequences. Richard Goerwitz's Icon termcap library, which includes ms-dos entries, is one solution. For those who don't want to use the termcap code, screen control sequences can be isolated in global strings or functions, so that porting doesn't require line-by-line changes of an entire program. While I'm griping, I'd urge that program instructions omit implementation-dependent exceptions: > # DRAW.ICN 12/15/90 BY TENAGLIA # > # # > # SIMPLE BUT FUN DRAW POKER GAME. WORKS ON ANSI SCREEN. # > # USAGE : ICONX DRAW [starting credits] # If I'm not wrong, the need for `iconx' before the program name is confined to ms-dos and VMS. Users of those systems surely know how to run Icon programs on their systems. My comments are not in any way intended as a flame of Chris Tenaglia's excellent game, which would probably work unchanged on some of the terminals here. With a few changes that would be easy when the code is written, though time-consuming later, the game would work right off the icon-group mailing list on any terminal and operating system running Icon. -- Ronald Florence ron@mlfarm.com From icon-group-request@arizona.edu Mon Dec 17 06:49:02 1990 Resent-From: icon-group-request@arizona.edu Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP id AA00502; Mon, 17 Dec 90 06:49:02 -0700 Received: from ucbvax.Berkeley.EDU by Arizona.edu; Mon, 17 Dec 90 06:48 MST Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA02160; Mon, 17 Dec 90 05:34:50 -0800 Received: from USENET by ucbvax.Berkeley.EDU with netnews for icon-group@arizona.edu (icon-group@arizona.edu) (contact usenet@ucbvax.Berkeley.EDU if you have questions) Resent-Date: Mon, 17 Dec 90 06:48 MST Date: 17 Dec 90 13:15:23 GMT From: eru!hagbard!sunic!sics.se!sics!soder@bloom-beacon.mit.edu Subject: Exit codes in SunOS 4.1 Sender: icon-group-request@arizona.edu Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: Message-Id: Organization: Swedish Institute of Microelectronics, Kista X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.edu Has anybody else noticed this: Problem: Icon programs return spurious (?) exit codes under recent versions of SunOS. When terminating normally the exit code is an unpredictable small integer, sometimes even negative (as reported by /bin/csh). The problem didn't appear until I ported some software we developed to SunOS 4.0.1 for the Sun 386i. Now the same symptom appears when porting the software to a SPARCstation 1+ under SunOS 4.1. (The 4.0.1 for the 386i is more similar to 4.1 than 4.0.3 for the SPARC.) My conclusion from browsing the Icon source is that even a 'procedure main (...)' that just flows out through its 'end' executes a proper Unix 'exit'. Can anybody confirm that? (Under these OSes a C program that just flows out through its final brace does not return a predictable return code.) Reply to me and I'll post a summary. Thanks. Hakan ---------------------------------------------------- Hakan Soderstrom Phone: +46 (8) 752 1138 NMP-CAD Fax: +46 (8) 750 8056 P.O. Box 1193 E-mail: soder@nmpcad.se S-164 22 Kista, Sweden -- ---------------------------------------------------- Hakan Soderstrom Phone: +46 (8) 752 1138 NMP-CAD Fax: +46 (8) 750 8056 P.O. Box 1193 E-mail: soder@nmpcad.se S-164 22 Kista, Sweden From goer%sophist@gargoyle.uchicago.edu Mon Dec 17 08:54:29 1990 Resent-From: goer%sophist@gargoyle.uchicago.edu Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP id AA03897; Mon, 17 Dec 90 08:54:29 -0700 Return-Path: goer@sophist.uchicago.edu Received: from gargoyle.uchicago.edu by Arizona.edu; Mon, 17 Dec 90 08:53 MST Received: by gargoyle.uchicago.edu from sophist (sophist.uchicago.edu) (4.0/1.14) id AA08765; Mon, 17 Dec 90 09:53:13 CST Received: by sophist (4.1/UofC3.1X) id AA01710; Mon, 17 Dec 90 09:56:15 CST Resent-Date: Mon, 17 Dec 90 08:53 MST Date: Mon, 17 Dec 90 09:56:15 CST From: Richard Goerwitz Subject: followup on games Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: Message-Id: <9012171556.AA01710@sophist> X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.edu I'd like to add a strong second to Richard Goerwitz's comments on code portability. One of the most welcome features of Icon is the implementation independence of the code. With few exceptions, Icon code works on a broad range of machines. How depressing, then, to discover valuable utilites and clever games which require hours of porting with an editor because of hard-coded screen-control escape sequences. Richard Goerwitz's Icon termcap library, which includes ms-dos entries, is one solution... ...albeit a slightly clumsy one for DOS. For DOS the only advantage to us- ing these routines is that they allow you to move your code unaltered over to Unix. And you don't have to know the slightest thing about Unix, other than the basic termcap codes (e.g. "so" for boldface, etc.). Termcap files, though, don't know about color, about the difference between bold and re- verse video, and can't take advantage of really fancy terminal features. It's a mixed bag. I'll be glad to send the full DOS/UNIX Icon termlib-type routines in their latest incarnation to anyone that asks. The most recent changes have been a full DOS implementation. The main point is just to isolate screen control codes in a single proce- dure, and to output them via a separate routine. Anyone who does this is going to make porting his or her code to another OS or output device a real snap. While I'm griping, I'd urge that program instructions omit implementation-dependent exceptions: > # DRAW.ICN 12/15/90 BY TENAGLIA # > # # > # SIMPLE BUT FUN DRAW POKER GAME. WORKS ON ANSI SCREEN. # > # USAGE : ICONX DRAW [starting credits] # If I'm not wrong, the need for `iconx' before the program name is confined to ms-dos and VMS. Users of those systems surely know how to run Icon programs on their systems. I've only used Icon under Unix and MS-DOS. I'm sure that's pretty typical. I mean, few have run it under more than one or two operating systems. I gather that Chris is MS-DOS/VMS. Just so happens that these don't support direct execution of Icon programs (as you point out). (For those who don't know, "direct execution" means, in practical terms, that you can just type the name of the program, and don't need to type in "iconx"). My comments are not in any way intended as a flame of Chris Tenaglia's excellent game, which would probably work unchanged on some of the terminals here. Yes, we don't want to discourage Chris from posting! He's written some very interesting stuff. And he's one of the few VMS users we see posting, so it is very nice to have his input (esp. for people like me who hardly know VMS from MVS). Incidentally, the game runs here on my Xenix console. -Richard From fps!mis.mcw.edu!mis.mcw.edu!TENAGLIA@uwm.edu Mon Dec 17 15:15:35 1990 Received: from uwm.edu by megaron.cs.arizona.edu (5.61/15) via SMTP id AA17643; Mon, 17 Dec 90 15:15:35 -0700 Received: by uwm.edu; id AA08233; Mon, 17 Dec 90 16:15:03 -0600 Received: from mis.mcw.edu by fps.mcw.edu (DECUS UUCP ///1.2a/2.5/); Mon, 17 Dec 90 14:13:51 CDT Received: by mis.mcw.edu with UUCP/PMDF (DECUS UUCP); Mon, 17 Dec 1990 13:43 CDT Date: Mon, 17 Dec 1990 13:43 CDT From: Chris Tenaglia - 257-8765 Subject: crt handler library To: icon-group@cs.arizona.edu Message-Id: <2D9076E640200646@mis.mcw.edu> X-Organization: Medical College of Wisconsin MIS Department (Milwaukee, WI) X-Envelope-To: icon-group@cs.arizona.edu X-Vms-To: IN%"icon-group@cs.arizona.edu" Well, appararently raw ansi escape sequences in write() statements are not as commonplace as I thought. I put together a video manipulator library collection. Since I only have VT terminals and ansi to work with, I coded in only those cases. Someone else will have to fill in the rest. These procedures generate escape sequence strings for write() commands. In places where this doesn't apply, one would have them return "", and generate the desired side effect. For example,... write(crt_dark(),crt_clear(),crt_upper_half(),crt_mode("high","inverse"), center("Header",39),crt_mode("normal")) write(crt_lower_half(),crt_mode("high","inverse"),center("Header",39), crt_mode("normal")) Would output the header to some screen in double sized characters centered at the top of the screen in bright, inverse video. This scenario requires a global variable called TERM that defines the terminal used. On unix systems a getenv() could probably generate sufficient clues to have this determined at run time. Granted, my draw poker game was a quick and dirty implementation. On VMS screen painting is so slow with ICON that I didn't want to further slow the application by adding layers of object oriented display managers. Thanx for the suggestions! Below are 162 lines of code, in 22 or so procedures. Have fun! Chris Tenaglia (System Manager) | Medical College of Wisconsin 8701 W. Watertown Plank Rd. | Milwaukee, WI 53226 (414)257-8765 | tenaglia@mis.mcw.edu, mcwmis!tenaglia # # CRT.ICN CREATED 12/17/90 BY TENAGLIA # # THIS IS A SCREEN FUNCTION LIBRARY. I AM SUBMITTING PARTS PERTAINING TO # VT,ANSI EMULATION. OTHERS, PLEASE FEEL FREE TO ADD YOURS. UNDER VT # TERMINAL EMULATION SPECIAL STRINGS BEGINNING WITH ESCAPE X'1B' START # SEQUENCES THAT DO USEFUL THINGS TO DISPLAYS. THE VT FUNCTIONS RETURN # THE ESCAPE SEQUENCES. OTHER VIDEO METHODS MAY PERFORM INTERRUPTS, PORT # OR I/O RETURNING "" TO ACCOMPLISH THE SAME THING. # global TERM # DEFINE A GLOBAL VARIABLE CALLED TERM procedure main() # IT DECLARES THE TERMINAL TYPE. "VT" IS TERM := "VT" # FOR DEC VT100,2XX,3XX,4XX SERIES. end # OTHERS MAY BE "X", "4014", "TTY", ETC,... procedure crt_error() stop("TERM as (",TERM,") not properly defined.") end procedure crt_clear() case TERM of { "VT" : return "\e[2J\e[H" # CLEAR SCREEN AND HOME default : crt_error() } end procedure crt_home() case TERM of { "VT" : return "\e[H" # MOVE CURSOR TO TOP OF SCREEN LEFT SIDE default : crt_error() } end procedure crt_goto(x,y) # SET CURSOR TO X(COLUMN) Y(ROW) SCREEN POSITION case TERM of { "VT" : return "\e[" || y || ";" || x || "f" default : crt_error() } end procedure crt_upper_half() # case TERM of { # TOP HALF OF DOUBLE WIDTH, DOUBLE HEIGHT CHARS "VT" : return "\e#3" # default : crt_error() } end procedure crt_lower_half() # case TERM of { # BOTTOM HALF OF DOUBLE WIDTH, DOUBLE HEIGHT "VT" : return "\e#4" # default : crt_error() } end procedure crt_mode(p1,p2,p3,p4,p5) # /p5 := "n/a" # THIS ROUTINE SETS THE OUTPUT /p4 := "n/a" # ATTRIBUTES FOR CHARACTERS. /p3 := "n/a" # SOME ENVIRONMENTS MAY USE /p2 := "n/a" # COLORS. /p1 := "n/a" # all := [p1,p2,p3,p4,p5] # case TERM of { # "VT" : { # seq := "\e[" # every mode := !all do # THESE CAN BE COMBINED MUCH case mode of # LIKE SETTING BITS. { # "normal : seq ||:= "0;" # NORMAL VIDEO "high" : seq ||:= "1;" # HIGH INTENSITY "dim" : seq ||:= "2;" # LOW INTENSITY "under" : seq ||:= "4;" # UNDERSCORED "blink" : seq ||:= "5;" # BLINKING "inverse" : seq ||:= "7;" # INVERSE VIDEO "conceal" : seq ||:= "8;" # INVISIBLE default : &null # IGNORE OTHERS } # seq[-1] := "m" # return seq # } # default : crt_error() } end procedure crt_graphic() # case TERM of { # TURN ON ANSI LINE GRAPHICS CHARACTERS "VT" : return "\e(0" # default : crt_error() } end procedure crt_nographic() # case TERM of { # TURN OFF ANSI LINE GRAPHICS CHARACTERS "VT" : return "\e(B" # default : crt_error() } end procedure crt_smooth() # case TERM of { # PUTS CRT IN SMOOTH SCROLLING MODE "VT" : return "\e[?4h" # default : crt_error() } end procedure crt_jump() # case TERM of { # PUTS CRT IN JUMP SCROLLING MODE "VT" : return "\e[?4l" # default : crt_error() } end procedure crt_scroll(t,b) # /b := "" # SET UP SCROLLING /t := "" # REGIONS ON THE SCREEN case TERM of { # T IS THE TOP MARGIN "VT" : { # B IS THE BOTTOM MARGIN if (t=="") & (b=="") then return "\e[r" # OMIT B, THEN BOTTOM OF if b=="" then return "\e[" || t || "r" # SCREEN IS BOTTOM MARGIN return "\e[" || t || ";" || b || "r" # OMIT B & T TO RESET TO } # NORMAL FULL SCREEN default : crt_error() } end procedure crt_erase_eol() # case TERM of { # ERASE CHARACTERS FROM CURSOR TO "VT" : return "\e[K" # END OF LINE default : crt_error() } end procedure crt_erase_sol() # case TERM of { # ERASE CHARACTERS FROM CURSOR TO "VT" : return "\e[1K" # START OF LINE default : crt_error() } end procedure crt_erase_eos() # case TERM of { # ERASE CHARACTERS FROM CURSOR TO "VT" : return "\e[J" # END OF SCREEN default : crt_error() } end procedure crt_erase_tos() # case TERM of { # ERASE CHARACTERS FROM CURSOR TO "VT" : return "\e[1J" # TOP OF SCREEN default : crt_error() } end procedure crt_light() # case TERM of { # MAKE SCREEN LIGHT BACKGROUND "VT" : return "\e[?5h" # default : crt_error() } end procedure crt_dark() # case TERM of { # MAKE SCREEN DARK BACKGROUND "VT" : return "\e[?5l" # default : crt_error() } end procedure crt_132() # case TERM of { # MAKE SCREEN 132 COLUMNS WIDE "VT" : return "\e[?3h" # default : crt_error() } end procedure crt_80() # case TERM of { # MAKE SCREEN 80 COLUMNS WIDE "VT" : return "\e[?3l" # default : crt_error() } end From goer%sophist@gargoyle.uchicago.edu Mon Dec 17 18:26:02 1990 Resent-From: goer%sophist@gargoyle.uchicago.edu Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP id AA23453; Mon, 17 Dec 90 18:26:02 -0700 Return-Path: goer@sophist.uchicago.edu Received: from gargoyle.uchicago.edu by Arizona.edu; Mon, 17 Dec 90 18:25 MST Received: by gargoyle.uchicago.edu from sophist (sophist.uchicago.edu) (4.0/1.14) id AA23714; Mon, 17 Dec 90 19:25:05 CST Received: by sophist (4.1/UofC3.1X) id AA02016; Mon, 17 Dec 90 19:28:06 CST Resent-Date: Mon, 17 Dec 90 18:25 MST Date: Mon, 17 Dec 90 19:28:06 CST From: Richard Goerwitz Subject: crt_dark() Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: Message-Id: <9012180128.AA02016@sophist> X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.edu write(crt_lower_half(),crt_mode("high","inverse"),center("Header",39), crt_mode("normal")) This approach is good. The better you hide terminal characteristics behind a high-level interface, the easier it will be to port your software. write(crt_dark(),crt_clear(),crt_upper_half()... One suggestion: Make crt_dark() and crt_clear() and crt_mode() into a single routine. That way I don't have to go try to modify all the different procedures. You could, of course, just do this: procedure output(s) case s of { "clear" : crt_clear() "dark" : crt_dark() "normal": etc.... This would make porting a snap, and I wouldn't even have to modify the crt_clear routine. To port your software to Unix, all I'd have to do is insert my own screen clearing routine in place of crt_clear(). Just some thoughts. -Richard From goer%sophist@gargoyle.uchicago.edu Mon Dec 17 22:30:04 1990 Resent-From: goer%sophist@gargoyle.uchicago.edu Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP id AA00811; Mon, 17 Dec 90 22:30:04 -0700 Return-Path: goer@sophist.uchicago.edu Received: from gargoyle.uchicago.edu by Arizona.edu; Mon, 17 Dec 90 22:29 MST Received: by gargoyle.uchicago.edu from sophist (sophist.uchicago.edu) (4.0/1.14) id AA00435; Mon, 17 Dec 90 23:29:17 CST Received: by sophist (4.1/UofC3.1X) id AA02212; Mon, 17 Dec 90 23:32:18 CST Resent-Date: Mon, 17 Dec 90 22:29 MST Date: Mon, 17 Dec 90 23:32:18 CST From: Richard Goerwitz Subject: termcap md/me Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: Message-Id: <9012180532.AA02212@sophist> X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.edu Hmmm. It's true that md and me are present in my termcap entries, but this isn't discussed in my man pages (Xenix). I note that the SunOS man pages for sophist here do discuss md/me. I'm no expert on termcap's history. -Richard From mlfarm!ron@hsi.hsi.com Tue Dec 18 07:17:16 1990 Received: from hsi.hsi.com by megaron.cs.arizona.edu (5.61/15) via SMTP id AA14911; Tue, 18 Dec 90 07:17:16 -0700 Received: by hsi.hsi.com (5.61+++/1.34) id AA18203; Tue, 18 Dec 90 09:15:33 -0500 Received: by mlfarm.com (smail2.5) id AA11465; 18 Dec 90 08:26:01 EST (Tue) To: icon-group@cs.arizona.edu In-Reply-To: Chris Tenaglia - 257-8765's message of Mon Dec 17 13:43 CDT Subject: crt handler library Message-Id: <9012180826.AA11465@mlfarm.com> Date: 18 Dec 90 08:26:01 EST (Tue) From: mlfarm!ron@hsi.hsi.com (Ronald Florence) Chris Tenaglia - 257-8765 writes: > Well, appararently raw ansi escape sequences in write() statements are not > as commonplace as I thought. I put together a video manipulator library > collection. Since I only have VT terminals and ansi to work with, I coded > in only those cases. Someone else will have to fill in the rest. > [...] This scenario requires > a global variable called TERM that defines the terminal used. On unix > systems a getenv() could probably generate sufficient clues to have this > determined at run time. Bravo to Chris for a quick and generous response to comments. His solution is a great improvement to the chaos of screen-writing code. Still, a problem remains ... Ms-dos and VMS implementations, like Chris', are written for systems which assume that screen displays are on a limited variety of terminals. Adding another terminal requires hand-coding another option in each case statement. Most Unix systems automatically determine the user's terminal-type at login, then use a database of terminal characteristics (termcap or terminfo) to look up the screen display sequences. For example, our small system here has ansi 25-line terminals, ansi 43-line terminals, a Wyse 150 emulating a Wyse50+, a Wyse 99gt emulating a vt220, various vt100 emulations, laptops emulating whatever their software can do, and occasional logins from odd places with odd terminals. Users expect all of these terminals to function with full-screen displays _automatically_. I'd like to see us arrive at a convention or library of display functions to simplify the porting of Icon code with full-screen displays. Perhaps the way to do it would be to include a lookup of &features in an initialization function, which would then toggle between a termcap library (for Unix systems), hard-coded ansi display strings (for ms-dos systems), and a case statement with a few options (for VMS systems). If we could develop such a library, porting a game like Chris' to Unix or ms-dos would require only the linking of an appropriate library during the make. Am I crazy or fascist to propose this? -- Ronald Florence ron@mlfarm.com From nowlin@iwtqg.att.com Tue Dec 18 09:31:54 1990 Message-Id: <9012181631.AA21106@megaron.cs.arizona.edu> Received: from att.att.com by megaron.cs.arizona.edu (5.61/15) via SMTP id AA21106; Tue, 18 Dec 90 09:31:54 -0700 From: nowlin@iwtqg.att.com Date: Tue, 18 Dec 90 09:34 CST Original-From: iwtqg!nowlin (Jerry D Nowlin +1 312 979 7268) To: icon-group@cs.arizona.edu Subject: Re: crt handler library > ... Perhaps the way to do it would be to include a lookup of > &features in an initialization function, which would then toggle > between a termcap library (for Unix systems), hard-coded ansi > display strings (for ms-dos systems), and a case statement with a > few options (for VMS systems). If we could develop such a library, > porting a game like Chris' to Unix or ms-dos would require only the > linking of an appropriate library during the make. > > Am I crazy or fascist to propose this? > -- > > Ronald Florence ron@mlfarm.com I frequently use the UNIX tput command with read pipes in Icon to define a series of terminal specific escape sequences before having a program do fancy stuff with screen output. If the list of screen attributes is relatively short this is a good way to populate a few global values at the start of UNIX programs. If there is some equivalent VMS command then UNIX and VMS could be handled easily. The PC is pretty standard and set definitions for PC screen attributes would make more sense. This would make implementing the above scheme relatively simple. Here's a small example of what I'm talking about: global CLEAR, ON, OFF procedure main() term_attr_set() write(CLEAR) write("\n\n\t",ON,"Happy",OFF," ~ ",ON,"Holidays",OFF,"\n\n") end procedure term_attr_set() CLEAR := \do_tput("clear") ON := \do_tput("smso") ON ||:= \do_tput("blink") OFF := \do_tput("sgr0") end procedure do_tput(attr) local cmd, in, ret cmd := "tput " || attr in := open(cmd,"rp") ret := read(in) close(in) return ret end Jerry Nowlin (...!att!iwtqg!nowlin) From callas@eris.enet.dec.com Tue Dec 18 09:36:24 1990 Received: from decpa.pa.dec.com by megaron.cs.arizona.edu (5.61/15) via SMTP id AA21263; Tue, 18 Dec 90 09:36:24 -0700 Received: by decpa.pa.dec.com; id AA27630; Tue, 18 Dec 90 08:17:35 -0800 Message-Id: <9012181617.AA27630@decpa.pa.dec.com> Received: from eris.enet; by decwrl.enet; Tue, 18 Dec 90 08:17:37 PST Date: Tue, 18 Dec 90 08:17:37 PST From: This message sent with 100% recycled bits 18-Dec-1990 1103 To: icon-group@cs.arizona.edu Subject: CRT handling Actually, on VMS systems, there is a termcap-like library of terminals, and it's easily extensible. Also, the C run-time library contains an implementation of curses. No doubt there's a way to code an application so that it'll not port between some unix and VMS, but I've tossed programs around with little trouble. Jon Callas From goer%sophist@gargoyle.uchicago.edu Tue Dec 18 13:43:48 1990 Resent-From: goer%sophist@gargoyle.uchicago.edu Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP id AA29612; Tue, 18 Dec 90 13:43:48 -0700 Return-Path: goer@sophist.uchicago.edu Received: from gargoyle.uchicago.edu by Arizona.edu; Tue, 18 Dec 90 13:42 MST Received: by gargoyle.uchicago.edu from sophist (sophist.uchicago.edu) (4.0/1.14) id AA16957; Tue, 18 Dec 90 14:42:45 CST Received: by sophist (4.1/UofC3.1X) id AA02520; Tue, 18 Dec 90 14:45:45 CST Resent-Date: Tue, 18 Dec 90 13:43 MST Date: Tue, 18 Dec 90 14:45:45 CST From: Richard Goerwitz Subject: RE: crt library Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: Message-Id: <9012182045.AA02520@sophist> X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.edu Jerry Nowlin writes: global CLEAR, ON, OFF procedure main() term_attr_set() write(CLEAR) write("\n\n\t",ON,"Happy",OFF," ~ ",ON,"Holidays",OFF,"\n\n") end procedure term_attr_set() CLEAR := \do_tput("clear") ON := \do_tput("smso") ON ||:= \do_tput("blink") OFF := \do_tput("sgr0") end etc... This is a very good solution. All we have to do in order to port the software to a new OS is to change this one procedure, term_attr_set(). Is it time for a repost of my itlib routines, with the DOS port, UNIX getch(), getche(), kbhit() hacks, and various support rou- tines (e.g. clear(), underline(), and other procedures meant to work even on magic cookie terminals)? The post would not be small. It would probably need to be sent out as a five-part shar, with a pro- mise to mail individual copies to people who can't unpack shell ar- chives. Should I post to alt.sources? Post at all? I expect that an energetic VMS user could easily code up a set of equivalent routines for that OS. The basic routines a) read the termcap database file, 2) check to see what terminal type the user is using, and then 3) make the codes in the terminal database available to the user via calls to a procedure called getval(). Output of codes is done through a separate iputs() command, which takes care of time delays and padding. In most cases, one could just use writse() instead of iputs, since only the most ornery of terminals still need silly things like padding. The only difficulty I envision (and it is hardly a difficulty) is to work things so that by calling getval() with a Unix capname, such as "so" (i.e. getval("so")), the VMS port would a) be able to recognize what "so" means, and b) be able to access its VMS equi- valent. I'll make an offer: If someone will make up a set of VMS routines that can look up a user's terminal type at run-time, and then ac- cess the database for that terminal by a single routine (e.g. lookup("clear")), I'll put a wrapper around the procedure that will be compatible with my Unix/DOS termlib-like routines. Naturally, it would help if someone doing this had half an eye on the Unix/DOS termlib-like routines, so that the structure of the system is analogous to what's already been done by me. -Richard (goer@sophist.uchicago.edu) From @po10.andrew.cmu.edu:mss+@andrew.cmu.edu Wed Dec 19 14:28:49 1990 Received: from po10.andrew.cmu.edu by megaron.cs.arizona.edu (5.61/15) via SMTP id AA02468; Wed, 19 Dec 90 14:28:49 -0700 Received: by po10.andrew.cmu.edu (5.54/3.15) id for icon-group@cs.arizona.edu; Wed, 19 Dec 90 16:28:07 EST Received: via switchmail; Wed, 19 Dec 90 16:28:01 -0500 (EST) Received: from po10.andrew.cmu.edu via qmail ID ; Sat, 15 Dec 90 16:52:17 -0500 (EST) Received: from mss.andrew.cmu.edu via qmail ID ; Sat, 15 Dec 90 16:50:37 -0500 (EST) Received: from mss.andrew.cmu.edu via qmail ID ; Sat, 15 Dec 1990 16:49:24 -0500 (EST) Received: from Messages.7.14.N.CUILIB.3.45.SNAP.NOT.LINKED.mss.andrew.cmu.edu.rt.r3 via MS.5.6.mss.andrew.cmu.edu.rt_r3; Sat, 15 Dec 1990 16:49:23 -0500 (EST) Message-Id: <0bOddXa00VsAMAfWFb@andrew.cmu.edu> Date: Sat, 15 Dec 1990 16:49:23 -0500 (EST) From: Mark Sherman To: icon-group@cs.arizona.edu Subject: Mac graphics from Icon I'm probably displaying some ignorance, but... Does anyone know of a way to get native Macintosh graphics from within Icon on the Macintosh? In reading the TR on personalized interpreters, I am led to believe that the facility is only available on Unix machines, so trying to build my own Mac system may not be an answer. -Mark From ralph Wed Dec 19 14:40:50 1990 Received: from cheltenham.cs.arizona.edu by megaron.cs.arizona.edu (5.61/15) via SMTP id AA02880; Wed, 19 Dec 90 14:40:50 -0700 Date: Wed, 19 Dec 90 14:40:49 MST From: "Ralph Griswold" Message-Id: <9012192140.AA04124@cheltenham.cs.arizona.edu> Received: by cheltenham.cs.arizona.edu; Wed, 19 Dec 90 14:40:49 MST To: mss+@andrew.cmu.edu Subject: Re: Mac graphics from Icon Cc: icon-group Personalized interpreters are available only under UNIX Icon. They just make it possible to add functionality without having to have or recompile the entire source. You can add functionality to any version of Icon, given the source code and enough knowledge of Icon internals. I won't attempt to characterize the difficulty of accessing the Macintosh Toolbox in any general way, however. Ralph Griswold / Dept of Computer Science / Univ of Arizona / Tucson, AZ 85721 +1 602 621 6609 ralph@cs.arizona.edu uunet!arizona!ralph From fps!mis.mcw.edu!mis.mcw.edu!TENAGLIA@uwm.edu Thu Dec 20 13:02:52 1990 Received: from uwm.edu by megaron.cs.arizona.edu (5.61/15) via SMTP id AA11489; Thu, 20 Dec 90 13:02:52 -0700 Received: by uwm.edu; id AA12489; Thu, 20 Dec 90 14:02:17 -0600 Received: from mis.mcw.edu by fps.mcw.edu (DECUS UUCP ///1.2a/2.5/); Thu, 20 Dec 90 13:41:03 CDT Received: by mis.mcw.edu with UUCP/PMDF (DECUS UUCP); Thu, 20 Dec 1990 08:30 CDT Date: Thu, 20 Dec 1990 08:30 CDT From: Chris Tenaglia - 257-8765 Subject: Code Dichotomy To: icon-group@cs.arizona.edu Message-Id: <5D628D4580200921@mis.mcw.edu> X-Organization: Medical College of Wisconsin MIS Department (Milwaukee, WI) X-Envelope-To: icon-group@cs.arizona.edu X-Vms-To: IN%"icon-group@cs.arizona.edu" Why is it, The prettier (and more consistent) the user interface, The uglier the code? Or maybe this is the mark of true software craftsman, to couple elegant looking (and readible) code with elegant looking and consistent functionality. Any comments? Chris Tenaglia (System Manager) | Medical College of Wisconsin 8701 W. Watertown Plank Rd. | Milwaukee, WI 53226 (414)257-8765 | tenaglia@mis.mcw.edu, mcwmis!tenaglia From djbailey@skyler.mavd.honeywell.com Thu Dec 20 14:55:06 1990 Message-Id: <9012202155.AA15557@megaron.cs.arizona.edu> Received: from skyler.mavd.honeywell.com by megaron.cs.arizona.edu (5.61/15) via SMTP id AA15557; Thu, 20 Dec 90 14:55:06 -0700 Date: 20 Dec 90 15:52:00 CDT From: "BAILEY, DON" Subject: Re: Code Dichotomy To: "icon-group" >Why is it, The prettier (and more consistent) the user interface, The >uglier the code? Or maybe this is the mark of true software craftsman, >to couple elegant looking (and readible) code with elegant looking and >consistent functionality. Any comments? I have a theory that there is a specific amount of mental effort associated with solving a problem. You can move the effort around but you can't get rid of it. Computer programs that are driven by the real world always seem to have some "naughty bits" that just aren't very nice. If you do solve a real world problem without any "naughty bits" you have done well. (Of course, your solution is resting on someone else's naughty bits in the language processor or operating system.) From icon-group-request@arizona.edu Thu Dec 20 23:54:59 1990 Resent-From: icon-group-request@arizona.edu Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP id AA28309; Thu, 20 Dec 90 23:54:59 -0700 Received: from ucbvax.Berkeley.EDU by Arizona.edu; Thu, 20 Dec 90 23:54 MST Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA21082; Thu, 20 Dec 90 22:46:28 -0800 Received: from USENET by ucbvax.Berkeley.EDU with netnews for icon-group@arizona.edu (icon-group@arizona.edu) (contact usenet@ucbvax.Berkeley.EDU if you have questions) Resent-Date: Thu, 20 Dec 90 23:54 MST Date: 21 Dec 90 06:13:05 GMT From: midway!ellis.uchicago.edu!goer@handies.ucar.edu Subject: itlib on alt.sources Sender: icon-group-request@arizona.edu Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: Message-Id: <1990Dec21.061305.25347@midway.uchicago.edu> Organization: University of Chicago X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.edu Rather than mail out individual copies of my Icon termlib-like routines, I decided to post them to alt.sources. People who don't get alt.sources, write me. I will send out individual copies to those who request them. I've burdened this non-source group with a lot of source code already, and I believe it will be much bet- ter to put this rather largish posting in a more appropriate place. This is a repost, but I believe it is justified by the improvements I've made, and also by the simple fact that I was asked to post them again. -Richard (goer@sophist.uchicago.edu) From reid@ctc.contel.com Fri Dec 21 06:51:16 1990 Received: from ctc.contel.com (turing.ctc.contel.com) by megaron.cs.arizona.edu (5.61/15) via SMTP id AA09522; Fri, 21 Dec 90 06:51:16 -0700 Received: from absurd.ctc.contel.com by ctc.contel.com (4.0/SMI-4.0) id AA11474; Fri, 21 Dec 90 08:50:45 EST Date: Fri, 21 Dec 90 08:50:45 EST From: reid@ctc.contel.com (Tom Reid x4505) Message-Id: <9012211350.AA11474@ctc.contel.com> To: djbailey@skyler.mavd.honeywell.com, icon-group@cs.arizona.edu Subject: Re: Code Dichotomy Cc: reid@ctc.contel.com, sel@ctc.contel.com = = >Why is it, The prettier (and more consistent) the user interface, The = >uglier the code? Or maybe this is the mark of true software craftsman, = >to couple elegant looking (and readible) code with elegant looking and = >consistent functionality. Any comments? = = = I have a theory that there is a specific amount of mental effort = associated with solving a problem. You can move the effort = around but you can't get rid of it. Computer programs that are driven = by the real world always seem to have some "naughty bits" that just = aren't very nice. If you do solve a real world problem without any = "naughty bits" you have done well. (Of course, your solution is = resting on someone else's naughty bits in the language processor = or operating system.) = Ugly or voluminous code is an indication that the abstractions supported by the language do not support (well) those of the problem domain. Traditional languages supported "algorithmic" programming well. ICON has excellent list processing and stream processing abstractions. There are few (any?) languages that have graphics or user interface abstractions. Still evolving libraries (Interviews, X, OpenLook, Motif) are the state-of-the-art. Visual languages are still in their infancy. Of course, the limits of how well a basically one-dimensional technology (traditional text languages) can describe two and three dimensional problem domains is another question. From nowlin@iwtqg.att.com Fri Dec 21 07:22:01 1990 Message-Id: <9012211422.AA10123@megaron.cs.arizona.edu> Received: from att.att.com by megaron.cs.arizona.edu (5.61/15) via SMTP id AA10123; Fri, 21 Dec 90 07:22:01 -0700 From: nowlin@iwtqg.att.com Date: Fri, 21 Dec 90 07:36 CST Original-From: iwtqg!nowlin (Jerry D Nowlin +1 312 979 7268) To: icon-group@cs.arizona.edu Subject: Re: Code Dichotomy > >Why is it, The prettier (and more consistent) the user interface, The > >uglier the code? Or maybe this is the mark of true software craftsman, > >to couple elegant looking (and readible) code with elegant looking and > >consistent functionality. Any comments? > > I have a theory that there is a specific amount of mental effort > associated with solving a problem. You can move the effort > around but you can't get rid of it. Computer programs that are driven > by the real world always seem to have some "naughty bits" that just > aren't very nice. If you do solve a real world problem without any > "naughty bits" you have done well. (Of course, your solution is > resting on someone else's naughty bits in the language processor > or operating system.) When there's a finite amount of mental effort available (I'd extend this to a finite amount of available time and other computing resources when working in the real world) you have to balance that time between making it easy for the people that use your code, making it easy for the people that maintain your code, and making it easy on yourself as the programmer. The usual balance seems to be making it easy on the user and the programmer and the maintainer gets the short end of the stick. That explains the ugly code. A reason for this balance is that too many programmers think their code is good and why would they or someone else ever want to change it. These are usually (no slur intended) non-real world types who don't have managers or users to pick at all their nits or market pressure to constantly improve their products. The balance should be to make it easy for the user first. If they don't buy/use your software who cares how elegant it is or how easy it is to maintain. The second priority should be maintainability. Maintainability doesn't just mean fixing bugs is easy. It also means modifying your code to add functionality is easy. If your software is good someone will one-up you and you'd better be able to leap frog them fast when they do. Finally, the ease of development/implementation should be considered but never at the expense of the first two priorities. You should be in this for the long haul. One shot programs are for personal use. To treat distributed software that way is naive. Another thing that hurts software is lack of testing. Software is like wine with testing being analogous to aging. It should never be released before its time. Too much software currently out there is the equivalent of Ripple or Boones Farm. Jerry Nowlin (...!att!iwtqg!nowlin) From icon-group-request@arizona.edu Fri Dec 21 12:13:47 1990 Resent-From: icon-group-request@arizona.edu Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP id AA20751; Fri, 21 Dec 90 12:13:47 -0700 Received: from ucbvax.Berkeley.EDU by Arizona.edu; Fri, 21 Dec 90 12:13 MST Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA04971; Fri, 21 Dec 90 10:54:45 -0800 Received: from USENET by ucbvax.Berkeley.EDU with netnews for icon-group@arizona.edu (icon-group@arizona.edu) (contact usenet@ucbvax.Berkeley.EDU if you have questions) Resent-Date: Fri, 21 Dec 90 12:13 MST Date: 21 Dec 90 17:08:47 GMT From: swrinde!zaphod.mps.ohio-state.edu!casbah.acns.nwu.edu!accuvax.nwu.edu!midway!ellis.uchicago.edu!goer@ucsd.edu Subject: itlib (blanket explanation) Sender: icon-group-request@arizona.edu Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: Message-Id: <1990Dec21.170847.6080@midway.uchicago.edu> Organization: University of Chicago X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.edu My mailbox was pretty full this morning, mostly with requests for the termlib-like routines I said I'd put on alt.sources. I again state that I am happy to send out individual copies to people who don't get alt.sources. I received a couple of questions regarding programs I've posted be- fore - programs which were packed with earlier versions of itlib. The questions were mostly along the lines of, "Does the current ver- sion of itlib and associated routines serve as a drop-in replace- ment for earlier itlib incarnations?" The answer is "yes." This means that anyone running klondike - Unix _hack_ hebcalen - Unix port of Alan Corre's calendar program snake - cute "game" can use the new routines if he/she desires (if the old ones work fine, though, I really don't see the point). Itlib is now packed 1) with generalized routines for turning on empha- size and underline modes (yes, they even work on many magic cookie terminals), 2) implementations for getch() and getche() under Unix, and 3) a DOS port of the itlib routines themselves. Included is a DOS termcap file. I forget where I got it. It works, but could surely use some messaging. Many of these changes and improvements were posted to the icon-group. This posting integrates them all into one package. I'm sorry to have taken so much space. It just seemed sensible to post the information I'm being asked for repeatedly by email. The offer still stands that if someone creates a set of equivalent routines for VMS, I'll put a wrapper around them that will render them compatible with itlib. -Richard Goerwitz (goer@sophist.uchicago.edu) From cjeffery Fri Dec 21 13:25:44 1990 Received: from caslon.cs.arizona.edu by megaron.cs.arizona.edu (5.61/15) via SMTP id AA23022; Fri, 21 Dec 90 13:25:44 -0700 Date: Fri, 21 Dec 90 13:25:39 -0700 From: "Clinton Jeffery" Message-Id: <9012212025.AA01028@caslon.cs.arizona.edu> Received: by caslon.cs.arizona.edu; Fri, 21 Dec 90 13:25:39 -0700 To: reid@ctc.contel.com Cc: djbailey@skyler.mavd.honeywell.com, icon-group@cs.arizona.edu, sel@ctc.contel.com In-Reply-To: Tom Reid x4505's message of Fri, 21 Dec 90 08:50:45 EST <9012211350.AA11474@ctc.contel.com> Subject: Code Dichotomy > Of course, the limits of how well a basically one-dimensional technology > (traditional text languages) can describe two and three dimensional > problem domains is another question. Text languages are only one dimensional when you lay them out "flat" in source files. When they execute, they are something else; recursion (for example) just doesn't seem one-dimensional to me. Outside the realm of graphics and visualization modern text languages are routinely used to solve multidimensional problems. A language's support for multidimensional problem domains might be limited by its control and data structures, but I think the bigger problem for graphics applications (as well as natural language processing) is the "semantic gap" between the source language and the problem domain. Semantic gap can, I think, be addressed linguistically once it is understood. From ralph Sat Dec 22 07:39:40 1990 Received: from cheltenham.cs.arizona.edu by megaron.cs.arizona.edu (5.61/15) via SMTP id AA18753; Sat, 22 Dec 90 07:39:40 -0700 Date: Sat, 22 Dec 90 07:39:38 MST From: "Ralph Griswold" Message-Id: <9012221439.AA05788@cheltenham.cs.arizona.edu> Received: by cheltenham.cs.arizona.edu; Sat, 22 Dec 90 07:39:38 MST To: icon-group Subject: ProIcon 2.0 Version 2.0 of ProIcon, an implementation of Icon for the Macintosh, is now available. ProIcon is a stand-alone application with a standard Macintosh interface. It includes a capable program editor and has facilities for compiling and running Icon programs, setting program options, managing windows, and so forth; programs can be created, tested, and debugged without leaving the application. Program execution can be suspended and resumed at will or terminated at any time. On-line help is provided. ProIcon has many extensions beyond the standard version of Icon, including o function tracing (in addition to procedure tracing) o an optional termination dump of variables and their values o functions for manipulating windows, their contents, and the clipboard o functions for navigating through folders o functions for determining and setting file signatures Version 2.0 of ProIcon corresponds to Version 8 of Icon and has all its features. New with ProIcon 2.0 is support for external functions that provide access to HyperCard XCMDs and XFCNs, as well as functions that manipulate Icon data directly. ProIcon 2.0 also supports Icon's memory monitoring facility for saving details of storage allocation and garbage collection in allocation history files. A separate application provides animated color displays of allocation history files. Programs compiled under ProIcon can be given or sold to others; there are no licensing requirements or royalty fees for such distribution. For information about ProIcon, contact: Catspaw, Inc. P.O. Box 1123 Salida, Colorado 81201-1123 (719) 539-3884 Ralph Griswold / Dept of Computer Science / Univ of Arizona / Tucson, AZ 85721 (602) 621-6609 ralph@cs.arizona.edu uunet!arizona!ralph From R.J.Hare@edinburgh.ac.uk Mon Dec 24 03:21:01 1990 Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP id AA19706; Mon, 24 Dec 90 03:21:01 -0700 Received: from UKACRL.BITNET by Arizona.edu; Mon, 24 Dec 90 03:20 MST Received: from RL.IB by UKACRL.BITNET (Mailer R2.07) with BSMTP id 0079; Mon, 24 Dec 90 10:20:02 GMT Received: from RL.IB by UK.AC.RL.IB (Mailer R2.07) with BSMTP id 9567; Mon, 24 Dec 90 10:20:02 GMT Date: 24 Dec 90 10:20:18 gmt From: R.J.Hare@edinburgh.ac.uk Subject: system routine To: icon-group@cs.arizona.edu Message-Id: <24 Dec 90 10:20:18 gmt 060101@EMAS-A> Via: UK.AC.ED.EMAS-A; 24 DEC 90 10:20:00 GMT X-Envelope-To: icon-group@cs.arizona.edu Hi. I wrote the following short routine to demonstrate (prove) to someone that the system routine worked (I included the modified prompt as visual evidence of the proof). procedure main() writes(&clock[1:6]," ERCVAX:") #main loop while line:=read() do Eif line=="quit" then exit() else Esystem(line) write() writes(&clock[1:6]," ERCVAX:")LL end The program seems to work ok in that if I pass a VMS command string to the program, it all works fine *except* that if I do a set default mumble, mumble], ie: try to change directories, it fails. Any ideas why please? Thanks. Roger Hare. From R.J.Hare@edinburgh.ac.uk Mon Dec 24 04:16:07 1990 Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP id AA22283; Mon, 24 Dec 90 04:16:07 -0700 Received: from UKACRL.BITNET by Arizona.edu; Mon, 24 Dec 90 04:15 MST Received: from RL.IB by UKACRL.BITNET (Mailer R2.07) with BSMTP id 0243; Mon, 24 Dec 90 11:15:13 GMT Received: from RL.IB by UK.AC.RL.IB (Mailer R2.07) with BSMTP id 9789; Mon, 24 Dec 90 11:15:13 GMT Date: 24 Dec 90 11:15:34 gmt From: R.J.Hare@edinburgh.ac.uk Subject: Last message To: icon-group@cs.arizona.edu Message-Id: <24 Dec 90 11:15:34 gmt 060109@EMAS-A> Via: UK.AC.ED.EMAS-A; 24 DEC 90 11:15:12 GMT X-Envelope-To: icon-group@cs.arizona.edu Please ignore my last message - I should have sent it to the Icon project, not to the Icon group. Roger Hare. From mlfarm!ron@hsi.hsi.com Wed Dec 26 07:29:57 1990 Received: from hsi.hsi.com by megaron.cs.arizona.edu (5.61/15) via SMTP id AA24245; Wed, 26 Dec 90 07:29:57 -0700 Received: by hsi.hsi.com (5.61+++/1.34) id AA21170; Wed, 26 Dec 90 09:28:10 -0500 Received: by mlfarm.com (smail2.5) id AA07340; 23 Dec 90 07:39:17 EST (Sun) To: icon-group@cs.arizona.edu Subject: Icon as a teaching language Message-Id: <9012230739.AA07340@mlfarm.com> Date: 23 Dec 90 07:39:17 EST (Sun) From: mlfarm!ron@hsi.hsi.com (Ronald Florence) With the Christmas vacation upon us and a 12-year old around the house, I wonder if anyone has had experience with Icon as a first structured language. My son is adept at vi and gnuplot, and for homework problems I have occasionally kludged together awk scripts, which he then modifies as he needs. I suspect some of the more elegant and terse Icon constructions could be daunting, but the multiplicity of approaches to a given problem could be fun. Has anyone tried this? Any wisdom or suggestions? -- Ronald Florence ron@mlfarm.com From wgg@cs.washington.edu Wed Dec 26 11:40:25 1990 Received: from june.cs.washington.edu by megaron.cs.arizona.edu (5.61/15) via SMTP id AA29524; Wed, 26 Dec 90 11:40:25 -0700 Received: by june.cs.washington.edu (5.64/7.0jh) id AA07710; Wed, 26 Dec 90 10:40:10 -0800 Date: Wed, 26 Dec 90 10:40:10 -0800 From: wgg@cs.washington.edu (William Griswold) Return-Path: Message-Id: <9012261840.AA07710@june.cs.washington.edu> To: icon-group@cs.arizona.edu, mlfarm!ron@hsi.hsi.com Subject: Re: Icon as a teaching language >From: mlfarm!ron@hsi.hsi.com (Ronald Florence) > >With the Christmas vacation upon us and a 12-year old around the >house, I wonder if anyone has had experience with Icon as a first >structured language.... Well, I was programming in SNOBOL at this age. The results were fun but aesthetically disasterous. Certainly Icon would be at least as fun and perhaps a better language to begin with. If you can get him playing with some of the more advanced functions, such as map and random selection (kids eat this stuff up), he'll have a blast. Actually, giving him something to modify could be very effective. Small changes in small Icon programs can yield vastly different but useful results. The Icon books are full of small programs that are easy to write and modify. Don't forget numeric calculations as well. Your child may be old enough to program a sieve for primes (my first program divided by all the numbers less than or equal to 1/2 the number. It wasn't long before I figured out I could leave out most of the even numbers....) or some other such program. Unfortunately Icon isn't interactively interpretive, so you can't run-as-you-program. I've written a little line-oriented interpreter loop for Icon, but it changes the syntax and doesn't allow procedures.... Bill Griswold From fps!mis.mcw.edu!mis.mcw.edu!TENAGLIA@uwm.edu Fri Dec 28 09:23:47 1990 Received: from uwm.edu by megaron.cs.arizona.edu (5.61/15) via SMTP id AA04048; Fri, 28 Dec 90 09:23:47 -0700 Received: by uwm.edu; id AA29316; Fri, 28 Dec 90 10:23:25 -0600 Received: from mis.mcw.edu by fps.mcw.edu (DECUS UUCP ///1.2a/2.5/); Fri, 28 Dec 90 09:32:52 CDT Received: by mis.mcw.edu with UUCP/PMDF (DECUS UUCP); Fri, 28 Dec 1990 09:05 CST Date: Fri, 28 Dec 1990 09:05 CST From: Chris Tenaglia - 257-8765 Subject: TAR To: icon-group@cs.arizona.edu Message-Id: X-Organization: Medical College of Wisconsin MIS Department (Milwaukee, WI) X-Envelope-To: icon-group@cs.arizona.edu X-Vms-To: IN%"icon-group@cs.arizona.edu" I run Icon V8 under VAX/VMS 5.2. I occasionally come across tar tapes/files. I know tar is built into unix. But I'll ask anyway, Has anyone written their own TAR utility in ICON? If not, could someone mail or post me the spec, both the syntax of the tar utility, and the data layout. Chris Tenaglia (System Manager) | Medical College of Wisconsin 8701 W. Watertown Plank Rd. | Milwaukee, WI 53226 (414)257-8765 | tenaglia@mis.mcw.edu, mcwmis!tenaglia From fps!mis.mcw.edu!mis.mcw.edu!TENAGLIA@uwm.edu Fri Dec 28 10:08:21 1990 Received: from uwm.edu by megaron.cs.arizona.edu (5.61/15) via SMTP id AA05206; Fri, 28 Dec 90 10:08:21 -0700 Received: by uwm.edu; id AA29925; Fri, 28 Dec 90 11:08:17 -0600 Received: from mis.mcw.edu by fps.mcw.edu (DECUS UUCP ///1.2a/2.5/); Fri, 28 Dec 90 10:40:20 CDT Received: by mis.mcw.edu with UUCP/PMDF (DECUS UUCP); Fri, 28 Dec 1990 09:36 CST Date: Fri, 28 Dec 1990 09:36 CST From: Chris Tenaglia - 257-8765 Subject: iconx To: icon-group@cs.arizona.edu Message-Id: X-Organization: Medical College of Wisconsin MIS Department (Milwaukee, WI) X-Envelope-To: icon-group@cs.arizona.edu X-Vms-To: IN%"icon-group@cs.arizona.edu" I noticed on my postings that some had commented that the ICONX PROGRAM ... is unnecessary. This may be partly true under unix. MSDOS needs the ICONX all the time. Under VMS we have a script called IEXE which converts ICONX PROG unto a symbol(alias) PROG. This is handy for utilities that are used very commonly. Under VMS icon paints screens so slow that I usually use DCL (shell commands) to build the screen or menu, and build icon filters to manipulate the files underneathe. Some years ago I ported ICON to a ZS-1 super-minicomputer from Astronautics. There were certain configuration parameters that were set before building the software. One or more parameters were concerned with whether icon utilities needed iconx explicitly, or if it rolled a little executable into the icode. However, since main(){printf("hello\n");} generated about 200k of executable. The icode of most of the utilities I wrote was typically 2-4k, and the disks were pretty full, it was smarter there to keep the icode separate, so iconx would be required. That was in the Icon 7.0 days, and maybe Icon 8 is much different under unix. Chris Tenaglia (System Manager) | Medical College of Wisconsin 8701 W. Watertown Plank Rd. | Milwaukee, WI 53226 (414)257-8765 | tenaglia@mis.mcw.edu, mcwmis!tenaglia From mlfarm!ron@hsi.hsi.com Sat Dec 29 09:47:04 1990 Received: from hsi.hsi.com by megaron.cs.arizona.edu (5.61/15) via SMTP id AA08896; Sat, 29 Dec 90 09:47:04 -0700 Received: by hsi.hsi.com (5.61+++/1.34) id AA23539; Sat, 29 Dec 90 11:45:16 -0500 Received: by mlfarm.com (smail2.5) id AA14370; 29 Dec 90 11:43:14 EST (Sat) To: icon-group@cs.arizona.edu In-Reply-To: Chris Tenaglia - 257-8765's message of Fri Dec 28 09:36 CST Subject: iconx Message-Id: <9012291143.AA14370@mlfarm.com> Date: 29 Dec 90 11:43:14 EST (Sat) From: mlfarm!ron@hsi.hsi.com (Ronald Florence) Chris Tenaglia - 257-8765 writes: > I noticed on my postings that some had commented that the > > ICONX PROGRAM ... > > is unnecessary. What I wrote was that the `ICONX' is system-specific, and that the users of systems which do not have direct execution (VMS, ms-dos) will know to use it. Because commands are case-sensitive, `ICONX PROGRAM' won't work on most unix systems. > The icode of most of the utilities I wrote was typically 2-4k, and the disks > were pretty full, it was smarter there to keep the icode separate, so iconx > would be required. It would be interesting to compare the size of the compiled code on various systems. The canonical hello.icn compiles to 6941 bytes here (Xenix 386, direct execution). Is it much smaller on VMS or ms-dos systems without direct execution? -- Ronald Florence ron@mlfarm.com From fps!mis.mcw.edu!mis.mcw.edu!TENAGLIA@uwm.edu Tue Jan 1 09:42:36 1991 Received: from uwm.edu by megaron.cs.arizona.edu (5.61/15) via SMTP id AA00177; Tue, 1 Jan 91 09:42:36 -0700 Received: by uwm.edu; id AA01354; Tue, 1 Jan 91 08:34:39 -0600 Received: from mis.mcw.edu by fps.mcw.edu (DECUS UUCP ///1.2a/2.5/); Tue, 1 Jan 91 08:01:24 CDT Received: by mis.mcw.edu with UUCP/PMDF (DECUS UUCP); Tue, 1 Jan 1991 07:32 CST Date: Tue, 1 Jan 1991 07:31 CST From: Chris Tenaglia - 257-8765 Subject: Happy New Year ! Black Jack Game. To: icon-group@cs.arizona.edu Message-Id: X-Organization: Medical College of Wisconsin MIS Department (Milwaukee, WI) X-Envelope-To: icon-group@cs.arizona.edu X-Vms-To: IN%"icon-group@cs.arizona.edu" Happy New Year! After considering all the good advice on the draw poker game I kloojed together a simple version of black jack. It's about 291 lines. The shuffling on the draw poker game also wasn't very good, so this game uses the technique in the IPL which I think is more correct anyway. Enjoy! Yours truly, Chris Tenaglia (System Manager) | Medical College of Wisconsin 8701 W. Watertown Plank Rd. | Milwaukee, WI 53226 (414)257-8765 | tenaglia@mis.mcw.edu, mcwmis!tenaglia ######################################################### # # # BJ.ICN 12/19/90 BY TENAGLIA # # # # SIMPLE BUT FUN BLACK JACK GAME. WORKS ON ANSI SCREEN. # # USAGE : iconx bj [starting credits] # # # ######################################################### global deck, message, lookup, user_money, host_money, user_hand, host_hand procedure main(param) user_money := integer(param[1]) | 3 ; host_money := user_money write(screen("cls")," ",screen("top"),screen("hinv"), "BLACK JACK",screen("norm")) write(" ",screen("bot"),screen("hinv"), "BLACK JACK",screen("norm")) bonus := 0 repeat { if not any('y',(map(input(at(1,4) || screen("under") || "Want to play? y/n :"|| screen("norm") || screen("eeol")))[1])) then break writes(at(1,4),screen("eeos")) display_score() deck := shuffle() message := "" user_hand := [] ; host_hand := [] put(user_hand,pop(deck)) ; put(host_hand,pop(deck)) put(user_hand,pop(deck)) ; put(host_hand,pop(deck)) user_points := first(host_hand[1]) if user_points > 21 then { writes(at(1,14),user_points," points. You went over. You loose.") user_money -:= 1 ; host_money +:= 1 + bonus ; bonus := 0 display_score() next } display_host(2) host_points := second(user_points) if host_points > 21 then { writes(at(50,23),host_points," points. ",&host," went over.") writes(at(1,14),screen("hiblink"),"You win.",screen("norm")) host_money -:= 1 ; user_money +:= 1 + bonus ; bonus := 0 display_score() next } if host_points = user_points then { writes(at(1,23),screen("hiblink"),"It's a draw at ",user_points, ". The ANTY goes to bonus.",screen("norm")) bonus +:= 2 ; host_money -:= 1 ; user_money -:= 1 display_score() next } writes(at(20,13),user_points," points for user.") writes(at(1,15),host_points," points for ",&host) if user_points < host_points then { write(at(1,23),screen("hiblink"),&host," wins.", screen("norm"),screen("eeol")) user_money -:= 1 ; host_money +:= 1 + bonus ; bonus := 0 display_score() next } else { writes(at(1,13),screen("hiblink"),"You win.",screen("norm"),screen("eeol")) user_money +:= 1 + bonus ; host_money -:= 1 ; bonus := 0 display_score() next } } write(screen("clear")) end # # THIS PROCEDURE ALLOWS THE USER TO PLAY AND TAKE HITS # procedure first(host_card) display_user() display_host(1) points := value(user_hand) # just in case writes(at(1,10),"(",points,") ") repeat if any('hy',map(input(at(1,23) || "Hit ? y/n :" || screen("eeol")))) then { put(user_hand,pop(deck)) display_user() if (points := value(user_hand)) > 21 then return points writes(at(1,10),"(",points,") ") } else break (points > 0) | (points := value(user_hand)) writes(at(1,10),"(",points,") ") write(at(60,12),"You stay with ",points) return points end # # THIS SECOND PROCEDURE IS THE HOST PLAYING AGAINST THE USER # procedure second(ceiling) static limits initial limits := [14,14,15,15,19,16,17,18] stop_at := ?limits ; points := 0 until (points := value(host_hand)) > stop_at do { if points > ceiling then return points writes(at(1,20),"(",points,") ") write(at(1,23),screen("eeol"),&host," will take a hit.",screen("eeol")) put(host_hand,pop(deck)) display_host(2) } (points > 0) | (points := value(host_hand)) writes(at(1,20),"(",points,") ") return points end # # THIS ROUTINE DISPLAYS THE CURRENT SCORE # procedure display_score() writes(screen("nocursor")) writes(screen("dim"),at(1,8),"Credits",screen("norm")) writes(screen("high"),at(1,9),right(user_money,7),screen("norm")) writes(screen("dim"),at(1,18),"Credits",screen("norm")) writes(screen("high"),at(1,19),right(host_money,7),screen("norm")) end # # THIS PROCEDURE EVALUATES THE POINTS OF A HAND. IT TRIES TO MAKE THEM # AS HIGH AS POSSIBLE WITHOUT GOING OVER 21. # procedure value(sample) hand := copy(sample) possible := [] repeat { sum := 0 every card := !hand do sum +:= lookup[card[1]] put(possible,sum) if Aces(hand) == "none" then break else every i := 1 to *hand do if hand[i][1] == "A" then hand[i][1] := "a" } every score := !possible do if score <= 21 then return score return possible[1] end # # ARE THERE ANY 11 POINT ACES LEFT IN HAND # procedure Aces(cards) every look := !cards do if look[1] == "A" then return "some" return "none" end # # THIS ROUTINE DISPLAYS THE USER HAND AND STATUS # procedure display_user() writes(screen("nocursor"),at(4,7),screen("hinv"),"USER",screen("norm")) x := 10 ; y := 5 every card := !user_hand do { display(card,x,y) x +:= 7 } end # # THIS ROUTINE DISPLAYS THE HOST HAND AND STATUS # procedure display_host(flag) writes(screen("nocursor"),at(1,17),screen("hinv"),&host,screen("norm")) x := 10 ; y := 15 ; /flag := 0 every card := !host_hand do { if (flag=1) & (x=10) then card := "XX" display(card,x,y) x +:= 7 } end # # THIS ROUTINE DISPLAYS A GIVEN CARD AT A GIVEN X,Y SCREEN LOCATION # procedure display(card,x,y) all := [] ; j := y if find(card[2],"CS") then card := screen("hinv") || card || screen("norm") shape := [at(x,(j+:=1)) || screen("gchar") || "lqqqqqqqk"] put(shape,at(x,(j+:=1)) || "x " || card || " x") put(shape,at(x,(j+:=1)) || "x x") put(shape,at(x,(j+:=1)) || "x x") put(shape,at(x,(j+:=1)) || "x x") put(shape,at(x,(j+:=1)) || "x " || card || " x") put(shape,at(x,(j+:=1)) || "mqqqqqqqj" || screen("nchar")) put(all,shape) x +:= 14 while shape := pop(all) do every writes(!shape) end # # THIS ROUTINE SHUFFLES THE CARD DECK # procedure shuffle() static faces, suits local cards, i initial { &random := map(&clock,":","7") # initial on multiple shuffles faces := ["2","3","4","5","6","7","8","9","T","J","Q","K","A"] suits := ["D","H","C","S"] lookup := table(0) every i := 2 to 9 do insert(lookup,string(i),i) insert(lookup,"T",10) insert(lookup,"J",10) insert(lookup,"Q",10) insert(lookup,"K",10) insert(lookup,"A",11) insert(lookup,"a",1) } cards := [] every put(cards,!faces || !suits) every i := *cards to 2 by -1 do cards[?i] :=: cards[i] return cards end # # THIS ROUTINE PARSES A STRING WITH RESPECT TO SOME DELIMITER # procedure parse(line,delims) static chars chars := &cset -- delims tokens := [] line ? while tab(upto(chars)) do put(tokens,tab(many(chars))) return tokens end # # THIS ROUTINE PROMPTS FOR INPUT AND RETURNS A STRING # procedure input(prompt) writes(screen("cursor"),prompt) return read() end # # THIS ROUTINE SETS THE VIDEO OUTPUT ATTRIBUTES FOR VT102 OR LATER # COMPATIBLE TERMINALS. # procedure screen(attr) case attr of { "cls" : return "\e[2J\e[H" # CLEAR SCREEN "clear": return "\e[2J\e[H" # CLEAR SCREEN "top" : return "\e#3" # UPPER HALF CHARACTERS "bot" : return "\e#4" # LOWER HALF CHARACTERS "fat" : return "\e#6" # SINGLE HEIGHT FAT LETTERS "thin" : return "\e#5" # NORMAL SIZED CHARACTERS "hinv" : return "\e[1;7m" # HIGH INTENSITY & INVERSE "norm" : return "\e[m" # RESTORE NORMAL VIDEO ATTRIBUTES "dim" : return "\e[2m" # LOW INTENSITY VIDEO "blink": return "\e[5m" # VIDEO BLINKING ATTRIBUTE "hiblink": return "\e[1;5m" # HIGH INTENSITY BLINKING "under": return "\e[4m" # VIDEO UNDERLINING ATTRIBUTE "high" : return "\e[1m" # VIDEO HIGH INTENSITY ATTRIBUTE "inv" : return "\e[7m" # VIDEO INVERSE ATTRIBUTE "eeol" : return "\e[K" # ERASE TO END OF LINE "esol" : return "\e[1K" # ERASE TO START OF LINE "eeos" : return "\e[J" # ERASE TO END OF SCREEN "gchar": return "\e(0" # TURN ON ANSI GRAPHICS MODE "nchar": return "\e(B" # TURN OFF ANSI GRAPHICS MODE "light": return "\e[?5h" # LIGHT COLORED SCREEN "dark" : return "\e[?5l" # DARK COLORED SCREEN "80" : return "\e[?3l" # 80 COLUMNS ON SCREEN "132" : return "\e[?3h" # 132 COLUMNS ON SCREEN "smooth": return "\e[?4h" # SMOOTH SCREEN SCROLLING "jump" : return "\e[?4l" # JUMP SCREEN SCROLLING "cursor": return "\e[?25h" # MAKE SURE CURSOR IS VISIBLE "nocursor": return "\e[?25l" # HIDE THE CURSOR default: return "("||attr||")" } end # # THIS ROUTINE SETS THE CURSOR TO A GIVEN X (COL) Y(ROW) SCREEN LOCATION # procedure at(x,y) return "\e[" || y || ";" || x || "f" end From @um.cc.umich.edu:Paul_Abrahams@Wayne-MTS Tue Jan 1 20:06:36 1991 Received: from umich.edu by megaron.cs.arizona.edu (5.61/15) via SMTP id AA12591; Tue, 1 Jan 91 20:06:36 -0700 Received: from um.cc.umich.edu by umich.edu (5.61/1123-1.0) id AA04966; Tue, 1 Jan 91 22:06:27 -0500 Received: from Wayne-MTS by um.cc.umich.edu via MTS-Net; Tue, 1 Jan 91 22:03:41 EST Date: Tue, 1 Jan 91 16:34:36 EST From: Paul_Abrahams%Wayne-MTS@um.cc.umich.edu To: icon-group@cs.arizona.edu Message-Id: <281696@Wayne-MTS> Subject: Message conventions This isn't exactly an Icon question, but..... I've noticed that in many of the postings to icon-group, the messages have excerpts from previous messages preceded by "> ". Could anyone let me know what software you're using to get this effect, and how you're using it? Thanks. Paul Abrahams abrahams%wayne-mts@um.cc.umich.edu From icon-group-request@arizona.edu Tue Jan 1 21:52:02 1991 Resent-From: icon-group-request@arizona.edu Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP id AA14616; Tue, 1 Jan 91 21:52:02 -0700 Received: from ucbvax.Berkeley.EDU by Arizona.edu; Tue, 1 Jan 91 21:51 MST Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA29802; Tue, 1 Jan 91 20:44:27 -0800 Received: from USENET by ucbvax.Berkeley.EDU with netnews for icon-group@arizona.edu (icon-group@arizona.edu) (contact usenet@ucbvax.Berkeley.EDU if you have questions) Resent-Date: Tue, 1 Jan 91 21:51 MST Date: 2 Jan 91 02:56:21 GMT From: netnews.upenn.edu!msuinfo!midway!quads.uchicago.edu!goer@rutgers.edu Subject: bj, part 3 of 3 Sender: icon-group-request@arizona.edu Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: Message-Id: <1991Jan2.025621.21511@midway.uchicago.edu> Organization: University of Chicago X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.edu References: <1991Jan2.025428.21379@midway.uchicago.edu> stty: Operation not supported on socket ---- Cut Here and feed the following to sh ---- #!/bin/sh # this is bj.03 (part 3 of a multipart archive) # do not concatenate these parts, unpack them in order with /bin/sh # file itlibdos.icn continued # if test ! -r _shar_seq_.tmp; then echo 'Please unpack part 1 first!' exit 1 fi (read Scheck if test "$Scheck" != 3; then echo Please unpack part "$Scheck" next! exit 1 else exit 0 fi ) < _shar_seq_.tmp || exit 1 if test ! -f _shar_wnt_.tmp; then echo 'x - still skipping itlibdos.icn' else echo 'x - continuing file itlibdos.icn' sed 's/^X//' << 'SHAR_EOF' >> 'itlibdos.icn' && X range := "(" || tc_table["co"]-1 || "," || tc_table["li"]-1 || ")" X er("igoto",colline || " out of range " || (\range|""),9) X } X X # Use the Iconish 1;1 upper left corner & not the C-ish 0 offsets X increment := -1 X outstr := "" X X cm ? { X while outstr ||:= tab(find("%")) do { X tab(match("%")) X chr := move(1) X if case chr of { X "." : outstr ||:= char(line + increment) X "+" : outstr ||:= char(line + ord(move(1)) + increment) X "d" : { X str := string(line + increment) X outstr ||:= right(str, integer(tab(any('23'))), "0") | str X } X } X then line :=: col X else { X case chr of { X "n" : line := ixor(line,96) & col := ixor(col,96) X "i" : increment := 0 X "r" : line :=: col X "%" : outstr ||:= "%" X "B" : line := ior(ishift(line / 10, 4), line % 10) X ">" : { X x := move(1); y := move(1) X line > ord(x) & line +:= ord(y) X &null X } X } | er("goto","bad termcap entry",5) X } X } X return outstr || tab(0) X } X Xend X X X Xprocedure iputs(cp, affcnt) X X # Writes cp to the screen. Use this instead of writes() for X # compatibility with the Unix version (which will need to send X # null padding in some cases). Iputs() also does a useful type X # check. X X static num_chars X initial num_chars := &digits ++ '.' X X type(cp) == "string" | X er("iputs","you can't iputs() a non-string value!",10) X X cp ? { X if tab(many(num_chars)) & ="*" then X stop("iputs: MS-DOS termcap files shouldn't specify padding.") X writes(tab(0)) X } X X return X Xend SHAR_EOF echo 'File itlibdos.icn is complete' && true || echo 'restore of itlibdos.icn failed' rm -f _shar_wnt_.tmp fi # ============= termcap.dos ============== if test -f 'termcap.dos' -a X"$1" != X"-c"; then echo 'x - skipping termcap.dos (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp echo 'x - extracting termcap.dos (Text)' sed 's/^X//' << 'SHAR_EOF' > 'termcap.dos' && Xansi|color|ansi-color|ibm|ibmpc|ANSI.SYS color:\ X :co#80:li#24:bs:pt:bl=^G:le=^H:do=^J:\ X :cl=\E[H\E[2J:ce=\E[K:\ X :ho=\E[H:cm=\E[%i%d;%dH:\ X :up=\E[A:do=\E[B:le=\E[C:ri=\E[D:nd=\E[C:\ X :ti=\E[0;44m:te=\E[0m:\ X :so=\E[1;35;44m:se=\E[0;44m:\ X :us=\E[1;31;44m:ue=\E[0;44m:\ X :mb=\E[5m:md=\E[1m:me=\E[0;44m: Xmono|ansi-mono|ANSI.SYS:\ X :co#80:li#24:bs:pt:bl=^G:le=^H:do=^J:\ X :cl=\E[H\E[2J:ce=\E[K:\ X :ho=\E[H:cm=\E[%i%d;%dH:\ X :up=\E[A:do=\E[B:le=\E[C:ri=\E[D:nd=\E[C:\ X :so=\E[1m:se=\E[m:us=\E[4m:ue=\E[m:\ X :mb=\E[5m:md=\E[1m:me=\E[m: Xnnansi-mono|NNANSI.SYS:\ X :co#80:li#25:bs:pt:bl=^G:le=^H:do=^J:\ X :cl=\E[2J:cd=\E[J:ce=\E[K:\ X :ho=\E[H:cm=\E[%i%d;%dH:\ X :up=\E[A:do=\E[B:le=\E[C:ri=\E[D:nd=\E[C:\ X :so=\E[1m:se=\E[2m:\ X :us=\E[4m:ue=\E[24m:\ X :mb=\E[5m:md=\E[1m:mh=\E[2m:mr=\E[7m:me=\E[m:\ X :al=\E[L:dl=\E[M:ic=\E[@:dc=\E[P: Xnnansi|nnansi-color|NNANSI.SYS color:\ X :co#80:li#25:bs:pt:bl=^G:le=^H:do=^J:\ X :cl=\E[2J:cd=\E[J:ce=\E[K:\ X :ho=\E[H:cm=\E[%i%d;%dH:\ X :up=\E[A:do=\E[B:le=\E[C:ri=\E[D:nd=\E[C:\ X :ti=\E[0;44m:te=\E[0m:\ X :so=\E[1;35;44m:se=\E[2;37m:\ X :us=\E[4m:ue=\E[24m:\ X :mb=\E[5m:md=\E[1m:mh=\E[2m:mr=\E[7m:me=\E[0;44m:\ X :al=\E[L:dl=\E[M:ic=\E[@:dc=\E[P: Xnansi-mono|zansi-mono|N/ZANSI.SYS:\ X :co#80:li#25:bs:pt:bl=^G:le=^H:do=^J:\ X :cl=\E[2J:ce=\E[K:\ X :ho=\E[H:cm=\E[%i%d;%dH:\ X :up=\E[A:do=\E[B:le=\E[C:ri=\E[D:nd=\E[C:\ X :ti=\E[0m:te=\E[0m:\ X :so=\E[1;35m:se=\E[0m:\ X :us=\E[1;31m:ue=\E[0m:\ X :mb=\E[5m:md=\E[1m:mr=\E[7m:me=\E[m:\ X :al=\E[L:dl=\E[M:ic=\E[@:dc=\E[P: Xnansi|zansi|nansi-color|zansi-color|N/ZANSI.SYS color:\ X :co#80:li#25:bs:pt:bl=^G:le=^H:do=^J:\ X :cl=\E[2J:ce=\E[K:\ X :ho=\E[H:cm=\E[%i%d;%dH:\ X :up=\E[A:do=\E[B:le=\E[C:ri=\E[D:nd=\E[C:\ X :ti=\E[0;44m:te=\E[0m:\ X :so=\E[1;35;44m:se=\E[0;44m:\ X :us=\E[1;31;44m:ue=\E[0;44m:\ X :mb=\E[5m:md=\E[1m:mr=\E[7m:me=\E[0;44m:\ X :al=\E[L:dl=\E[M:ic=\E[@:dc=\E[P: XAX|ANSI X3.64|full ANSI X3.64 (1977) standard:\ X :co#80:li#24:bs:pt:am:mi:bl=^G:le=^H:\ X :cl=\E[2J:ce=\E[K:cd=\E[J:\ X :ho=\E[H:cm=\E[%i%d;%dH:cs=\E[%i%d;%dr:\ X :up=\E[A:do=\E[B:le=\E[C:ri=\E[D:nd=\E[C:\ X :UP=\E[%dA:DO=\E[%dB:LE=\E[%dC:RI=\E[%dD:\ X :so=\E[7m:se=\E[m:us=\E[4m:ue=\E[m:\ X :mb=\E[5m:md=\E[1m:mr=\E[7m:me=\E[m:as=^N:ae=^O:\ X :ku=\E[A:kd=\E[B:kl=\E[C:kr=\E[D:kb=^H:\ X :kn#4:k1=\EOP:k2=\EOQ:k3=\EOR:k4=\EOS:\ X :im=\E[4h:ei=\E[4l:al=\E[L:dl=\E[M:ic=\E[@:dc=\E[P:sf=\ED:sr=\EM: SHAR_EOF true || echo 'restore of termcap.dos failed' rm -f _shar_wnt_.tmp fi # ============= README ============== if test -f 'README' -a X"$1" != X"-c"; then echo 'x - skipping README (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp echo 'x - extracting README (Text)' sed 's/^X//' << 'SHAR_EOF' > 'README' && XThis package is a simple UNIX port of Chris Tenaglia's blackjack Xgame for full ANSI terminals. Because of the structure of the Xoriginal program (read: because I was lazy) this port won't work Xwith magic cookie terminals. It works best on terminals that have Xboldface, reverse, dim, and blink modes. If any of these are mis- Xsing, the appearance of the game will be somewhat altered. Ter- Xminals must be at least 24x80. X XTo make for UNIX, just copy Makefile.dist to Makefile and type X"make." If all goes well, and you have root priviledges, su to Xroot and type "make install." You'll have to edit the makefile Xto reflect local file structures and conventions. X XIncluded with this distribution is also a DOS implementation of Xthe itlib routines and a termcap file. To run this program on a XDOS system, first compile using X X icont -o bj bj.icn itlibdos.icn X XRead the directions in the file itlibdos.icn for instructions as Xto how to install a termcap file. NOTE WELL: THE TERMCAP FOR XDOS IS NOT TERRIBLY GOOD, AND IN ORDER TO GET IT TO WORK, YOU XWILL CERTAINLY NEED TO FIX IT UP. I don't use DOS much, and will Xjust have to hope that some any revisions that get made will make Xtheir way back to me. X XNaturally, UNIX users can erase all the DOS files ("rm *dos*"). XDOS users can erase itlibdos.icn and Makefile.dist. If anything Xgoes awry, or if a standard terminal such as a VT-XXX or and XANSI fails to run bj, please let me know. I expect that older Xterminals without a full assortment of modes - if they run it Xat all - will not do so very smartly. X XEnjoy Chris's game, and have a good 1991! X X-Richard Goerwitz (goer@sophist.uchicago.edu) SHAR_EOF true || echo 'restore of README failed' rm -f _shar_wnt_.tmp fi # ============= Makefile.dist ============== if test -f 'Makefile.dist' -a X"$1" != X"-c"; then echo 'x - skipping Makefile.dist (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp echo 'x - extracting Makefile.dist (Text)' sed 's/^X//' << 'SHAR_EOF' > 'Makefile.dist' && X# Don't change this unless you know what you are doing :-). XPROGNAME = bj X X# Please edit these to reflect your local file structure & conventions. XDESTDIR = /usr/local/bin XOWNER = bin XGROUP = bin X X# Please don't change these. XSRC = $(PROGNAME).icn itlib.icn X X# I hope you won't have to use this. X# DEBUGFLAG = -t X X$(PROGNAME): $(SRC) X /usr/local/bin/icont $(DEBUGFLAG) -o $(PROGNAME) $(SRC) X X# Pessimistic assumptions regarding the environment (in particular, X# I don't assume you have the BSD "install" shell script). Xinstall: $(PROGNAME) X @sh -c "test -d $(DESTDIR) || (mkdir $(DESTDIR) && chmod 755 $(DESTDIR))" X cp $(PROGNAME) $(DESTDIR)/ X chgrp $(GROUP) $(DESTDIR)/$(PROGNAME) X chown $(OWNER) $(DESTDIR)/$(PROGNAME) X @echo "\nInstallation done.\n" X SHAR_EOF true || echo 'restore of Makefile.dist failed' rm -f _shar_wnt_.tmp fi rm -f _shar_seq_.tmp echo You have unpacked the last part exit 0 From icon-group-request@arizona.edu Tue Jan 1 21:52:26 1991 Resent-From: icon-group-request@arizona.edu Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP id AA14625; Tue, 1 Jan 91 21:52:26 -0700 Received: from ucbvax.Berkeley.EDU by Arizona.edu; Tue, 1 Jan 91 21:51 MST Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA29795; Tue, 1 Jan 91 20:44:06 -0800 Received: from USENET by ucbvax.Berkeley.EDU with netnews for icon-group@arizona.edu (icon-group@arizona.edu) (contact usenet@ucbvax.Berkeley.EDU if you have questions) Resent-Date: Tue, 1 Jan 91 21:51 MST Date: 2 Jan 91 02:55:23 GMT From: netnews.upenn.edu!msuinfo!midway!quads.uchicago.edu!goer@rutgers.edu Subject: bj, part 2 of 3 Sender: icon-group-request@arizona.edu Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: Message-Id: <1991Jan2.025523.21456@midway.uchicago.edu> Organization: University of Chicago X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.edu References: <1991Jan2.025428.21379@midway.uchicago.edu> stty: Operation not supported on socket ---- Cut Here and feed the following to sh ---- #!/bin/sh # this is bj.02 (part 2 of a multipart archive) # do not concatenate these parts, unpack them in order with /bin/sh # file itlib.icn continued # if test ! -r _shar_seq_.tmp; then echo 'Please unpack part 1 first!' exit 1 fi (read Scheck if test "$Scheck" != 2; then echo Please unpack part "$Scheck" next! exit 1 else exit 0 fi ) < _shar_seq_.tmp || exit 1 if test ! -f _shar_wnt_.tmp; then echo 'x - still skipping itlib.icn' else echo 'x - continuing file itlib.icn' sed 's/^X//' << 'SHAR_EOF' >> 'itlib.icn' && X (tab(find(":")+1), tab(0))) X return entry X } X else { X \line := &null # must precede the next line X entry ||:= trim(trim(tab(0),'\\'),':') X } X } X } X } X } X X close(f) X er("getentry","can't find and/or process your termcap entry",3) X Xend X X X Xprocedure read_file(f) X X # Suspends all non #-initial lines in the file f. X # Removes leading tabs and spaces from lines before suspending X # them. X X local line X X \f | er("read_tcap_file","no valid termcap file found",3) X while line := read(f) do { X match("#",line) & next X line ?:= (tab(many('\t ')) | &null, tab(0)) X suspend line X } X X fail X Xend X X X Xprocedure maketc_table(entry) X X # Maketc_table(s) (where s is a valid termcap entry for some X # terminal-type): Returns a table in which the keys are termcap X # capability designators, and the values are the entries in X # "entry" for those designators. X X local k, v X X /entry & er("maketc_table","no entry given",8) X if entry[-1] ~== ":" then entry ||:= ":" X X /tc_table := table() X X entry ? { X X tab(find(":")+1) # tab past initial (name) field X X while tab((find(":")+1) \ 1) ? { X &subject == "" & next X if k := 1(move(2), ="=") X then tc_table[k] := Decode(tab(find(":"))) X else if k := 1(move(2), ="#") X then tc_table[k] := integer(tab(find(":"))) X else if k := 1(tab(find(":")), pos(-1)) X then tc_table[k] := true() X else er("maketc_table", "your termcap file has a bad entry",3) X } X } X X return tc_table X Xend X X X Xprocedure getval(id) X X /tc_table := maketc_table(getentry(getname())) | X er("getval","can't make a table for your terminal",4) X X return \tc_table[id] | fail X # er("getval","the current terminal doesn't support "||id,7) X Xend X X X Xprocedure Decode(s) X X # Does things like turn ^ plus a letter into a genuine control X # character. X X new_s := "" X X s ? { X X while new_s ||:= tab(upto('\\^')) do { X chr := move(1) X if chr == "\\" then { X new_s ||:= { X case chr2 := move(1) of { X "\\" : "\\" X "^" : "^" X "E" : "\e" X "b" : "\b" X "f" : "\f" X "n" : "\n" X "r" : "\r" X "t" : "\t" X default : { X if any(&digits,chr2) then { X char(integer("8r"||chr2||move(2 to 0 by -1))) | X er("Decode","bad termcap entry",3) X } X else chr2 X } X } X } X } X else new_s ||:= char(ord(map(move(1),&lcase,&ucase)) - 64) X } X new_s ||:= tab(0) X } X X return new_s X Xend X X X Xprocedure igoto(cm,col,line) X X local colline, range, increment, str, outstr, chr, x, y X X if col > (tc_table["co"]) | line > (tc_table["li"]) then { X colline := string(\col) || "," || string(\line) | string(\col|line) X range := "(" || tc_table["co"]-1 || "," || tc_table["li"]-1 || ")" X er("igoto",colline || " out of range " || (\range|""),9) X } X X # Use the Iconish 1;1 upper left corner & not the C-ish 0 offsets X increment := -1 X outstr := "" X X cm ? { X while outstr ||:= tab(find("%")) do { X tab(match("%")) X chr := move(1) X if case chr of { X "." : outstr ||:= char(line + increment) X "+" : outstr ||:= char(line + ord(move(1)) + increment) X "d" : { X str := string(line + increment) X outstr ||:= right(str, integer(tab(any('23'))), "0") | str X } X } X then line :=: col X else { X case chr of { X "n" : line := ixor(line,96) & col := ixor(col,96) X "i" : increment := 0 X "r" : line :=: col X "%" : outstr ||:= "%" X "B" : line := ior(ishift(line / 10, 4), line % 10) X ">" : { X x := move(1); y := move(1) X line > ord(x) & line +:= ord(y) X &null X } X } | er("goto","bad termcap entry",5) X } X } X return outstr || tab(0) X } X Xend X X X Xprocedure iputs(cp, affcnt) X X local baud_rates, char_rates, i, delay, PC X static num_chars, char_times X # global tty_speed X X initial { X num_chars := &digits ++ '.' X char_times := table() X # Baud rates in decimal, not octal (as in termio.h) X baud_rates := [0,7,8,9,10,11,12,13,14,15] X char_rates := [0,333,166,83,55,41,20,10,10,10] X every i := 1 to *baud_rates do { X char_times[baud_rates[i]] := char_rates[i] X } X } X X type(cp) == "string" | X er("iputs","you can't iputs() a non-string value!",10) X X cp ? { X delay := tab(many(num_chars)) X if ="*" then { X delay *:= \affcnt | X er("iputs","affected line count missing",6) X } X writes(tab(0)) X } X X if (\delay, tty_speed ~= 0) then { X PC := tc_table["pc"] | "\000" X char_time := char_times[tty_speed] | (return "speed error") X delay := (delay * char_time) + (char_time / 2) X every 1 to delay by 10 X do writes(PC) X } X X return X Xend X X X Xprocedure getspeed() X X local stty_g, stty_output, c_cflag, o_speed X X stty_g := open("/bin/stty -g 2>&1","pr") | X er("getspeed","Can't access your stty command.",4) X stty_output := !stty_g X close(stty_g) X X \stty_output ? { X # tab to the third field of the output of the stty -g cmd X tab(find(":")+1) & tab(find(":")+1) & X c_cflag := integer("16r"||tab(find(":"))) X } | er("getspeed","Unable to unwind your stty -g output.",4) X X o_speed := iand(15,c_cflag) X return o_speed X Xend SHAR_EOF echo 'File itlib.icn is complete' && true || echo 'restore of itlib.icn failed' rm -f _shar_wnt_.tmp fi # ============= itlibdos.icn ============== if test -f 'itlibdos.icn' -a X"$1" != X"-c"; then echo 'x - skipping itlibdos.icn (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp echo 'x - extracting itlibdos.icn (Text)' sed 's/^X//' << 'SHAR_EOF' > 'itlibdos.icn' && X########################################################################## X# X# Name: itlibdos.icn X# X# Title: Icon termlib-type tools (MS-DOS version) X# X# Author: Richard L. Goerwitz X# X# Version: 1.12 X# X########################################################################### X# X# I place this and future versions of itlibdos in the public domain - RLG X# X########################################################################### X# X# The following library represents a series of rough functional X# equivalents to the standard Unix low-level termcap routines. They X# are not meant as exact termlib clones. Nor are they enhanced to X# take care of magic cookie terminals, terminals that use \D in their X# termcap entries, or, in short, anything I felt would not affect my X# normal, day-to-day work with ANSI and vt100 terminals. X# X# Requires: An MS-DOS platform & co-expressions. The MS-DOS version X# is a port of the Unix version. Software you write for this library X# can be made to run under Unix simply by substituting the Unix ver- X# sion of this library. See below for additional notes on how to use X# this MS-DOS port. X# X# setname(term) X# Use only if you wish to initialize itermlib for a terminal X# other than what your current environment specifies. "Term" is the X# name of the termcap entry to use. Normally this initialization is X# done automatically, and need not concern the user. X# X# getval(id) X# Works something like tgetnum, tgetflag, and tgetstr. In the X# spirit of Icon, all three have been collapsed into one routine. X# Integer valued caps are returned as integers, strings as strings, X# and flags as records (if a flag is set, then type(flag) will return X# "true"). Absence of a given capability is signalled by procedure X# failure. X# X# igoto(cm,destcol,destline) - NB: default 1 offset (*not* zero)! X# Analogous to tgoto. "Cm" is the cursor movement command for X# the current terminal, as obtained via getval("cm"). Igoto() X# returns a string which, when output via iputs, will cause the X# cursor to move to column "destcol" and line "destline." Column and X# line are always calculated using a *one* offset. This is far more X# Iconish than the normal zero offset used by tgoto. If you want to X# go to the first square on your screen, then include in your program X# "iputs(igoto(getval("cm"),1,1))." X# X# iputs(cp,affcnt) X# Equivalent to tputs. "Cp" is a string obtained via getval(), X# or, in the case of "cm," via igoto(getval("cm"),x,y). Affcnt is a X# count of affected lines. It is only relevant for terminals which X# specify proportional (starred) delays in their termcap entries. X# X# Notes on the MS-DOS version: X# There are two basic reasons for using the I/O routines X# contained in this package. First, by using a set of generalized X# routines, your code will become much more readable. Secondly, by X# using a high level interface, you can avoid the cardinal X# programming error of hard coding things like screen length and X# escape codes into your programs. X# To use this collection of programs, you must do two things. X# First, you must add the line "device=ansi.sys" (or the name of some X# other driver, like zansi.sys, nansi.sys, or nnansi.sys [=new X# nansi.sys]) to your config.sys file. Secondly, you must add two X# lines to your autoexec.bat file: 1) "set TERM=ansi-mono" and 2) X# "set TERMCAP=\location\termcap." The purpose of setting the TERM X# variable is to tell this program what driver you are using. If you X# have a color system, use "ansi-color" instead of "ansi-mono," and X# if you are using nansi or zansi instead of vanilla ansi, use one of X# these names instead of the "ansi" (e.g. "zansi-mono"). The purpose X# of setting TERMCAP is to make it possible to determine where the X# termcap file is located. The termcap file (which should have been X# packed with this library as termcap.dos) is a short database of all X# the escape sequences used by the various terminal drivers. Set X# TERMCAP so that it reflects the location of this file (which should X# be renamed as termcap, for the sake of consistency with the Unix X# version). Naturally, you must change "\location\" above to reflect X# the correct path on your system. X# Although I make no pretense here of providing here a complete X# introduction to the format of the termcap database file, it will be X# useful, I think, to explain a few basic facts about how to use this X# program in conjunction with it. If, say, you want to clear the X# screen, add the line, X# X# iputs(getval("cl")) X# X# to your program. The function iputs() outputs screen control X# sequences. Getval retrieves a specific sequence from the termcap X# file. The string "cl" is the symbol used in the termcap file to X# mark the code used to clear the screen. By executing the X# expression "iputs(getval("cl"))," you are 1) looking up the "cl" X# (clear) code in the termcap database entry for your terminal, and X# the 2) outputting that sequence to the screen. X# Some other useful termcap symbols are "ce" (clear to end of X# line), "ho" (go to the top left square on the screen), "so" (begin X# standout mode), and "se" (end standout mode). To output a X# boldfaced string, str, to the screen, you would write - X# X# iputs(getval("so")) X# writes(str) X# iputs(getval("se")) X# X# You could write "iputs(getval("so") || str || getval("se")), but X# this would only work for DOS. Some Unix terminals require padding, X# and iputs() handles them specially. Normally you should not worry X# about Unix quirks under DOS. It is in general wise, though, to X# separate out screen control sequences, and output them via iputs(). X# It is also heartily to be recommended that MS-DOS programmers X# try not to assume that everyone will be using a 25-line screen. X# Some terminals are 24-line. Some 43. Some have variable window X# sizes. If you want to put a status line on, say, the 2nd-to-last X# line of the screen, then determine what that line is by executing X# "getval("li")." The termcap database holds not only string-valued X# sequences, but numeric ones as well. The value of "li" tells you X# how many lines the terminal has (compare "co," which will tell you X# how many columns). To go to the beginning of the second-to-last X# line on the screen, type in: X# X# iputs(igoto(getval("cm"), 1, getval("li")-1)) X# X# The "cm" capability is a special capability, and needs to be output X# via igoto(cm,x,y), where cm is the sequence telling your computer X# to move the cursor to a specified spot, x is the column, and y is X# the row. The expression "getval("li")-1" will return the number of X# the second-to-last line on your screen. X# X########################################################################## X# X# Requires: MS-DOS, coexpressions X# X# See also: iscreen.icn (a set of companion utilities) X# X########################################################################## X X Xglobal tc_table Xrecord true() X X Xprocedure check_features() X X local in_params, line X X initial { X find("ms-dos",map(&features)) | X er("check_features","MS-DOS system required",1) X find("o-expres",&features) | X er("check_features","co-expressions not implemented - &$#!",1) X } X X return X Xend X X X Xprocedure setname(name) X X # Sets current terminal type to "name" and builds a new termcap X # capability database (residing in tc_table). Fails if unable to X # find a termcap entry for terminal type "name." If you want it X # to terminate with an error message under these circumstances, X # comment out "| fail" below, and uncomment the er() line. X X #tc_table is global X X check_features() X X tc_table := maketc_table(getentry(name)) | fail X # er("setname","no termcap entry found for "||name,3) X return X Xend X X X Xprocedure getname() X X # Getname() first checks to be sure we're running under DOS, and, X # if so, tries to figure out what the current terminal type is, X # checking the value of the environment variable TERM, and if this X # is unsuccessful, defaulting to "mono." X X local term, tset_output X X check_features() X term := getenv("TERM") | "mono" X X return \term | X er("getname","can't seem to determine your terminal type",1) X Xend X X X Xprocedure er(func,msg,errnum) X X # short error processing utility X write(&errout,func,": ",msg) X exit(errnum) X Xend X X X Xprocedure getentry(name, termcap_string) X X # "Name" designates the current terminal type. Getentry() scans X # the current environment for the variable TERMCAP. If the X # TERMCAP string represents a termcap entry for a terminal of type X # "name," then getentry() returns the TERMCAP string. Otherwise, X # getentry() will check to see if TERMCAP is a file name. If so, X # getentry() will scan that file for an entry corresponding to X # "name." If the TERMCAP string does not designate a filename, X # getentry() will look through ./termcap for the correct entry. X # Whatever the input file, if an entry for terminal "name" is X # found, getentry() returns that entry. Otherwise, getentry() X # fails. X X local f, getline, line, nm, ent1, ent2 X X /termcap_string := getenv("TERMCAP") X X if \termcap_string ? (not match("\\"), pos(0) | tab(find("|")+1), =name) X then return termcap_string X else { X X # The logic here probably isn't clear. The idea is to try to use X # the termcap environment variable successively as 1) a termcap en- X # try and then 2) as a termcap file. If neither works, 3) go to X # the ./termcap file. The else clause here does 2 and, if ne- X # cessary, 3. The "\termcap_string ? (not match..." expression X # handles 1. X X if find("\\",\termcap_string) X then f := open(termcap_string) X /f := open("termcap") | X er("getentry","I can't access your termcap file",1) X X getline := create read_file(f) X X while line := @getline do { X if line ? (pos(1) | tab(find("|")+1), =name, any(':|')) then { X entry := "" X while (\line | @getline) ? { X if entry ||:= 1(tab(find(":")+1), pos(0)) X then { X close(f) X # if entry ends in tc= then add in the named tc entry X entry ?:= tab(find("tc=")) || X # recursively fetch the new termcap entry X (move(3), getentry(tab(find(":"))) ? X # remove the name field from the new entry X (tab(find(":")+1), tab(0))) X return entry X } X else { X \line := &null # must precede the next line X entry ||:= trim(trim(tab(0),'\\'),':') X } X } X } X } X } X X close(f) X er("getentry","can't find and/or process your termcap entry",3) X Xend X X X Xprocedure read_file(f) X X # Suspends all non #-initial lines in the file f. X # Removes leading tabs and spaces from lines before suspending X # them. X X local line X X \f | er("read_tcap_file","no valid termcap file found",3) X while line := read(f) do { X match("#",line) & next X line ?:= (tab(many('\t ')) | &null, tab(0)) X suspend line X } X X fail X Xend X X X Xprocedure maketc_table(entry) X X # Maketc_table(s) (where s is a valid termcap entry for some X # terminal-type): Returns a table in which the keys are termcap X # capability designators, and the values are the entries in X # "entry" for those designators. X X local k, v X X /entry & er("maketc_table","no entry given",8) X if entry[-1] ~== ":" then entry ||:= ":" X X tc_table := table() X X entry ? { X X tab(find(":")+1) # tab past initial (name) field X X while tab((find(":")+1) \ 1) ? { X X &subject == "" & next X if k := 1(move(2), ="=") X then tc_table[k] := Decode(tab(find(":"))) X else if k := 1(move(2), ="#") X then tc_table[k] := integer(tab(find(":"))) X else if k := 1(tab(find(":")), pos(-1)) X then tc_table[k] := true() X else er("maketc_table", "your termcap file has a bad entry",3) X } X } X X return tc_table X Xend X X X Xprocedure getval(id) X X /tc_table := maketc_table(getentry(getname())) | X er("getval","can't make a table for your terminal",4) X X return \tc_table[id] | fail X # er("getval","the current terminal doesn't support "||id,7) X Xend X X X Xprocedure Decode(s) X X # Does things like turn ^ plus a letter into a genuine control X # character. X X new_s := "" X X s ? { X while new_s ||:= tab(upto('\\^')) do { X chr := move(1) X if chr == "\\" then { X new_s ||:= { X case chr2 := move(1) of { X "\\" : "\\" X "^" : "^" X "E" : "\e" X "b" : "\b" X "f" : "\f" X "n" : "\n" X "r" : "\r" X "t" : "\t" X default : { X if any(&digits,chr2) then { X char(integer("8r"||chr2||move(2 to 0 by -1))) | X er("Decode","bad termcap entry",3) X } X else chr2 X } X } X } X } X else new_s ||:= char(ord(map(move(1),&lcase,&ucase)) - 64) X } X new_s ||:= tab(0) X } X X return new_s X Xend X X X Xprocedure igoto(cm,col,line) X X local colline, range, increment, str, outstr, chr, x, y X X if col > (tc_table["co"]) | line > (tc_table["li"]) then { X colline := string(\col) || "," || string(\line) | string(\col|line) SHAR_EOF true || echo 'restore of itlibdos.icn failed' fi echo 'End of part 2' echo 'File itlibdos.icn is continued in part 3' echo 3 > _shar_seq_.tmp exit 0 From icon-group-request@arizona.edu Tue Jan 1 21:52:55 1991 Resent-From: icon-group-request@arizona.edu Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by megaron.cs.arizona.edu (5.61/15) via SMTP id AA14640; Tue, 1 Jan 91 21:52:55 -0700 Received: from ucbvax.Berkeley.EDU by Arizona.edu; Tue, 1 Jan 91 21:51 MST Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA29778; Tue, 1 Jan 91 20:43:37 -0800 Received: from USENET by ucbvax.Berkeley.EDU with netnews for icon-group@arizona.edu (icon-group@arizona.edu) (contact usenet@ucbvax.Berkeley.EDU if you have questions) Resent-Date: Tue, 1 Jan 91 21:52 MST Date: 2 Jan 91 02:54:28 GMT From: netnews.upenn.edu!msuinfo!midway!quads.uchicago.edu!goer@rutgers.edu Subject: UNIX port of bj, part 1 of 3 Sender: icon-group-request@arizona.edu Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: Message-Id: <1991Jan2.025428.21379@midway.uchicago.edu> Organization: University of Chicago X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.edu Tenaglia's blackjack game was very cleanly written, and I ported it before dinner tonight. Some of the character graphics and fonts couldn't be reproduced portably using standard Unix terminals, so I had to remove them. Oh well. Needless to say, I haven't tested this program terribly thoroughly on any system but my own, and even there some bugs might remain. Still, I don't expect that anyone will encounter any big problems running it (or fixing it up). It's a nice game. In fact, I must hurry up, since my son is breathing down my neck to let him have the console so that he can run it here at home. Here's the first of three shell archives. -Richard (goer@sophist.uchicago.edu) stty: Operation not supported on socket ---- Cut Here and feed the following to sh ---- #!/bin/sh # This is a shell archive (produced by shar 3.49) # To extract the files from this archive, save it to a file, remove # everything above the "!/bin/sh" line above, and type "sh file_name". # # made 01/02/1991 02:37 UTC by goer@sophist.uchicago.edu # Source directory /u/richard/Bj # # existing files will NOT be overwritten unless -c is specified # This format requires very little intelligence at unshar time. # "if test", "cat", "rm", "echo", "true", and "sed" may be needed. # # This is part 1 of a multipart archive # do not concatenate these parts, unpack them in order with /bin/sh # # This shar contains: # length mode name # ------ ---------- ------------------------------------------ # 10389 -r--r--r-- bj.icn # 12240 -r--r--r-- itlib.icn # 14586 -r--r--r-- itlibdos.icn # 2391 -r--r--r-- termcap.dos # 1654 -rw-r--r-- README # 754 -rw-r--r-- Makefile.dist # if test -r _shar_seq_.tmp; then echo 'Must unpack archives in sequence!' echo Please unpack part `cat _shar_seq_.tmp` next exit 1 fi # ============= bj.icn ============== if test -f 'bj.icn' -a X"$1" != X"-c"; then echo 'x - skipping bj.icn (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp echo 'x - extracting bj.icn (Text)' sed 's/^X//' << 'SHAR_EOF' > 'bj.icn' && X############################################################################ X# X# Names: bj.icn X# X# Title: blackjack game X# X# Author: Chris Tenaglia (modified by Richard L. Goerwitz) X# X# Version: 1.1 X# X############################################################################ X# X# Simple but fun blackjack game. The original version was for an ANSI X# screen. This version has been modified to work with the Unix termcap X# database file. X# X############################################################################ X# X# Links: X# X############################################################################ X Xglobal deck, message, lookup, X user_money, host_money, X user_hand, host_hand X Xprocedure main(param) X user_money := integer(param[1]) | 3 ; host_money := user_money X write(screen("cls")) X# Most terminals don't do oversize characters like this. X# write(screen("cls")," ",screen("top"),screen("hinv"), X# "BLACK JACK",screen("norm")) X# write(" ",screen("bot"),screen("hinv"), X# "BLACK JACK",screen("norm")) X write(screen("high")," ---- BLACK JACK ----",screen("norm")) X bonus := 0 X repeat X { X if not any('y',(map(input(at(1,3) || " " || screen("under") || X "Play a game? y/n : "|| screen("norm") || X screen("eeol")))[1])) then break X every writes(at(1,3|4),screen("eeos")) X display_score() X deck := shuffle() X message := "" X user_hand := [] ; host_hand := [] X put(user_hand,pop(deck)) ; put(host_hand,pop(deck)) X put(user_hand,pop(deck)) ; put(host_hand,pop(deck)) X user_points := first(host_hand[1]) X if user_points > 21 then X { X writes(at(1,13),user_points," points. You went over. You lose.") X user_money -:= 1 ; host_money +:= 1 + bonus ; bonus := 0 X display_score() X next X } X display_host(2) X host_points := second(user_points) X if host_points > 21 then X { X writes(at(50,22),host_points," points. ",&host ? tab(find(" ")), X " went over.") X writes(at(1,13),screen("hiblink"),"You win.",screen("norm")) X host_money -:= 1 ; user_money +:= 1 + bonus ; bonus := 0 X display_score() X next X } X if host_points = user_points then X { X writes(at(1,22),screen("hiblink"),"It's a draw at ",user_points, X ". The ANTY goes to bonus.",screen("norm")) X bonus +:= 2 ; host_money -:= 1 ; user_money -:= 1 X display_score() X next X } X writes(at(20,12),user_points," points for user.") X writes(at(1,14),host_points," points for ",&host ? tab(find(" "))) X if user_points < host_points then X { X write(at(1,22),screen("hiblink"),&host ? tab(find(" "))," wins.", X screen("norm"),screen("eeol")) X user_money -:= 1 ; host_money +:= 1 + bonus ; bonus := 0 X display_score() X next X } else { X writes(at(1,12),screen("hiblink"),"You win.",screen("norm"), X screen("eeol")) X user_money +:= 1 + bonus ; host_money -:= 1 ; bonus := 0 X display_score() X next X } X } X write(screen("clear")) X end X X# X# THIS PROCEDURE ALLOWS THE USER TO PLAY AND TAKE HITS X# Xprocedure first(host_card) X display_user() X display_host(1) X points := value(user_hand) # just in case X writes(at(1,9),"(",points,") ") X repeat X if any('hy',map(input(at(1,23) || "Hit ? y/n : " || screen("eeol")))) then X { X put(user_hand,pop(deck)) X display_user() X if (points := value(user_hand)) > 21 then return points X writes(at(1,9),"(",points,") ") X } else break X (points > 0) | (points := value(user_hand)) X writes(at(1,9),"(",points,") ") X write(at(60,11),"You stay with ",points) X return points X end X X# X# THIS SECOND PROCEDURE IS THE HOST PLAYING AGAINST THE USER X# Xprocedure second(ceiling) X static limits X initial limits := [14,14,15,15,19,16,17,18] X stop_at := ?limits ; points := 0 X until (points := value(host_hand)) > stop_at do X { X if points > ceiling then return points X writes(at(1,19),"(",points,") ") X# write(at(1,22),screen("eeol"),&host," will take a hit.",screen("eeol")) X write(at(1,22),screen("eeol"),&host ? tab(find(" ")), X " will take a hit.",screen("eeol")) X put(host_hand,pop(deck)) X display_host(2) X } X (points > 0) | (points := value(host_hand)) X writes(at(1,19),"(",points,") ") X return points X end X X# X# THIS ROUTINE DISPLAYS THE CURRENT SCORE X# Xprocedure display_score() X writes(screen("nocursor")) X writes(screen("dim"),at(1,7),"Credits",screen("norm")) X writes(screen("high"),at(1,8),right(user_money,7),screen("norm")) X writes(screen("dim"),at(1,17),"Credits",screen("norm")) X writes(screen("high"),at(1,18),right(host_money,7),screen("norm")) X end X# X# THIS PROCEDURE EVALUATES THE POINTS OF A HAND. IT TRIES TO MAKE THEM X# AS HIGH AS POSSIBLE WITHOUT GOING OVER 21. X# Xprocedure value(sample) X hand := copy(sample) X possible := [] X repeat X { X sum := 0 X every card := !hand do sum +:= lookup[card[1]] X put(possible,sum) X if Aces(hand) == "none" then break else X every i := 1 to *hand do if hand[i][1] == "A" then hand[i][1] := "a" X } X every score := !possible do X if score <= 21 then return score X return possible[1] X end X X# X# ARE THERE ANY 11 POINT ACES LEFT IN HAND X# Xprocedure Aces(cards) X every look := !cards do if look[1] == "A" then return "some" X return "none" X end X X# X# THIS ROUTINE DISPLAYS THE USER HAND AND STATUS X# Xprocedure display_user() X writes(screen("nocursor"),at(1,6),screen("hinv"),"USER",screen("norm")) X x := 10 ; y := 4 X every card := !user_hand do X { X display(card,x,y) X x +:= 7 X } X end X X# X# THIS ROUTINE DISPLAYS THE HOST HAND AND STATUS X# Xprocedure display_host(flag) X writes(screen("nocursor"),at(1,16),screen("hinv"), X &host ? tab(find(" ")),screen("norm")) X x := 10 ; y := 14 ; /flag := 0 X every card := !host_hand do X { X if (flag=1) & (x=10) then card := "XX" X display(card,x,y) X x +:= 7 X } X end X X# X# THIS ROUTINE DISPLAYS A GIVEN CARD AT A GIVEN X,Y SCREEN LOCATION X# Xprocedure display(card,x,y) X all := [] ; j := y X if find(card[2],"CS") then card := screen("hinv") || card || screen("norm") X# shape := [at(x,(j+:=1)) || screen("gchar") || "lqqqqqqqk"] X shape := [at(x,(j+:=1)) || screen("inv") || " " || screen("norm")] X put(shape,at(x,(j+:=1)) || screen("inv") || " " || screen("norm") || X " " || card || " " || screen("inv") || " " || screen("norm")) X put(shape,at(x,(j+:=1)) || screen("inv") || " " || screen("norm") || X " " || screen("inv") || " " || screen("norm")) X put(shape,at(x,(j+:=1)) || screen("inv") || " " || screen("norm") || X " " || screen("inv") || " " || screen("norm")) X put(shape,at(x,(j+:=1)) || screen("inv") || " " || screen("norm") || X " " || screen("inv") || " " || screen("norm")) X# put(shape,at(x,(j+:=1)) || "x x") X# put(shape,at(x,(j+:=1)) || "x x") X put(shape,at(x,(j+:=1)) || screen("inv") || " " || screen("norm") || X " " || card || " " || screen("inv") || " " || screen("norm")) X# put(shape,at(x,(j+:=1)) || "mqqqqqqqj" || screen("nchar")) X put(shape,at(x,(j+:=1)) || screen("inv") || " " || screen("norm")) X put(all,shape) X x +:= 14 X while shape := pop(all) do every writes(!shape) X end X X# X# THIS ROUTINE SHUFFLES THE CARD DECK X# Xprocedure shuffle() X static faces, suits X local cards, i X initial { X &random := map(&clock,":","7") # initial on multiple shuffles X faces := ["2","3","4","5","6","7","8","9","T","J","Q","K","A"] X suits := ["D","H","C","S"] X lookup := table(0) X every i := 2 to 9 do insert(lookup,string(i),i) X insert(lookup,"T",10) X insert(lookup,"J",10) X insert(lookup,"Q",10) X insert(lookup,"K",10) X insert(lookup,"A",11) X insert(lookup,"a",1) X } X cards := [] X every put(cards,!faces || !suits) X every i := *cards to 2 by -1 do cards[?i] :=: cards[i] X return cards X end X X# X# THIS ROUTINE PARSES A STRING WITH RESPECT TO SOME DELIMITER X# Xprocedure parse(line,delims) X static chars X chars := &cset -- delims X tokens := [] X line ? while tab(upto(chars)) do put(tokens,tab(many(chars))) X return tokens X end X X# X# THIS ROUTINE PROMPTS FOR INPUT AND RETURNS A STRING X# Xprocedure input(prompt) X writes(screen("cursor"),prompt) X return read() X end X X X# X# THIS ROUTINE SETS THE VIDEO OUTPUT ATTRIBUTES FOR VT102 OR LATER X# COMPATIBLE TERMINALS. X# Xprocedure screen(attr) X initial if getval("ug"|"mg"|"sg") > 0 then X er("screen","oops, magic cookie terminal!",34) X return { X case attr of X { X "cls" : getval("cl") X "clear": getval("cl") X # HIGH INTENSITY & INVERSE X "hinv" : (getval("md") | "") || getval("so") X "norm" : (getval("se") | "") || (getval("me") | "") || (getval("ue")|"") X # LOW INTENSITY VIDEO X "dim" : getval("mh"|"me") X "blink": getval("mb"|"md"|"so") X # HIGH INTENSITY BLINKING X "hiblink": (getval("md") | "") || getval("mb") | getval("so") X "under": getval("us"|"md"|"so") X "high" : getval("md"|"so"|"ul") X "inv" : getval("so"|"md"|"ul") X # ERASE TO END OF LINE X "eeol" : getval("ce") X # ERASE TO START OF LINE X "esol" : getval("cb") X # ERASE TO END OF SCREEN X "eeos" : getval("cd") X # MAKE CURSOR INVISIBLE X "cursor": getval("vi"|"CO") | "" X # MAKE CURSOR VISIBLE X "nocursor": getval("ve"|"CF") | "" X# # START ALTERNATE FONT <- very non-portable X# "gchar": getval("as") | "" X# # END ALTERNATE FONT X# "nchar": getval("ae") | "" X# "light": return "\e[?5h" # LIGHT COLORED SCREEN X# "dark" : return "\e[?5l" # DARK COLORED SCREEN X# "80" : return "\e[?3l" # 80 COLUMNS ON SCREEN X# "132" : return "\e[?3h" # 132 COLUMNS ON SCREEN X# "smooth": return "\e[?4h" # SMOOTH SCREEN SCROLLING X# "jump" : return "\e[?4l" # JUMP SCREEN SCROLLING X default : er("screen",attr||" is just too weird for most terminals",34) X } | er("screen","I just can't cope with your terminal.",35) X } X end X X# X# THIS ROUTINE SETS THE CURSOR TO A GIVEN X (COL) Y(ROW) SCREEN LOCATION X# Xprocedure at(x,y) X# return "\e[" || y || ";" || x || "f" X return igoto(getval("cm"),x,y) X end X SHAR_EOF true || echo 'restore of bj.icn failed' rm -f _shar_wnt_.tmp fi # ============= itlib.icn ============== if test -f 'itlib.icn' -a X"$1" != X"-c"; then echo 'x - skipping itlib.icn (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp echo 'x - extracting itlib.icn (Text)' sed 's/^X//' << 'SHAR_EOF' > 'itlib.icn' && X######################################################################## X# X# Name: itlib.icn X# X# Title: Icon termlib-type tools X# X# Author: Richard L. Goerwitz X# X# Version: 1.23 X# X######################################################################### X# X# I place this and future versions of itlib in the public domain - RLG X# X######################################################################### X# X# The following library represents a series of rough functional X# equivalents to the standard Unix low-level termcap routines. They X# are not meant as exact termlib clones. Nor are they enhanced to X# take care of magic cookie terminals, terminals that use \D in their X# termcap entries, or, in short, anything I felt would not affect my X# normal, day-to-day work with ANSI and vt100 terminals. X# X# Requires: A unix platform & co-expressions. There is an MS-DOS X# version, itlibdos.icn. X# X# setname(term) X# Use only if you wish to initialize itermlib for a terminal X# other than what your current environment specifies. "Term" is the X# name of the termcap entry to use. Normally this initialization is X# done automatically, and need not concern the user. X# X# getval(id) X# Works something like tgetnum, tgetflag, and tgetstr. In the X# spirit of Icon, all three have been collapsed into one routine. X# Integer valued caps are returned as integers, strings as strings, X# and flags as records (if a flag is set, then type(flag) will return X# "true"). Absence of a given capability is signalled by procedure X# failure. X# X# igoto(cm,destcol,destline) - NB: default 1 offset (*not* zero)! X# Analogous to tgoto. "Cm" is the cursor movement command for X# the current terminal, as obtained via getval("cm"). Igoto() X# returns a string which, when output via iputs, will cause the X# cursor to move to column "destcol" and line "destline." Column and X# line are always calculated using a *one* offset. This is far more X# Iconish than the normal zero offset used by tgoto. If you want to X# go to the first square on your screen, then include in your program X# "iputs(igoto(getval("cm"),1,1))." X# X# iputs(cp,affcnt) X# Equivalent to tputs. "Cp" is a string obtained via getval(), X# or, in the case of "cm," via igoto(getval("cm"),x,y). Affcnt is a X# count of affected lines. It is only relevant for terminals which X# specify proportional (starred) delays in their termcap entries. X# X# Bugs: I have not tested these routines on terminals that require X# padding. These routines WILL NOT WORK if your machines stty com- X# mand has no -g option (tisk, tisk). This includes NeXT worksta- X# tions, and some others that I haven't had time to pinpoint. X# X########################################################################## X# X# Requires: UNIX, co-expressions X# X# See also: iscreen.icn (a set of companion utilities) X# X########################################################################## X X Xglobal tc_table, tty_speed Xrecord true() X X Xprocedure check_features() X X local in_params, line X # global tty_speed X X initial { X find("unix",map(&features)) | X er("check_features","unix system required",1) X find("o-expres",&features) | X er("check_features","co-expressions not implemented - &$#!",1) X system("/bin/stty tabs") | X er("check_features","can't set tabs option",1) X } X X # clumsy, clumsy, clumsy, and probably won't work on all systems X tty_speed := getspeed() X return "term characteristics reset; features check out" X Xend X X X Xprocedure setname(name) X X # Sets current terminal type to "name" and builds a new termcap X # capability database (residing in tc_table). Fails if unable to X # find a termcap entry for terminal type "name." If you want it X # to terminate with an error message under these circumstances, X # comment out "| fail" below, and uncomment the er() line. X X #tc_table is global X X check_features() X X tc_table := table() X tc_table := maketc_table(getentry(name)) | fail X # er("setname","no termcap entry found for "||name,3) X return "successfully reset for terminal " || name X Xend X X X Xprocedure getname() X X # Getname() first checks to be sure we're running under Unix, and, X # if so, tries to figure out what the current terminal type is, X # checking successively the value of the environment variable X # TERM, and then the output of "tset -". Terminates with an error X # message if the terminal type cannot be ascertained. X X local term, tset_output X X check_features() X X if not (term := getenv("TERM")) then { X tset_output := open("/bin/tset -","pr") | X er("getname","can't find tset command",1) X term := !tset_output X close(tset_output) X } X return \term | X er("getname","can't seem to determine your terminal type",1) X Xend X X X Xprocedure er(func,msg,errnum) X X # short error processing utility X write(&errout,func,": ",msg) X exit(errnum) X Xend X X X Xprocedure getentry(name, termcap_string) X X # "Name" designates the current terminal type. Getentry() scans X # the current environment for the variable TERMCAP. If the X # TERMCAP string represents a termcap entry for a terminal of type X # "name," then getentry() returns the TERMCAP string. Otherwise, X # getentry() will check to see if TERMCAP is a file name. If so, X # getentry() will scan that file for an entry corresponding to X # "name." If the TERMCAP string does not designate a filename, X # getentry() will scan /etc/termcap for the correct entry. X # Whatever the input file, if an entry for terminal "name" is X # found, getentry() returns that entry. Otherwise, getentry() X # fails. X X local f, getline, line, nm, ent1, ent2 X X # You can force getentry() to use a specific termcap file by cal- X # ling it with a second argument - the name of the termcap file X # to use instead of the regular one, or the one specified in the X # termcap environment variable. X /termcap_string := getenv("TERMCAP") X X if \termcap_string ? (not match("/"), pos(0) | tab(find("|")+1), =name) X then return termcap_string X else { X X # The logic here probably isn't clear. The idea is to try to use X # the termcap environment variable successively as 1) a termcap en- X # try and then 2) as a termcap file. If neither works, 3) go to X # the /etc/termcap file. The else clause here does 2 and, if ne- X # cessary, 3. The "\termcap_string ? (not match..." expression X # handles 1. X X if find("/",\termcap_string) X then f := open(termcap_string) X /f := open("/etc/termcap") | X er("getentry","I can't access your /etc/termcap file",1) X X getline := create read_file(f) X X while line := @getline do { X if line ? (pos(1) | tab(find("|")+1), =name, any(':|')) then { X entry := "" X while (\line | @getline) ? { X if entry ||:= 1(tab(find(":")+1), pos(0)) X then { X close(f) X # if entry ends in tc= then add in the named tc entry X entry ?:= tab(find("tc=")) || X # recursively fetch the new termcap entry X (move(3), getentry(tab(find(":"))) ? X # remove the name field from the new entry SHAR_EOF true || echo 'restore of itlib.icn failed' fi echo 'End of part 1' echo 'File itlib.icn is continued in part 2' echo 2 > _shar_seq_.tmp exit 0