From ralph Thu Jun 13 12:10:02 1991 Date: Thu, 13 Jun 91 12:10:02 MST From: "Ralph Griswold" Message-Id: <9106131910.AA20178@cheltenham.cs.arizona.edu> Received: by cheltenham.cs.arizona.edu; Thu, 13 Jun 91 12:10:02 MST To: uunet!luvthang.aquin.ori-cal.com!talmage Subject: Re: Increasing the number of concurrently open files Cc: icon-group The number of files you can have open at the same time is determined by your operating system, not by Icon. On some operating systems, you can specify the number. The method varies with the operating system. On other systems, it's "hardwired" and there's nothing you can do about it. Ralph Griswold / Dept of Computer Science / Univ of Arizona / Tucson, AZ 85721 +1 602 621 6609 ralph@cs.arizona.edu uunet!arizona!ralph From isidev!nowlin@uunet.uu.net Fri Jun 14 15:44:24 1991 Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Fri, 14 Jun 91 15:44:24 MST Received: from relay2.UU.NET by optima.cs.arizona.edu (4.1/15) id AA24767; Fri, 14 Jun 91 15:44:21 MST Received: from uunet.uu.net (via LOCALHOST.UU.NET) by relay2.UU.NET with SMTP (5.61/UUNET-internet-primary) id AA22433; Fri, 14 Jun 91 18:44:26 -0400 Date: Fri, 14 Jun 91 18:44:26 -0400 From: isidev!nowlin@uunet.uu.net Message-Id: <9106142244.AA22433@relay2.UU.NET> Received: from isidev.UUCP by uunet.uu.net with UUCP/RMAIL (queueing-rmail) id 184343.9427; Fri, 14 Jun 1991 18:43:43 EDT To: uunet!cs.arizona.edu!icon-group@uunet.uu.net Subject: Re: ansi routines > From: Richard L. Goerwitz > > shafto@EOS.ARC.NASA.GOV (Michael Shafto) writes: > > > Yes, and I would be interested in testing your new improved version. > > I wasn't clear enough: My version is expanded (in the sense that the ANSI > interface can be applied to non-ANSI terminals). I'm not sure that it > really constitutes an improvement. Anyway, I haven't had enough requests > to consider posting, so I reiterate the offer of sending them to anyone who > wants to use them. We (ISI) would like to see the expanded ansi routines to compare with the beta version of our Enhanced Character Interface (ECI). This is a character based windowing interface implemented in Icon at the C level. We demonstrated a prototype at the last ICEBOL conference. > It's really a good idea to used generalized I/O for any programs written in > Icon, since Icon runs on so many platforms. These new ANSI routines have > ... > The idea is to have a generalized library of screen functions that DOS > users can blindly use, which take up minimal space, are fairly fast, and > which can be augmented for Unix without having to change a single line of > ... > You know, speaking of screen control, I wrote a set of Icon-based windowing > routines some time ago. They let you open up virtual screens, move them > ... > The reason I didn't post them is quite simple: Although they were fast > enough for most purposes, they ate up way, way too much memory. > ... > I guess I wish that Icon had some sort of explicit pointer data type. ISI's Icon for 386 UNIX will provide an interesting interface to the standard curses/eti (Extended Terminal Interface) functionality introduced to UNIX with SVR3.2. We think many programs can benefit from a screen oriented user interface so we came up with ECI. It has the ability to open multiple "text", "menu", or "form" windows. Window borders, titles, sizes, etc. all have defaults but can be explicitly specified by the user. Everything happens at the C level so it's fast and pointers aren't needed. Programming with ECI is done at the appropriate level in Icon. For example, the code to create a menu looks something like this: choices := ["bank","savings and loan","mattress"] smenu := wcreate("menu","Choose a Savings Plan",choices) choice := post_menu(smenu) # displays the menu window and # returns the user's choice unpost_menu(smenu) # erases the menu We're interested in feedback on whether this functionality should be made a standard part of our Icon or an add-on. The reason for making it an add-on is because all this doesn't come for free. The size of iconx at least doubles. Any and all comments are appreciated. Thanks. --- --- | S | Iconic Software, Inc. - Jerry Nowlin - uunet!isidev!nowlin --- --- From icon-group-request@arizona.edu Fri Jun 14 19:43:50 1991 Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Fri, 14 Jun 91 19:43:50 MST Resent-From: icon-group-request@arizona.edu Received: from Arizona.edu (Merlin.Telcom.Arizona.EDU) by optima.cs.arizona.edu (4.1/15) id AA00938; Fri, 14 Jun 91 19:43:47 MST Received: from ucbvax.Berkeley.EDU by Arizona.edu with PMDF#10282; Fri, 14 Jun 1991 19:43 MST Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA15793; Fri, 14 Jun 91 19:36:27 -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, 14 Jun 1991 19:43 MST Date: 15 Jun 91 01:40:43 GMT From: cis.ohio-state.edu!pacific.mps.ohio-state.edu!linac!midway!ellis.uchicago.edu!goer@ucbvax.berkeley.edu (Richard L. Goerwitz) Subject: RE: ansi routines Sender: icon-group-request@arizona.edu Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: <088BCD8B5E200B2B@Arizona.edu> Message-Id: <1991Jun15.014043.20745@midway.uchicago.edu> X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.edu Organization: University of Chicago References: <9106142244.AA22433@relay2.UU.NET> In article <9106142244.AA22433@relay2.UU.NET> nowlin@isidev.UUCP writes: >We (ISI) would like to see the expanded ansi routines to compare with the >beta version of our Enhanced Character Interface (ECI). This is a >character based windowing interface implemented in Icon at the C level. We >demonstrated a prototype at the last ICEBOL conference. They are very minimal ANSI routines, and in fact are completely compatible with the ansi.icn file included in the IPL. I've been accumulating enough requests that I've decided to post the routines. They are appended below. >[Stuff on ECI - a great idea - deleted, as also some examples illustrating >high-level, generalized screen control.] > >We're interested in feedback on whether this functionality should be made a >standard part of our Icon or an add-on. The reason for making it an add-on >is because all this doesn't come for free. The size of iconx at least >doubles. Any and all comments are appreciated. Thanks. I'd vote that that you not include it as part of the standard package. First of all, is it OS-specific (only for systems with SysVr3 curses)? If so, then it definitely needs to be separated out. I hear of inter- faces being built for X, and perhaps for other visual environments, in addition to ECI. I guess I'd like to see them all built as add-ons. What would be really nice is if everyone kept in touch, and attempted to use a similar approach. -Richard ----------------------------- ansi2.icn ------------------------------ ############################################################################ # # Name: ansi2.icn # # Title: ANSI-based terminal control library # # Author: Ralph E. Griswold and Richard Goerwitz # # Version: 1.1 (pretty much untested) # ############################################################################ # # This package of procedures implements a subset of the ANSI terminal # control sequences. The names of the procedures are taken directly from # the ANSI names. If it is necessary to use these routines with non-ANSI # devices, link in iolib.icn, and (optionally) iscreen.icn as well. Use # will be made of whatever routines are made available via either of these # libraries. Be careful of naming conflicts if you link in iscreen.icn. # It contains procedures like "clear" and "boldface." # # CUB(i) Moves the cursor left i columns # CUD(i) Moves the cursor down i rows # CUF(i) Moves the cursor right i columns # CUP(i,j) Moves the cursor to row i, column j # CUU(i) Moves the cursor up i rows # ED(i) Erases screen: i = 0, cursor to end; i = 1, # beginning to cursor; i = 2, all (default 2) # EL(i) Erases data in cursor row: i = 0, cursor to # end; i = 1, beginning to cursor; i = 2, all # (default 0) # SGR(i) Sets video attributes: 0 = off; 1 = bold; 4 = # underscore; 5 = blink; 7 = reverse (default # 0) # # Note that not all so-called ANSI terminals support every ANSI # screen control sequence - not even the limited subset included in # this file. # # If you plan on using these routines with non-ANSI magic-cookie # terminals (e.g. a Wyse-50) then it is strongly recommended that you # link in iolib or itlib *and* iscreen (not just iolib or itlib by # itself). The routines WILL WORK with most magic cookie terminals; # they just don't always get all the modes displayed (because they # are basically too busy erasing the cookies). # ############################################################################ # # links: iolib or itlib, iscreen (all optional) # # see also: ansi.icn # ############################################################################ # For DOS, or any system using ANSI-conformant output devices, there # is no need to link any routines in. # For Unix systems, you may choose to link in itlib or iolib, and (if # desired) iscreen as well. Some of these may be in the IPL. You can # get any that aren't from Richard Goerwitz (goer@sophist.uchicago.edu). # link iolib, iscreen procedure _isANSI() static isANSI initial { if find("MS-DOS",&features) then { isANSI := 1 } else { if type(getname) == "procedure" then { if find("ansi",map(getname())) | getname() == "li" then isANSI := 1 else isANSI := &null } else { # We'll take a chance on the user knowing what he/she # is doing. isANSI := 1 # If you're not so confident, comment out the following # line: # stop("_isANSI: you need to link itlib or iolib") } } } return \isANSI end procedure CUD(i) if _isANSI() then writes("\^[[",i,"B") else { iputs(igoto(getval("DO"),i)) | { every 1 to i do iputs(getval("do")) | stop("CUD: no do capability") } } return end procedure CUB(i) if _isANSI() then writes("\^[[",i,"D") else { iputs(igoto(getval("LE"),i)) | { every 1 to i do iputs(getval("le")) | stop("CUB: no le capability") } } return end procedure CUF(i) if _isANSI() then writes("\^[[",i,"C") else { iputs(igoto(getval("RI"),i)) | { every 1 to i do iputs(getval("nd")) | stop("CUF: no nd capability") } } return end procedure CUP(i,j) if _isANSI() then writes("\^[[",i,";",j,"H") else iputs(igoto(getval("cm"), j, i)) | stop("CUP: no cm capability") return end procedure CUU(i) if _isANSI() then writes("\^[[",i,"A") else { iputs(igoto(getval("UP"),i)) | { every 1 to i do iputs(getval("up")) | stop("CUU: no up capability") } } return end procedure ED(i) /i := 2 if _isANSI() then { writes("\^[[",i,"J") } else { case i of { 0: iputs(getval("cd")) | stop("ED: no cd capability") 1: stop("ED: termcap doesn't specify capability") 2: { if type(emphasize) == "procedure" then clear() else iputs(getval("cl")) | stop("ED: no cl capability") } default: stop("ED: unknown clear code, ",i) } } return end procedure EL(i) /i := 0 if _isANSI() then { if i = 0 then writes("\^[[K") else writes("\^[[",i,"K") } else { case i of { 0: iputs(getval("ce")) | stop("EL: no ce capability") 1: stop("EL: termcap doesn't specify capability") 2: stop("EL: try using CUP to go to col 1, then EL(0)") default: stop("EL: unknown line clear code, ",i) } } return end procedure SGR(i) static isISCR initial { if type(emphasize) == "procedure" then isISCR := 1 } /i := 0 if _isANSI() then { writes("\^[[",i,"m") } else { case i of { 0: (\isISCR, normal()) | { every iputs(getval("me"|"so"|"ue")) } 1: (\isISCR, boldface()) | { iputs(getval("md"|"so"|"us")) } 4: (\isISCR, underline()) | { iputs(getval("us"|"md"|"so")) } 5: (\isISCR, blink()) | { iputs(getval("mb"|"us"|"me"|"so")) } 7: (\isISCR, emphasize()) | { iputs(getval("so"|"me"|"ue")) } default: stop("SGR: unknown mode, ",i) } } return end -- -Richard L. Goerwitz goer%sophist@uchicago.bitnet goer@sophist.uchicago.edu rutgers!oddjob!gide!sophist!goer From uunet!men2a!aquin!luvthang!talmage Wed Jun 19 11:02:15 1991 Received: from univers.cs.arizona.edu by cheltenham.cs.arizona.edu; Wed, 19 Jun 91 11:02:15 MST Received: from uunet.UUCP by univers.cs.arizona.edu; Wed, 19 Jun 91 11:02:11 MST Received: from uunet.uu.net (via LOCALHOST.UU.NET) by relay1.UU.NET with SMTP (5.61/UUNET-internet-primary) id AA13263; Wed, 19 Jun 91 11:30:08 -0400 Received: from men2a.UUCP by uunet.uu.net with UUCP/RMAIL (queueing-rmail) id 112857.16672; Wed, 19 Jun 1991 11:28:57 EDT Received: by men2a.ori-cal.com (smail2.5) id AA15669; 19 Jun 91 05:13:55 EDT (Wed) Received: by aquin.ORI-CAL.COM (smail2.5) id AA19638; 19 Jun 91 04:42:58 EDT (Wed) Received: by luvthang.aquin.ori-cal.com (1.05D/Amiga) id AA02459; Tue, 18 Jun 91 22:24:07 EST Date: Tue, 18 Jun 91 22:24:07 EST Message-Id: <9106190324.AA02459@luvthang.aquin.ori-cal.com> From: uunet!luvthang.aquin.ori-cal.com!talmage (David W. Talmage) To: uunet!icon-group Subject: FileManager class I've been thinking about that max open files problem I asked the Icon-Group about. One way to fix my problem is to recompile icont and iconx with a larger number of available file handles. I don't like that solution because it might involve a lot of compiler-specific work. Maybe there's a better way using Idol. Suppose there is a File class, a FileManager class, and at most one FileManager object per program. The FileManager guarantees there are no more than MaxOpenFiles (whatever that is) open at one time. Each File object registers itself with the FileManager, who keeps a table of files and their state (opened or closed). Before any File method can actually touch the file, that method must inform the FileManager object who ensures the file is opened by closing some other open file if necessary. Similarly, the FileManager object reopens temporarily closed files and positions their pointers to where ever they were when last closed. I like this solution because I can do it entirely in Idol and Icon. I dislike it because I'm now doing stuff the operating system should handle for me. ----------------------------------------------------------------------------- David W. Talmage (talmage@luvthang.aquin.ori-cal.com) "I need fifty dollars to make you hollar. I get paid to run this luvthang." From icon-group-request@arizona.edu Sun Jun 23 12:45:34 1991 Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Sun, 23 Jun 91 12:45:34 MST Resent-From: icon-group-request@arizona.edu Received: from Arizona.edu (Merlin.Telcom.Arizona.EDU) by optima.cs.arizona.edu (4.1/15) id AA00638; Sun, 23 Jun 91 12:45:30 MST Received: from ucbvax.Berkeley.EDU by Arizona.edu with PMDF#10282; Sun, 23 Jun 1991 12:44 MST Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA07687; Sun, 23 Jun 91 12:43:30 -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: Sun, 23 Jun 1991 12:45 MST Date: 23 Jun 91 17:42:41 GMT From: midway!ellis.uchicago.edu!goer@uunet.uu.net (Richard L. Goerwitz) Subject: Icon text-database Sender: icon-group-request@arizona.edu Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: Message-Id: <1991Jun23.174241.10359@midway.uchicago.edu> X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.edu Organization: University of Chicago This is the README file from a package I've been using now, on and off, for about a year. Some parts are better tested than others. I'll be happy to mail a shell archive of the whole package to anyone who asks. This is not a finished product, but rather a collection of tools that I'd enjoy having a few people play with, if they are so inclined. -Richard ________________________________________________________________________ Name: retrieve Language: Icon Contents: tools for word-based, indexed access to text files Requires: up-to-date Icon Program Library, up-to-date iconc/icont, UNIX -------- Overview: Scholars have traditionally split so-called "Classics," the Quran, the Bible, and generally any closely studied literary or religious text, into hierarchically arranged divisions (in the case of the Bible, these are books, chapters, and verses). Such divisions drastically simplify the process of citation and reference. Fortunately for those of us who need electronic access to these files, this hierarchical system of divisions permits easy representation using bit-fields, i.e. fixed-width series' of binary digits. Such representations are compact, and allow the programmer to implement high-level boolean operations and range-based searches using simple shifts, additions, and subtractions. The package in which this README file comes - "retrieve" - offers a naive, but generalized and fairly high-level tool for indexing texts which are divided up in the manner just described, and for performing word-based searches on them. These word-based searches offer wildcard-based access to word patterns (e.g. "give me every passage containing a word with the letters 'NIX'"). The search facilities also permit boolean and range-based specifications (e.g. "give me every instance of word X occurring within eleven sections of the word Y"). One can also access passages by both absolute (e.g. "give me book 1, chapter 3, verse 4"), and relative, location (e.g. "give me the passage occurring before/after the one I just looked at"). Retrieve does no compression of any kind, and is written entirely in Icon. As a result it is something of a disk hog, and takes a long time to index files. Surprisingly, though, once set up, files incorporated into the retrieve package can be accessed quite rapidly. After a brief initialization process (takes 2-4 seconds on a Sun4), absolute locations can be retrieved with no perceptible delay. The same is true of relative locations (again, after a lag on first invocation). Regular expression-based searches appear instantaneous on a fast machine (there is a just perceptible delay on a Sun4 for a four megabyte indexed file, five to ten seconds on a Xenix/386 box with a relatively slow disk). Boolean and range-based searches take the longest, varying widely according to their complexity and the number of "hits." -------- Installation: Retrieve is really not a program as such. It is a set of routines for indexing, and accessing indexed, files. Installation consists of four basic steps: 1) creating an indexable file 2) indexing that file 3) writing a program using the retrieve interface 4) compiling and running what you wrote in (3) These steps are discussed in detail in the following sections. -------- Step 1: Creating an Indexable File The format for indexable files must conform to a simple, but strict, set of guidelines. Basically, it must interleave a series of location designators (internally represented by so-called "bitmaps") with actual text: ::001:001:001 This is text. ::001:001:002 This is more text. The initial :: (double colon) delimits lines containing the location designators. These designators translate into integers dividable internally into (in this case) three bit-fields of length 10 (enough to handle 999:999:999), which serve as a location markers for the text that goes with them. Note that the translation process is invisible. All you need to do is make sure, a) that the location designators are correctly paired with blocks of text, and b) that the fields are numbered consistently, beginning with the same low value (usually 1 or 0), and continuing in ascending order until they roll over again to their low value Rather than speak merely in the abstract about the format, let me offer a simple illustration taken from the King James Bible. The first verse in the Bible is Genesis chapter 1 verse 1. This passage might be designated 1:1:1. Verses in Genesis chapter 1 would continue in ascending order to verse 31 (1:1:31), after which chapter 2 would begin (i.e. 1:2:1). The resulting text would look like: ::1:1:1 In the beginning God created the heaven and the earth. ::1:1:2 And the earth was without form, and void; and darkness was upon the face of the deep. And the Spirit of God moved upon the face of the waters. ::1:1:3 And God said, Let there be light: and there was light. ::1:1:4 And God saw the light, that it was good: and God divided the light from the darkness. ::1:1:5 And God called the light Day, and the darkness he called Night. And the evening and the morning were the first day. ... ::1:2:1 Thus the heavens and the earth were finished, and all the host of them. Although you can use any number of fields you want or need, and can use any nonnumeric separator (e.g. 01-01-01-05-03), lines containing location designators *must* begin with "::," and must be ordered sequentially throughout the input file, paired with the correct text block in each instance. -------- Step 2: Indexing the File Indexing the file created in step (1) entails compiling and invoking a program called "makeind." The compilation end of this process would typically be achieved by typing: icont -o makeind makeind.icn gettokens.icn indexutl.icn One of the files listed just above, gettokens.icn is of particular interest. It contains the tokenizing routine to be used in creating the main word index. Should this routine prove unsatisfactory for one reason or another, you are free to replace it with something more to your liking. Just comment out the old gettokens() routine, and insert the new one in its place. Then recompile. Once you have compiled makeind, you must invoke it for the text file you created in step (1). Invoking makeind involves specifying a file to be indexed, the number of fields in location markers for that file, and the maximum value for fields. If you plan on invoking passages by relative location, you must also use the -l option, which tells makeind to build a .LIM file, which records the high values for a specific field throughout the file being indexed. Let us say you have examined Genesis 1:31 in the Bible, and want to look at the next verse. The only easy way the the procedure which handles this particular chore can know the maximum verse value for Genesis chapter 1 (31) is to store this maximum value in a file. By supplying makeind with an -l argument, you are telling it to create such a file. Just for illustration's sake, let us suppose you want to index the King James Bible. How might you invoke makeind to accomplish this? First you would need to determine the maximum field value for your text. In the case of the Christian English Bible, this is 176. The English Bible (including Apocrypha) contains 73 books. The Protestant KJV contains 66. The maximum number of chapters in any book is 150 (Psalms). The maximum number of verses in any one chapter in any one book is 176 (Psalm 119). 176 would therefore be the maximum value any field would have to contain. You would pass this information to makeind via the -m option. The total number of fields is three, naturally (book, chapter, and verse). This value would be passed using the -n option. As noted above, in order to use relative locations you would need to tell makeind what field to record max values for. In our hypothesized scenario, you would want makeind to store the max value for the verse field for every chapter of every book in the input file. The verse field (field #3), in other words, is your "rollover" field, and would be passed to makeind using the -l option. Assuming "kjv" to be the name of your input file, this set of circumstances would imply the following invocation for makeind: makeind -f kjv -m 176 -n 3 -l 3 If you were to want a case-sensitive index (not a good idea), you would add "-s" to the argument list above. Actual English Bible texts usually take up 4-5 megabytes. Indexing one would require at least twice that much core memory, and would take at least an hour on a fast machine. The end result would be a set of data files occupying about 2 megabytes plus the 4-5 megabytes of the original file. Once these data files were created, they could be moved, along with the original source file, to any platform you desired. Having indexed, and having moved the files to wherever you wanted them, you would then be ready for step 3. -------- Step 3: Writing a Program to Access Indexed Files When accessing text files such as the Bible, the most useful unit for searches is normally the word. Let us suppose you are a zealous lay-speaker preparing a talk on fire imagery and divine wrath in the Bible. You would probably want to look for every passage in the text that contained words like fire, firy burn furnace etc. To refine the search, let us say that you want every instance of one of these fire words that occurs within one verse of a biblical title for God: God LORD etc. The searches for fire, firy, burn, etc. would be accomplished by calling a routine called retrieve(). Retrieve takes three arguments: retrieve(pattern, filename, invert_search) The first argument should be a string containing a regular expression based pattern, such as fir(y|e|iness)|flam(e|ing)|burn.*? Note that the pattern must match words IN THEIR ENTIRETY. So, for instance, "fir[ie]" would not catch "firiness," but rather only "fire." Likewise, if you want every string beginning with the sequence "burn," the string "burn" will not work. Use "burn.*" instead. The filename argument supplies retrieve() with the name of the original text file. The last argument, if nonnull, inverts the sense of the search (a la egrep -v). In the case of the fire words mentioned above, one would invoke retrieve() as follows: hits1 := retrieve("fir(y|e|iness)|flam(e|ing)|burn.*?", "kjv") For the divine names, one would do something along these lines: hits2 := retrieve("god|lord", "kjv") Having finished the basic word searches, one would then perform a set intersection on them. If we are looking for fire words which occur at most one verse away from a divine name, then we would specify 1 as our range (as opposed to, say, zero), and the verse as our unit. The utility you would use to carry out the search is r_and(). R_and() would be invoked as follows: hits3 := r_and(hits1, hits2, "kjv", 3, 1) The last two arguments, 3 and 1, specify field three (the "verse" field) and field 1 (the range). To display the text for your "hit list" (hits3 above), you would call bitmap_2_text(): every write(!bitmap_2_text(hits3, "kjv")) Bitmap_2_text converts the location designators contained in hits3 into actual text. The three basic functions mentioned above - retrieve(), r_and(), and bitmap_2_text() - are contained in the three files retrieve.icn, retrops.icn, and bmp2text.icn, respectively. Other useful routines are included in these files, and also in whatnext.icn. If you are planning on writing a retrieval engine for serious work of some kind, you would probably want to construct a mini interpreter, which would convert strings typed in by the user at run-time into internal search and retrieval operations. Note that I have included no routine to parse or expand human-readable input (the nature of which will naturally vary from text to text). For instance, it would be very useful to be able to ask for every passage in, say, Genesis chapters 2 through 4 in a biblical text, and to be able to print these to the screen. Doing this would require a parsing routine to break down the references, and map them to retrieve-internal format. The routine would then have to generate all valid locations from the minimum value in chapter 2 above to the max in chapter 4. See the file whatnext.icn for an illustration of how to generate location designators in a suitably step-like fashion. -------- Step 4: Compiling and Running Your Program Assuming you have written a search/retrieval program using the routines contained in retrieve.icn, retrops.icn, bmp2text.icn, and whatnext.icn, you would now be ready to compile it. In order to function properly, these routines would need to be linked with initfile.icn and indexutl.icn. Specific dependencies are noted in the individual files in case there is any confusion. If you have made significant use of this package, you probably should not worry about the exact dependencies, though. Just link everything in together, and worry about what isn't needed after you have fully tested your program: icont -o yourprog yourprog.icn initfile.icn indexutl.icn \ retrieve.icn retrops.icn bmp2text.icn binsrch.icn -------- Problems, bugs: This is really an alpha release of the retrieve package. I use it for various things. For instance, I recently retrieved a text file containing informal reviews of a number of Science Fiction works. My father likes SciFi, and it was close to Fathers' Day, so I indexed the file, and performed cross-referenced searches for words like "very good," "brilliant," and "excellent," omitting authors my father has certainly read (e.g. Herbert, Azimov, etc.). I also had occasion to write a retrieval engine for the King James Bible (hence the many examples from this text), and to construct a retrieval package for the Hebrew Bible, which I am now using to gather data for various chapters of my dissertation. If anyone else finds these routines useful, then great. Obviously, they could be written/maintained in C or something that might offer much better performance. They would, however, lose a lot of flexibility, and would have taken much, much longer to write. Right now, they occupy about 60k of basic source files, probably most of which consists of comments. When compiled together with a moderate-size user interface, the total package typically comes to about 120k. In core size typically runs about 350k on my home machine here (a Xenix/386 box), with the basic run-time interpreter taking up a good chunk of that space all on its own. It's not a small package, but I've found it a nice base for rapid prototyping and development of small search and retrieval engines. -- -Richard L. Goerwitz goer%sophist@uchicago.bitnet goer@sophist.uchicago.edu rutgers!oddjob!gide!sophist!goer From icon-group-request@arizona.edu Wed Jun 26 22:51:17 1991 Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Wed, 26 Jun 91 22:51:17 MST Resent-From: icon-group-request@arizona.edu Received: from Arizona.edu (Merlin.Telcom.Arizona.EDU) by optima.cs.arizona.edu (4.1/15) id AA08451; Wed, 26 Jun 91 22:51:14 MST Received: from ucbvax.Berkeley.EDU by Arizona.edu with PMDF#10282; Wed, 26 Jun 1991 22:50 MST Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA16039; Wed, 26 Jun 91 22:42:14 -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: Wed, 26 Jun 1991 22:51 MST Date: 27 Jun 91 04:15:03 GMT From: cis.ohio-state.edu!pacific.mps.ohio-state.edu!linac!midway!ellis.uchicago.edu!goer@ucbvax.berkeley.edu (Richard L. Goerwitz) Subject: gettext text retrieval routines Sender: icon-group-request@arizona.edu Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: <90B96666E4203D31@Arizona.edu> Message-Id: <1991Jun27.041503.4700@midway.uchicago.edu> X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.edu Organization: University of Chicago I posted some simple table-like access routines for files a while ago. If anyone cares, I used them in a package posted to comp. sources.misc called "jargon." They are a simple example of how these routines might be used. What I'm really posting for now is to see whether anyone has tried these routines out under anything but UNIX (say MS-DOS). I've not really tested them on anything but UNIX, and I just wonder whether anyone has beaten them around enough on another platform to know whether they work there. -- -Richard L. Goerwitz goer%sophist@uchicago.bitnet goer@sophist.uchicago.edu rutgers!oddjob!gide!sophist!goer From pearce@sce.carleton.ca Fri Jun 28 09:08:53 1991 Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Fri, 28 Jun 91 09:08:53 MST Received: from cygnus.sce.carleton.ca by optima.cs.arizona.edu (4.1/15) id AA13239; Fri, 28 Jun 91 09:08:48 MST Received: from terminus.sce.carleton.ca by cygnus.sce.carleton.ca (4.1/SMI-4.0) id AA04370; Fri, 28 Jun 91 12:10:19 EDT From: pearce@sce.carleton.ca (Trevor Pearce) Received: by terminus.sce.carleton.ca (4.1/Sun-Client) id AA14293; Fri, 28 Jun 91 12:10:17 EDT Message-Id: <9106281610.AA14293@terminus.sce.carleton.ca> Subject: ICON theorem prover? To: icon-group@cs.arizona.edu (ICON news group) Date: Fri, 28 Jun 91 12:10:16 EDT X-Mailer: ELM [version 2.3 PL11] Hello, I am new to the news group and I am a "beginner" with ICON. My research involves a string-oriented software specification technique and I am interested in experimenting with support tools programmed in ICON. More ambitiously, I am interested in the suitability of ICON for constructing a first-order logic theorem prover. (As an introduction to ICON I programmed a "toy" theorem prover that uses the tableau method to try to find counter-examples of propositional logic "theorems". The code is not pretty -- typical of a novice -- but it seems to work on simple examples.) I would be glad to communicate with anyone who has experience with (or is interested in) using ICON to construct a theorem prover. Regards, Trevor Pearce Department of Systems and Computer Engineering Carleton University Ottawa, Canada K1S 5B6 email: pearce@sce.carleton.ca From icon-group-request@arizona.edu Sun Jun 30 08:41:37 1991 Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Sun, 30 Jun 91 08:41:37 MST Resent-From: icon-group-request@arizona.edu Received: from Arizona.edu (Merlin.Telcom.Arizona.EDU) by optima.cs.arizona.edu (4.1/15) id AA04073; Sun, 30 Jun 91 08:41:35 MST Received: from ucbvax.Berkeley.EDU by Arizona.edu with PMDF#10282; Sun, 30 Jun 1991 08:41 MST Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA04303; Sun, 30 Jun 91 08:40:31 -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: Sun, 30 Jun 1991 08:41 MST Date: 30 Jun 91 09:00:41 GMT From: coyote!jmh@noao.edu (John Hughes) Subject: A Strange/Dumb SNOBOL/SPITBOL Question... Sender: icon-group-request@arizona.edu Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: <3EB11B66DC800DA8@Arizona.edu> Message-Id: <1991Jun30.090041.23568@coyote.datalog.com> X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.edu Organization: Datalog Consulting, Tucson, AZ Please pardon what might seem like an odd question, but... I am currently looking about for a Unix version of SPITBOL. I've seen some references to something called SPITBOL-68 (which would be just right for me, since the machine of intent happens to be a 68000-based box). Does anyone have information about such a thing? Many thanks in advance. -- | John M. Hughes | "...unfolding in consciousness at the | | datalog.com!moondog!jmh | deliberate speed of pondering." - Daniel Dennet | | jmh%coyote@noao.edu |--------------------------------------------------| | jmh%moondog@datalog.com | P.O.Box 43305, Tucson, AZ 85733 602-624-8008 | From icon-group-request@arizona.edu Sun Jun 30 10:58:01 1991 Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Sun, 30 Jun 91 10:58:01 MST Resent-From: icon-group-request@arizona.edu Received: from Arizona.edu (Merlin.Telcom.Arizona.EDU) by optima.cs.arizona.edu (4.1/15) id AA06347; Sun, 30 Jun 91 10:58:00 MST Received: from ucbvax.Berkeley.EDU by Arizona.edu with PMDF#10282; Sun, 30 Jun 1991 10:57 MST Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA06575; Sun, 30 Jun 91 10:43:11 -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: Sun, 30 Jun 1991 10:57 MST Date: 30 Jun 91 17:38:18 GMT From: cis.ohio-state.edu!zaphod.mps.ohio-state.edu!caen!hellgate.utah.edu!basset.utah.edu!hollaar@ucbvax.berkeley.edu (Lee Hollaar) Subject: RE: A Strange/Dumb SNOBOL/SPITBOL Question... Sender: icon-group-request@arizona.edu Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: <51BF7B62828009C5@Arizona.edu> Message-Id: <1991Jun30.113818.16300@hellgate.utah.edu> X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.edu Organization: University of Utah CS Dept References: <1991Jun30.090041.23568@coyote.datalog.com> In article <1991Jun30.090041.23568@coyote.datalog.com> jmh@coyote.datalog.com (John Hughes) writes: >I am currently looking about for a Unix version of SPITBOL. I've seen some >references to something called SPITBOL-68 (which would be just right for me, >since the machine of intent happens to be a 68000-based box). Does anyone >have information about such a thing? SPITBOL-68000 is available from: Catspaw, Inc. Post Office Box 1123 Salida CO 81201 719/539-3384 It runs on a variety of 68000-based machines, including Sun-3's, Apollos, and HP's. There is also Sparc SPITBOL for Sun-4's. From uunet!men2a!aquin!luvthang!talmage Tue Jul 2 08:56:17 1991 Received: from univers.cs.arizona.edu by cheltenham.cs.arizona.edu; Tue, 2 Jul 91 08:56:17 MST Received: from uunet.UUCP by univers.cs.arizona.edu; Tue, 2 Jul 91 08:56:16 MST Received: from uunet.uu.net (via LOCALHOST.UU.NET) by relay1.UU.NET with SMTP (5.61/UUNET-internet-primary) id AA12230; Tue, 2 Jul 91 11:05:12 -0400 Received: from men2a.UUCP by uunet.uu.net with UUCP/RMAIL (queueing-rmail) id 110445.6814; Tue, 2 Jul 1991 11:04:45 EDT Received: by men2a.ori-cal.com (smail2.5) id AA28645; 2 Jul 91 11:08:46 EDT (Tue) Received: by aquin.ORI-CAL.COM (smail2.5) id AA11489; 2 Jul 91 10:56:16 EDT (Tue) Received: by luvthang.aquin.ori-cal.com (1.05D/Amiga) id AA02475; Tue, 2 Jul 91 07:19:14 EST Date: Tue, 2 Jul 91 07:19:14 EST Message-Id: <9107021219.AA02475@luvthang.aquin.ori-cal.com> From: uunet!luvthang.aquin.ori-cal.com!talmage (David W. Talmage) To: arizona!icon-group Subject: Re: gettext text retrieval routines Richard L. Goerwitz (goer%sophist@uchicago.bitnet) writes: :What I'm really posting for now is to see whether anyone has tried :these routines out under anything but UNIX (say MS-DOS). I've not I've made them work under AmigaDOS on my Amiga 2000. They worked nearly without change. I've even used them with Clint Jeffery's Idol langauge to construct a class called IndexedFile. ----------------------------------------------------------------------------- David W. Talmage (talmage@luvthang.aquin.ori-cal.com) "I need fifty dollars to make you hollar. I get paid to run this luvthang." From icon-group-request@arizona.edu Tue Jul 2 11:36:53 1991 Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Tue, 2 Jul 91 11:36:53 MST Resent-From: icon-group-request@arizona.edu Received: from Arizona.edu (Merlin.Telcom.Arizona.EDU) by optima.cs.arizona.edu (4.1/15) id AA08030; Tue, 2 Jul 91 11:36:50 MST Received: from ucbvax.Berkeley.EDU by Arizona.edu with PMDF#10282; Tue, 2 Jul 1991 11:36 MST Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA18430; Tue, 2 Jul 91 11:28:58 -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: Tue, 2 Jul 1991 11:36 MST Date: 2 Jul 91 17:54:35 GMT From: cis.ohio-state.edu!pacific.mps.ohio-state.edu!linac!midway!ellis.uchicago.edu!goer@ucbvax.berkeley.edu (Richard L. Goerwitz) Subject: king james bible browser Sender: icon-group-request@arizona.edu Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: Message-Id: <1991Jul2.175435.4687@midway.uchicago.edu> X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.edu Organization: University of Chicago As a base for testing some other software I have around, I've written a King James Bible browser, which offers full and quick access to any passage in the Bible, as well as word and word-pattern based searches, and also boolean and range-based operations. Even though it's writ- ten in Icon, it's still very fast. For example, finding every passage which contains the word "love" takes a fraction of a second on my home machine (a Xenix/386 box with a slow disk). Finding every passage that contains the words sackcloth and ashes takes about half a second. Finding every passage that contains the word patterns "cry.*" and "weep.*" takes five seconds. A killer search, such as one for every passage that contains "lord" and "god," takes 25 seconds. On a Sun4, the times are cut down to as little as 1/10 of what they are for me at home. The real disadvantage to the package is that it is a memory hog, both in terms of mass and main storage. The King James Bible is a 5 mega- byte text, and the indexes for it take up another 2 megs. Creating the indexes takes up to 14 meg core memory, and will bring many workstations to their knees. Sorry. I wrote the blasted thing just on a whim, so don't send me hate male while your machine swaps itself into oblivion. It's a useful package once you've gotten past the hump. The program requires an Icon Program Library, and will probably work under Icon version 7 or 8 (haven't tried 7, actually). It also needs a Unix box to run efficiently. Anyone interested, please let me know. I'll mail you a shell archive. -- -Richard L. Goerwitz goer%sophist@uchicago.bitnet goer@sophist.uchicago.edu rutgers!oddjob!gide!sophist!goer From icon-group-request@arizona.edu Tue Jul 2 14:35:22 1991 Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Tue, 2 Jul 91 14:35:22 MST Resent-From: icon-group-request@arizona.edu Received: from Arizona.edu (Merlin.Telcom.Arizona.EDU) by optima.cs.arizona.edu (4.1/15) id AA15584; Tue, 2 Jul 91 14:35:20 MST Received: from ucbvax.Berkeley.EDU by Arizona.edu with PMDF#10282; Tue, 2 Jul 1991 14:34 MST Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA24399; Tue, 2 Jul 91 14:26:48 -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: Tue, 2 Jul 1991 14:35 MST Date: 2 Jul 91 20:44:39 GMT From: usc!elroy.jpl.nasa.gov!sdd.hp.com!zaphod.mps.ohio-state.edu!cis.ohio-state.edu!pacific.mps.ohio-state.edu!linac!midway!ellis.uchicago.edu!goer@ucsd.edu (Richard L. Goerwitz) Subject: RE: king james bible browser Sender: icon-group-request@arizona.edu Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: <0270BF4CDC8014B3@Arizona.edu> Message-Id: <1991Jul2.204439.9692@midway.uchicago.edu> X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.edu Organization: University of Chicago References: <1991Jul2.175435.4687@midway.uchicago.edu> I, goer@ellis.uchicago.edu (Richard L. Goerwitz), write (regarding a simple King James Bible viewer): >Anyone interested, please let me know. I'll mail you a shell archive. I had no idea that there were so many religious (or just plain curious) people on this newsgroup. My mailbox is suddenly full - and this right before the 4th. Anyway, I think it's going to make sense to post the program to comp. sources.misc or alt.sources. Perhaps here. Suggestions? Two people asked me whether the King James Bible text was included with the package. For space reasons (5 meg or so), no. You can get it from simtel, or from a number of other places. There exist versions which will not work. I see one here on midway.uchicago.edu. Two other people asked whether they had to use the KJV, and not some other version. The answer is: If you *have* another version, and can write a small program to put it into indexable format, then yes, you can use any biblical text you want. The program is really very gen- eral in design. In fact, the reason I wrote it was to test a program package I wrote as a set of generalized search/retrieval utilities. The KJV browser is just a simple front-end for this more basic pack- age. Anyway, the bottom line is: I'm looking for a sensible way to dis- tribute the program, without necessitating mailing out shell archives to everyone. Ideas? -- -Richard L. Goerwitz goer%sophist@uchicago.bitnet goer@sophist.uchicago.edu rutgers!oddjob!gide!sophist!goer From nowlin@iwtqg.att.com Tue Jul 2 16:34:18 1991 Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Tue, 2 Jul 91 16:34:18 MST Message-Id: <9107022334.AA20011@optima.cs.arizona.edu> Received: from att.att.com by optima.cs.arizona.edu (4.1/15) id AA20011; Tue, 2 Jul 91 16:34:16 MST From: nowlin@iwtqg.att.com Date: Tue, 2 Jul 91 15:02 CDT Original-From: iwtqg!nowlin (Jerry D Nowlin +1 312 979 7268) To: icon-group@cs.arizona.edu Subject: Re: king james bible browser > The program requires an Icon Program Library, and will probably work > under Icon version 7 or 8 (haven't tried 7, actually). It also needs > a Unix box to run efficiently. You left out the most crucial requirement. It also requires an on-line King James Bible. That'll be too big to post unless you limit it to the parts everyone agrees on. To save time I included those at the end of this message :-) Jerry Nowlin ...!att!iwtqg!nowlin From icon-group-request@arizona.edu Tue Jul 2 22:03:45 1991 Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Tue, 2 Jul 91 22:03:45 MST Resent-From: icon-group-request@arizona.edu Received: from Arizona.edu (Merlin.Telcom.Arizona.EDU) by optima.cs.arizona.edu (4.1/15) id AA29763; Tue, 2 Jul 91 22:03:40 MST Received: from ucbvax.Berkeley.EDU by Arizona.edu with PMDF#10282; Tue, 2 Jul 1991 22:03 MST Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA08291; Tue, 2 Jul 91 21:49:20 -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: Tue, 2 Jul 1991 22:03 MST Date: 3 Jul 91 04:15:13 GMT From: midway!ellis.uchicago.edu!goer@uunet.uu.net (Richard L. Goerwitz) Subject: RE: king james bible browser Sender: icon-group-request@arizona.edu Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: <41102FEA2C801984@Arizona.edu> Message-Id: <1991Jul3.041513.21190@midway.uchicago.edu> X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.edu Organization: University of Chicago References: <9107022334.AA20011@optima.cs.arizona.edu> Jerry Nowlin (nowlin@iwtqg.att.com) writes, regarding my lapse (forget- ting to tell people they need a KJV text to run my browser): >You left out the most crucial requirement. It also requires an on-line >King James Bible. That'll be too big to post unless you limit it to the >parts everyone agrees on. To save time I included those at the end of >this message :-) You can get the original PC-SIG KJV distribution (19 disks) from the Simtel archive. You can also get it from helens.stanford.edu, and from several other places (check the anonymous ftp listings). Note that not all of these texts will work with the browser. Many have been mangled in various ways. If anyone has another version, please send me a sam- ple, and I'll code up a program to "fix" it for use with the browser. BTW: Jerry, I figured I could count on some sarcastic comment from someone - if not about using the archaic King James version, then about posting a Bible browser at all. I guess I didn't figure you for the perpetrator. Let me just send the browser to those who are interested, and we can discuss its deeper ramifications over a beer some day. The decision has been made to post to alt.sources for the first round. I'll then post it to comp.sources.misc if there's demand. Those who don't get the alt hierarchy, please ask me for a shell archive. This time around the requests should be few enough that I'll be able to handle them all individually. Thanks to everyone who wrote. It's nice to feel like some of this software I write for other purposes can be made useful to a broader sector (in this case, simply by putting a visual wrapper around it, and setting it up for the KJV). -- -Richard L. Goerwitz goer%sophist@uchicago.bitnet goer@sophist.uchicago.edu rutgers!oddjob!gide!sophist!goer From icon-group-request@arizona.edu Wed Jul 3 08:20:53 1991 Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Wed, 3 Jul 91 08:20:53 MST Resent-From: icon-group-request@arizona.edu Received: from Arizona.edu (Merlin.Telcom.Arizona.EDU) by optima.cs.arizona.edu (4.1/15) id AA19834; Wed, 3 Jul 91 08:20:51 MST Received: from ucbvax.Berkeley.EDU by Arizona.edu with PMDF#10282; Wed, 3 Jul 1991 08:20 MST Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA21175; Wed, 3 Jul 91 08:08:50 -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: Wed, 3 Jul 1991 08:20 MST Date: 3 Jul 91 14:18:06 GMT From: cis.ohio-state.edu!zaphod.mps.ohio-state.edu!rpi!news-server.csri.toronto.edu!utgpu!cunews!bnrgate!bwdls58!bcarh172!channen@ucbvax.berkeley.edu (Peter Channen) Subject: source code for icon Sender: icon-group-request@arizona.edu Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: <974A27E38C80173F@Arizona.edu> Message-Id: <7191@bwdls58.bnr.ca> X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.edu Organization: Bell-Northern Research Ltd. Hi, I recently acquired Richard Goerwitz's jargon program (posted to comp.sources.misc), but don't have icon to compile it. Is there an anonymous ftp site that I can ftp the source for icon to run under HP-UX 7.05? Thanks in advance, Peter Channen channen@bnr.ca From icon-group-request@arizona.edu Thu Jul 11 13:16:59 1991 Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Thu, 11 Jul 91 13:16:59 MST Resent-From: icon-group-request@arizona.edu Received: from Arizona.edu (Merlin.Telcom.Arizona.EDU) by optima.cs.arizona.edu (4.1/15) id AA00198; Thu, 11 Jul 91 13:16:57 MST Received: from ucbvax.Berkeley.EDU by Arizona.edu with PMDF#10282; Thu, 11 Jul 1991 13:16 MST Received: by ucbvax.berkeley.edu (5.63/1.42) id AA12577; Thu, 11 Jul 91 13:01:47 -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, 11 Jul 1991 13:16 MST Date: 11 Jul 91 17:37:16 GMT From: agate!spool.mu.edu!sol.ctr.columbia.edu!ira.uka.de!ira.uka.de@ucbvax.berkeley.edu (Angelo Schneider Betr.Prechelt) Subject: How to call a generator from everywhere Sender: icon-group-request@arizona.edu Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: <09FAADBF2E80373D@Arizona.edu> Message-Id: X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.edu Organization: University of Karlsruhe, FRG Well, I hope my Problem is simple! I have a generator which gives me every word from the inputstream. So I can write: every write(GetWord()) But I want something like this: procedure main() ... if GetWord() == "KEYWORD" then DoKeyword(); ... end #main; procedure DoKeyword() ... if GetWord() == "anything" then do anything; ^^^^^^^^^^^^ end #DoKeyword; ^^^here I want GetWord to continue ( resume ) at that state it suspended in main. Is this possible? thanx angelo From icon-group-request@arizona.edu Thu Jul 11 17:16:43 1991 Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Thu, 11 Jul 91 17:16:43 MST Resent-From: icon-group-request@arizona.edu Received: from Arizona.edu (Merlin.Telcom.Arizona.EDU) by optima.cs.arizona.edu (4.1/15) id AA09335; Thu, 11 Jul 91 17:16:40 MST Received: from ucbvax.Berkeley.EDU by Arizona.edu with PMDF#10282; Thu, 11 Jul 1991 17:15 MST Received: by ucbvax.berkeley.edu (5.63/1.42) id AA21155; Thu, 11 Jul 91 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, 11 Jul 1991 17:16 MST Date: 11 Jul 91 20:09:29 GMT From: att!linac!midway!ellis.uchicago.edu!goer@ucbvax.berkeley.edu (Richard L. Goerwitz) Subject: RE: How to call a generator from everywhere Sender: icon-group-request@arizona.edu Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: <2B753D509E803520@Arizona.edu> Message-Id: <1991Jul11.200929.23411@midway.uchicago.edu> X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.edu Organization: University of Chicago References: Angelo rites: >I have a generator which gives me every word from the input stream, >so I can write: > > every write(GetWord()) > >But I want something like this: > >procedure main() >... > if GetWord() == "KEYWORD" then DoKeyword(); >... >end #main; > >procedure DoKeyword() >... > if GetWord() == "anything" then do anything; >end #DoKeyword; > >^^^here I want GetWord to continue ( resume ) at that state it suspended > in main. > > Is this possible? It looks to me as though you want to do this, every word := GetWord() do { case word of { pattern1 : action1() pattern2 : action2() etc. default : write(word) } } where pattern1, pattern2 etc. are keywords, and action1, action2, etc. are procedures which do something when their corresponding keywords are encoun- tered. If you want to get really clever, you could write procedures that are the same as the keywords, yielding: procedure main() every word := GetWord() do write(proc(word)() | word) end procedure KEYWORD() return "Wow, a keyword." end procedure anything() return "did anything" end This way, if word == "KEYWORD" or "anything" the procedure corresponding to these strings will get invoked. If no such procedure exists, proc() will fail, and word will get written. I expect this won't be altogether clear, so try playing around with it a bit. -- -Richard L. Goerwitz goer%sophist@uchicago.bitnet goer@sophist.uchicago.edu rutgers!oddjob!gide!sophist!goer From icon-group-request@arizona.edu Sat Jul 13 11:49:29 1991 Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Sat, 13 Jul 91 11:49:29 MST Resent-From: icon-group-request@arizona.edu Received: from Arizona.edu (Merlin.Telcom.Arizona.EDU) by optima.cs.arizona.edu (4.1/15) id AA17622; Sat, 13 Jul 91 11:49:27 MST Received: from ucbvax.Berkeley.EDU by Arizona.edu with PMDF#10282; Sat, 13 Jul 1991 11:48 MST Received: by ucbvax.berkeley.edu (5.63/1.42) id AA23815; Sat, 13 Jul 91 11:36:08 -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: Sat, 13 Jul 1991 11:49 MST Date: 13 Jul 91 18:20:22 GMT From: mcsun!unido!ira.uka.de!ira.uka.de@uunet.uu.net (Angelo Schneider Betr.Prechelt) Subject: RE: How to call a generator from everywhere Sender: icon-group-request@arizona.edu Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: <9015FEC44E8014B6@Arizona.edu> Message-Id: X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.edu Organization: University of Karlsruhe, FRG References: , <1991Jul11.200929.23411@midway.uchicago.edu> [ My earlier posting deleted ] In article <1991Jul11.200929.23411@midway.uchicago.edu|, goer@ellis.uchicago.edu (Richard L. Goerwitz) writes: | | It looks to me as though you want to do this, | every word := GetWord() do { | case word of { | pattern1 : action1() | pattern2 : action2() | etc. | default : write(word) | } | } | [ some stuff deleted here ] | If you want to get really clever, you could write procedures that are the | same as the keywords, yielding: | | procedure main() From icon-group-request@arizona.edu Mon Jul 15 08:56:10 1991 Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Mon, 15 Jul 91 08:56:10 MST Resent-From: icon-group-request@arizona.edu Received: from Arizona.edu (Merlin.Telcom.Arizona.EDU) by optima.cs.arizona.edu (4.1/15) id AA25846; Mon, 15 Jul 91 08:55:47 MST Received: from ucbvax.Berkeley.EDU by Arizona.edu with PMDF#10282; Mon, 15 Jul 1991 08:52 MST Received: by ucbvax.berkeley.edu (5.63/1.42) id AA16509; Mon, 15 Jul 91 08:50:58 -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: Mon, 15 Jul 1991 08:54 MST Date: 15 Jul 91 15:49:38 GMT From: cis.ohio-state.edu!zaphod.mps.ohio-state.edu!qt.cs.utexas.edu!cs.utexas.edu!uwm.edu!convex.csd.uwm.edu!corre@ucbvax.berkeley.edu (Alan D Corre) Subject: getch(e)() Sender: icon-group-request@arizona.edu Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: <0A016E5D3E804228@Arizona.edu> Message-Id: <14078@uwm.edu> X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.edu Organization: University of Wisconsin - Milwaukee In the kind of programming I do, I find it useful to allow the user to view or not view input at will. Typically, the input may be processed a character at a time, possibly appearing in a different font. The following procedure initially behaves exactly like getche(). If it is called with an argument it subsequently behaves like getch() and will continue to do so until toggled by another call with an argument. The user can precipitate this by entering some predetermined character, e.g. if char == "~" then {getc(1); next} procedure getc(a) static g,other local ch initial g := ((other := "getch") || "e") if \a then g :=: other else ch := g() return ch end From icon-group-request@arizona.edu Fri Jul 19 13:18:20 1991 Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Fri, 19 Jul 91 13:18:20 MST Resent-From: icon-group-request@arizona.edu Received: from Arizona.edu (Merlin.Telcom.Arizona.EDU) by optima.cs.arizona.edu (4.1/15) id AA23299; Fri, 19 Jul 91 13:17:14 MST Received: from ucbvax.Berkeley.EDU by Arizona.edu with PMDF#10282; Thu, 18 Jul 1991 16:17 MST Received: by ucbvax.berkeley.edu (5.63/1.42) id AA02482; Thu, 18 Jul 91 16:05:34 -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 Jul 1991 16:17 MST Date: 18 Jul 91 21:08:45 GMT From: midway!ellis.uchicago.edu!goer@uunet.uu.net (Richard L. Goerwitz) Subject: KJV program posted to comp.sources.misc Sender: icon-group-request@arizona.edu Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: Message-Id: <1991Jul18.210845.1956@midway.uchicago.edu> X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.edu Organization: University of Chicago Due to a somewhat higher than expected demand for the Bible browser I've mentioned here, I eventually ended up posting to comp.sources. misc. Just not enough sites got alt.sources, and I kept having lots of people write, saying stuff like "I heard about your KJV program, but the original alt.sources posting has since expired, and...." Now it's in the comp.sources.misc archives, and can be ftp'd by anyone who ends up deciding to give it a test drive. Note: It's not anything very complicated, and the real meat of the package is really not meant for Bible work - it's just a generalized interface for text retrieval. Anyone with a CCAT RSV online, please drop me a line, and I will send you patches relative to the comp.sources.misc posting (version 1.0) that might actually make installation automatic for you as well (I do not have the disk space to test the installation for the RSV here). Please don't send me mail asking for the CCAT RSV, by the way. It's a huge text, and I can't put it up for ftp (still less keep in online here). There's a certain amount of red tape involved in getting it, and you're best off just sending a note to: CCAT Box 36 College Hall University of Pennsylvania Philadelphia (my home town!), PA 19104 USA -- -Richard L. Goerwitz goer%sophist@uchicago.bitnet goer@sophist.uchicago.edu rutgers!oddjob!gide!sophist!goer From icon-group-request@arizona.edu Sat Jul 20 02:16:10 1991 Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Sat, 20 Jul 91 02:16:10 MST Resent-From: icon-group-request@arizona.edu Received: from Arizona.edu (Osprey.Telcom.Arizona.EDU) by optima.cs.arizona.edu (4.1/15) id AA22991; Sat, 20 Jul 91 02:16:07 MST Received: from ucbvax.Berkeley.EDU by Arizona.edu with PMDF#10282; Sat, 20 Jul 1991 02:15 MST Received: by ucbvax.berkeley.edu (5.63/1.42) id AA29016; Sat, 20 Jul 91 02:05:53 -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: Sat, 20 Jul 1991 02:15 MST Date: 19 Jul 91 05:44:13 GMT From: agate!usenet.ins.cwru.edu!magnus.acs.ohio-state.edu!zaphod.mps.ohio-state.edu!usc!orion.oac.uci.edu!unogate!unocal!genisco!arcturus!felix!ka%felix.UUCP@ucbvax.berkeley.edu (Kenneth Almquist) Subject: RE: How to call a generator from everywhere Sender: icon-group-request@arizona.edu Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: Message-Id: <167724@felix.UUCP> X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.edu References: angelo@i43s3.ira.uka.de (Angelo Schneider Betr.Prechelt) writes: > I have a generator which gives me every word from the inputstream. > [But I want to invoke the generator from multiple locations without > restarting it.] To do this you need a co-expression. The GetNextWord procedure below illustrates how this is done. Simply replace your calls to GetWord with calls to GetNextWord. (Of course GetNextWord is sufficiently simple that you might want to simply substitute the code in line rather than use a this procedure.) Note that a given call to GetNextWord will only return a single result. The GetWord procedure which appears below illustrates how to perform the opposite conversion. The first time GetWord is invoked, it loops calling ReadWord (a routine which has the same semantics as GetNextWord, but which doesn't call GetWord), and suspends with each word read. It also stores the words in the list "l", so that subsequent invocations of GetWord will start at the beginning of the input. By the way, can anyone suggest something thats better than "while 1" for infinite loops? Kenneth Almquist --------------------------------- procedure main() # Perform a simple test of GetNextWord and GetWord. local word # Write all input words, two per line while word := GetNextWord() do { writes(word) if word := GetNextWord() then writes(" ", word) write() } # Write all input words, one per line every write(GetWord()) end procedure GetNextWord() static coexpr # The coexpression initial coexpr := create GetWord() # Create coexpression on first call return @coexpr # Return next value of coexpression end procedure GetWord() static l # list of words read local word # the word just read initial l := [] suspend !l # Return any words read previously while word := ReadWord() do { # Read the next word of input put(l, word) # Remember word (for subsequent calls) suspend word # Pass word back to caller } end procedure ReadWord() static line, loc, wordset, eofflag local start initial wordset := &lcase ++ &ucase if \eofflag then fail while 1 do { if /line then { line := read() | break loc := 1 } if start := upto(wordset, line, loc, 0) then { loc := many(wordset, line, start, 0) return line[start : loc] } line := &null } eofflag := 1 fail end From icon-group-request@arizona.edu Sat Jul 20 03:18:23 1991 Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Sat, 20 Jul 91 03:18:23 MST Resent-From: icon-group-request@arizona.edu Received: from Arizona.edu (Osprey.Telcom.Arizona.EDU) by optima.cs.arizona.edu (4.1/15) id AA26164; Sat, 20 Jul 91 03:18:15 MST Received: from ucbvax.Berkeley.EDU by Arizona.edu with PMDF#10282; Sat, 20 Jul 1991 03:17 MST Received: by ucbvax.berkeley.edu (5.63/1.42) id AA01571; Sat, 20 Jul 91 03:03:59 -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: Sat, 20 Jul 1991 03:17 MST Date: 20 Jul 91 08:02:44 GMT From: agate!usenet.ins.cwru.edu!magnus.acs.ohio-state.edu!zaphod.mps.ohio-state.edu!uwm.edu!linac!mp.cs.niu.edu!ux1.cso.uiuc.edu!midway!ellis.uchicago.edu!goer@ucbvax.berkeley.edu (Richard L. Goerwitz) Subject: Huffman encoding tools Sender: icon-group-request@arizona.edu Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: Message-Id: <1991Jul20.080244.10740@midway.uchicago.edu> X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.edu Organization: University of Chicago A long time ago, I asked whether anyone had written compression programs for Icon. I received a pointer to one program - press.icn (in the Icon Program Library). It's basically a dictionary-inspired method that's re- flected in press (LZW), and it has the advantage of being adaptive. For reasons which I don't want to burden anyone with, I found that for some projects I'm working on, I had to be able to encode and decode blocks at random locations within a file, so LZW was out. Here are some Huffman encoding tools that do the trick. This post is in fulfillment of several promises I made to summarize anything useful I found out. -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 07/20/1991 08:38 UTC by goer@sophist.uchicago.edu # Source directory /u/richard/Huffstuf # # 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 # ------ ---------- ------------------------------------------ # 9663 -r--r--r-- huffstuf.icn # 1205 -r--r--r-- inbits.icn # 3067 -r--r--r-- outbits.icn # 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 # ============= huffstuf.icn ============== if test -f 'huffstuf.icn' -a X"$1" != X"-c"; then echo 'x - skipping huffstuf.icn (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp echo 'x - extracting huffstuf.icn (Text)' sed 's/^X//' << 'SHAR_EOF' > 'huffstuf.icn' && X############################################################################ X# X# Name: huffstuf.icn X# X# Title: huffman coding tools X# X# Author: Richard L. Goerwitz X# X# Version: 1.2 X# X############################################################################ X# X# An odd assortment of tools that lets me compress text using an X# Iconish version of a generic Huffman algorithm. X# X############################################################################ X# X# Links: codeobj ./outbits.icn ./inbits.icn X# X# See also: hufftab.icn, press.icn X# X############################################################################ X X# From the IPL. Xlink codeobj X X# Necessary records. Xrecord nodE(l,r,n) Xrecord _ND(l,r) Xrecord leaF(c,n) Xrecord huffcode(c,i,len) X X# For debugging purposes. X# link ximage X X# Count of chars in input file. Xglobal count_of_all_chars X X Xprocedure main(a) X X local direction, usage, size, char_tbl, heap, tree, h_tbl X usage := "huffcode -i|o filename1" X X direction := pop(a) | stop(usage) X direction ?:= { ="-"; tab(any('oi')) } | stop(usage) X *a = 1 | stop(usage) X X intext := open(a[1]) | quitprog("huffcode", "can't open "||a[1], 1) X size := 80 X X if direction == "o" then { X X char_tbl := table() X while count_chars_in_s(reads(intext), char_tbl) X heap := initialize_heap(char_tbl) X tree := heap_2_tree(heap) X h_tbl := hash_codes(tree) X X put_tree(&output, tree) X seek(intext, 1) X every writes(&output, encode_string(|reads(intext, size), h_tbl)) X X } X else { X tree := get_tree(intext) X every writes(&output, decode_rest_of_file(intext, size, tree)) X } X Xend X X Xprocedure count_chars_in_s(s, char_tbl) X X # X # Count chars in s, placing stats in char_tbl (keys = chars in X # s, values = leaF records, with the counts for each chr in s X # contained in char_tbl[chr].n). X # X local chr X initial { X /char_tbl & X quitprog("count_chars_in_s", "need 2 args - 1 string, 2 table", 9) X *char_tbl ~= 0 & X quitprog("count_chars_in_s","start me with an empty table",8) X count_of_all_chars := 0 X } X X # Reset character count on no-arg invocation. X /s & /char_tbl & { X count_of_all_chars := 0 X return X } X X # Insert counts for characters into char_tbl. Note that we don't X # just put them into the table as-is. Rather, we put them into X # a record which contains the character associated with the count. X # These records are later used by the Huffman encoding algorithm. X s ? { X while chr := move(1) do { X count_of_all_chars +:= 1 X /char_tbl[chr] := leaF(chr,0) X char_tbl[chr].n +:= 1 X } X } X return *char_tbl # for lack of anything better X Xend X X Xprocedure initialize_heap(char_tbl) X X # X # Create heap data structure out of the table filled out by X # successive calls to count_chars_in_s(s,t). The heap is just a X # list. Naturally, it's size can be obtained via *heap. X # X local heap X X heap := list() X every push(heap, !char_tbl) do X reshuffle_heap(heap, 1) X return heap X Xend X X Xprocedure reshuffle_heap(h, k) X X # X # Based loosely on Sedgewick (2nd. ed., 1988), p. 160. Take k-th X # node on the heap, and walk down the heap, switching this node X # along the way with the child whose value is the least AND whose X # value is less than this node's. Stop when you find no children X # whose value is less than that of the original node. Elements on X # heap are records of type leaF, with the values contained in the X # "n" field. X # X local j X X # While we haven't spilled off the end of the heap (the size of the X # heap is *h; *h / 2 is the biggest k we need to look at)... X while k <= (*h / 2) do { X X # ...double k, assign the result to j. X j := k+k X X # If we aren't at the end of the heap... X if j < *h then { X # ...check to see which of h[k]'s children is the smallest, X # and make j point to it. X if h[j].n > h[j+1].n then X # h[j] :=: h[j+1] X j +:= 1 X } X X # If the current parent (h[k]) has a value less than those of its X # children, then break; we're done. X if h[k].n <= h[j].n then break X X # Otherwise, switch the parent for the child, and loop around X # again, with k (the pointer to the parent) now pointing to the X # new offset of the element we have been working on. X h[k] :=: h[j] X k := j X X } X X return k X Xend X X Xprocedure heap_2_tree(h) X X # X # Construct the Huffman tree out of heap h. Find the smallest X # element, pop it off the heap, then reshuffle the heap. After X # reshuffling, replace the top record on the stack with a nodE() X # record whose n field equal to the sum of the n fields for the X # element popped off the stack originally, and the one that is X # now about to be replaced. Link the new nodE record to the 2 X # elements on the heap it is now replacing. Reshuffle the heap X # again, then repeat. You're done when the size of the heap is X # 1. That one element remaining (h[1]) is your Huffman tree. X # X # Based loosely on Sedgewick (2nd ed., 1988), p. 328-9. X # X local frst, scnd, count X X until *h = 1 do { X X h[1] :=: h[*h] # Reverse first and last elements. X frst := pull(h) # Pop last elem off & save it. X reshuffle_heap(h, 1) # Resettle the heap. X scnd := !h # Save (but don't clobber) top element. X X count := frst.n + scnd.n X frst := { if *frst = 2 then frst.c else _ND(frst.l, frst.r) } X scnd := { if *scnd = 2 then scnd.c else _ND(scnd.l, scnd.r) } X X h[1] := nodE(frst, scnd, count) # Create new nodE(). X reshuffle_heap(h, 1) # Resettle once again. X } X X # H is no longer a stack. It's single element - the root of a X # Huffman tree made up of nodE()s and leaF()s. Put the l and r X # fields of that element into an _ND record, and return the new X # record. X return _ND(h[1].l, h[1].r) X Xend X X Xprocedure hash_codes(tr) X X # X # Hash Huffman codes. Tr (arg 1) is a Huffman tree created by X # heap_2_tree(heap). Output is a table, with the keys X # representing characters, and the values being records of type X # huffcode(i,len), where i is the Huffcode (an integer) and len is X # the number of bits it occupies. X # X local code X X huff_tbl := table() X every code := collect_bits(tr) do X insert(huff_tbl, code.c, code) X return huff_tbl X Xend X X Xprocedure collect_bits(tr, i, len) X X # X # Decompose Huffman tree tr into huffcode() records which contain X # 3 fields: c (the character encoded), i (its integer code), X # and len (the number of bytes the integer code occupies). Sus- X # pend one such record for each character encoded in tree tr. X # X X if type(tr) == "string" then X return huffcode(tr, i, len) X else { X (/len := 1) | (len +:= 1) X (/i := 0) | (i *:= 2) X suspend collect_bits(tr.l, i, len) X i +:= 1 X suspend collect_bits(tr.r, i, len) X } X Xend X X Xprocedure put_tree(f, tr) X X # X # Writes Huffman tree tr to file f. Uses first two bits to store X # the size of the tree. X # X local stringized_tr X # global count_of_all_chars X X /f | /tr & quitprog("put_tree","I need two nonnull arguments",7) X X stringized_tr := encode(tr) X every writes(f, outbits(*stringized_tr, 16)) # use two bytes X outbits() # just in case X writes(f, stringized_tr) X # How many characters are there in the input file? X every writes(f, outbits(count_of_all_chars, 32)) X outbits() X Xend X X Xprocedure get_tree(f) X X # X # Reads in Huffman tree from file f, sets pointer to the first X # encoded bit (as opposed to the bits which form the tree des- X # cription) in file f. X # X local stringized_tr_size, tr X # global count_of_all_chars X X stringized_tr_size := inbits(f, 16) X tr := decode(reads(f, stringized_tr_size)) | X quitprog("get_tree", "can't decode tree", 6) X count_of_all_chars := inbits(f, 32) | X quitprog("get_tree", "garbled input file", 10) X return tr X Xend X X Xprocedure encode_string(s, huffman_table) X X # X # Encode string s using the codes in huffman_table (created by X # hash_codes, which in turns uses the Huffman tree created by X # heap_2_tree). X # X # Make sure you are using reads() and not read, unless you don't X # want to preserve newlines. X # X local s2, chr, hcode # hcode stores huffcode records X static chars_written X initial chars_written := 0 X X s2 := "" X s ? { X while chr := move(1) do { X chars_written +:= 1 X hcode := \huffman_table[chr] | X quitprog("encode_string", "unexpected char, "||image(chr), 11) X every s2 ||:= outbits(hcode.i, hcode.len) X } X # If at end of output stream, then flush outbits buffer. X if chars_written = count_of_all_chars then { X chars_written := 0 X s2 ||:= outbits() X } else { X if chars_written > count_of_all_chars then { X chars_written := 0 X quitprog("encode_string", "you're trying to write _ X more chars than you originally tabulated", 12) X } X } X } X return s2 X Xend X X Xprocedure decode_rest_of_file(f, size, huffman_tree) X X local s2, line, E, chr, bit X static chars_decoded X initial chars_decoded := 0 X X E := huffman_tree X while line := reads(f, size) do { X line ? { X s2 := "" X while chr := move(1) do { X every bit := iand(1, ishift(ord(chr), -7 to 0)) do { X E := { if bit = 0 then E.l else E.r } X if s2 ||:= string(E) then { X chars_decoded +:= 1 X if chars_decoded = count_of_all_chars then { X chars_decoded := 0 X break { break break } X } X else E := huffman_tree X } X } X } X suspend s2 X } X } X suspend s2 X Xend X X Xprocedure quitprog(p, m, c) X X /m := "program error" X write(&errout, p, ": ", m) X exit(\c | 1) X Xend SHAR_EOF true || echo 'restore of huffstuf.icn failed' rm -f _shar_wnt_.tmp fi # ============= inbits.icn ============== if test -f 'inbits.icn' -a X"$1" != X"-c"; then echo 'x - skipping inbits.icn (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp echo 'x - extracting inbits.icn (Text)' sed 's/^X//' << 'SHAR_EOF' > 'inbits.icn' && X############################################################################ X# X# Name: inbits.icn X# X# Title: read in variable length characters from a file X# X# Author: Richard L. Goerwitz X# X# Version: 1.2 X# X############################################################################ X# X# This procedure, inbits(), re-imports data converted into writable X# form by outbits(). See the file outbits.icn for all the whys and X# hows. X# X############################################################################ X# X# Links: none X# X# See also: outbits.icn X# X############################################################################ X X Xprocedure inbits(f, len) X X local i, byte, old_byte_mask X static old_byte, old_len, byte_length X initial { X old_byte := old_len := 0 X byte_length := 8 X } X X old_byte_mask := (0 < 2^old_len - 1) | 0 X old_byte := iand(old_byte, old_byte_mask) X i := ishift(old_byte, len-old_len) X X len -:= (len > old_len) | { X old_len -:= len X return i X } X X while byte := ord(reads(f)) do { X i := ior(i, ishift(byte, len-byte_length)) X len -:= (len > byte_length) | { X old_len := byte_length-len X old_byte := byte X return i X } X } X Xend SHAR_EOF true || echo 'restore of inbits.icn failed' rm -f _shar_wnt_.tmp fi # ============= outbits.icn ============== if test -f 'outbits.icn' -a X"$1" != X"-c"; then echo 'x - skipping outbits.icn (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp echo 'x - extracting outbits.icn (Text)' sed 's/^X//' << 'SHAR_EOF' > 'outbits.icn' && X############################################################################ X# X# Name: outbits.icn X# X# Title: output variable-length characters in byte-size chunks X# X# Author: Richard L. Goerwitz X# X# Version: 1.5 X# X############################################################################ X# X# In any number of instances (e.g. when outputting variable-length X# characters or fixed-length encoded strings), the programmer must X# fit variable and/or non-byte-sized blocks into standard 8-bit X# bytes. Outbits() performs this task. X# X# Pass to outbits(i, len) an integer i, and a length parameter (len), X# and outbits will suspend byte-sized chunks of i converted to X# characters (most significant bits first) until there is not enough X# left of i to fill up an 8-bit character. The remaining portion is X# stored in a buffer until outbits() is called again, at which point X# the buffer is combined with the new i and then output in the same X# manner as before. The buffer is flushed by calling outbits() with X# a null i argument. Note that len gives the number of bits there X# are in i (or at least the number of bits you want preserved; those X# that are discarded are the most significant ones). X# X# A trivial example of how outbits() might be used: X# X# outtext := open("some.file.name","w") X# l := [1,2,3,4] X# every writes(outtext, outbits(!l,3)) X# writes(outtext, outbits(&null,3)) # flush buffer X# X# List l may be reconstructed with inbits() (see inbits.icn): X# X# intext := open("some.file.name") X# l := [] X# while put(l, inbits(intext, 3)) X# X# Note that outbits() is a generator, while inbits() is not. X# X############################################################################ X# X# Links: none X# See also: inbits.icn X# X############################################################################ X X Xprocedure outbits(i, len) X X local old_part, new_part, window, old_byte_mask X static old_i, old_len, byte_length, byte_mask X initial { X old_i := old_len := 0 X byte_length := 8 X byte_mask := (2^byte_length)-1 X } X X old_byte_mask := (0 < 2^old_len - 1) | 0 X window := byte_length - old_len X old_part := ishift(iand(old_i, old_byte_mask), window) X X # If we have a no-arg invocation, then flush buffer (old_i). X if /i then { X if old_len > 0 then { X old_i := old_len := 0 X return char(old_part) X } else { X old_i := old_len := 0 X fail X } X } else { X new_part := ishift(i, window-len) X len -:= (len >= window) | { X old_len +:= len X old_i := ior(ishift(old_part, len-window), i) X fail X } X# For debugging purposes. X# write("old_byte_mask = ", old_byte_mask) X# write("window = ", image(window)) X# write("old_part = ", image(old_part)) X# write("new_part = ", image(new_part)) X# write("outputting ", image(ior(old_part, new_part))) X suspend char(ior(old_part, new_part)) X } X X until len < byte_length do { X suspend char(iand(ishift(i, byte_length-len), byte_mask)) X len -:= byte_length X } X X old_len := len X old_i := i X fail X Xend SHAR_EOF true || echo 'restore of outbits.icn failed' rm -f _shar_wnt_.tmp fi exit 0 -- -Richard L. Goerwitz goer%sophist@uchicago.bitnet goer@sophist.uchicago.edu rutgers!oddjob!gide!sophist!goer From isidev!nowlin@uunet.uu.net Sat Jul 20 06:10:10 1991 Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Sat, 20 Jul 91 06:10:10 MST Received: from relay1.UU.NET by optima.cs.arizona.edu (4.1/15) id AA29080; Sat, 20 Jul 91 06:10:07 MST Received: from uunet.uu.net (via LOCALHOST.UU.NET) by relay1.UU.NET with SMTP (5.61/UUNET-internet-primary) id AA25593; Sat, 20 Jul 91 09:10:05 -0400 Date: Sat, 20 Jul 91 09:10:05 -0400 From: isidev!nowlin@uunet.uu.net Message-Id: <9107201310.AA25593@relay1.UU.NET> Received: from isidev.UUCP by uunet.uu.net with UUCP/RMAIL (queueing-rmail) id 090958.24960; Sat, 20 Jul 1991 09:09:58 EDT To: uunet!cs.arizona.edu!icon-group@uunet.uu.net Subject: Re: ...generator from everywhere > Kenneth Almquist writes: > > angelo@i43s3.ira.uka.de (Angelo Schneider Betr.Prechelt) writes: > > I have a generator which gives me every word from the inputstream. > > [But I want to invoke the generator from multiple locations without > > restarting it.] > > To do this you need a co-expression... This is an excellent example of a use for co-expressions. Good response. > By the way, can anyone suggest something thats better than "while 1" > for infinite loops? Icon has a built in infinite loop control structure called repeat. You just do this: repeat { other stuff } The only way out of this loop is a return or break. --- --- | S | Iconic Software, Inc. - Jerry Nowlin - uunet!isidev!nowlin --- --- From icon-group-request@arizona.edu Sat Jul 20 21:46:20 1991 Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Sat, 20 Jul 91 21:46:20 MST Resent-From: icon-group-request@arizona.edu Received: from Arizona.edu (Osprey.Telcom.Arizona.EDU) by optima.cs.arizona.edu (4.1/15) id AA17051; Sat, 20 Jul 91 21:46:18 MST Received: from ucbvax.Berkeley.EDU by Arizona.edu with PMDF#10282; Sat, 20 Jul 1991 21:45 MST Received: by ucbvax.berkeley.edu (5.63/1.42) id AA02420; Sat, 20 Jul 91 21:38:52 -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: Sat, 20 Jul 1991 21:46 MST Date: 13 Jul 91 18:20:22 GMT From: bloom-picayune.mit.edu!snorkelwacker.mit.edu!ira.uka.de!ira.uka.de@bloom-beacon.mit.edu (Angelo Schneider Betr.Prechelt) Subject: RE: How to call a generator from everywhere Sender: icon-group-request@arizona.edu Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: <63A0FDCE9060C8B8@Arizona.edu> Message-Id: X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.edu Organization: University of Karlsruhe, FRG References: , <1991Jul11.200929.23411@midway.uchicago.edu> [ My earlier posting deleted ] In article <1991Jul11.200929.23411@midway.uchicago.edu|, goer@ellis.uchicago.edu (Richard L. Goerwitz) writes: | | It looks to me as though you want to do this, | every word := GetWord() do { | case word of { | pattern1 : action1() | pattern2 : action2() | etc. | default : write(word) | } | } | [ some stuff deleted here ] | If you want to get really clever, you could write procedures that are the | same as the keywords, yielding: | | procedure main() From uunet!men2a!aquin!luvthang!talmage Mon Jul 22 15:17:20 1991 Received: from univers.cs.arizona.edu by cheltenham.cs.arizona.edu; Mon, 22 Jul 91 15:17:20 MST Received: from uunet.UUCP by univers.cs.arizona.edu; Mon, 22 Jul 91 15:17:19 MST Received: from uunet.uu.net (via LOCALHOST.UU.NET) by relay2.UU.NET with SMTP (5.61/UUNET-internet-primary) id AA22855; Mon, 22 Jul 91 13:22:15 -0400 Received: from men2a.UUCP by uunet.uu.net with UUCP/RMAIL (queueing-rmail) id 132118.16539; Mon, 22 Jul 1991 13:21:18 EDT Received: by men2a.ori-cal.com (smail2.5) id AA17051; 22 Jul 91 13:16:20 EDT (Mon) Received: by aquin.ORI-CAL.COM (smail2.5) id AA11868; 22 Jul 91 13:04:22 EDT (Mon) Received: by luvthang.aquin.ori-cal.com (1.05D/Amiga) id AA02575; Mon, 22 Jul 91 11:48:39 EST Date: Mon, 22 Jul 91 11:48:39 EST Message-Id: <9107221648.AA02575@luvthang.aquin.ori-cal.com> From: uunet!luvthang.aquin.ori-cal.com!talmage (David W. Talmage) To: uunet!icon-group Subject: Looking for Idol users Over the past seven months, I've been using Clint Jeffery's Idol lanagage. I find it a useful and well-designed language. I'd like to other Idol users about starting a mailing list, tentatively called idol-group. Its purpose will be similar to that of the icon-group: to further discussion about Idol and to provide a forum for exchanging useful code. I volunteer to maintain the list for now. If you're interested, even vaguely, please contact me by e-mail. David W. Talmage uunet!luvthang!talmage talmage@luvthang.aquin.ori-cal.com From R.J.Hare@edinburgh.ac.uk Tue Jul 23 17:58:19 1991 Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Tue, 23 Jul 91 17:58:19 MST Received: from Arizona.edu (Osprey.Telcom.Arizona.EDU) by optima.cs.arizona.edu (4.1/15) id AA07122; Tue, 23 Jul 91 17:57:48 MST Received: from UKACRL.BITNET (MAILER@UKACRL) by Arizona.edu with PMDF#10282; Tue, 23 Jul 1991 17:36 MST Received: from RL.IB by UKACRL.BITNET (Mailer R2.07) with BSMTP id 5948; Tue, 23 Jul 91 16:46:01 BST Received: from RL.IB by UK.AC.RL.IB (Mailer R2.07) with BSMTP id 1006; Tue, 23 Jul 91 16:46:00 BST Date: 23 Jul 91 16:46:50 bst From: R.J.Hare@edinburgh.ac.uk Subject: comparing one file to another To: icon-group@cs.arizona.edu Message-Id: <23 Jul 91 16:46:50 bst 060328@EMAS-A> X-Envelope-To: icon-group@cs.arizona.edu Via: UK.AC.ED.EMAS-A; 23 JUL 91 16:45:57 BST I have at last persuaded some colleagues to use Icon, and they are getting pretty enthusiastic. They have an application involving the searching of large files containing postcodes (plus other information) for matches with postcodes contained in smaller files, and displaying the whole record from the larger file when a match is made. I can see several ways of doing this, but don't have a feel for which is the 'best' For example, should we read the postcodes being searched for into a list or set and then compare every member of the list or set with the postcode portion of the record from the main file? Any advice would be appreciated. Thanks. Roger Hare. PS: A postcode is the UK equivalent of a zip code, I guess. From wgg@cs.washington.edu Wed Jul 24 08:52:08 1991 Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Wed, 24 Jul 91 08:52:08 MST Received: from june.cs.washington.edu by optima.cs.arizona.edu (4.1/15) id AA06722; Wed, 24 Jul 91 08:52:04 MST Received: by june.cs.washington.edu (5.64a/7.1ju) id AA21779; Wed, 24 Jul 91 08:51:47 -0700 Date: Wed, 24 Jul 91 08:51:47 -0700 From: wgg@cs.washington.edu (William Griswold) Return-Path: Message-Id: <9107241551.AA21779@june.cs.washington.edu> To: R.J.Hare@edinburgh.ac.uk, icon-group@cs.arizona.edu Subject: Re: comparing one file to another >From: R.J.Hare@edinburgh.ac.uk >Subject: comparing one file to another >... >searching of large files containing postcodes (plus other information) >for matches with postcodes contained in smaller files, and displaying >the whole record from the larger file when a match is made. >... >For example, should we read the postcodes being searched for into a list >or set and then compare every member of the list or set with the >postcode portion of the record from the main file? >... I would consider translating the smaller file into a set of postal codes, and then the following would be possible: postalcodes := set() while insert(postalcodes,read(postalcode_file)) while entry := get_entry(big_address_file) do if member(postalcodes, entry.postalcode) then display_entry(entry) As written, this requires defining an address record type and some functions for manipulating addresses, which wouldn't be a bad idea if you ever planned on doing anything else with the addresses. However, if you preferred, you could just code string parsing operations in-line. I'm sure that there are cleverer solutions, but this should be fine. Bill Griswold From uunet!men2a!aquin!luvthang!talmage Wed Jul 24 15:09:44 1991 Received: from univers.cs.arizona.edu by cheltenham.cs.arizona.edu; Wed, 24 Jul 91 15:09:44 MST Received: from uunet.UUCP by univers.cs.arizona.edu; Wed, 24 Jul 91 15:09:45 MST Received: from uunet.uu.net (via LOCALHOST.UU.NET) by relay1.UU.NET with SMTP (5.61/UUNET-internet-primary) id AA10220; Wed, 24 Jul 91 15:06:32 -0400 Received: from men2a.UUCP by uunet.uu.net with UUCP/RMAIL (queueing-rmail) id 150514.21326; Wed, 24 Jul 1991 15:05:14 EDT Received: by men2a.ori-cal.com (smail2.5) id AA28667; 24 Jul 91 15:04:52 EDT (Wed) Received: by aquin.ORI-CAL.COM (smail2.5) id AA08065; 24 Jul 91 15:00:59 EDT (Wed) Received: by luvthang.aquin.ori-cal.com (1.05D/Amiga) id AA02699; Wed, 24 Jul 91 13:28:51 EST Date: Wed, 24 Jul 91 13:28:51 EST Message-Id: <9107241828.AA02699@luvthang.aquin.ori-cal.com> From: uunet!luvthang.aquin.ori-cal.com!talmage (David W. Talmage) To: uunet!icon-group Subject: Icon version of reopen()? Does anyone have an Icon version of the file function reopen()? It's supposed to reopen a new file using an existing file handle, closing the old file before reusing the handle. I've written one in Idol for a file manager I wrote, but I don't have one for Icon that works exactly as I've described. ----------------------------------------------------------------------------- David W. Talmage (talmage@luvthang.aquin.ori-cal.com) "I need fifty dollars to make you hollar. I get paid to run this luvthang." From R.J.Hare@edinburgh.ac.uk Thu Jul 25 15:52:12 1991 Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Thu, 25 Jul 91 15:52:12 MST Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by optima.cs.arizona.edu (4.1/15) id AA10777; Thu, 25 Jul 91 15:52:07 MST Received: from UKACRL.BITNET (MAILER@UKACRL) by Arizona.edu with PMDF#10282; Thu, 25 Jul 1991 15:51 MST Received: from RL.IB by UKACRL.BITNET (Mailer R2.07) with BSMTP id 9592; Thu, 25 Jul 91 09:35:56 BST Received: from RL.IB by UK.AC.RL.IB (Mailer R2.07) with BSMTP id 2266; Thu, 25 Jul 91 09:35:56 BST Date: 25 Jul 91 09:36:48 bst From: R.J.Hare@edinburgh.ac.uk Subject: File comparing To: icon-group@cs.arizona.edu Message-Id: <25 Jul 91 09:36:48 bst 060620@EMAS-A> X-Envelope-To: icon-group@cs.arizona.edu Via: UK.AC.ED.EMAS-A; 25 JUL 91 9:35:54 BST Thanks to all who replied to my query about matching lines in a query file with thos in a master file for UK Postcodes. Several approaches, all look good in different circumstances. What I have done is provide a short deomnstration program (all that is needed at this stage) using sets to prove that Icon can handle the large(ish) amounts of data being processed. A simple postcode search program (about 9 lines) gets through the 5Mb Scottish postcode file in about 90 seconds. Good enough, I am told. Once again, thanks to all who responded - I think I replied to each message individually - if I didn't please accept this message as my thanks. Roger Hare. From uunet!men2a!aquin!luvthang!talmage Fri Jul 26 10:46:29 1991 Received: from univers.cs.arizona.edu by cheltenham.cs.arizona.edu; Fri, 26 Jul 91 10:46:29 MST Received: from uunet.UUCP by univers.cs.arizona.edu; Fri, 26 Jul 91 10:46:27 MST Received: from uunet.uu.net (via LOCALHOST.UU.NET) by relay1.UU.NET with SMTP (5.61/UUNET-internet-primary) id AA21563; Fri, 26 Jul 91 13:11:24 -0400 Received: from men2a.UUCP by uunet.uu.net with UUCP/RMAIL (queueing-rmail) id 131034.24374; Fri, 26 Jul 1991 13:10:34 EDT Received: by men2a.ori-cal.com (smail2.5) id AA04229; 26 Jul 91 13:09:43 EDT (Fri) Received: by aquin.ORI-CAL.COM (smail2.5) id AA06835; 26 Jul 91 13:03:45 EDT (Fri) Received: by luvthang.aquin.ori-cal.com (1.05D/Amiga) id AA02771; Fri, 26 Jul 91 07:52:39 EST Date: Fri, 26 Jul 91 07:52:39 EST Message-Id: <9107261252.AA02771@luvthang.aquin.ori-cal.com> From: uunet!luvthang.aquin.ori-cal.com!talmage (David W. Talmage) To: uunet!idol-group Cc: uunet!icon-group Subject: Idol-group charter About a week ago, I solicited interest in forming an Idol mailing list. Here my proposal for the mailing list charter, it's statement of purpose. Please send comments, if any, to uunet!luvthang!idol-group or idol-group@luvthang.aquin.ori-cal.com. David W. Talmage uunet!luvthang!talmage talmage@luvthang.aquin.ori-cal.com ---------- This is the proposed charter of the idol-group. The idol-group is an unmoderated mailing list for people interested in the Idol language. Idol, an "Icon-derived object language"[1], is "an object-oriented extension and environment for the Icon programming language."[2] The idol-group will be a forum for discussing Idol programming, object-oriented programming, and Idol implementation issues. It will also be a place to exchange Idol classes and programs, contributing to the library of useful Idol code. To submit something to the idol-group, send e-mail to uunet!luvthang!idol-group or idol-group-request@luvthang.aquin.ori-cal.com. For idol-group administrivia, including subscribing and unsubscribing, send e-mail to uunet!luvthang!idol-group-request or idol-group-request@luvthang.aquin.ori-cal.com. If you want to subscribe, please give your name, your e-mail address, and an optional summary of your interest in Idol. These introductions will be forwarded to the idol-group at your request. To unsubscribe, send an e-mail request to uunet!luvthang!idol-group-request or idol-group-request@luvthang.aquin.ori-cal.com. Ask to be removed from the list. Please include your name and e-mail address. David Talmage, idol-group coordinator uunet!luvthang!talmage talmage@luvthang.aquin.ori-cal.com [1], [2]: Jeffery, Clinton L., "TR90-10", Dept. of Computer Science, University of Arizona. May 8, 1991. From iphase!!chuck@uunet.uu.net Tue Jul 30 12:47:55 1991 Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Tue, 30 Jul 91 12:47:55 MST Resent-From: iphase!!chuck@uunet.uu.net Received: from Arizona.edu (Merlin.Telcom.Arizona.EDU) by optima.cs.arizona.edu (4.1/15) id AA11598; Tue, 30 Jul 91 12:47:52 MST Received: from relay2.UU.NET by Arizona.edu with PMDF#10282; Tue, 30 Jul 1991 12:47 MST Received: from uunet.uu.net (via LOCALHOST.UU.NET) by relay2.UU.NET with SMTP (5.61/UUNET-internet-primary) id AA22093; Tue, 30 Jul 91 15:47:20 -0400 Received: from iphase.UUCP by uunet.uu.net with UUCP/RMAIL (queueing-rmail) id 154636.22767; Tue, 30 Jul 1991 15:46:36 EDT Received: by iphase (4.0/SMI-4.0) id AA07743; Tue, 30 Jul 91 14:14:11 CDT Resent-Date: Tue, 30 Jul 1991 12:47 MST Date: Tue, 30 Jul 91 14:14:10 CDT From: chuck%@@uunet.uu.net (Chuck Diehl COMM) Subject: SUBSCRIBE Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: Message-Id: <9107301914.AA07743@iphase> X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.edu X-Mailer: ELM [version 2.3 PL0] From ksr!ksr.com!tim@uunet.uu.net Fri Aug 2 22:56:47 1991 Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Fri, 2 Aug 91 22:56:47 MST Received: from relay2.UU.NET by optima.cs.arizona.edu (4.1/15) id AA17896; Fri, 2 Aug 91 22:56:34 MST Received: from uunet.uu.net (via LOCALHOST.UU.NET) by relay2.UU.NET with SMTP (5.61/UUNET-internet-primary) id AA08875; Sat, 3 Aug 91 01:56:31 -0400 Received: from ksr.UUCP by uunet.uu.net with UUCP/RMAIL (queueing-rmail) id 015519.11903; Sat, 3 Aug 1991 01:55:19 EDT Received: from kaos.ksr.com by ksr.com (4.0/SMI-3.2) id AA21869; Sat, 3 Aug 91 01:30:24 EDT Received: by kaos.ksr.com (4.0/SMI-3.2) id AA26526; Sat, 3 Aug 91 01:30:23 EDT Message-Id: <9108030530.AA26526@kaos.ksr.com> To: icon-group@cs.arizona.edu Subject: Coexp memory leak in Icon V8 (UNIX, SPARC)?; i^0 bug Date: Sat, 03 Aug 91 01:30:21 -0400 From: Tim Peters Apologies in advance if this isn't the right place to report suspected Icon problems. Have a rather large Icon program that's crawling over linked graph structures (dags, really -- but it doesn't matter). Wrote the graph traversal algorithms to be invoked as coexpressions, as in posttrav := create traverse_postorder( root_of_graph ) while next_vertex := @posttrav do ... Inside the graph-crawlers, "the next" vertex is returned to the caller via next_vertex @ &source The graph-crawlers are highly recursive, and the real point of doing a coexp switch instead of a suspend inside them (coupled with an "every" in the caller) was to avoid the overhead of suspending & resuming thru many recursive levels each time. Timing in fact showed that this *did* save a good chunk of time over the more-straightforward coding via every/suspend. But when the problem instances started getting bigger, very large slowdowns (factors of 10-50) started showing up, and memory use went thru the roof. The simple program below reproduces what I think the culprit to be: the used-up coexp memory is apparently never being reclaimed, so garbage collection keeps uselessly thrashing over larger & larger regions of "lost" memory (or, if that isn't the case, it's a darned good imitation of the truth ). Here's the program: >>> BEGIN TEST CASE record vertex( a, b, c, d, e, f, g ) procedure main( args ) local i, limit, coexp limit := integer(get(args)) | 100 write( "Host: ", &host ) write( "Version: ", &version ) write( "Features:" ) every write( " ", &features ) every i := 1 to limit do { (i < 5 | i = limit) & dumpstats(i) coexp := create inner() while @coexp } end # procedure main procedure inner() vertex() @ &source fail end # procedure inner procedure dumpstats( i ) local c c := create &collections # gimmick to skip the first return value write( "iter ", i ) writes(r("collections")); @c; every writes(r(|@c)); write() writes(r("regions")); every writes(r(®ions)); write() writes(r("storage")); every writes(r(&storage)); write() end # procedure dumpstats procedure r( s ) return right( s, 12 ) end # procedure r >>> END TEST CASE And here's the output: >>> BEGIN OUTPUT Host: kaos Version: Icon Version 8.0. May 7, 1990 Features: UNIX ASCII co-expressions direct execution environment variables error trace back executable images expandable regions external functions large integers math functions memory monitoring pipes string invocation system function iter 1 collections 0 0 0 regions 20000 65024 65024 storage 20000 124 192 iter 2 collections 1 0 0 regions 30000 65024 65024 storage 30000 120 288 iter 3 collections 2 0 0 regions 30000 65024 65024 storage 30000 120 384 iter 4 collections 4 0 0 regions 40000 65024 65024 storage 40000 120 480 iter 100 collections 101 0 0 regions 1000000 65024 65024 storage 1000000 120 9696 >>> END OUTPUT This was run on a SPARC (Solbourne) -- know a way around it? Some notes: - It does *not* make any difference to add the lines coexp := &null or coexp := &null; collect() after the "while @coexp" line. - The coexpression in dumpstats() has no effect on this one way or the other; just used it here because it was convenient; the problem remains if dumpstats is purged of coexpressions. - The output above shows that the static region just grows & grows. It's also true (although the output above does not show this (at least not clearly)) that the block region grows & grows too; I think because the block stuff created by the coexpressions isn't reclaimed because the coexps themselves aren't reclaimed. - The exact output above is "almost always" reproducible. But once in a blue moon it dies with the baffling runtime error 302 (system stack overflow). This makes me wonder whether it might not be a local installation problem, or that maybe the coexp switch code isn't saving & restoring all that it should be ... ? The coexp code for a machine with register windows must be a real pain! Might as well clean out my bug list here . I get burned by this one a couple times each month: procedure main() write( 3^0 ) end # procedure main This prints "0". I realize that the proper value (if any) of "0^0" is the subject of intense religious debate, but far as I know *everyone* agrees that "i^0" is 1 whenever i ~= 0 (e.g., try "pow" in C or "**" in Fortran or an HP calculator or any number of textbooks ...). E.g., 543 = 5*10^2 + 4*10^1 + 3*10^0 = 5*100 + 4*10 + 3*1, and that hints at why the i^0=1 convention is helpful. Maybe a more Iconish way is to consider that ishift(1,i) = 2^i isn't an identity for i=0 unless the i^0=1 convention is followed (and if that convention is followed, it's an identity for all integer i). Maybe the most compelling way is to note that the basic recurrence (arguably the *definition* of "^" for integers) x^n = x * x^(n-1) doesn't hold for n=1 unless x^0=1. More rabid arguments on request . iconingly y'rs - tim Tim Peters Kendall Square Research Corp tim@ksr.com, ksr!tim@uunet.uu.net From icon-group-request@arizona.edu Sat Aug 3 02:12:50 1991 Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Sat, 3 Aug 91 02:12:50 MST Resent-From: icon-group-request@arizona.edu Received: from Arizona.edu (Osprey.Telcom.Arizona.EDU) by optima.cs.arizona.edu (4.1/15) id AA27055; Sat, 3 Aug 91 02:12:47 MST Received: from ucbvax.Berkeley.EDU by Arizona.edu with PMDF#10282; Sat, 3 Aug 1991 02:12 MST Received: by ucbvax.berkeley.edu (5.63/1.42) id AA11501; Sat, 3 Aug 91 02:07:09 -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: Sat, 3 Aug 1991 02:12 MST Date: 3 Aug 91 08:22:24 GMT From: cis.ohio-state.edu!pacific.mps.ohio-state.edu!linac!midway!quads.uchicago.edu!goer@ucbvax.berkeley.edu (Richard L. Goerwitz) Subject: RE: Coexp memory leak in Icon V8 (UNIX, SPARC)?; i^0 bug Sender: icon-group-request@arizona.edu Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: Message-Id: <1991Aug3.082224.12971@midway.uchicago.edu> X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.edu Organization: University of Chicago References: <9108030530.AA26526@kaos.ksr.com> In article <9108030530.AA26526@kaos.ksr.com> tim@ksr.com (Tim Peters) writes: > > every i := 1 to limit do { > (i < 5 | i = limit) & dumpstats(i) > coexp := create inner() > while @coexp > } Eek, you've been bitten by the "unreachable coexpressions" bug. Make coexp global, and the problem *should* go away quite magically. -- -Richard L. Goerwitz goer%sophist@uchicago.bitnet goer@sophist.uchicago.edu rutgers!oddjob!gide!sophist!goer From icon-group-request@arizona.edu Sat Aug 3 19:14:05 1991 Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Sat, 3 Aug 91 19:14:05 MST Resent-From: icon-group-request@arizona.edu Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by optima.cs.arizona.edu (4.1/15) id AA18973; Sat, 3 Aug 91 19:14:02 MST Received: from ucbvax.Berkeley.EDU by Arizona.edu with PMDF#10282; Sat, 3 Aug 1991 19:13 MST Received: by ucbvax.berkeley.edu (5.63/1.42) id AA29415; Sat, 3 Aug 91 19:00:51 -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: Sat, 3 Aug 1991 19:13 MST Date: 4 Aug 91 01:53:29 GMT From: ksr!tim@uunet.uu.net (Tim Peters) Subject: RE: Coexp memory leak in Icon V8 (UNIX, SPARC)?; i^0 bug Sender: icon-group-request@arizona.edu Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: <4EAB8F3B8C001430@Arizona.edu> Message-Id: <4891@ksr.com> X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.edu Organization: Kendall Square Research Corp. References: <9108030530.AA26526@kaos.ksr.com>, <1991Aug3.082224.12971@midway.uchicago.edu> In article <1991Aug3.082224.12971@midway.uchicago.edu> goer@quads.uchicago.edu (Richard L. Goerwitz) writes: >In article <9108030530.AA26526@kaos.ksr.com> tim@ksr.com (Tim Peters) writes: >> >> every i := 1 to limit do { >> (i < 5 | i = limit) & dumpstats(i) >> coexp := create inner() >> while @coexp >> } > >Eek, you've been bitten by the "unreachable coexpressions" bug. Make >coexp global, and the problem *should* go away quite magically. Excellent suggestion, Richard! Steve Wampler tried to explain what's "really" going on here in E-Mail, and suggested a similar trick. Alas, turns out nothing (so far) makes a real difference. Making coexp global slightly slows the growth of the block region, but doesn't affect the growth of the static region (which is sucking up another 10K per iteration) at all. I'll attach the current version of the test case in case you'd like to play with it -- still don't know whether this is a local glitch or unique to SPARC or ... But thanks for the idea! It's clever & appreciated, and I certainly agree it *"should"* have worked. exploring-icon's-dark-side-ly y'rs - tim Tim Peters Kendall Square Research Corp tim@ksr.com, ksr!tim@uunet.uu.net Terminal session with current version; output is identical to that of the original version, except that the block region is growing a little bit slower now: kaos 38= cat leak2.icn record vertex( a, b, c, d, e, f, g ) global coexp # get rid of all the local pointers to the "create" procedure main( args ) local i, limit # removed coexp from this list limit := integer(get(args)) | 100 write( "Host: ", &host ) write( "Version: ", &version ) write( "Features:" ) every write( " ", &features ) every i := 1 to limit do { (i < 5 | i = limit) & dumpstats(i) coexp := &null # paranoia coexp := create inner() while @coexp } end # procedure main procedure inner() vertex() @ &source # switching to &main doesn't help either fail end # procedure inner procedure dumpstats( i ) local c c := create &collections # gimmick to skip the first return value write( "iter ", i ) writes(r("collections")); @c; every writes(r(|@c)); write() writes(r("regions")); every writes(r(®ions)); write() writes(r("storage")); every writes(r(&storage)); write() end # procedure dumpstats procedure r( s ) return right( s, 12 ) end # procedure r kaos 39= /usr/local/lib/icon/v8/bin/icont -u leak2 -x Translating: leak2.icn: main (823/15000) inner (123/15000) dumpstats (728/15000) r (109/15000) No errors Linking: Executing: Host: kaos Version: Icon Version 8.0. May 7, 1990 Features: UNIX ASCII co-expressions direct execution environment variables error trace back executable images expandable regions external functions large integers math functions memory monitoring pipes string invocation system function iter 1 collections 0 0 0 regions 20000 65024 65024 storage 20000 124 192 iter 2 collections 1 0 0 regions 30000 65024 65024 storage 30000 120 280 iter 3 collections 2 0 0 regions 30000 65024 65024 storage 30000 120 368 iter 4 collections 4 0 0 regions 40000 65024 65024 storage 40000 120 456 iter 100 collections 101 0 0 regions 1000000 65024 65024 storage 1000000 120 8904 kaos 40= >>> END OF MSG From icon-group-request@arizona.edu Sun Aug 4 23:45:07 1991 Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Sun, 4 Aug 91 23:45:07 MST Resent-From: icon-group-request@arizona.edu Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by optima.cs.arizona.edu (4.1/15) id AA29230; Sun, 4 Aug 91 23:45:05 MST Received: from ucbvax.Berkeley.EDU by Arizona.edu with PMDF#10282; Sun, 4 Aug 1991 23:44 MST Received: by ucbvax.berkeley.edu (5.63/1.42) id AA29642; Sun, 4 Aug 91 23:30:47 -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: Sun, 4 Aug 1991 23:44 MST Date: 5 Aug 91 06:18:59 GMT From: ksr!tim@uunet.uu.net (Tim Peters) Subject: A pretty use of co-expressions Sender: icon-group-request@arizona.edu Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: <3DB3AAC044001725@Arizona.edu> Message-Id: <4894@ksr.com> X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.edu Organization: Kendall Square Research Corp. "Primes" below generates the sequence of prime integers (2, 3, 5, 7, 11, 13, ...) via a devious co-expression implementation of the old Sieve of Eratosthenes (start with the list (2,3,4,5,...); then repeatedly pick the first integer off the list and remove all its multiples). I think it's pretty enough that other Icon fanatics might enjoy it, but it's definitely *not* a practical method for generating lots of primes. Each new prime has to wind its way through a chain of co-expressions of depth equal to the number of primes previously generated, so time & space use grow fast. As written, "main" prints the first 100 primes, and that takes a megabyte of memory on my UNIX(tm)-on-SPARC(tm) Icon; it's also prone to flaky run-time errors (bus errors, system stack overflow), the frequency of which I can reduce but not eliminate by setting COEXPSIZE to larger & larger values. Would be interested to hear whether other folks experience flaky errors too! started-life-as-a-mean-coexp-test-but-it-deserves-a-better-fate-than- that-ly y'rs - tim Tim Peters Kendall Square Research Corp tim@ksr.com, ksr!tim@uunet.uu.net procedure main() every write( Primes()\100 ) end procedure Primes() local first, sequence, val sequence := create seq(2) repeat { suspend first := @sequence sequence := create | if (val := @sequence) % first ~= 0 then val else @sequence } end >>> END OF MSG From gmt Mon Aug 5 10:13:47 1991 Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Mon, 5 Aug 91 10:13:47 MST Resent-From: "Gregg Townsend" Received: from Arizona.edu (Merlin.Telcom.Arizona.EDU) by optima.cs.arizona.edu (4.1/15) id AA19865; Mon, 5 Aug 91 10:13:45 MST Received: from optima.cs.arizona.edu by Arizona.edu with PMDF#10282; Mon, 5 Aug 1991 10:13 MST Received: from owl.cs.arizona.edu by optima.cs.arizona.edu (4.1/15) id AA19852; Mon, 5 Aug 91 10:12:56 MST Received: by owl.cs.arizona.edu; Mon, 5 Aug 91 10:12:55 MST Resent-Date: Mon, 5 Aug 1991 10:13 MST Date: Mon, 5 Aug 91 10:12:55 MST From: Gregg Townsend Subject: RE: A pretty use of co-expressions Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu, ksr!tim@uunet.uu.net Resent-Message-Id: <958472EF9220102A@Arizona.edu> Message-Id: <9108051712.AA18033@owl.cs.arizona.edu> X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.edu, ksr!tim@uunet.uu.net Here's another Icon generator of prime numbers. It doesn't use coexpressions; it doesn't even use any arithmetic! ## primes(): a generator returning the successive prime numbers # # Gregg Townsend # University of Arizona # October, 1987 # # How it works: let n be the last odd integer considered. n is not actually # recorded but reflects the size of the list lf, which contains factors of the # next n odd integers beyond n (n+2 to 3*n). Every odd prime less than or # equal to n appears exactly once, in the list of its next multiple beyond n. # # Each time around the loop, the first entry in lf is popped. If this sublist # is empty, the new n is prime and its value is produced. Then all factors # on the popped sublist, or the new prime, are re-entered in their correct new # positions. # # lf needs to be size n whenever a new prime is inserted, and is grown # constantly to maintain that size. procedure primes() suspend 2 # do this once, then forget the even numbers lf := [[]] repeat { # at each iteration: f := get(lf) # get sublist of factors put(lf,[]) # grow the list put(lf,[]) put(lf,f) # reuse the list we popped in position lf[n] if *f = 0 then { # if empty, no smaller factors, so it's prime! put(f,*lf) # add n as a factor (remember, list was reused) suspend *lf # pass back the prime } else while v := get(f) do # take each popped factor put(lf[v],v) # and add to the list at its next multiple } end From icon-group-request@arizona.edu Mon Aug 5 22:20:17 1991 Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Mon, 5 Aug 91 22:20:17 MST Resent-From: icon-group-request@arizona.edu Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by optima.cs.arizona.edu (4.1/15) id AA01535; Mon, 5 Aug 91 22:20:14 MST Received: from ucbvax.Berkeley.EDU by Arizona.edu with PMDF#10282; Mon, 5 Aug 1991 22:19 MST Received: by ucbvax.berkeley.edu (5.63/1.42) id AA15233; Mon, 5 Aug 91 22:02:04 -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: Mon, 5 Aug 1991 22:19 MST Date: 5 Aug 91 19:58:34 GMT From: mcsun!ukc!slxsys!ibmpcug!demon!news@uunet.uu.net (Paul Moore) Subject: RE: Coexp memory leak in Icon Sender: icon-group-request@arizona.edu Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: Message-Id: <1991Aug05.195834.8933@demon.co.uk> X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.edu Organization: Gated to News by demon.co.uk From tim@ksr.com (Tim Peters) > I'll attach the current version of the test case in case you'd like to > play with it -- still don't know whether this is a local glitch or > unique to SPARC or ... I tried your test program on Archimedes Icon (the Archimedes is a non-Unix personal computer made by Acorn in the UK - the Icon port is my own). I got the same type of result. Output follows. Don't know if this helps at all... It's a fixed-regions version where yours is expandable regions, though. Gustav. >>> Output from test routine Host: Acorn Archimedes (RISC OS 2.00) Version: Icon Version 8.0. April 1, 1990 Features: Acorn Archimedes ASCII co-expressions environment variables error trace back external functions fixed regions keyboard functions large integers math functions memory monitoring pipes string invocation system function Archimedes extensions iter 1 collections 0 0 0 regions 0 65000 65000 storage 0 151 192 iter 2 collections 0 0 0 regions 0 65000 65000 storage 0 295 432 iter 3 collections 0 0 0 regions 0 65000 65000 storage 0 439 672 iter 4 collections 0 0 0 regions 0 65000 65000 storage 0 583 912 iter 100 collections 0 0 0 regions 0 65000 65000 storage 0 120 10704 --------------------------------------------------------------------------- Paul Moore | "If you could have any amount of money... pmoore@cix.compulink.co.uk | any amount of money at all... gustav@tharr.UUCP | how much would you want?" ----------------------------| "All of it." Opinions? Not me, surely? | Cerebus, Church & State. --------------------------------------------------------------------------- From icon-group-request@arizona.edu Mon Aug 5 23:45:17 1991 Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Mon, 5 Aug 91 23:45:17 MST Resent-From: icon-group-request@arizona.edu Received: from Arizona.edu (Osprey.Telcom.Arizona.EDU) by optima.cs.arizona.edu (4.1/15) id AA03413; Mon, 5 Aug 91 23:45:14 MST Received: from ucbvax.Berkeley.EDU by Arizona.edu with PMDF#10282; Mon, 5 Aug 1991 23:44 MST Received: by ucbvax.berkeley.edu (5.63/1.42) id AA19539; Mon, 5 Aug 91 23:27:28 -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: Mon, 5 Aug 1991 23:44 MST Date: 6 Aug 91 06:14:18 GMT From: world!ksr!tim@decwrl.dec.com (Tim Peters) Subject: RE: Coexp memory leak in Icon Sender: icon-group-request@arizona.edu Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: <06E07D9104001F0E@Arizona.edu> Message-Id: <4913@ksr.com> X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.edu Organization: Kendall Square Research Corp. References: <1991Aug05.195834.8933@demon.co.uk> In article <1991Aug05.195834.8933@demon.co.uk> Paul Moore writes: > ... >I tried your test program on Archimedes Icon (the Archimedes is a >non-Unix personal computer made by Acorn in the UK - the Icon port is my >own). I got the same type of result. Output follows. Don't know if this >helps at all... It's a fixed-regions version where yours is expandable >regions, though. > ... [output for last iteration follows] ... >iter 100 > collections 0 0 0 > regions 0 65000 65000 > storage 0 120 10704 Thanks for giving it a try, Paul! I'm not sure whether it shows anything either -- the test case doesn't generate enough stuff to trigger any collections in the string or block regions, so the "10704" used in the block region at the end may well be there just because no attempt was ever made at collection. Would be interesting to see what happens if you put a "collect()" before the "dumpstats(i)" to try to force the issue. After playing around some more I found different ways to write the test that did & didn't leak; a summary follows, & it's quite baffling. In all cases "coexp" is a global (I understand now why the memory leaked when coexp was local, and happy to post an explanation if it's not the universally-known folklore it appears to be ): 1) The original "inner": procedure inner() vertex() @ &source end The coexp & block memory doesn't get reclaimed. 2) Neither is the memory reclaimed if the guts of inner are changed to vertex() @ &main 3) Two variations where the memory *is* reclaimed, by replacing the guts of "inner" with either suspend vertex() or return vertex() 4) The real baffler (considered along with variations #1 and #2): The memory leak also goes away if the "create" is changed to coexp := create inner(¤t) and "inner" is changed to procedure inner( source ) vertex() @ source end Far as I know, variation #4 "should be" semantically equivalent in every respect to variation #1, so why the latter leaks while the former doesn't is beyond me. Seems to be triggered specifically by using the keywords "&source" or "&main" as explicit targets of a coexp switch ... but that's too odd to believe . clues-confirmations-&-denials-still-solicited-ly y'rs - tim Tim Peters Kendall Square Research Corp tim@ksr.com, ksr!tim@uunet.uu.net From kwalker Wed Aug 7 20:14:40 1991 Received: from gacham.cs.arizona.edu by cheltenham.cs.arizona.edu; Wed, 7 Aug 91 20:14:40 MST Date: Wed, 7 Aug 91 14:37:40 MST From: "Kenneth Walker" Message-Id: <9108072137.AA09526@gacham.cs.arizona.edu> Received: by gacham.cs.arizona.edu; Wed, 7 Aug 91 14:37:40 MST In-Reply-To: <9108070806.AA25327@kaos.ksr.com> To: tim@ksr.com Subject: Re: Coexp memory leak in Icon Cc: icon-group > Date: Wed, 07 Aug 91 04:06:42 -0400 > From: Tim Peters > >... > 2) That explained the behavior of the most-recent version of "the test > case". But in trying to exploit that knowledge, I keep hitting > snags. E.g., > > global drive, coexp > > procedure main() > coexp := create ("OK" @ &source) > drive := create @coexp > write( @drive | "failed?" ) > collect() > end > > That prints "failed?". I expected "OK", but I think I know why it's > happening (basically that "drive" returns to "coexp" instead of to > &main -- drive's original "fall off the end" return point is altered > *by* the "@ &source" in coexp -- a real head-twister!). > >... > [a vague suggestion by me for tackling the problem] > > Sorry, but this was the one paragraph I didn't think I could follow. An > example would sure help. As the other little test case above showed, I > think I'm missing something basic here. Actually my suggestion was what you tried in the above example. Obviously I didn't attempt it before making the suggestion, sorry. The bus error problem does not seem to exist in our working copy of the interpreter (however, this will not be available to the public for a while). Your point about a co-expression not needing its activation stack once it starts to fail is a good one. I wonder if there are other rules like that which could be used to improve the implementation. It would be nice to have a simple useful description of the possible paths through a set of co-expressions taking into account activation, and returning and failing by falling off the end. As you mentioned, the subtlies of coexpression activation are hard to understand. 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 kwalker Wed Aug 7 20:14:41 1991 Received: from gacham.cs.arizona.edu by cheltenham.cs.arizona.edu; Wed, 7 Aug 91 20:14:41 MST Date: Tue, 6 Aug 91 11:25:10 MST From: "Kenneth Walker" Message-Id: <9108061825.AA08780@gacham.cs.arizona.edu> Received: by gacham.cs.arizona.edu; Tue, 6 Aug 91 11:25:10 MST In-Reply-To: <4913@ksr.com> To: icon-group, world!ksr!tim@decwrl.dec.com Subject: RE: Coexp memory leak in Icon > Date: Sat, 03 Aug 91 01:30:21 -0400 > From: Tim Peters > > Inside the graph-crawlers, "the next" vertex is returned to the caller > via > > next_vertex @ &source > > The graph-crawlers are highly recursive, and the real point of doing a > coexp switch instead of a suspend inside them (coupled with an "every" > in the caller) was to avoid the overhead of suspending & resuming thru > many recursive levels each time. Timing in fact showed that this *did* > save a good chunk of time over the more-straightforward coding via > every/suspend. I think the optimizing compiler should be able to dynamically collapse the suspend chain and eliminate the performance hit of suspending through all those recurse calls (somewhat similar to the "tail recursion" optimization done for Lisp). It will take some thought to work through the details. Thanks for the bit of research! Now back to the real problem... The problem you have with coexpression build-up (once you get rid of the unreachable co-expression problems using the global variable) relates to the fact that co-expressions can "fall off the end" and return to their last activator. Co-expression keep a stack of their activators. They can be recursively activated a number of times and then repeatedly fall off the end on the way back down the recursive activation chain. (I think I explained this right. The possible paths of transfer of control through co-expressions is a little confusing.) If they are activated repeatedly and never fall off the end, the stack can get large. The stack is implementated in such a way as to often avoid that problem: sections of the stack consisting of the same activator are represented as the activator and a count of number of times it appears in a row. However, this "trick" doesn't always work. In this example, &main is repeated activated by different co-expressions. It keeps all of them on its activation stack, even when they can be reached no other way. (This is maybe a little bogus as &main can never fall off the end, but this same thing can be happen in another co-exprssion, so it is a real problem.) I don't know of any fix to the general problem. There have been long and complicated debates about the correct behavior of co-expressions when recursive activations and "ruturns" are done; maybe some other semantics would allow us to do away with the stack. As for your specific problem, can you set up a dyamically created co-expression, have the value passed directly to it,then have it "return" the value to the main co-expression by falling off the end? In this way, &main has no references to the intermediate co-expression and garbage collection can dispose of it and the the co-expression that does the real work? I have to admit that this is a rather gross solution, but I think it will work. > Date: 6 Aug 91 06:14:18 GMT > From: world!ksr!tim@decwrl.dec.com (Tim Peters) > >... > 4) The real baffler (considered along with variations #1 and #2): The > memory leak also goes away if the "create" is changed to > > coexp := create inner(¤t) > > and "inner" is changed to > > procedure inner( source ) > vertex() @ source > end Note that ¤t is evaluated within the coexpression; it is not &main and you might think at first. 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 ksr!ksr.com!tim@uunet.uu.net Wed Aug 7 20:18:09 1991 Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Wed, 7 Aug 91 20:18:09 MST Received: from relay2.UU.NET by optima.cs.arizona.edu (4.1/15) id AA03775; Wed, 7 Aug 91 01:26:12 MST Received: from uunet.uu.net (via LOCALHOST.UU.NET) by relay2.UU.NET with SMTP (5.61/UUNET-internet-primary) id AA24815; Wed, 7 Aug 91 04:26:09 -0400 Received: from ksr.UUCP by uunet.uu.net with UUCP/RMAIL (queueing-rmail) id 042508.20773; Wed, 7 Aug 1991 04:25:08 EDT Received: from kaos.ksr.com by ksr.com (4.0/SMI-3.2) id AA03514; Wed, 7 Aug 91 04:06:46 EDT Received: by kaos.ksr.com (4.0/SMI-3.2) id AA25327; Wed, 7 Aug 91 04:06:44 EDT Message-Id: <9108070806.AA25327@kaos.ksr.com> To: kwalker@cs.arizona.edu Subject: Re: Coexp memory leak in Icon Cc: icon-group@cs.arizona.edu Date: Wed, 07 Aug 91 04:06:42 -0400 From: Tim Peters Ken, many thanks for taking the time to explain the Deeper Mysteries! Everything makes sense so far, but I think I must still be missing a key piece of the puzzle. A few E-Mail msgs suggested that others are finding this educational too, so I'm keeping "the group" on the distribution list -- but if more people find this public flaunting of my ignorance just irritating, please let me know & I'll take it offline and summarize later. Easy one first: > > [me] > > 4) The real baffler (considered along with variations #1 and #2): The > > memory leak also goes away if the "create" is changed to > > coexp := create inner(¤t) > > and "inner" is changed to > > procedure inner( source ) > > vertex() @ source > > end > [ken] > Note that ¤t is evaluated within the coexpression; it is not > &main [as] you might think at first. I stand gratefully corrected. Changing the "create" to (e.g.) me := ¤t; coexp := create inner( me ) does what I mistakenly thought the above would do, and suffers the same "memory leak" as the #1 and #2 variations. So the behavior is consistent after all. Thanks! Next the explanation (& please hit me if I botch the paraphrase at the start -- I'm paraphrasing it precisely so that if I do misunderstand it, that will be obvious early on): > [Ken explains that each coexp maintains a stack of its activators, so > that in the test program the "vertex @ &source" line (which activates > &main) causes each of the many "coexp" coexps to be placed on &main's > stack-of-activators; & because they *are* on that stack, garbage > collection can't reclaim them. > Ken continues ... > ] > In this example, &main is repeatedly activated by different > co-expressions. It keeps all of them on its activation stack, even > when they can be reached no other way. (This is maybe a little bogus > as &main can never fall off the end, but this same thing can be > happen in another co-expression, so it is a real problem.) Two things: 1) It's certainly tempting to suggest that &main's stack-of-activators be ignored (as a special case) in the marking phase, but I can see that it's a more general problem. A twist on that coming later. 2) That explained the behavior of the most-recent version of "the test case". But in trying to exploit that knowledge, I keep hitting snags. E.g., global drive, coexp procedure main() coexp := create ("OK" @ &source) drive := create @coexp write( @drive | "failed?" ) collect() end That prints "failed?". I expected "OK", but I think I know why it's happening (basically that "drive" returns to "coexp" instead of to &main -- drive's original "fall off the end" return point is altered *by* the "@ &source" in coexp -- a real head-twister!). I can live with that, but then it *always* crashes with a system "Bus error" msg (which goes away if the "collect()" is removed). Of course this was part of an attempt to fill a throw-away coexp's ("drive"'s) stack-of-activators with "coexp" (instead of filling &main's stack). Not having much luck getting that to work, though. > I don't know of any fix to the general problem. There have been long > and complicated debates about the correct behavior of co-expressions > when recursive activations and "ruturns" are done; maybe some other > semantics would allow us to do away with the stack. The semantics are sure subtler than I thought, but I don't have a problem with that. One of the things I admire about Icon (& SNOBOL4 before it ...) is the willingness to *try* grand new ideas, even when all the implications are known to be unknown in advance. And I think the Icon Project has a remarkable track record for doing "almost everything just right" amidst such uncertainties. But *offhand* (I'm completely ignorant of Icon's implementation), and stipulating that Icon's coexp semantics are reasonable (although the test case above has me wondering ), perhaps the current *implementation* of those semantics could be optimized in some safe ways. E.g., suppose some coexp C fails. As I understand it, in the current implementation C's stack of activators stays around. But it's useless -- because, since C *has* failed, any future activation must immediately return failure to the direct activator. Closer to home , suppose coexp A activates coexp B, B re-activates A, A re-activates B (& carry this on more levels if you like; I think I *need* this many, though), and then B fails. E.g., if A === &main, and B === coexp, we pretty much have my test case. B can never be junked so long as A is alive, because B is on A's stack of activators. But there's something fishy about this: namely that B *did* fail, so although the entire range of its future behavior can be modeled by a simple "repeat &fail", all the space it occupies, and (I presume) all the space occupied by all the coexps on *its* stack of activators (& so on), sticks around uselessly. The irksome thing about my test case is that the huge amount of memory that stuck around was in support of coexps that couldn't possibly do anything but fail even if they *were* reachable -- happy to lose a couple hundred bytes to that, but not a couple dozen meg . I'm think I'm groping-- in both of those --at saying that "coexp failure" has massive (& known!) effects on that coexp's future prospects in life , and that the implementation could take better advantage of this drastic change in its status. Once a coexp has failed, it's not "really" a coexp any more (via any observable behavior), so perhaps the implementation could strip it of all the coexp overhead at the time it first does fail? It's "just" an optimization, of course, and I don't know how widely useful it would be -- but it would help the stuff I've been doing lately . > As for your specific problem, can you set up a dyamically created > co-expression, have the value passed directly to it,then have > it "return" the value to the main co-expression by falling off the > end? In this way, &main has no references to the intermediate > co-expression and garbage collection can dispose of it and the > the co-expression that does the real work? I have to admit that > this is a rather gross solution, but I think it will work. Sorry, but this was the one paragraph I didn't think I could follow. An example would sure help. As the other little test case above showed, I think I'm missing something basic here. > ... > I think the optimizing compiler should be able to dynamically collapse > the suspend chain and eliminate the performance hit of suspending > through all those recurse calls (somewhat similar to the "tail recursion" > optimization done for Lisp). It will take some thought to work through > the details. Fascinating idea, Ken! I'm a compiler jockey by trade, and for what it's worth I suspect you're right about this. Bet you're having fun with the compiler -- when it's not driving you crazy ... takes-one-to-know-one-ly y'rs - tim Tim Peters Kendall Square Research Corp tim@ksr.com, ksr!tim@uunet.uu.net ps: this collect()-free variation of the test case above gets a "Bus error" crash every time, apparently at the "@drive" line: global drive, coexp procedure main() coexp := create ("OK" @ &source) drive := create |@coexp @drive end From TELLEFSENGW@HIRAMB.BITNET Wed Aug 7 20:20:18 1991 Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Wed, 7 Aug 91 20:20:18 MST Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by optima.cs.arizona.edu (4.1/15) id AA02157; Tue, 6 Aug 91 11:26:22 MST Received: from HIRAMB (TELLEFSE@HIRAMB) by Arizona.edu with PMDF#10282; Tue, 6 Aug 1991 11:26 MST Date: Tue, 6 Aug 1991 14:25 EST From: TELLEFSENGW@HIRAMB.BITNET Subject: Automatic seeding for &random To: icon-group@cs.arizona.edu Message-Id: <81EB4403E0E0153D@HIRAMB> X-Envelope-To: icon-group@cs.arizona.edu X-Vms-To: IN%"icon-group@cs.arizona.edu" I'm new to Icon, so you may all have seen a procedure like this before, but I thought I'd take a chance and send it to you all. This is a little procedure that will set the random seed, &random, to a different value each time you run a program. It is based on the clock, and will only repeat seed values once per decade (and then only if you run your program at the exact same second you did a decade ago). To use it, just put "randomize()" at the beginning of the procedure "main." You might want to put in a "write(&random)" so you can record the seed in case it produces interesting results. If anyone can suggest improvements or possible problems, let me know... it seemed to work fine on my Amiga. procedure randomize() source:=map("defghijklmn", "abcd/ef/ghij:kl:mn", &date || &clock) source ? { &random:= (move(1) * 32140800 + (move(2) - 1) * 2678400 + (move(2) - 1) * 86400 + move(2) * 3600 + move(2) * 60 + move(2)) } end Guy Tellefsen TELLEFSENGW@HIRAMB From icon-group-request@arizona.edu Wed Aug 7 20:21:51 1991 Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Wed, 7 Aug 91 20:21:51 MST Resent-From: icon-group-request@arizona.edu Received: from Arizona.edu (Merlin.Telcom.Arizona.EDU) by optima.cs.arizona.edu (4.1/15) id AA25339; Tue, 6 Aug 91 09:33:25 MST Received: from ucbvax.Berkeley.EDU by Arizona.edu with PMDF#10282; Tue, 6 Aug 1991 09:32 MST Received: by ucbvax.berkeley.edu (5.63/1.42) id AA14111; Tue, 6 Aug 91 09:25:23 -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: Tue, 6 Aug 1991 09:33 MST Date: 6 Aug 91 15:06:10 GMT From: mcsun!cernvax!chx400!bernina!neptune!inf.ethz.ch!santas@uunet.uu.net (Filippos Santas) Subject: RE: comparing one file to another Sender: icon-group-request@arizona.edu Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: <590D753462201891@Arizona.edu> Message-Id: <30358@neptune.inf.ethz.ch> X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.edu Organization: Departement Informatik, ETH, Zurich References: <23.Jul.91..16:46:50.bst..060328@EMAS-A> This a test. Please ignore! From sbw@turing.cse.nau.edu Wed Aug 7 20:21:57 1991 Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Wed, 7 Aug 91 20:21:57 MST Received: from turing.cse.nau.edu by optima.cs.arizona.edu (4.1/15) id AA24564; Tue, 6 Aug 91 09:16:18 MST Received: by turing.cse.nau.edu (5.64/1.5-nau) id AA08816; Tue, 6 Aug 91 09:11:35 -0700 Message-Id: <9108061611.AA08816@turing.cse.nau.edu> From: sbw@turing.cse.nau.edu (Steve Wampler) Date: Tue, 6 Aug 1991 09:11:34 MST In-Reply-To: Tim Peters's mail message of Aug 5, 23:42. X-Mailer: Mail User's Shell (7.2.0 10/31/90) To: icon-group@cs.arizona.edu Subject: RE: Coexp memory leak in Icon On Aug 5 at 23:42, Tim Peters writes: } } 4) The real baffler (considered along with variations #1 and #2): The } memory leak also goes away if the "create" is changed to } } coexp := create inner(¤t) } } and "inner" is changed to } } procedure inner( source ) } vertex() @ source } end } } Far as I know, variation #4 "should be" semantically equivalent in every } respect to variation #1, so why the latter leaks while the former } doesn't is beyond me. Seems to be triggered specifically by using the } keywords "&source" or "&main" as explicit targets of a coexp switch ... } but that's too odd to believe . Time: Someone up on the current implementation of coexpressions will likely correct this, but here's a rough description of what is *most likely going on*: ¤t is the current co-expression (i.e. apointer to itself..) So, it doesn't contribute to any chains of coexpressions. &source is a reference to the *previously* activated coexpression (a link back to it). Now the fun stuff: Guess what happens when you activate @source? The coexpression you go to has &source set to point *back* to the coexpression you just left. This begins to build up a stack of coexpressions (I *think* this stack is the chain of coexpressions causing the problem - but there are some details I've forgotten now...) Similary, activating &main sets &source in &main to point back to the just exitted co-expression. Hoep this helps. (sorry for the typos I have about a 40 character typeahed on this connection!) -- Steve Wampler {....!arizona!naucse!sbw} {sbw@turing.cse.nau.edu} From icon-group-request@arizona.edu Thu Aug 8 09:08:02 1991 Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Thu, 8 Aug 91 09:08:02 MST Resent-From: icon-group-request@arizona.edu Received: from Arizona.edu (Merlin.Telcom.Arizona.EDU) by optima.cs.arizona.edu (4.1/15) id AA02471; Thu, 8 Aug 91 09:08:00 MST Received: from ucbvax.Berkeley.EDU by Arizona.edu with PMDF#10282; Thu, 8 Aug 1991 09:07 MST Received: by ucbvax.berkeley.edu (5.63/1.42) id AA06570; Thu, 8 Aug 91 08:56:51 -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, 8 Aug 1991 09:07 MST Date: 8 Aug 91 15:05:39 GMT From: midway!quads.uchicago.edu!goer@uunet.uu.net (Richard L. Goerwitz) Subject: RE: Automatic seeding for &random Sender: icon-group-request@arizona.edu Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: Message-Id: <1991Aug8.150539.1668@midway.uchicago.edu> X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.edu Organization: University of Chicago References: <81EB4403E0E0153D@HIRAMB> In article <81EB4403E0E0153D@HIRAMB> TELLEFSENGW@HIRAMB.BITNET writes: > > I'm new to Icon, so you may all have seen a procedure like this >before, but I thought I'd take a chance and send it to you all. > >procedure randomize() > source:=map("defghijklmn", "abcd/ef/ghij:kl:mn", > &date || &clock) > source ? { > &random:= (move(1) * 32140800 + > (move(2) - 1) * 2678400 + > (move(2) - 1) * 86400 + > move(2) * 3600 + > move(2) * 60 + > move(2)) > } > end It's great to see people post useful code like this. There's actually a procedure in the Icon Program Library that does the same thing (written by Bob Alexander). Not to say that his is better (though it is quite a bit shorter). I just like to point out that the IPL exists, and provides a lot of really useful material (my favorite right now is codeobj.icn, followed closely by ximage.icn). -- -Richard L. Goerwitz goer%sophist@uchicago.bitnet goer@sophist.uchicago.edu rutgers!oddjob!gide!sophist!goer From icon-group-request@arizona.edu Thu Aug 8 15:23:35 1991 Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Thu, 8 Aug 91 15:23:35 MST Resent-From: icon-group-request@arizona.edu Received: from Arizona.edu (Merlin.Telcom.Arizona.EDU) by optima.cs.arizona.edu (4.1/15) id AA23294; Thu, 8 Aug 91 15:23:32 MST Received: from ucbvax.Berkeley.EDU by Arizona.edu with PMDF#10282; Thu, 8 Aug 1991 15:22 MST Received: by ucbvax.berkeley.edu (5.63/1.42) id AA20140; Thu, 8 Aug 91 15:15:18 -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, 8 Aug 1991 15:23 MST Date: 8 Aug 91 21:00:42 GMT From: midway!quads.uchicago.edu!goer@mimsy.umd.edu (Richard L. Goerwitz) Subject: Bible reference program Sender: icon-group-request@arizona.edu Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: <1C4C9F2A66A004C2@Arizona.edu> Message-Id: <1991Aug8.210042.13539@midway.uchicago.edu> X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.edu Organization: University of Chicago Once again, I'd like to post a tidbit on bibleref - the Bible study aid I have mentioned several times. There's a new version now, with pre-indexed files and with the KJV included, on cs.arizona.edu. The Icon Project kindly consented to let me occupy a whopping 2 or 3 meg chunk of space in icon/contrib/bibleref.tar.Z. This version should install in minutes, assuming that the Icon run- time system and Icon Program Library on your system are current. No restrictions of any kind (shareware licenses, copyrights, etc.) come with the package. -- -Richard L. Goerwitz goer%sophist@uchicago.bitnet goer@sophist.uchicago.edu rutgers!oddjob!gide!sophist!goer From ksr!ksr.com!tim@uunet.uu.net Thu Aug 8 21:58:23 1991 Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Thu, 8 Aug 91 21:58:23 MST Received: from relay1.UU.NET by optima.cs.arizona.edu (4.1/15) id AA05747; Thu, 8 Aug 91 21:58:19 MST Received: from uunet.uu.net (via LOCALHOST.UU.NET) by relay1.UU.NET with SMTP (5.61/UUNET-internet-primary) id AA10022; Fri, 9 Aug 91 00:58:16 -0400 Received: from ksr.UUCP by uunet.uu.net with UUCP/RMAIL (queueing-rmail) id 005717.10532; Fri, 9 Aug 1991 00:57:17 EDT Received: from kaos.ksr.com by ksr.com (4.0/SMI-3.2) id AA24801; Fri, 9 Aug 91 00:26:27 EDT Received: by kaos.ksr.com (4.0/SMI-3.2) id AA21189; Fri, 9 Aug 91 00:26:26 EDT Message-Id: <9108090426.AA21189@kaos.ksr.com> To: icon-group@cs.arizona.edu Subject: Summary, re: Coexp memory leak in Icon Date: Fri, 09 Aug 91 00:26:25 -0400 From: Tim Peters Many thanks to Richard Goerwitz, Paul Moore, Steve Wampler and Ken Walker for their help and explanations! Summary follows; any errors are solely mine: First problem: Had a "dag traversal" program, along the lines of record thing( info, subthing1, subthing2, ..., mark ) every info := recurse( thing ).info do ... procedure recurse( thing ) thing.mark := 1 - thing.mark if (\thing.subthing1).mark ~= thing.mark then suspend recurse( thing.subthing1 ) if (\thing.subthing2).mark ~= thing.mark then suspend recurse( thing.subthing2 ) ... suspend thing end (Visiting the nodes of a graph in postorder; "mark" is a "have I been seen yet?" flag that cycles between all 0's and all 1's from one traversal to the next) This actually works fine. The only "problem" was that when the graphs were very "deep", the recursion was very deep, so lots of time was burned just suspending our way up long chains of nested invocations to get back to the "every" (and resuming our way back down the long chains to get back to the next piece of real work within "recurse"). It occurred to me (a little knowledge *is* a dangerous thing ) that co-expressions could be used to avoid this overhead, along the lines of: coexp := create recurse( thing ) while info := (@coexp).info do ... procedure recurse( thing ) thing.mark := 1 - thing.mark if (\thing.subthing1).mark ~= thing.mark then recurse( thing.subthing1 ) if (\thing.subthing2).mark ~= thing.mark then recurse( thing.subthing2 ) ... thing @ &source end Idea being that this way "recurse" sends each value *directly* back to the "while". This works fine too, and did save significant time in my particular application. But ... Second problem: When run for a long time, enormous slowdowns occurred, and memory use routinely exceeded a dozen megabytes (despite having only a few hundred K of "real data"). Turns out that was due to old co- expression space never being reclaimed. Cause #1: This appears to be widely known, and was actually an artifact in the first test case I posted (it wasn't actually happening in my "real" program). When a coexp is created into a dynamic local variable in a loop: local c while ... do { c := create something ... } the "old" co-expressions don't get reclaimed. The reason is that a coexp gets a copy of the dynamic local variables, so each time around the "old" value of c (c is a dynamic local variable!) gets copied into the new value of c, so each coexp is linked to the preceding one, so garbage collection thinks they're all potentially active. Indeed, the elegant little "primes" generator I posted a few days back *relied* on this behavior. In *most* applications I bet "the old" value is in fact unreachable, but Icon cannot in general know that. Workarounds: Take "c" out of the "dynamic local variable" class. E.g., make it a static local, or (in my judgement, better) make it global, or (IMJ, best) assign a non-coexp value to it right before the "create". E.g., c := &null # so new coexp doesn't have a pointer to old coexp c := create something Prospects: Didn't hear that anyone has plans to "fix this", but of course it's really not "a bug". I'm in the optimizing compiler biz, so naturally I think a lot could be done to avoid the problem in "the usual" cases, but the general case is clearly intractable (e.g., the "create" expression might contain "@variable(read())" -- you really can't tell for sure whether the "old" coexp *might* be referenced inside the new one, but given the right kind of analysis I bet you "almost always" could ...). Cause #2: This one appears to be less widely known, a bit harder to understand, and apparently much harder to work around. Turns out that, in order to support arbitrary patterns of invocation as co-routines, each Icon co-expression maintains a full-blown stack of all the co- expressions that have activated it. If garbage collection thinks a particular co-expression C is potentially live, it also thinks all the co-expressions on C's stack-of-activators are potentially live. So when my rewritten program does thing @ &source it puts the traversal co-expression ("coexp" in the driver) on &source's stack of activators, &source happened to be &main, and &main never popped anything off its stack-of-activators. Therefore, each time I created a new "coexp" traversal co-exp (& I did a lot of that!), it wound up on &main's stack-of-activators and never got off -- hence all of the traversal co-exp's were considered potentially live forever after. Workarounds: Haven't found one! It's overwhelmingly tempting to put a co-exp "between" &main and "coexp", so that the "thing @ &source" inside "recurse" returns its answers to the intermediate co-exp (and so fills up *its* stack-of-activators, which can presumably be thrown away by throwing away the intermediate co-exp itself). However, the difficulty appears to be in convincing the intermediate co-exp to return its result to &main: the "thing @ &source" (=== "thing @ intermediate_co-exp") doesn't just cause "thing" to be transmitted to &source, it also tells &source to deliver its next result (whether via "return" or "suspend" or "falling off the end") straight back to the "thing @ &source" line. In a sense, the problem is that I'm trying to use transmission as a goto or return, but Icon is treating it as a call. The following scheme "works" so long as we know recurse's result sequence is finite: global answers intermediate := drive( thing ) @intermediate every info := (!answers).info do ... procedure drive( thing ) local coexp answers := [] coexp := create recurse( thing ) while put( answers, @coexp ) end procedure recurse # exactly as above It "works" in the sense that it gets the right results, and all the coexp memory gets reclaimed, but before you think it's "the answer" (or even "an answer" ), do a trace of the control flow: "intermediate" and "coexp" take turns "falling off the end" to each other a number of times proportional to the number of results produced (or something like that -- not sure that's exactly right). Prospects: "Returns" from co-expressions are very involved (as reflected in the involved stack-of-activators implementation), and it's not clear (to me, since the Icon book doesn't really address it) *exactly* what semantics were intended. In any case, seems like there's room for significant optimizations in the most-common cases, but the issues are clearly subtle enough that out-thinking it would be A Project. In the meantime, this particular use for (abuse of?) co-expressions should be avoided. Epilogue: I actually rewrote "the real" program to get rid of the co-exps (and the recursion) anyway, so I no longer have a practical problem here. Exploring the co-exp approach was great fun, though, and thanks again to all for the invaluable help ... back-to-the-shadows-ly y'rs - tim Tim Peters Kendall Square Research Corp tim@ksr.com, ksr!tim@uunet.uu.net From ksr!ksr.com!tim@uunet.uu.net Thu Aug 8 22:10:12 1991 Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Thu, 8 Aug 91 22:10:12 MST Received: from relay1.UU.NET by optima.cs.arizona.edu (4.1/15) id AA06151; Thu, 8 Aug 91 22:10:09 MST Received: from uunet.uu.net (via LOCALHOST.UU.NET) by relay1.UU.NET with SMTP (5.61/UUNET-internet-primary) id AA11565; Fri, 9 Aug 91 01:10:06 -0400 Received: from ksr.UUCP by uunet.uu.net with UUCP/RMAIL (queueing-rmail) id 010952.12572; Fri, 9 Aug 1991 01:09:52 EDT Received: from kaos.ksr.com by ksr.com (4.0/SMI-3.2) id AA25472; Fri, 9 Aug 91 01:08:16 EDT Received: by kaos.ksr.com (4.0/SMI-3.2) id AA21750; Fri, 9 Aug 91 01:08:13 EDT Message-Id: <9108090508.AA21750@kaos.ksr.com> To: icon-group@cs.arizona.edu Subject: Correction to Re: Summary, re: Coexp memory leak in Icon Date: Fri, 09 Aug 91 01:08:13 -0400 From: Tim Peters > [me] > ... > The following scheme "works" so long as we know recurse's result > sequence is finite: > > global answers > > intermediate := drive( thing ) > @intermediate > every info := (!answers).info do ... > ... Sorry, that should have been intermediate := create drive( thing ) ^^^^^^ darned-mailer-errors-ly y'rs - tim Tim Peters Kendall Square Research Corp tim@ksr.com, ksr!tim@uunet.uu.net From LSADENIEMI@cc.helsinki.fi Wed Aug 14 01:11:21 1991 Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Wed, 14 Aug 91 01:11:21 MST Received: from cc.Helsinki.FI (hylka.Helsinki.FI) by optima.cs.arizona.edu (4.1/15) id AA05964; Wed, 14 Aug 91 01:11:11 MST Date: Wed, 14 Aug 1991 11:12 EET From: LEENA SADENIEMI HYLK Subject: Icon Version 8 for VMS To: icon-group@cs.arizona.edu, LSADENIE@kruuna.helsinki.fi Message-Id: X-Envelope-To: icon-group@cs.arizona.edu X-Vms-To: IN%"icon-group@cs.arizona.edu" X-Vms-Cc: LSADENIEMI Icon group, I sent an order form for Icon version 8 for VMS for the Computer Center of Helsinki Unversity last May and I got back my order form and a description of the contents of the installation tape. The date of the letter was May 30, 1991. The only problem is that a have not recieved a tape at all. I have tried to find it here but without results. So, it seems that I need another tape - or perhaps detailed advice how to get all I need via FTP, in which directories the VMS files are. Yours Leena Sadeniemi Computer Centre of Helsinki University Teollisuuskatu 23 005100 Helsinki Finland From R.J.Hare@edinburgh.ac.uk Wed Aug 14 07:47:41 1991 Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Wed, 14 Aug 91 07:47:41 MST Received: from Arizona.edu (Merlin.Telcom.Arizona.EDU) by optima.cs.arizona.edu (4.1/15) id AA16949; Wed, 14 Aug 91 07:47:11 MST Received: from UKACRL.BITNET (MAILER@UKACRL) by Arizona.edu with PMDF#10282; Wed, 14 Aug 1991 07:46 MST Received: from RL.IB by UKACRL.BITNET (Mailer R2.07) with BSMTP id 0597; Wed, 14 Aug 91 15:46:44 BST Received: from RL.IB by UK.AC.RL.IB (Mailer R2.07) with BSMTP id 2536; Wed, 14 Aug 91 15:45:50 BST Date: 14 Aug 91 15:44:14 bst From: R.J.Hare@edinburgh.ac.uk Subject: Document formatting programs To: icon-group@cs.arizona.edu Message-Id: <14 Aug 91 15:44:14 bst 060387@EMAS-A> X-Envelope-To: icon-group@cs.arizona.edu Via: UK.AC.ED.EMAS-A; 14 AUG 91 15:44:25 BST Some time ago, somone said they would put a simple (?) Icon text formatting program up on this board. I don't remember it ever appearing - is there any chance of the author re-posting the code, in case I missed it? Also, is anyone aware of any translation programs written in Icon? Thanks. Roger Hare. From icon-group-request@arizona.edu Fri Aug 16 16:21:40 1991 Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Fri, 16 Aug 91 16:21:40 MST Resent-From: icon-group-request@arizona.edu Received: from Arizona.edu (Merlin.Telcom.Arizona.EDU) by optima.cs.arizona.edu (4.1/15) id AA03392; Fri, 16 Aug 91 16:21:37 MST Received: from ucbvax.Berkeley.EDU by Arizona.edu with PMDF#10282; Fri, 16 Aug 1991 16:21 MST Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA15820; Fri, 16 Aug 91 16:02:58 -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, 16 Aug 1991 16:21 MST Date: 16 Aug 91 22:11:05 GMT From: midway!quads.uchicago.edu!goer@handies.ucar.edu (Richard L. Goerwitz) Subject: snapshot Sender: icon-group-request@arizona.edu Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: <6DBCC25316A03B16@Arizona.edu> Message-Id: <1991Aug16.221105.27902@midway.uchicago.edu> X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.edu Organization: University of Chicago I've posted something like this before. Could someone who uses the IPL routine snapshot() a lot try this out, and see how it works. I have always had trouble with how the supplied procedure only works well with lines that don't exceed the width of the terminal or the window you're in. This version is supposed to rectify the problem, but like I said, I'd like someone who uses snapshot() a lot try it out. -Richard ============================ latest version =========================== ############################################################################ # # Name: snapshot.icn # # Title: Show snapshot of Icon string scanning # # Author: Ralph E. Griswold and Randal L. Schwartz, modified by # Cheyenne Wills and Richard Goerwitz # # Date: July 19, 1991 # ############################################################################ # # The procedure snapshot(title,len) writes a snapshot of the state # of string scanning, showing the value of &subject and &pos, an # optional title (arg 1), and (again optionally) wrapping the display # for a terminal of len (arg 2) columns. # # For example, # # "((a+b)-delta)/(c*d))" ? { # tab(bal('+-/*')) # snapshot("example") # } # # produces # # ---example--------------------------- # | | # | | # | &subject = "((a+b)-delta)/(c*d))" | # | | | # | | # ------------------------------------- # # Note that the bar showing the &pos is positioned under the &posth # character (actual positions are between characters). If &pos is # at the end of &subject, the bar is positioned under the quotation # mark delimiting the subject. For example, # # "abcdefgh" ? (tab(0) & snapshot()) # # produces # # ------------------------- # | | # | | # | &subject = "abcdefgh" | # | | | # | | # ------------------------- # # Escape sequences are handled properly. For example, # # "abc\tdef\nghi" ? (tab(upto('\n')) & snapshot()) # # produces # # ------------------------------ # | | # | | # | &subject = "abc\tdef\nghi" | # | | | # | | # ------------------------------ # # The title argument places a title into the top bar, as in # # "abc\tdef\nghi" ? (tab(upto('\n')) & snapshot("upto('\n')") # # which produces # # --upto('\n')------------------- # | | # | | # | &subject = "abc\tdef\nghi" | # | | | # | | # ------------------------------- # # The len argument rewraps the display for a screen of len width. # ############################################################################ procedure snapshot(title,len) local bar1, bar2, bar3, is, is0, prefix, titlel, placement, POS /title := "" # no meaningful default \len <:= 20 # any less is really not useful prefix := "&subject = " is := image(&subject) is0 := *image(&subject[1:&pos]) | fail # # Set up top and bottom bars (not exceeding len width, if # len is nonnull). Fit title into top bar (bar1). # bar1 := bar3 := repl("-", *is + *prefix + 4)[1:\len-4|0] # in *is + *prefix + 4, the 4 is for two vbars/two spaces titlel := (*title > *bar3-4) | *title[1:\len-4|0] bar1 ?:= move(3) || (tab(4+titlel), title) || tab(0) # # Write bar1, then spacers (bar2). Then write out len-size chunks # of &subject, with the | pointer-line, where appropriate. Finally, # write out bar3 (like bar1, but with no title). # write(bar1) bar2 := "|" || repl(" ", *bar3 - 2) || "|" write(bar2, "\n", bar2) placement := *prefix + is0 (prefix || is) ? { until pos(0) do { POS := &pos - 1 write("| ", move(*bar3-4) | left(tab(0), *bar3-4), " |") if POS < placement < &pos then { writes("| ") writes(left(repl(" ", placement - POS - 1) || "|", *bar3-4)) write(" |\n", bar2) } else write(bar2, "\n", bar2) } } write(bar3) return # nothing useful to return end -- -Richard L. Goerwitz goer%sophist@uchicago.bitnet goer@sophist.uchicago.edu rutgers!oddjob!gide!sophist!goer From icon-group-request@arizona.edu Mon Aug 26 23:34:53 1991 Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Mon, 26 Aug 91 23:34:53 MST Resent-From: icon-group-request@arizona.edu Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by optima.cs.arizona.edu (4.1/15) id AA22339; Mon, 26 Aug 91 23:34:51 MST Received: from ucbvax.Berkeley.EDU by Arizona.edu with PMDF#10282; Mon, 26 Aug 1991 23:34 MST Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA25592; Mon, 26 Aug 91 23:24:32 -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: Mon, 26 Aug 1991 23:34 MST Date: 27 Aug 91 06:10:17 GMT From: usc!cs.utexas.edu!cse!utarlg.uta.edu!b912dieg@apple.com (DOUG WITMER) Subject: Machine Translation Program Sender: icon-group-request@arizona.edu Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: <85EC0E989EA05311@Arizona.edu> Message-Id: <1991Aug27.041259.14004@cse.uta.edu> X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.edu Organization: The University of Texas at Arlington 08/26/91 Dear Fellow ICON Enthusiasts: I have just placed a pre-release version of my machine translation program in the icon/contrib subdirectory at cs.arizona.edu. It can be down loaded via anonymous FTP, and then unzipped using the command: pkunzip -d -o -JHSR TRAN1 . It is my hope that a few of you will down load a copy of the program, and give me your comments on it. Of particular interest are questions like: 1) Can anything be done more efficiently? 2) Can anything be done in a more Iconish manner? 3) Have any standards of good programming practice been violated? 4) Do you see any obvious flaws or opportunities for improvement? Please send any comments to: Doug Witmer Internet: b912dieg@utarlg.uta.edu 1102 Enterprise Drive #149 Bitnet: b912dieg@utarlg Grand Prairie, Texas 75051 From pbewig@netcom.netcom.com Tue Aug 27 08:13:33 1991 Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Tue, 27 Aug 91 08:13:33 MST Received: from netcomsv.netcom.com by optima.cs.arizona.edu (4.1/15) id AA12177; Tue, 27 Aug 91 08:13:31 MST Received: from netcom.netcom.com by netcomsv.netcom.com (4.1/SMI-4.1) id AA25502; Tue, 27 Aug 91 08:12:58 PDT Received: by netcom.netcom.com (4.1/SMI-4.1) id AA16740; Tue, 27 Aug 91 08:12:58 PDT Date: Tue, 27 Aug 91 08:12:58 PDT From: pbewig@netcom.com (Phil Bewig) Message-Id: <9108271512.AA16740@netcom.netcom.com> X-Mailer: Mail User's Shell (7.2.3 5/22/91) To: icon-group@cs.arizona.edu Subject: limiting generation In a program which I am writing, I have a line while put(items, @getnext) \ maxitems which is an attempt to load initial values into a list, up to the specified maximum. However, the program doesn't work the way I expect; the maxitems limit is ignored. I have two questions: 1) Is it correct that the "\" limitation operator only applies to generators? Is while a control expression, not a generator, so limitation doesn't apply? 2) I solved the problem by rewriting as follows: while put(items, @getnext) do if *items > maxitems then break Is there a better way? Thanks for any help. Phil From icon-group-request@arizona.edu Wed Aug 28 05:39:48 1991 Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Wed, 28 Aug 91 05:39:48 MST Resent-From: icon-group-request@arizona.edu Received: from Arizona.edu (Osprey.Telcom.Arizona.EDU) by optima.cs.arizona.edu (4.1/15) id AA10743; Wed, 28 Aug 91 05:39:46 MST Received: from ucbvax.Berkeley.EDU by Arizona.edu with PMDF#10282; Wed, 28 Aug 1991 05:39 MST Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA18792; Wed, 28 Aug 91 05:22:15 -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: Wed, 28 Aug 1991 05:39 MST Date: 28 Aug 91 07:15:34 GMT From: world!ksr!tim@uunet.uu.net (Tim Peters) Subject: RE: limiting generation Sender: icon-group-request@arizona.edu Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: <82105E459EC0893E@Arizona.edu> Message-Id: <5228@ksr.com> X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.edu Organization: Kendall Square Research Corp. References: <9108271512.AA16740@netcom.netcom.com> In article <9108271512.AA16740@netcom.netcom.com> pbewig@NETCOM.COM (Phil Bewig) writes: > In a program which I am writing, I have a line > > while put(items, @getnext) \ maxitems > > which is an attempt to load initial values into a list, up to the > specified maximum. Think you'll be happiest with something equivalent to every put( items, (|@getnext)\maxitems ) Sticking "|" (repeated alternation) in front of a coexp invocation is a slick trick that's generally effective for problems "like this". Also works to move the limitation expression outside, yielding something closer to your original: every put( items, |@getnext ) \ maxitems Matter of taste; I think the first way is clearer because I think I'm "really" trying to limit the "getnext", not the "put". If you're not comfortable with repeated alternation, you might like this better: every 1 to maxitems & put( items, @getnext ) I suspect this will be less efficient if @getnext fails early, though (because the "1 to maxitems" part will go thru its whole range regardless of how early @getnext first fails). > However, the program doesn't work the way I expect; the maxitems limit > is ignored. Well, if you set maxitems to 0 you'll see that it's not really ignored -- it just doesn't do what you wanted . So long as maxitems is >= 1, it will *appear* to be "ignored" in the sense you intend. What's really going on is along these lines: while put(items, @getnext) \ maxitems 1. put( items, @getnext ) \ maxitems is evaluated. Assuming the "@getnext" produces a result and maxitems is >= 1, the put succeeds and produces "items". 2. Since the "put" produced a result ("items"), the "while" goes back to step 1 (and note particularly that maxitems and the limitation will be evaluated fresh each time you do go back to step 1). In short, you've got the makings of an infinite loop here; it won't stop until (unless, really) "@getnext" fails. > ... > 1) Is it correct that the "\" limitation operator only > applies to generators? I think not precisely, or "yes" but in a trivial sense: every expression in Icon may be a generator, and expressions are really all Icon has, so limitation can really be applied to anything. E.g., (write\9\3)((2\77) + (3\8))\(205\12) prints "5" (same as "write(2+3)"). Confused ? Hang in there -- it took me a long time to understand what role generators really play in Icon, but after a "Eureka!" experience or two it will seem both simple and natural. Darned convenient, too, so it's worth the effort. > Is while a control expression, not a generator, so limitation doesn't > apply? Limitation does apply, but in a degenerate way. If you have _The Icon Progamming Language_ book (2nd ed), reread the section on "Bounded Expressions" in chapter 7 (pg 85). The "while" expression is a bounded expression, meaning it cannot generate a sequence of results -- I guess I'd like that explanation better if it said it *can* generate a sequence of results but of length at most one. Alas, getting the reasons to "click" in your head requires grasping such subtleties. > 2) I solved the problem by rewriting as follows: > > while put(items, @getnext) do > if *items > maxitems then break > > Is there a better way? I think that way actually allows the list to grow one larger than you wanted (replace ">" by ">="), but the idea is certainly sound. "Better" depends on what you like; here are some similar alternatives you may or may not like better: while *put(items, @getnext) < maxitems while put(items, @getnext) & *items < maxitems while *items < maxitems do put(items, @getnext) | break every 1 to maxitems do put(items, @getnext) every 1 to maxitems do put(items, @getnext) | break there-are-a-hundred-ways-to-do-it-ly y'rs - tim Tim Peters Kendall Square Research Corp tim@ksr.com, ksr!tim@uunet.uu.net From icon-group-request@arizona.edu Wed Aug 28 11:26:16 1991 Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Wed, 28 Aug 91 11:26:16 MST Resent-From: icon-group-request@arizona.edu Received: from Arizona.edu (Maggie.Telcom.Arizona.EDU) by optima.cs.arizona.edu (4.1/15) id AA25920; Wed, 28 Aug 91 11:26:10 MST Received: from ucbvax.Berkeley.EDU by Arizona.edu with PMDF#10282; Wed, 28 Aug 1991 11:25 MST Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA02206; Wed, 28 Aug 91 11:07:18 -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: Wed, 28 Aug 1991 11:25 MST Date: 28 Aug 91 18:02:49 GMT From: cis.ohio-state.edu!zaphod.mps.ohio-state.edu!qt.cs.utexas.edu!cs.utexas.edu!utgpu!news-server.ecf!generic.physics.utoronto.ca!ists!newshub.ccs.yorku.ca!newshub.ccs.yorku.ca!haroldt@ucbvax. (Harold Tomlinson) Subject: Problems compiling Icon on a DecStation 2100. Sender: icon-group-request@arizona.edu Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: Message-Id: X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.edu Organization: York Computing Services Greetings... I'm attempting to compile Icon on my DS2100 using the configuration for a DS3100. I have two problems. (Life should be so simple.) The first problem to hit me is the use of the 'if' in the Makefiles. When make runs, for example, an 'if (grep -s NoRanlib define.h) then touch ../../../NoRanlib;...' the grep returns an error code (string is not found) and the Makefile exits. Since there are only two files with 'if's in them, I edited them manually. (src/runtime/Makefile and config/unix/Generic/Makefile.) The second problem is that, with the runtime Makefile, it tries to do the following: CheckFile: rswitch.o cd ../common; make if (test -f rt.a)\ then make -f rt.mke HDRS="$(HDRS)" Library;\ else ../rtt/rtt -i; fi Even manually this fails... paralandra> ../rtt/rtt -i rtt: File fstruct.rtt; Line 32: too few arguments for macro call to SElemPtrPtr paralandra> make -f rt.mke HDRS="../h/define.h ../h/config.h ../h/typedefs.h ../h/proto.h ../h/cstructs.h ../h/cpuconf.h ../h/rmacros.h ../h/rexterns.h ../h/rstructs.h ../h/rproto.h ../h/cproto.h" Library ../rtt/rtt -d rt ../common/long.o ar r rt.a ../common/long.o ar: Warning: creating rt.a ../rtt/rtt -d rt ../common/memory.o ar r rt.a ../common/memory.o ../rtt/rtt -d rt ../common/time.o ar r rt.a ../common/time.o ../rtt/rtt -d rt cnv.rtt rtt: File cnv.rtt; Line 424: too few arguments for macro call to TElemPtrPtr *** Error code 1 These are defined in src/h/inmacros.h to have trhee parameters. Why is it that the file src/runtime/Makefile does not include ../h/inmacros.h in it's list of HDRS? Has someone compiled this successfully on a DS2100 or DS3100. Could I pick up a tar'd&compress'd copy someplace to ensure that I've got everything? -- # Harold Tomlinson ## haroldt@paralandra.yorku.ca # # Computing & Communications Services ## (416)736-5257-33802 # # YORK UNIVERSITY, Ont, CANADA ## ########################### # From TENAGLIA@mis.mcw.edu Thu Aug 29 09:17:39 1991 Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Thu, 29 Aug 91 09:17:39 MST Received: from mis3.mis.mcw.edu by optima.cs.arizona.edu (4.1/15) id AA28735; Thu, 29 Aug 91 09:17:35 MST Date: Thu, 29 Aug 1991 11:18 CST From: Chris Tenaglia - 257-8765 Subject: Holiday Tidbit To: icon-group@cs.arizona.edu Message-Id: <7AA6AECFC04003EF@mis.mcw.edu> X-Organization: Medical College of Wisconsin MIS Department (Milwaukee, WI) X-Vms-To: IN%"icon-group@cs.arizona.edu" Labor day will soon be upon us and I thought it fitting to submit a code fragment as food for thought over the long long weekend. This one is called SOUNDEX. I recently read about it in a trade rag as being an algorhythm for cataloguing things. Credit houses use to file names and I thought it lended itself well to icon. Perhaps as a means of database key generation. Oh well, look at it, play with it, and maybe someone will find a cool application of it. 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 # # SOUNDEX.ICN 8/28/91 TENAGLIA # # THIS ICON PROGRAM IMPLEMENTS A SOUNDEX CATALOGUING # KEY COMPRESSOR. # procedure main() while map(line := input("Str:")) ~== "quit" do write(soundex(line)) end # # STR IS A STRING (USUALLY A LAST NAME) PHONETICALLY SPELLED. # NUMBER IS RETURNED WHICH IS A CATALOGUE LOOK UP KEY MADE FROM IT. # THE STEPS ARE AS FOLLOWS : # 1. SAVE THE FIRST CHARACTER FOR LATER USE # 2. REMOVE W AND H # 3. REMOVE ALL VOWELS EXCEPT WHEN IN FIRST POSITION # 4. MAP LEFTOVER STRING WITH A NUMBER TABLE # 5. DELETE DUPLICATE ADJACENT DIGITS # 6. MAKE NUMBER 6 CHARACTERS LONG (TRUNCATE OR PAD WITH 0S) # 7. REPLACE FIRST DIGIT WITH SAVED FIRST CHARACTER # procedure soundex(str) static vowels, tbl initial { vowels := 'aeiouy' tbl := "0123012 02245501262301 202" } str := map(str) first := str[1] ; tmp := first ; tmp2 := "" while i := find("w"|"h",str) do str[i] := "" every i := 2 to *str do tmp ||:= if any(vowels,str,i) then "" else str[i] str2 := map(tmp,&lcase,tbl) || "?" every i := 1 to *str2-1 do if str2[i] ~== str2[i+1] then tmp2 ||:= str2[i] number := if *tmp2 < 6 then left(tmp2,6,"0") else tmp2[1+:6] number[1] := first return number end # # GET A STRING OF INPUT FROM THE KEYBOARD # procedure input(prompt) writes(prompt) return read() end From cheyenne Fri Aug 30 19:26:37 1991 Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Fri, 30 Aug 91 19:26:37 MST Date: Fri, 30 Aug 91 19:26:36 MST From: "Cheyenne Wills" Message-Id: <9108310226.AA02456@optima.cs.arizona.edu> Received: by optima.cs.arizona.edu (4.1/15) id AA02456; Fri, 30 Aug 91 19:26:36 MST To: icon-group Subject: SOUNDEX revisited Several years ago I wrote a soundex program (found the algorithm in one of Knuths books). Anyway here it is: ----- procedure soundex(name) name := map(name,string(&lcase),string(&ucase)) # Convert to uppercase.. first := name[1] # Retain the first letter of the name, and convert all # occurrences of A,E,H,I,O,U,W,Y in other positions to "." # # Assign the following numbers to the remaining letters # after the first: # # B,F,P,V => 1 L => 4 # C,G,J,K,Q,S,X,Z => 2 M,N => 5 # D,T => 3 R => 6 name := map(name,"ABCDEFGHIJKLMNOPQRSTUVWXYZ", ".123.12..22455.12623.1.2.2") # If two or more letters with the same code were adjacent # in the original name, omit all but the first every c := !"123456" do while i := find(c||c,name) do name[i+:2] := c name[1] := first # Now delete our place holder ('.') while i := upto('.',name) do name[i] := "" return left(name,4,"0") end ------ Cheyenne Wills From @um.cc.umich.edu:Paul_Abrahams@MTS.cc.Wayne.edu Mon Sep 2 20:59:47 1991 Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Mon, 2 Sep 91 20:59:47 MST Received: from mailrus.cc.umich.edu by optima.cs.arizona.edu (4.1/15) id AA14882; Mon, 2 Sep 91 20:59:43 MST Received: from um.cc.umich.edu by mailrus.cc.umich.edu (5.61/1123-1.0) id AA09313; Mon, 2 Sep 91 23:56:03 -0400 Received: from MTS.cc.Wayne.edu by um.cc.umich.edu via MTS-Net; Mon, 2 Sep 91 23:58:01 EDT Date: Mon, 2 Sep 91 23:57:10 EDT From: Paul_Abrahams@mts.cc.wayne.edu To: icon-group@cs.arizona.edu Message-Id: <356668@MTS.cc.Wayne.edu> Subject: Editing Icon under Emacs Does anyone happen to have a set of Emacs mode definitions that's appropriate to editing Icon under Emacs? (I'm using Emacs 18.57.1, should that matter.) Paul Abrahams abrahams@mts.cc.wayne.edu From icon-group-request@arizona.edu Sun Sep 8 14:02:55 1991 Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Sun, 8 Sep 91 14:02:55 MST Resent-From: icon-group-request@arizona.edu Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by optima.cs.arizona.edu (4.1/15) id AA01315; Sun, 8 Sep 91 14:02:53 MST Received: from ucbvax.Berkeley.EDU by Arizona.edu with PMDF#10282; Sun, 8 Sep 1991 14:02 MST Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA13653; Sun, 8 Sep 91 14:01:05 -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: Sun, 8 Sep 1991 14:02 MST Date: 8 Sep 91 20:41:09 GMT From: cis.ohio-state.edu!zaphod.mps.ohio-state.edu!mips!news.cs.indiana.edu!msi.umn.edu!math.fu-berlin.de!ira.uka.de!ira.uka.de!news@ucbvax.berkeley.edu Subject: ! How to call a generator from everywhere Sender: icon-group-request@arizona.edu Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: <6D2C528A5AC0BF1C@Arizona.edu> Message-Id: X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.edu Organization: University of Karlsruhe, FRG Thanx to all who answered me here and -- of cource -- who mailed me. With coexpressions it workes fine! Well, I'm trying to write a Modula2 to C Translator in Icon. Any ideas or suggestions? angelo P.S. it matches now Procedure Headers, Procedure Bodys and Const Declarations. Now I work on Var Declarations From ralph Wed Sep 11 06:43:45 1991 Date: Wed, 11 Sep 91 06:43:45 MST From: "Ralph Griswold" Message-Id: <9109111343.AA07716@cheltenham.cs.arizona.edu> Received: by cheltenham.cs.arizona.edu; Wed, 11 Sep 91 06:43:45 MST To: icon-group Subject: Icon applications Occasionally we're asked what "major" applications have been written in Icon. We know of some, but we obviously have no way of knowing everything for which Icon has been used. If you have large applications written in Icon that get a significant amount of use, we'd appreciate hearing about them. A couple of lines indicating their nature and use are all we need. We'll keep names/organizations confidential unless you indicate otherwise. Please send the information directly to me. Ralph Griswold / Department of Computer Science The University of Arizona / Tucson, AZ 85721 ralph@cs.arizona.edu / uunet!arizona!ralph voice: 602-621-6609 / fax: 602-621-9618 From icon-group-request@arizona.edu Thu Sep 12 22:25:04 1991 Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Thu, 12 Sep 91 22:25:04 MST Resent-From: icon-group-request@arizona.edu Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by optima.cs.arizona.edu (4.1/15) id AA05509; Thu, 12 Sep 91 22:25:06 MST Received: from ucbvax.Berkeley.EDU by Arizona.edu with PMDF#10282; Thu, 12 Sep 1991 22:24 MST Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA10336; Thu, 12 Sep 91 22:12:06 -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, 12 Sep 1991 22:24 MST Date: 13 Sep 91 03:13:47 GMT From: csus.edu!wupost!zaphod.mps.ohio-state.edu!cis.ohio-state.edu!pacific.mps.ohio-state.edu!linac!midway!ellis!goer@ucdavis.ucdavis.edu (Richard L. Goerwitz) Subject: text retrieval tools Sender: icon-group-request@arizona.edu Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: Message-Id: <1991Sep13.031347.15378@midway.uchicago.edu> X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.edu Organization: University of Chicago Some months ago, I mentioned the existence of a text retrieval library I'd developed. What it essentially did (does) is to enable the user to index texts like the Quran, the Bible, and in general anything that is arranged into neat divisions, and to perform word-based retrievals on that text. I have a new version on-hand, and I'd be happy to mail it out to anyone who wants it. If there is a lot of demand, I'll post it to alt.sources. The package has been tested quite thoroughly by being incorporated into a biblical text retrieval package that I posted to comp.sources.misc. This package (after some improvements) was placed on cs.arizona.edu (icon/ contrib/bibleref.tar.Z). It's still there, and if you don't want to bo- ther asking me to send the software directly to you, you can get it in this form via anonymous ftp to cs.arizona.edu. -- -Richard L. Goerwitz goer%sophist@uchicago.bitnet goer@sophist.uchicago.edu rutgers!oddjob!gide!sophist!goer From icon-group-request@arizona.edu Mon Sep 16 11:57:32 1991 Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Mon, 16 Sep 91 11:57:32 MST Resent-From: icon-group-request@arizona.edu Received: from Arizona.edu (Merlin.Telcom.Arizona.EDU) by optima.cs.arizona.edu (4.1/15) id AA21691; Mon, 16 Sep 91 11:57:30 MST Received: from ucbvax.Berkeley.EDU by Arizona.edu with PMDF#10282; Mon, 16 Sep 1991 11:56 MST Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA05206; Mon, 16 Sep 91 11:48:28 -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: Mon, 16 Sep 1991 11:57 MST Date: 16 Sep 91 16:11:29 GMT From: mcsun!news.funet.fi!fuug!demos!news-server@uunet.uu.net Subject: What is Icon Sender: icon-group-request@arizona.edu Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: Message-Id: <829D488211@srcc.msu.su> X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.edu Organization: Research Computing Center, Moscow State University Hi, all out there! What is the Icon programming language? Is it a text processing one like SNOBOL? Any references to description will be appreciated. Valentine. From icon-group-request@arizona.edu Wed Sep 18 19:20:31 1991 Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Wed, 18 Sep 91 19:20:31 MST Resent-From: icon-group-request@arizona.edu Received: from Arizona.edu (Merlin.Telcom.Arizona.EDU) by optima.cs.arizona.edu (4.1/15) id AA05407; Wed, 18 Sep 91 18:37:18 MST Received: from ucbvax.Berkeley.EDU by Arizona.edu with PMDF#10282; Wed, 18 Sep 1991 18:36 MST Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA12355; Wed, 18 Sep 91 18:24:46 -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: Wed, 18 Sep 1991 18:37 MST Date: 18 Sep 91 23:57:06 GMT From: agate!spool.mu.edu!cs.umn.edu!lynx!nmsu!opus!pannaiya@ucbvax.berkeley.edu (Pradeepkumar Annaiyappa) Subject: icon compiler error Sender: icon-group-request@arizona.edu Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: <6F29B70492A03BB4@Arizona.edu> Message-Id: X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.edu Organization: NMSU Computer Science I down loaded the sources for the icon compiler and am trying to compile it on an RS6000 AIX 3.1.6. The compilation went through without any major errors. On trying to test the samples I get an 'out of memory' error. Has anyone faced this problem? Is there a solution. Thanks, pk PradeepKumar Annaiyappa, Computing Research Laboratory, Las Cruces, NM 88001 (505)-646-1482 pk@nmsu.edu From ralph Wed Sep 18 19:39:06 1991 Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Wed, 18 Sep 91 19:39:06 MST Resent-From: "Ralph Griswold" Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by optima.cs.arizona.edu (4.1/15) id AA06977; Wed, 18 Sep 91 19:39:05 MST Received: from optima.cs.arizona.edu by Arizona.edu with PMDF#10282; Wed, 18 Sep 1991 19:38 MST Received: from cheltenham.cs.arizona.edu by optima.cs.arizona.edu (4.1/15) id AA06971; Wed, 18 Sep 91 19:38:28 MST Received: by cheltenham.cs.arizona.edu; Wed, 18 Sep 91 19:38:27 MST Resent-Date: Wed, 18 Sep 1991 19:38 MST Date: Wed, 18 Sep 91 19:38:27 MST From: Ralph Griswold Subject: RE: icon compiler error Resent-To: icon-group@cs.arizona.edu To: agate!spool.mu.edu!cs.umn.edu!lynx!nmsu!opus!pannaiya@ucbvax.berkeley.edu, icon-group@arizona.edu Resent-Message-Id: <77CC6AA772A030BD@Arizona.edu> Message-Id: <9109190238.AA00670@cheltenham.cs.arizona.edu> X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: agate!spool.mu.edu!cs.umn.edu!lynx!nmsu!opus!pannaiya@ucbvax.berkeley.edu, icon-group@Arizona.edu What was the exact error message? If you tell us that, we probably can tell you what the problem is and how to fix it. Ralph Griswold / Department of Computer Science The University of Arizona / Tucson, AZ 85721 ralph@cs.arizona.edu / uunet!arizona!ralph voice: 602-621-6609 / fax: 602-621-9618 From icon-group-request@arizona.edu Wed Sep 18 22:07:31 1991 Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Wed, 18 Sep 91 22:07:31 MST Resent-From: icon-group-request@arizona.edu Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by optima.cs.arizona.edu (4.1/15) id AA11699; Wed, 18 Sep 91 22:07:30 MST Received: from ucbvax.Berkeley.EDU by Arizona.edu with PMDF#10282; Wed, 18 Sep 1991 22:06 MST Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA18650; Wed, 18 Sep 91 22:05:41 -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: Wed, 18 Sep 1991 22:07 MST Date: 19 Sep 91 04:13:51 GMT From: midway!ellis!goer@uunet.uu.net (Richard L. Goerwitz) Subject: RE: icon compiler error Sender: icon-group-request@arizona.edu Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: <8C8780D9D2A03725@Arizona.edu> Message-Id: <1991Sep19.041351.2372@midway.uchicago.edu> X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.edu Organization: University of Chicago References: pannaiya@nmsu.edu (Pradeepkumar Annaiyappa) writes: >I down loaded the sources for the icon compiler and am >trying to compile it on an RS6000 AIX 3.1.6. The >compilation went through without any major errors. >On trying to test the samples I get an 'out of memory' >error. Has anyone faced this problem? Is there a >solution. I responded privately, but now that I think about it it might be a good idea to post a note here as well. In general, it's better to start with the interpreter if you're installing Icon for the first time, or if you aren't trying to do some big-time development work. From the user's standpoint, executables produced by the interpreter will look and feel pretty much like their compiled equivalents, only slower and using much smaller executable files. My guess is that people are loggin into cs.arizona.edu, browsing, seeing both the compiler and the interpreter, and naturally thinking they want the compiler. This may, in fact, be the correct choice. For a first installation, though, it's probably not. I hope this helps save some people some frustration. Pradeepkumar may have already installed the interpreter, so perhaps this is all superfluous. If so, I apologize for dragging him into this :-). -- -Richard L. Goerwitz goer%sophist@uchicago.bitnet goer@sophist.uchicago.edu rutgers!oddjob!gide!sophist!goer From uunet!men2a!aquin!luvthang!talmage Fri Sep 20 19:55:32 1991 Received: from univers.cs.arizona.edu by cheltenham.cs.arizona.edu; Fri, 20 Sep 91 19:55:32 MST Received: from uunet.UUCP by univers.cs.arizona.edu; Fri, 20 Sep 91 19:55:31 MST Received: from uunet.uu.net (via LOCALHOST.UU.NET) by relay2.UU.NET with SMTP (5.61/UUNET-internet-primary) id AA13735; Fri, 20 Sep 91 13:33:14 -0400 Received: from men2a.UUCP by uunet.uu.net with UUCP/RMAIL (queueing-rmail) id 133239.18719; Fri, 20 Sep 1991 13:32:39 EDT Received: by men2a.ori-cal.com (smail2.5) id AA26119; 20 Sep 91 13:29:28 EDT (Fri) Received: by aquin.ORI-CAL.COM (smail2.5) id AA14463; 20 Sep 91 13:25:55 EDT (Fri) Received: by luvthang.aquin.ori-cal.com (V1.13/Amiga) id AA03360; Thu, 19 Sep 91 12:32:21 EST Date: Thu, 19 Sep 91 12:32:21 EST Message-Id: <9109191732.AA03360@luvthang.aquin.ori-cal.com> From: uunet!luvthang.aquin.ori-cal.com!talmage (David W. Talmage) To: icon-group@cs.arizona.edu Subject: Patterns -> Icon code The current wisdom in Natural Language Processing is to write a description of some part of a language and use a program which interprets the description to process the language. This is a flexible way to separate the data from the program code. Sometimes, though, this isn't especially quick. In that case, a program which generates other another program that can process the langauge directly is desirable. With that in mind, who can point me to a procedure that turns patterns (e.g. the UNIX-style *?{}[] patterns) into Icon code? The Icon Program Library includes the procedure wildcard(), but that one only finds patterns; it does not produce code. Thanks to those who can help. I'll summarize the replies if necessary. ----------------------------------------------------------------------------- David W. Talmage (talmage@luvthang.aquin.ori-cal.com) "Great big Idol with the golden head" From icon-group-request@arizona.edu Sat Sep 21 09:56:49 1991 Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Sat, 21 Sep 91 09:56:49 MST Resent-From: icon-group-request@arizona.edu Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by optima.cs.arizona.edu (4.1/15) id AA16605; Sat, 21 Sep 91 09:56:47 MST Received: from ucbvax.Berkeley.EDU by Arizona.edu with PMDF#10282; Sat, 21 Sep 1991 09:56 MST Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA10066; Sat, 21 Sep 91 09:46:04 -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: Sat, 21 Sep 1991 09:56 MST Date: 21 Sep 91 15:09:06 GMT From: cis.ohio-state.edu!zaphod.mps.ohio-state.edu!wupost!uwm.edu!linac!midway!ellis!goer@ucbvax.berkeley.edu (Richard L. Goerwitz) Subject: RE: Re: Patterns -> Icon code Sender: icon-group-request@arizona.edu Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: <81F18B73E0A0450E@Arizona.edu> Message-Id: <1991Sep21.150906.20881@midway.uchicago.edu> X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.edu Organization: University of Chicago References: <9109191732.AA03360@luvthang.aquin.ori-cal.com> talmage@luvthang.aquin.ori-cal.COM (David W. Talmage) writes: > >With that in mind, who can point me to a procedure that turns patterns >(e.g. the UNIX-style *?{}[] patterns) into Icon code? Whoops. I didn't really answer your specific request. A while back I tried to write a program that took a set of regular expressions (the egrep []()*+.^$ patterns), and create a deterministic finite state auto- maton that would recognize strings matching the pattern. It was slow. I just couldn't figure out a way of doing it fast in Icon. So I backtracked :-), and wrote a program that produces a much smaller nondeterministic pushdown automaton. That program made it into one or another of the IPL updates (number 1?). It's called findre.icn, and although the IPL version works fine, you can always get the latest ver- sion from me (assuming you want it). A lot of us have been asking about regexp support in Icon, but after all, regular expressions don't really fit into the language nicely, and no one can really agree on how they should be implemented. In retro- spect, I think I should have written matchre() before findre(), but I am onto other things now, and probably won't go back and do things over. If you have any ideas about how regular expression capability should be added to Icon, please post. Maybe I'll get back to findre, and rewrite it in the image of what people really want (if it's not OK right now). -- -Richard L. Goerwitz goer%sophist@uchicago.bitnet goer@sophist.uchicago.edu rutgers!oddjob!gide!sophist!goer From icon-group-request@arizona.edu Sat Sep 21 09:57:05 1991 Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Sat, 21 Sep 91 09:57:05 MST Resent-From: icon-group-request@arizona.edu Received: from Arizona.edu (Osprey.Telcom.Arizona.EDU) by optima.cs.arizona.edu (4.1/15) id AA16616; Sat, 21 Sep 91 09:57:03 MST Received: from ucbvax.Berkeley.EDU by Arizona.edu with PMDF#10282; Sat, 21 Sep 1991 09:56 MST Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA10153; Sat, 21 Sep 91 09:48:11 -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: Sat, 21 Sep 1991 09:56 MST Date: 21 Sep 91 16:01:28 GMT From: cis.ohio-state.edu!pacific.mps.ohio-state.edu!linac!midway!ellis!goer@ucbvax.berkeley.edu (Richard L. Goerwitz) Subject: Bible browser; another update Sender: icon-group-request@arizona.edu Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: <81FB40BA62C0491E@Arizona.edu> Message-Id: <1991Sep21.160128.21823@midway.uchicago.edu> X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.edu Organization: University of Chicago I'm feeling verbose today. The Bible browser I keep saying I'm done with (but then go on tweaking) is now on cs.arizona.edu (icon/contrib/bibleref-2.1.tar.Z) in updated form. The Huffman encoding algorithm is tighter (making for smaller files in some cases), and fewer disk seeks are required in order to retrieve text. Many ops still require further optimization, but the package is quite usable as- is. Note that I'm not posting patches. The patches would affect mainly the data files, and, since the data files are pre-built in the cs.arizona.edu archive, there isn't any point in sending out patches to everyone. Just ftp the whole (4 meg) affair from arizona, and (assuming your Icon interpreter is installed OK, and the IPL is there too) you should be in business within, say, a half hour (five or ten minutes, if you've installed Bibleref before). People who feel masochistic, and have a Bible text online already (KJV or RSV only, so far), can build the data files for themselves. Just write to me and ask for the shar files. Beware, though: Indexing, compressing, and optimizing the interface took our Sun4 here at the U of Chicago overnight, and at up a good 18 meg of core memory. (That's why I distribute the thing with pre-built data files!) The process is automatic, if that's any com- fort. If you have the choice, though, take the cs.arizona.edu tar distrib- ution. Note: This program is geared for UNIX. I suspect it would not function on a smaller system (the icode file is too big for MS-DOS, for instance). -- -Richard L. Goerwitz goer%sophist@uchicago.bitnet goer@sophist.uchicago.edu rutgers!oddjob!gide!sophist!goer From icon-group-request@arizona.edu Sat Sep 21 09:57:51 1991 Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Sat, 21 Sep 91 09:57:51 MST Resent-From: icon-group-request@arizona.edu Received: from Arizona.edu (Merlin.Telcom.Arizona.EDU) by optima.cs.arizona.edu (4.1/15) id AA16661; Sat, 21 Sep 91 09:57:49 MST Received: from ucbvax.Berkeley.EDU by Arizona.edu with PMDF#10282; Sat, 21 Sep 1991 09:57 MST Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA10032; Sat, 21 Sep 91 09:45:28 -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: Sat, 21 Sep 1991 09:57 MST Date: 21 Sep 91 14:56:21 GMT From: uwm.edu!linac!midway!ellis!goer@rutgers.edu (Richard L. Goerwitz) Subject: RE: Patterns -> Icon code Sender: icon-group-request@arizona.edu Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: <8216816D80A05711@Arizona.edu> Message-Id: <1991Sep21.145621.20677@midway.uchicago.edu> X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.edu Organization: University of Chicago References: <9109191732.AA03360@luvthang.aquin.ori-cal.com> talmage@luvthang.aquin.ori-cal.COM (David W. Talmage) writes: >The current wisdom in Natural Language Processing is to write a >description of some part of a language and use a program which >interprets the description to process the language. This is a >flexible way to separate the data from the program code. Sometimes, >though, this isn't especially quick. In that case, a program which >generates other another program that can process the langauge directly >is desirable. > >With that in mind, who can point me to a procedure that turns patterns >(e.g. the UNIX-style *?{}[] patterns) into Icon code? The Icon >Program Library includes the procedure wildcard(), but that one only >finds patterns; it does not produce code. What you want is something I've been wanting as well for some time. You want a parser generator. C programmers have long had yacc, which generates a deterministic pushdown automaton - a LALR(1) parser, to be exact. It recognizes only a limited subset of context free lang- uages, and requires what seem to a person like me to be very complex lookahead sets and state transition networks. Recently Tomita pub- lished an article on efficient parsing of the entire range of context free languages. His system, though, suffered from some faults, which are apparently being rectified in a dissertation (in progress) by Jan Rekers (and others) at Amsterdam. Their parser generators work by creating parallel parsing streams, which multiply and join, as needed, in order to remain deterministic (and still take into account all possible parses). The algorithm is surprisingly efficient, and handles the full range of context free languages, unlike yacc. When the Rekers is done, I've been toying with the idea of taking his ideas and using them to write an Icon parser generator. I have some code right here, but it was written in a LISP dialect that uses dynamic variables, and I have little hope of finding the time to try to figure out what is going on, and re-coding it in Icon or C. If anyone is thinking of creating a parser generator that outputs Icon code, please let us all know about it! Maybe we can knock heads to- gether and come up with something. For now, if you can stand writing grammars that aren't left recursive, you can use an IPL program called recgen (yes, there's the IPL I keep reminding people about). It essentially takes a set of BNFs and uses them to create a recursive-descent backtracking recognizer. It does not actually parse or take any actions (a la yacc's action fields), but it will let you prototype certain types of specifications. Watch out, though, for those left-recursive rules (in English we don't have many of these [e.g. the 's rule], but programming languages make heavy use of them in their specs). Good luck, and please offer a summary of anything you find out! -- -Richard L. Goerwitz goer%sophist@uchicago.bitnet goer@sophist.uchicago.edu rutgers!oddjob!gide!sophist!goer From icon-group-request@arizona.edu Thu Oct 3 03:45:36 1991 Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Thu, 3 Oct 91 03:45:36 MST Resent-From: icon-group-request@arizona.edu Received: from Arizona.edu (Merlin.Telcom.Arizona.EDU) by optima.cs.arizona.edu (4.1/15) id AA00944; Thu, 3 Oct 91 03:45:31 MST Received: from ucbvax.Berkeley.EDU by Arizona.edu with PMDF#10282; Thu, 3 Oct 1991 03:44 MST Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA03470; Thu, 3 Oct 91 03:36:51 -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, 3 Oct 1991 03:45 MST Date: 2 Oct 91 21:10:41 GMT From: hsi!mlfarm!rosie!ron@uunet.uu.net (Ronald Florence) Subject: post.icn (v1.5) Sender: icon-group-request@arizona.edu Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: Message-Id: <1991Oct2.211041.226@mlfarm.com> X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.edu Organization: Maple Lawn Farm, Stonington, CT I posted an early version of this newsposter a year ago. Since then it has gotten new features, had a few bugs exterminated, and allowed me to learn a bit of Icon. The current version has been tested on Unix and ms-dos systems running C-news, B-news, and bsnews. The trn and rn users here prefer it to Pnews. The user-configuration is isolated and commented at the top of the code. The Makefile may need hacking if options.icn from the IPL isn't in the default directory, to change the installation directories for the executable and the man page, or for ms-dos. Ronald Florence ron@mlfarm.com #! /bin/sh # This is a shell archive, meaning: # 1. Remove everything above the #! /bin/sh line. # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh (not csh) to create: # post.icn # Makefile # post.1 # This archive created: Wed Oct 2 17:01:50 1991 # By: Ronald Florence (Maple Lawn Farm, Stonington, CT ) export PATH; PATH=/bin:/usr/bin:$PATH if test -f 'post.icn' then echo shar: "will not over-write existing file 'post.icn'" else cat << \SHAR_EOF > 'post.icn' ############################################################################ # # Name: post.icn # # Title: News Poster # # Author: Ronald Florence (ron@mlfarm.com) # # Date: 2 October 1991 # # Version: 1.5 # ############################################################################ # This program posts a news article to Usenet. Given an optional # argument of the name of a file containing a news article, or an # argument of "-" and a news article via stdin, post creates a # follow-up article, with an attribution and quoted text. The # newsgroups, subject, distribution, follow-up, and quote-prefix can # optionally be specified on the command line. # # usage: post [options] [article | -] # -n newsgroups # -s subject # -d distribution # -f followup-to # -p quote-prefix (default ` > ') # # See the site & system configuration options below. On systems # posting via inews, post validates newsgroups and distributions in # the `active' and `distributions' files in the news library directory. # ############################################################################ # # Link: options # Bugs: Newsgroup validation assumes the `active' file is sorted. # Non-Unix sites need hardcoded system information. # ############################################################################ link options global mode, sysname, domain, tz, tmpfile, opts, console, newslib, org procedure main(arg) usage := ["usage: post [options] [article]", "\t-n newsgroups", "\t-s subject", "\t-d distribution", "\t-f followup-to", "\t-p quote-prefix (default ` > ')", "\t- read article from stdin"] # Site configuration. Mode can be # "local" (post via inews), # "uux" (post via rnews to an upstream host), # "mail" (post via mail to an upstream host). # For either uux or mail mode, # smarthost := the uucp nodename of the upstream news feed. # Use generic_from to force a generic address instead # of the hostname provided by system commands. mode := "local" smarthost := "" editor := "vi" domain := ".UUCP" default_distribution := "world" generic_from := &null # For Unix, the rest of the configuration is automatic. if find("UNIX", &features) then { console := "/dev/tty" newslib := "/usr/lib/news/" tz := "unix" tmpdir := "/tmp/" logname := pipe("logname") sysname := trim(pipe("hostname", "uname -n", "uuname -l")) # BSD passwd: `:fullname[,...]:' # SysV passwd: `-fullname(' \logname & every lookup("/etc/passwd") ? { =(logname) & { every tab(upto(':')+1) \4 fullname := (tab(upto('-')+1), tab(upto('(:'))) | tab(upto(',:')) break } } sigfile := getenv("HOME") || "/.signature" } # For non-Unix systems, we need hard coded configuration: # console := the system's name for the user's terminal. # libdir := the directory for news configuration files, like # an `organization' file. # tmpdir := optional directory for temporary files; terminated # with the appropriate path separator: `/' or `\\'. # logname := user's login name. # tz := local time zone (e.g., EST). # fullname := user's full name. # sigfile := full path of file with user's email signature. else { console := "CON" newslib := "" tmpdir := "" logname := &null tz := &null fullname := &null sigfile := &null sysname := getenv("HOST") | &host } # End of user configuration. (\logname & \sysname & \tz & (mode == "local" | *smarthost > 0)) | stop("post: missing system information") opts := options(arg, "n:s:d:f:p:h?") \opts["h"] | \opts["?"] | arg[1] == "?" & { every write(!usage) exit(-1) } org := getenv("ORGANIZATION") | lookup(newslib || "organization") article := open(tmpfile := tempname(tmpdir), "w") | stop("post: cannot write temp file") write(article, "Path: ", sysname, "!", logname) writes(article, "From: ", logname, "@", \generic_from | sysname, domain) \fullname & writes(article, " (", fullname, ")") write(article) # For a follow-up article, reply_headers() does the work. if \arg[1] then { inf := (arg[1] == "-" & &input) | open(arg[1]) | (remove(tmpfile) & stop("post: cannot read " || arg[1])) reply_headers(inf, article) every write(article, \opts["p"] | " > ", !inf) close(inf) } # Query if newsgroups, subject, and distribution have # not been specified on the command line. else { write(article, "Newsgroups: ", validate(\opts["n"] | query("Newsgroups: "), "active")) write(article, "Subject: ", \opts["s"] | query("Subject: ")) write(article, "Distribution: ", validate(\opts["d"] | query("Distribution: ", default_distribution), "distributions")) every write(article, req_headers()) write(article, "\n") } close(article) edstr := (getenv("EDITOR") | editor) || " " || tmpfile || " < " || console system(edstr) upto('nN', query("Are you sure you want to post this to Usenet y/n? ")) & { if upto('yY', query("Save your draft article y/n? ")) then stop("Your article is saved in ", tmpfile) else { remove(tmpfile) stop("Posting aborted.") } } # For inews, we supply the headers, inews supplies the .signature. if mode == "local" then mode := newslib || "inews -h" else { \sigfile & { article := open(tmpfile, "a") write(article, "--") every write(article, lookup(sigfile)) } # To post via sendnews (mail), we prefix lines with 'N'. # For rnews, don't force an immediate poll. case mode of { "mail": { mode ||:= " " || smarthost || "!rnews" outf := open(tmp2 := tempname(tmpdir), "w") every write(outf, "N", lookup(tmpfile)) remove(tmpfile) rename(tmp2, tmpfile) } "uux": mode ||:= " - -r " || smarthost || "!rnews" } } mode ||:= " < " || tmpfile (system(mode) = 0) & write("Article posted!") remove(tmpfile) end # To parse the original article, we use case-insensitive # matches on the headers. The Reply-to and Followup-To # headers usually appear later than From and Newsgroups, so # they take precedence. By usenet convention, we query # the user if Followup-To on the original is `poster'. procedure reply_headers(infile, art) every !infile ? { tab(match("from: " | "reply-to: ", map(&subject))) & { if find("<") then { fullname := (trim(tab(upto('<'))) ~== "") address := (move(1), tab(find(">"))) } else { address := trim(tab(upto('(') | 0)) fullname := (move(1), tab(find(")"))) } quoter := (\fullname | address) } tab(match("date: ", map(&subject))) & date := tab(0) tab(match("message-id: ", map(&subject))) & id := tab(0) tab(match("subject: ", map(&subject))) & subject := tab(0) tab(match("distribution: ", map(&subject))) & distribution := tab(0) tab(match("newsgroups: " | "followup-to: ", map(&subject))) & group := tab(0) tab(match("references: ", map(&subject))) & refs := tab(0) (\quoter & *&subject = 0) & { find("poster", group) & { write(quoter, " has requested followups by email.") upto('yY', query("Do you want to abort this posting y/n? ")) & { remove(tmpfile) stop("Posting aborted.") } group := &null } write(art, "Newsgroups: ", \group | validate(\opts["n"] | query("Newsgroups: "), "active")) write(art, "Subject: ", \opts["s"] | \subject | query("Subject: ")) \distribution | distribution := validate(\opts["d"], "distributions") & write(art, "Distribution: ", distribution) write(art, "References: ", (\refs ||:= " ") | "", id) every write(art, req_headers()) write(art, "In-reply-to: ", quoter, "'s message of ", date) write(art, "\nIn ", id, ", ", quoter, " writes:\n") return } } end # We need a unique message-id, and a date in RFC822 format. # Easy with Unix systems that support `date -u'; with the # others, we leave the local timezone. The first inews site # will correct it. procedure req_headers() uniq := "<" &date || &clock ? while tab(upto(&digits)) do uniq ||:= tab(many(&digits)) uniq ||:= "@" || sysname || domain || ">" if tz == "unix" then { date := pipe("date -u", "date") date ? { month := (tab(find(" ") + 1), tab(many(&letters))) day := (tab(upto(&digits)), tab(many(&digits))) time := (tab(upto(&digits++':')), tab(many(&digits++':'))) zone := (tab(upto(&ucase)), tab(many(&ucase))) year := (tab(upto(&digits)+ 2), tab(0)) } date := day || " " || month || " " || year || " " || time || " " || zone } else { &dateline ? { month := left((tab(find(" ")+1), tab(many(&letters))), 3) || " " date := (tab(upto(&digits)), tab(many(&digits))) || " " || month date ||:= (tab(upto(&digits)), right(tab(many(&digits)), 2)) } date ||:= " " || &clock || " " || tz } mode ~== "local" & suspend "Message-ID: " || uniq suspend "Date: " || date \org & suspend "Organization: " || org \opts["f"] & return "Followup-To: " || ((opts["f"] == "poster") | validate(opts["f"], "active")) end # Richard Goerwitz's generator. procedure tempname(dir) every temp_name := dir || "article." || right(1 to 999,3,"0") do { close(open(temp_name)) & next suspend \temp_name } end # On systems with pipes, pipe() will read from the first # successful command of the list given as arguments. procedure pipe(cmd[]) initial find("pipes" | "compiled", &features) | stop("No pipes.") while inf := open("(" || pop(cmd) || ") 2>&1", "pr") do { got := [] every put(got, !inf) close(inf) = 0 & { suspend !got break } } end # The dirty work of reading from a file. procedure lookup(what) inf := open(what, "r") | fail suspend !inf close(inf) end # Query opens stdin because the system call to the editor # redirects input. The optional parameter is a default # response if the user answers with . procedure query(prompt, def) static stdin initial stdin := open(console) writes(prompt) ans := read(stdin) return (*ans = 0 & \def) | ans end # A quick and dirty kludge. Validate() builds a sorted list. # When an element is found, it is popped and the search moves # to the next item. The procedure assumes the file is also # sorted. procedure validate(what, where) mode ~== "local" & return what valid := &letters ++ '.-' ++ &digits stuff := [] what ? while tab(upto(valid)) do put(stuff,tab(many(valid))) sf := open(newslib || where) | { remove(tmpfile) stop("post: cannot open ", newslib || where) } stuff := sort(stuff) a := pop(stuff) every !sf ? match(a) & (a := pop(stuff)) | return what remove(tmpfile) stop("`", a, "' is not in ", newslib || where) end SHAR_EOF if test 10945 -ne "`wc -c < 'post.icn'`" then echo shar: "error transmitting 'post.icn'" '(should have been 10945 characters)' fi fi if test -f 'Makefile' then echo shar: "will not over-write existing file 'Makefile'" else cat << \SHAR_EOF > 'Makefile' # Makefile for post BINDIR= /usr/local/bin MANDIR= /usr/man/manl MANEXT= l .SUFFIXES: .icn .u1 .icn.u1: icont -c $< .icn: icont $@ #options.u1: # icont -c ../lib/options.icn post: post.icn options.u1 icont $@ install: post post.1 cp post $(BINDIR) cp post.1 $(MANDIR)/post.$(MANEXT) clean: rm -f *.u[12] SHAR_EOF if test 318 -ne "`wc -c < 'Makefile'`" then echo shar: "error transmitting 'Makefile'" '(should have been 318 characters)' fi fi if test -f 'post.1' then echo shar: "will not over-write existing file 'post.1'" else cat << \SHAR_EOF > 'post.1' .\" post.man version 1.5 .\" copyright 1991 Ronald Florence .TH POST LOCAL "2 Oct 1991" .SH NAME post \- news poster .SH SYNOPSIS .B post [ .BI \-n\ newsgroups ] [ .BI \-s\ subject ] [ .BI \-d\ distribution ] [ .BI \-f\ followup-to ] [ .BI \-p\ quote-prefix ] [ .B \- | .I news-article ] .SH DESCRIPTION .I Post posts a news article to Usenet via inews, uux, or mail. Given an optional argument of the name of a file containing a news article, or an argument of `\-' and a news article via stdin, .I post creates a follow-up article, with an attribution and quoted text. .I Post can be invoked as a filter from a newsreader: .RB ` "|post \-" ' would create a followup article to the current article in the newsreader. The newsgroups, subject, distribution, follow-up, and quote-prefix (the default is ` > ') can be specified on the command line. .PP .I Post is compatible with C-News, B-news, and bsnews (Bootstrap News). On systems with inews, the newsgroups and distribution are validated in the appropriate news system files. .SH ENVIRONMENT The environment variable .SM EDITOR overrides the default editor. .SM ORGANIZATION overrides the file /usr/lib/news/organization to specify an optional Organization header. On non-Unix\u\s-3TM\s0\d systems, the environment variable .SM HOST may be used to override the Icon keyword .I &host as the sitename. .SH BUGS The code to validate newsgroups assumes the file /usr/lib/news/active is sorted. .SH AUTHOR Ronald Florence (ron\s-2@\s0mlfarm.com). The code to generate a temporary file name is from Richard Goerwitz (goer\s-2@\s0sophist.uchicago.edu). Options.icn is from the Icon Program Library. SHAR_EOF if test 1660 -ne "`wc -c < 'post.1'`" then echo shar: "error transmitting 'post.1'" '(should have been 1660 characters)' fi fi exit 0 # End of shell archive -- Ronald Florence ron@mlfarm.com From mlfarm!ron@hsi.hsi.com Thu Oct 10 06:09:42 1991 Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Thu, 10 Oct 91 06:09:42 MST Received: from hsi.hsi.com by optima.cs.arizona.edu (4.1/15) id AA28687; Thu, 10 Oct 91 06:09:35 MST Received: by hsi.hsi.com (5.61+++/1.34) id AA06909; Thu, 10 Oct 91 09:07:26 -0400 Received: by rosie.mlfarm.com (4.1/SMI-4.1) id AA06230; Thu, 10 Oct 91 09:06:16 EDT Date: Thu, 10 Oct 91 09:06:16 EDT Message-Id: <9110101306.AA06230@rosie.mlfarm.com> From: mlfarm!ron@hsi.hsi.com (Ronald Florence) To: icon-group@cs.arizona.edu Subject: icon-group <-> comp.lang.icon We receive both the icon-group mailing list and the comp.lang.icon newsgroup. We feed the newsgroup to another site. Our own newsfeed gets the newsgroup directly from uunet. Although there has been no traffic on either the mailing list or the newsgroup recently, I've noticed in the past that some material posted to icon-group does not crossover to the newsgroup, although material posted to the newsgroup makes it to the mailing list. If anyone else has had this experience, I'd welcome hearing from you. I miss news from both. Is Richard Goerwitz too busy for Icon these days? ;-) Ronald Florence ron@mlfarm.com From icon-group-request@arizona.edu Fri Oct 11 00:13:35 1991 Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Fri, 11 Oct 91 00:13:35 MST Resent-From: icon-group-request@arizona.edu Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by optima.cs.arizona.edu (4.1/15) id AA12682; Fri, 11 Oct 91 00:13:32 MST Received: from ucbvax.Berkeley.EDU by Arizona.edu with PMDF#10282; Fri, 11 Oct 1991 00:12 MST Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA00323; Thu, 10 Oct 91 23:58:40 -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, 11 Oct 1991 00:13 MST Date: 10 Oct 91 23:25:28 GMT From: midway!ellis!goer@uunet.uu.net (Richard L. Goerwitz) Subject: RE: icon-group <-> comp.lang.icon Sender: icon-group-request@arizona.edu Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: Message-Id: <1991Oct10.232528.16542@midway.uchicago.edu> X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.edu Organization: University of Chicago References: <9110101306.AA06230@rosie.mlfarm.com> Ron@mlfarm (Ronald Florence) writes: > >Although there has been no traffic on either the mailing list or the >newsgroup recently, I've noticed in the past that some material posted >to icon-group does not crossover to the newsgroup, although material >posted to the newsgroup makes it to the mailing list. If anyone else >has had this experience, I'd welcome hearing from you. > >I miss news from both. Is Richard Goerwitz too busy for Icon these >days? ;-) Never too busy to cut code, but often too busy to clean it up for posting :o). -- -Richard L. Goerwitz goer%sophist@uchicago.bitnet goer@sophist.uchicago.edu rutgers!oddjob!gide!sophist!goer From icon-group-request@arizona.edu Sat Oct 12 15:11:11 1991 Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Sat, 12 Oct 91 15:11:11 MST Resent-From: icon-group-request@arizona.edu Received: from Arizona.edu (Merlin.Telcom.Arizona.EDU) by optima.cs.arizona.edu (4.1/15) id AA06196; Sat, 12 Oct 91 15:11:08 MST Received: from ucbvax.Berkeley.EDU by Arizona.edu with PMDF#10282; Sat, 12 Oct 1991 15:10 MST Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA09244; Sat, 12 Oct 91 14:53:21 -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: Sat, 12 Oct 1991 15:10 MST Date: 12 Oct 91 18:28:46 GMT From: midway!ellis!goer@uunet.uu.net (Richard L. Goerwitz) Subject: windowing; an exercize Sender: icon-group-request@arizona.edu Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: <2E55FA85C0A10496@Arizona.edu> Message-Id: <1991Oct12.182846.10147@midway.uchicago.edu> X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.edu Organization: University of Chicago I wrote the following code partly as an exercize, and partly as a sub-part of a project I'm working on. Ron had lamented the dearth of material that's been coming in lately. Here's something to mull over. -Richard ------ ############################################################################ # # Name: iwinds.icn # # Title: windowing routines # # Author: Richard L. Goerwitz # # Version: 1.4 (a very preliminary version) # ############################################################################ # # This file contains a relatively small windowing package for use on # UNIX systems with an installed (and updated) Icon Program Library. # It will probably work under MS-DOS and other such systems as well, # although you'll need to read the docs for iolib.icn and iscreen.icn # in the IPL. Note that some systems have problems with getchlib in # the IPL. The last SunOS version did (in NFS environments). # # Note: This is not a curses clone, and it is very slow. I was just # trying to decide how a windowing interface might possibly be done # in Icon (which has no pointers, and hence forces me to use things # like records and global variables where I'd like to use explicit # pointers to smaller data types). It's an exercize, and I'd really # appreciate any advice on how to speed it up. # # For those seriously interested in character-based I/O that will work # using stock terminals, check out the work being done by Iconic Soft- # ware Inc. They have a curses interface for their Icon interpreter # that is terminfo based, and runs on most i386 UNIX versions. As of # this writing, it's in the end stages of beta testing. # ############################################################################ # # This file contains the following routines: # # createw(begy, begx, lines, cols, wmode, wchar, border, bmode) # exit_prog(procname, message, exit_code) # hidew(w) # movew(w, begy, begx) # redraw() # readw(w, ypos, xpos, mode) # getchw(w, ypos, xpos, mode) - for no-echo, just use getch() # window(mode) # writew(w, s, pos, xpos, mode) # # To initiate windowing mode one must call window() with the argu- # ment "on". To end it, one must call it with the argument "off". # To "stop" a program while in windowing mode, call exit_prog(), # using the current function name as arg 1, a diagnostic message as # arg 2, and an exit code as arg 3. If you don't follow this # protocol under UNIX, you'll find your terminal locked up in raw # mode. # # To create a window, call createw() with the following arguments, in # order: 1) the beginning line and 2) the beginning column for the # upper left-hand square of the window; 3) the number of lines and 4) # columns the window occupies; if desired, you can specify a default # mode (5 - where 0 = normal, 1 = reverse video, 2 = underline, and 3 # = boldface), and a default character (6). You can, also specify # border (7) and a default mode for the border (8). Note that the # border argument must be a string or list with 8 members, # corresponding to the top left, top, top right, right, bottom right, # bottom, bottom left, and left characters used to form the border # (e.g. "+-+|+-+|"). # # To hide a window on the screen, call hidew(w). If you want to free # up the storage occupied by a window, hide it, and then set variables # that point to it to &null. If you are anal-retentive, you can call # collect(). Hidew() fails if you try to hide _mainw, or try to hide # an already-hidden window. # # The redraw() procedure (no arguments) redraws the entire physical # screen. Movew(w, y, x) moves window w so that its upper left-hand # corner is at line y and column x. # # Writew(w, s, y, x, mode) writes string s to window w beginning at # position y,x using mode as the default mode. There is no scroll or # wordwrap, although writes to the bottom right corner will come back # around to the upper left corner. I forget why I did things this # way. # # Readw(w, y, x, mode) reads and returns a string, echoing it, while # it is being typed, to window w, starting at position y,x using mode # as the default mode. If you want to do non-echoing reads, just use # getch(). In general, don't read &input using read(), reads(), or # getche() while in windowing mode. It will look silly on the screen, # and if you're running under UNIX, the read functions may not work as # expected (remember, you're in raw mode). # ############################################################################ # # Here's a brief example of how to use this library to do pretty things # on the screen. It's nothing very complicated - just some simple window # drawing and moving exercizes, with one window being used for a message. # # # for UNIX - make sure your IPL is fully updated! # link iwinds, iolib, iscreen, getchlib # # # non-UNIX # # link iwinds, iolib, iscreen (make sure you have getch()) # # procedure main() # # # global LINES, COLS (defined in iwinds.icn) # local w, w2, w3, y, x # # # Initiate windowing mode. # window("on") # # # Display a 10x30 window in the upper left corner of the screen. # # Give it a border of spaces in reverse video mode. Fill the box # # with "x" characters in normal mode. # w := createw(1, 1, 10, 30, 0, "x", " ", 1) # # # Now for fun, move the window just created diagonally down, until # # it gets to the bottom of the screen. Be sure not to overrun the # # screen. # x := 1 # every y := 3 to LINES - 10 by 3 do # movew(w, y, x +:= 6) # # # Lay down a small window. # w2 := createw(8, 20, 3, 10, 1) # # Print the word "hello" in it. # writew(w2, "hello", 1, 1) # # # Lay down a window over top of the first one. # w3 := createw(14, 50, 9, 30, 0, ".", " ",1) # # # Move the small window down on top of the other two. # x := 20 # every y := 11 to LINES - 7 by 3 do # movew(w2, y, x +:= 7) # # # Change the message in the little window. # writew(w2, "done!! ", 1, 1, 3) # # Erase the two big windows. # hidew(w3) # hidew(w) # # # Move the little window back up to where it started. # every y := y to 3 by -3 do # movew(w2, y, x -:= 7) # # # Quit. # window("off") # exit_prog() # # end # ############################################################################ # # Links: itlib or iolib, iscreen, and some implementation of getche() # ############################################################################ # UNIX - link itlib, iscreen, getchlib # for debugging purposes # link ximage, radcon global _stdscr, _mainw, isUNIX, COLS, LINES record _square(val, over, under) record _window(wlist, begy,begx, lines,cols, ypos,xpos, border) procedure window(mode) # # Initiates/ends windowing mode. If arg1 == "on", then windowing # mode is turned on; "off" does the opposite. Returns a string # containing the current mode. No arg invocation works the same, # except that no change occurs in the current mode. # static wmode #global isUNIX initial { wmode := "off" find("UNIX", &features) & isUNIX := "yes" } if /mode | (wmode === mode) then return wmode else { case mode of { "off" : { \isUNIX & reset_tty() normal() iputs(igoto(getval("cm"), 1, LINES)) } "on" : { \isUNIX & setup_tty() initscr() } default: { exit_prog("window", "mode arg must be \"on\" or \"off\"", 11) } } } return wmode := mode end procedure initscr(wmode, wchar, border) # # Creates _stdscr, and the main window which covers the terminal # screen (unless TERM has am capability, i.e. won't let us write # to the last column without wrapping; in which case make _stdscr # one column narrower than the physical screen). # local begy, begx, ypos, xpos, default_cell, wlist, wlist2, r, c, tmp # global _stdscr, _mainw, COLS, LINES, isUNIX \isUNIX & setup_tty() # initializes raw mode (see getchlib.icn) # # Set up default size, position, etc. # begy := 1 # initialize variables for a single, blank begx := 1 # normal-mode window starting at 1,1 that LINES := getval("li") # covers the entire screen COLS := getval("co") if getval("am") then # don't use last col if wordwrap will COLS -:= 1 # occur ypos := 1 xpos := 1 /border := &null # main window normally doesn't get a border /wmode := 0 # default mode for _mainw is always 0 /wchar := " " # default char for _mainw is always " " if 0 < *wchar < 2 # then default_cell := -(ishift(wmode,16) + ord(wchar)) then default_cell := -((wmode * 65536) + ord(wchar)) else exit_prog("initscr", "wchar must be a single char or &null", 41) # # Create a LINES X COLS array of _square() records. # every !(wlist := list(LINES)) := list(COLS) every !(wlist2 := list(LINES)) := list(COLS) # # If blank spaces aren't the default, then flag each square for update. if wmode = 0 & wchar == " " then { default_cell := abs(default_cell) clear() } # every r := 1 to LINES do { every c := 1 to COLS do { tmp := _square(default_cell, &null, &null) wlist[r][c] := tmp wlist2[r][c] := tmp } } _mainw := _window(wlist, begy,begx, LINES,COLS, ypos,xpos, border) _stdscr := _window(wlist, begy,begx, LINES,COLS, ypos,xpos) if not (wmode = 0 & wchar == " " & /border) then refreshw(_mainw) return _mainw end procedure refreshw(w) # # Foregrounds & redraws window w on the screen. # local y, x, stdscr_y, stdscr_x, stdscr_square, window_square, oldval /w := _mainw # _mainw is the default (covers whole screen) every y := 1 to w.lines do { every x := 1 to w.cols do { # Create a handle for manipulating the current square in w. window_square := w.wlist[y][x] # If the window isn't to be foregrounded, and the square isn't # visible, then skip this square. Go right to the next one. if \dont_foreground then if \window_square.over then next # Calculate this square's position on _stdscr. stdscr_y := y + w.begy - 1 stdscr_x := x + w.begx - 1 # Create a handle for manipulating the square which previously # occupied the spot we're about to put the current window square # into. Drop new square into the old one's spot. stdscr_square := _stdscr.wlist[stdscr_y][stdscr_x] _stdscr.wlist[stdscr_y][stdscr_x] := window_square # If window w already occupies this square in _stdscr, then # there's no need to reshuffle the _stdscr structure. If w # does not occupy this square, though... if window_square ~=== stdscr_square then { # ...check to see if the window is farther down the _stdscr # stacks; if so, then remove it from the stack... if \window_square.over then { (\window_square.under).over := window_square.over window_square.over.under := window_square.under } # ...then push the old topmost square "down" the stack, and # finally place the current square on top. window_square.under := stdscr_square window_square.over := stdscr_square.over stdscr_square.over := window_square # The old square will need to be updated when it's # uncovered. oldval := stdscr_square.val stdscr_square.val := -abs(oldval) # Paranoid check. The topmost member of the stack should # always have &null as its "over" pointer. # /window_square.over | { # # write(&errout, "window:\n", (\ximage)(window_square)) # exit_prog("refreshw", "bizarre stack malformation", 21) # } } # Update the current square on the screen. Don't bother # drawing it if the previous one had the same val, and it # wasn't flagged for update. if stdscr_square.val ~= window_square.val | ((\oldval | stdscr_square.val) \ 1) < 0 then draw_it(window_square, stdscr_y, stdscr_x) else window_square.val := abs(window_square.val) oldval := &null } } return end procedure draw_it(sq, y, x) # # Draws square sq on the physical screen at y,x. # local mode static cm, last_mode, last_y, last_x # global COLS (number of columns in _stdscr) initial { cm := getval("cm") # initialize to impossible values last_mode := last_y := last_x := -1 } # mask out update flag so this square doesn't get updated again sq.val := abs(sq.val) # If we aren't at the right position already, then reposition the # cursor manually. if not (y = last_y & x = (last_x + 1)) then { # termlib routines put x before y. iputs(igoto(cm, x, y)) # If we have to reposition the cursor, reset the mode as well. # This may not be necessary for most terminals. We'll see. # last_mode := -1 } # record the position we're at last_y := y; last_x := x # mode is recorded in bits 16-31 of sq.val # mode := iand(ishift(sq.val, -16), 32767) mode := sq.val / 65536 # If there's been a mode change since the last square was written, # or if the cursor's been repositioned, or if we're at the start # of a line, then reset the mode. if (last_mode ~=:= mode) | (y = 1) then { case mode of { 0 : normal() 1 : emphasize() 2 : underline() 3 : boldface() 4 : blink() default : { # write(&errout, "mode for ", y, ",", x, " = ", mode) normal() } } } # Turn lower 16 bits of sq.val into a character. 8 bits is # the usual now, but soon it'll be 16 bits for characters (I # hope). return writes(char(iand(sq.val, 65535))) end procedure hidew(w) # # Foregrounds & redraws window w on the screen. # local y, x, stdscr_y, stdscr_x, window_square w === _mainw & fail # can't hide main window # window is already hidden if over and under pointers are null /w.wlist[1][1].over & /w.wlist[1][1].under & fail every y := 1 to w.lines do { every x := 1 to w.cols do { # Create a handle for manipulating the current square in w. window_square := w.wlist[y][x] # If the over pointer is nonnull, then we're not on top # of the stack for position y,x. if \window_square.over then { # So link the record underneath (if there is one) to # the one on top; link the one on top to the one # underneath (to &null if there isn't one underneath). (\window_square.under).over := window_square.over window_square.over.under := window_square.under } # Over pointer is null, but under pointer is not, so the # square is on-screen at _stdscr.wlist[stdscr_y][stdscr_x]. # Remove it; make _stdscr.wlist[stdscr_y][stdscr_x] point # to window_square.under. Set window_square.under.over to # &null to indicate that it is now on the top of the stack. else { window_square.under.over := &null stdscr_y := y + w.begy - 1 stdscr_x := x + w.begx - 1 _stdscr.wlist[stdscr_y][stdscr_x] := window_square.under if window_square.val ~= window_square.under.val | window_square.val < 0 then draw_it(window_square.under, stdscr_y, stdscr_x) else window_square.val := abs(window_square.val) } window_square.over := &null window_square.under := &null # Paranoid check. The topmost member of the stack should # always have &null as its "over" pointer. # /(((_stdscr.wlist)[stdscr_y][stdscr_x]).over) | { # write(&errout,"window:\n", # (\ximage)(_stdscr.wlist[stdscr_y][stdscr_x].over)) # exit_prog("hidew", "bizarre stack malformation", 21) # } } } return end procedure createw(begy, begx, lines, cols, wmode, wchar, border, bmode) # # Creates a new window with the upper left corner at begy,begx, and # a size of lines,cols, a default mode of wmode, and a default fill # char of wchar; a border is drawn if border is nonnull. # local default_cell, wlist, r, c, w if /(begy | begx | lines | cols) then exit_prog("createw", "first four arguments must all be nonnull", 31) /wmode := 0 # default mode is 0 (normal) /wchar := " " # default char is a space # default_cell := -(ishift(wmode,16) + ord(wchar)) default_cell := -((wmode * 65536) + ord(wchar)) /border := &null # # Create a lines X cols array of _square() records. # every !(wlist := list(LINES)) := list(COLS) every !(wlist2 := list(LINES)) := list(COLS) # every r := 1 to lines do every c := 1 to cols do wlist[r][c] := _square(default_cell, &null, &null) w := _window(wlist, begy,begx, lines, cols, ypos,xpos, border) make_border(w, \border, \bmode | wmode) refreshw(w) return w end procedure redraw() # # Simple redraw of the entire screen. # local r, c #global LINES, COLS # clear() every r := _stdscr.begy to LINES do { every c := _stdscr.begx to COLS do { draw_it(_stdscr.wlist[r][c], r, c) } } return "screen redrawn" end procedure movew(w, begy, begx) local wlist, wlist2, y, x, w2, window_square w === _mainw & fail # can't move main window /begy | /begx & exit_prog("movew","null argument 2 and/or 3!",61) wlist := w.wlist wlist2 := list(w.lines) every (!wlist2) := list(w.cols) every y := 1 to w.lines do { every x := 1 to w.cols do { window_square := (wlist2[y][x] := copy(wlist[y][x])) window_square.val := -abs(window_square.val) window_square.over := &null window_square.under := &null } } w2 := copy(w) w2.wlist := wlist2 w2.begy := begy w2.begx := begx refreshw(w2) hidew(w) w.wlist := wlist2 w.begy := begy w.begx := begx return end procedure make_border(w, border, mode) local ulc, uc, urc, rc, brc, bc, blc, lc # mode := ishift(\mode, 16) | 0 mode := (\mode * 65536) | 0 if type(border) === ("list"|"string") then { *border = 8 | exit_prog("make_border", "*border must be 8", 41) ulc := -(mode + ord(border[1])) uc := -(mode + ord(border[2])) urc := -(mode + ord(border[3])) rc := -(mode + ord(border[4])) brc := -(mode + ord(border[5])) bc := -(mode + ord(border[6])) blc := -(mode + ord(border[7])) lc := -(mode + ord(border[8])) } else { ulc := -(mode + ord("+")) uc := -(mode + ord("-")) urc := -(mode + ord("+")) rc := -(mode + ord("|")) brc := -(mode + ord("+")) bc := -(mode + ord("-")) blc := -(mode + ord("+")) lc := -(mode + ord("|")) } w.border := [ulc, uc, urc, rc, brc, bc, blc, lc] # Now draw in all the appropriate charcters. Be sure to check # whether the window is big enough! w.wlist[1][1].val := ulc every x := 2 to w.cols-1 do { w.wlist[1][x].val := uc w.wlist[w.lines][x].val := bc } w.wlist[1][w.cols].val := urc w.wlist[w.lines][w.cols].val := brc every y := 2 to w.lines-1 do { w.wlist[y][w.cols].val := rc w.wlist[y][1].val := lc } w.wlist[w.lines][1].val := blc return w.border end procedure writew(w, s, y, x, mode) local begy, begx, maxy, maxx, stdscr_square, newval static controls, spaces initial { controls := "" every controls ||:= char((0 to 7) | 9 | 11 | 12 | (14 to 31)) spaces := repl(" ", *controls) # write(&errout, image(controls)) } begy := 1 begx := 1 maxy := w.lines maxx := w.cols ypos := \y | w.ypos xpos := \x | w.xpos # see below on mode if \w.border then { # just in case it's forgotten that there's a border, and an # attempt is made to write to spaces occupied by the border ypos <= begy & ypos := 2 ypos >= maxy & ypos := 2 & xpos := 2 xpos <= begx | xpos >= maxx & xpos := 2 # reset boundaries to account for the smaller available space begy +:= 1 begx +:= 1 maxy -:= 1 maxx -:= 1 } begy <= ypos <= maxy | begx <= xpos <= maxx | exit_prog("writew", "coordinate out of range: "||ypos||","||xpos, 51) # Reposition the cursor. iputs(igoto(getval("cm"), xpos + w.begx - 1, ypos + w.begy - 1)) s := map(s, controls, spaces) # write(&errout, image(s)) # mode := ishift(\mode, 16) mode := (\mode * 65536) every c := !s do { # write(&errout, image(c)) if any('\n\r', c) then { ypos +:= 1 xpos := begx - 1 } else { if c == "\b" then { (begx <= (xpos <- (xpos - 1))) | next writew(w, " ", ypos, xpos, mode, "immediate") iputs(igoto(getval("cm"), xpos + w.begx - 1, ypos + w.begy- 1)) next } # write(&errout, # "old char cell ",radcon(w.wlist[ypos][xpos].val,10,2)) stdscr_square := w.wlist[ypos][xpos] newval := (\mode | iand(abs(w.wlist[ypos][xpos].val),2147418112))+ ord(c) if stdscr_square.val < 0 | stdscr_square.val ~= newval then { stdscr_square.val := -newval if /stdscr_square.over then draw_it(stdscr_square, ypos+w.begy - 1, xpos+w.begx - 1) } else stdscr_square.val := newval # write(&errout, "mode = ", radcon(\mode,10,2)) # write(&errout, # "char cell = ", radcon(w.wlist[ypos][xpos].val, 10, 2)) } ypos > maxy & ypos := begy & xpos := begx xpos < maxx & xpos +:= 1 } w.ypos := ypos w.xpos := xpos return end procedure readw(w, y, x, mode) # # Reads a string from window w, at pos y,x within that window, # echoing the string to the screen. Characters get echoed as # they are typed. Terminates on a CR or LF & returns the string # just read (minus the CR/LF). # local chr, s # Move the cursor to the spot we're to start reading at. writew(w, "", y, x, mode) # Check to be sure this square is visible on the screen. /_stdscr.wlist[y + w.begy - 1][x + w.begx - 1].over | { write(&errout, "error (readw): square isn't visible") fail } s := "" repeat { case chr := getch() | fail of { "\r"|"\n" : return s (\c_cc).vkill : { if *s < 1 then next every 1 to *s do writew(w,"\b",,,mode) s := "" } "\b" : { if *s < 1 then next writew(w,"\b",,,mode) s := s[1:-1] } default : { writew(w,chr,,,mode) s ||:= chr } } } end procedure getchw(w, y, x, mode) # # Reads a string from window w, at pos y,x within that window, # echoing the string to the screen. Characters get echoed as # they are typed. Terminates on a CR or LF & returns the string # just read (minus the CR/LF). # local chr, s # Move the cursor to the spot we're to start reading at. writew(w, "", y, x, mode) # Check to be sure this square is visible on the screen. /_stdscr.wlist[y + w.begy - 1][x + w.begx - 1].over | { write(&errout, "error (getchw): square isn't visible") fail } chr := getch() | fail writew(w,chr,,,mode) return chr end procedure exit_prog(func, msg, errcode) # # Program termination utility. Prints error message "msg" for # function "func," resets the terminal, then aborts with exit code # "errcode." For normal exits, call exit_prog() without any args. # # global LINES func := " (" || (trim(\func, ': ') || "): ") | ": " write(&errout, "error", func, \msg) window("off") normal(); clear() iputs(igoto(getval("cm"), 1, LINES-1)) exit(errcode) # abort program with exit code errcode end -- -Richard L. Goerwitz goer%sophist@uchicago.bitnet goer@sophist.uchicago.edu rutgers!oddjob!gide!sophist!goer From icon-group-request@arizona.edu Sat Oct 12 22:24:12 1991 Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Sat, 12 Oct 91 22:24:12 MST Resent-From: icon-group-request@arizona.edu Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by optima.cs.arizona.edu (4.1/15) id AA14839; Sat, 12 Oct 91 22:24:10 MST Received: from ucbvax.Berkeley.EDU by Arizona.edu with PMDF#10282; Sat, 12 Oct 1991 22:23 MST Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA26112; Sat, 12 Oct 91 22:10: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: Sat, 12 Oct 1991 22:23 MST Date: 13 Oct 91 03:53:54 GMT From: cis.ohio-state.edu!zaphod.mps.ohio-state.edu!mips!atha!aunro!ersys!arktik@ucbvax.berkeley.edu (Ryan Daum) Subject: Icon sources. Sender: icon-group-request@arizona.edu Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: <6AD47F174EC0D8B8@Arizona.edu> Message-Id: X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.edu Organization: Edmonton Remote Systems, Edmonton, AB, Canada Where are Icon sources available? What about tutorials, libraries, etc? -------------------------------------------------------------------------- arktik@ersys.edmonton.ab.ca -- Ryan Werner Daum -- "A man leaves his ---------------------------------------------------- impress on life and Opiate on LambdaMOO ... Epicurus on DikuMUD -- outside of that Citadels, TinyMUCKS -- there is nothing." ---------------------------------------------------- Jean-Paul Satre From icon-group-request@arizona.edu Mon Oct 14 11:45:22 1991 Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Mon, 14 Oct 91 11:45:22 MST Resent-From: icon-group-request@arizona.edu Received: from Arizona.edu (Merlin.Telcom.Arizona.EDU) by optima.cs.arizona.edu (4.1/15) id AA08438; Mon, 14 Oct 91 11:45:20 MST Received: from ucbvax.Berkeley.EDU by Arizona.edu with PMDF#10282; Mon, 14 Oct 1991 11:44 MST Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA16171; Mon, 14 Oct 91 11:41:02 -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: Mon, 14 Oct 1991 11:45 MST Date: 14 Oct 91 15:37:12 GMT From: midway!quads!goer@handies.ucar.edu (Richard L. Goerwitz) Subject: RE: windowing; an exercize Sender: icon-group-request@arizona.edu Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: Message-Id: <1991Oct14.153712.15751@midway.uchicago.edu> X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.edu Organization: University of Chicago References: <1991Oct12.182846.10147@midway.uchicago.edu>, <1991Oct14.001550.21718@mlfarm.com> In <1991Oct14.001550.21718@mlfarm.com> ron@mlfarm.com (Ronald Florence) writes: >Richard L. Goerwitz writes: > > # Note: This is not a curses clone, and it is very slow. I was just > # trying to decide how a windowing interface might possibly be done > # in Icon (which has no pointers, and hence forces me to use things > # like records and global variables where I'd like to use explicit > # pointers to smaller data types). It's an exercize, and I'd really > # appreciate any advice on how to speed it up. > >My hunch is that the speed cannot be increased appreciably by refinements >of the code; the slowness is a necessary consequence of character-based >output and an interpreted language. > >I wonder whether there isn't a way to accomplish this kind of >windowing through external bitblit functions called from Icon. >Linking the Icon to X-windows functions for Unix systems, or a >comparable interface (I confess ignorance) for ms-dos, might provide a >quick and versatile screen display, while allowing the coder to write >with the economy of Icon. Is this possible? Is anyone working on >this sort of approach? Oh, yes. I'm not the one doing it, but the work is happening. A company called Iconic Software Inc. is working on (actually, almost done) a SYSV r{3,4}/{3,4}86-based system which provides Icon programmers high-level ac- cess functions to curses and ETI functions. There have also been several individuals who have expressed interest in setting up an X interface, and I understand that substantial work has been done in this area already (not ready for release, though). Of course, ProIcon has a set of windowing tools built into it (ProIcon is a commercial Mac implementation of Icon). About the speed of the package: I note that the character-based I/O is not the worst bottleneck. Actually, the sample file I posted does a lot of internal optimization (e.g. when a window is [re]drawn, only those squares that need to be updated are actually placed on the screen). The odd thing is that it's the internal machinations that take the time, and not so much the actual interaction with the terminal. I gather you under- stood this, Ron. So I'd just modify your statement that the problem is one of character-based I/O in an interpreted system to say merely that the problem is simply one inherent in interpreted systems. LISP programmers have the same problems when writing systems like emacs (the code for which has to be done largely in C). I tried compiling the program, incidentally, using the experimental com- piler available on cs.arizona.edu. I was unable to get it compiled with the optimizations (I waited 10 minutes, and when no C code got generated, I gave up). With all the optimizations turned off, iolib (from the IPL) did not work correctly. What I wanted to do was see how much of a per- formance difference I could get with the compiler. I'd guess it would be significant. Would it be significant enough to make the performance ac- ceptable? I don't know. One other big problem is the space that gets used. As I noted in the paragraph you quoted above, I had to coopt much larger data types than I wanted to, and access them in clumsy ways. This is not to say that Icon should have explicit pointer semantics - which would create all kinds of com- plications. My guess is that most of what is needed could be accomplished by using a call-by-reference mechanism - say some sort of mechanism like the "var" parameters of Pascal. If a language is going to be able to be used as a production system, I'd say it needs some way of presenting a user interface, and that the interface should be well integrated into the rest of the language. The demo I posted was just a primitive attempt on my part to see what opinions other people had about things like interfaces, interface types, interpreted languages, pointer semantics, and what not. One thing I want to avoid doing is making this into a kind of "what's wrong with Icon" discussion, because Icon (as it is) is a very clean and useful language. And it's PD. And the distribution is relatively bug-free. I'd just be curious what people think about what a reasonable Iconish interface would look like. In my case, an X interface is totally uninteresting, be- cause it's single-platform, and X itself is *huge*. Just huge. Unless a fairy from heaven comes down and doubles my mass storage resources, I can't reasonably talk about anything other than character-based I/O. -- -Richard L. Goerwitz goer%sophist@uchicago.bitnet goer@sophist.uchicago.edu rutgers!oddjob!gide!sophist!goer From cjeffery Mon Oct 14 13:05:30 1991 Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Mon, 14 Oct 91 13:05:30 MST Resent-From: "Clinton Jeffery" Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by optima.cs.arizona.edu (4.1/15) id AA16549; Mon, 14 Oct 91 13:05:28 MST Received: from optima.cs.arizona.edu by Arizona.edu with PMDF#10282; Mon, 14 Oct 1991 13:04 MST Received: from cheltenham.cs.arizona.edu by optima.cs.arizona.edu (4.1/15) id AA16426; Mon, 14 Oct 91 13:04:30 MST Received: by cheltenham.cs.arizona.edu; Mon, 14 Oct 91 13:04:28 MST Resent-Date: Mon, 14 Oct 1991 13:05 MST Date: Mon, 14 Oct 91 13:04:28 MST From: "Clinton L. Jeffery" Subject: windowing; an exercize In-Reply-To: Richard L. Goerwitz's message of 14 Oct 91 15:37:12 GMT <1991Oct14.153712.15751@midway.uchicago.edu> Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: Message-Id: <9110142004.AA20060@cheltenham.cs.arizona.edu> X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.edu ****>>Ronald Florence by Richard Goerwitz as saying: >>Linking the Icon to X-windows functions for Unix systems, or a >>comparable interface (I confess ignorance) for ms-dos, might provide a >>quick and versatile screen display, while allowing the coder to write >>with the economy of Icon. Is this possible? Is anyone working on >>this sort of approach? ****>To which Richard replied to all of us: >There have also been several >individuals who have expressed interest in setting up an X interface, and >I understand that substantial work has been done in this area already (not >ready for release, though). Of course, ProIcon has a set of windowing >tools built into it (ProIcon is a commercial Mac implementation of Icon). An X interface for Icon has been described in the '91 ICEBOL Proceedings and in UA Department of CS Technical Report #91-1. Unlike the other "windowing" tools mentioned in the current discussion, X-Icon allows easy access to graphics, colors, fonts, and mouse input. Icon adds quite a bit of leverage in writing X applications and thanks to the Icon interpreter, X-Icon binaries are incredibly tiny compared to C-based X applications. >In my case, an X interface is totally uninteresting, be- >cause it's single-platform, and X itself is *huge*. Richard is right that X is huge; one generally needs a UNIX system with a spare 20 megabytes as a bare minimum, and this will exclude some people for another few years as disk prices continue to drop. But in discussing language designs to support user-interface programming I don't see why a character-based interface can't be a compatible subset of a graphical interface--allowing character-based applications to run in either context. For this reason I hope people writing user interface libraries will be interested in each other's designs and I think discussion would be fruitful. From icon-group-request@arizona.edu Tue Oct 15 01:49:52 1991 Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Tue, 15 Oct 91 01:49:52 MST Resent-From: icon-group-request@arizona.edu Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by optima.cs.arizona.edu (4.1/15) id AA02327; Tue, 15 Oct 91 01:49:47 MST Received: from ucbvax.Berkeley.EDU by Arizona.edu with PMDF#10282; Tue, 15 Oct 1991 01:49 MST Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA11967; Tue, 15 Oct 91 01:43:14 -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: Tue, 15 Oct 1991 01:49 MST Date: 15 Oct 91 07:36:36 GMT From: midway!quads!goer@handies.ucar.edu (Richard L. Goerwitz) Subject: iwinds, part 4 of 4 Sender: icon-group-request@arizona.edu Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: <19E109C648A11996@Arizona.edu> Message-Id: <1991Oct15.073636.24919@midway.uchicago.edu> X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.edu Organization: University of Chicago References: <1991Oct15.073456.24722@midway.uchicago.edu> ---- Cut Here and feed the following to sh ---- #!/bin/sh # this is iwinds.04 (part 4 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" != 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 getchlib.icn' else echo 'x - continuing file getchlib.icn' sed 's/^X//' << 'SHAR_EOF' >> 'getchlib.icn' && 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. Note that it will X# not work on all systems. In particular, certain Suns (with a X# screwy stty command) and the NeXT 1.0 OS (lacking the -g option for X# stty) do not run getchlib properly. See the bugs section below for X# workarounds. 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. If you are on a BSD X# system where the network configuration makes stty | more impossible, X# then substitute /usr/5bin/stty (or whatever your system calls the X# System V stty command) for /bin/stty in this file. If you have no X# SysV stty command online, then you can try replacing every instance X# of "stty -g 2>&1" below with "stty -g 2>&1 1> /dev/tty" or X# something similar. 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 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 # ============= complete.icn ============== if test -f 'complete.icn' -a X"$1" != X"-c"; then echo 'x - skipping complete.icn (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp echo 'x - extracting complete.icn (Text)' sed 's/^X//' << 'SHAR_EOF' > 'complete.icn' && X############################################################################ X# X# Name: complete.icn X# X# Title: complete partial input string X# X# Author: Richard L. Goerwitz X# X# Version: 1.7 X# X############################################################################ X# X# This file contains a single procedure, complete(s,st), which X# completes a string (s) relative to a set or list of strings (st). X# Put differently, complete() lets you supply a partial string, s, X# and get back those strings in st that s is either equal to or a X# substring of. X# X# Lots of command interfaces allow completion of partial input. X# Complete() simply represents my personal sentiments about how this X# might best be done in Icon. If you strip away the profuse comments X# below, you end up with only about thirty lines of actual source X# code. X# X# I have arranged things so that only that portion of an automaton X# which is needed to complete a given string is actually created and X# stored. Storing automata for later use naturally makes complete() X# eat up more memory. The performance gains can make it worth the X# trouble, though. If, for some reason, there comes a time when it X# is advisable to reclaim the space occupied by complete's static X# structures, you can just call it without arguments. This X# "resets" complete() and forces an immediate garbage collection. X# X# Example code: X# X# commands := ["run","stop","quit","save","load","continue"] X# while line := read(&input) do { X# cmds := list() X# every put(cmds, complete(line, commands)) X# case *cmds of { X# 0 : input_error(line) X# 1 : do_command(cmds[1]) X# default : display_possible_completions(cmds) X# } X# etc... X# X# More Iconish methods might include displaying successive X# alternatives each time the user presses the tab key (this would, X# however, require using the nonportable getch() routine). Another X# method might be to use the first string suspended by complete(). X# X# NOTE: This entire shebang could be replaced with a slightly slower X# and much smaller program suggested to me by Jerry Nowlin and Bob X# Alexander. X# X# procedure terscompl(s, st) X# suspend match(s, p := !st) & p X# end X# X# This program will work fine for lists with just a few members, and X# also for cases where s is fairly large. It will also use much less X# memory. X# X############################################################################ X# X# Links: none X# X############################################################################ X X X Xprocedure complete(s,st) X X local dfstn, c, l, old_chr, chr, newtbl, str, strset X static t X initial t := table() X X # No-arg invocation wipes out static structures & causes an X # immediate garbage collection. X if /s & /st then { X t := table() X collect() # do it NOW X fail X } X type(st) == ("list"|"set") | X stop("error (complete): list or set expected for arg2") X X # Seriously, all that's being done here is that possible states X # are being represented by sets containing possible completions of X # s relative to st. Each time a character is snarfed from s, we X # check to see what strings in st might represent possible X # completions, and store these in yet another set. At some X # point, we either run into a character in s that makes comple- X # tion impossible (fail), or we run out of characters in s (in X # which case we succeed, & suspend each of the possible X # completions). X X # Store any sets we have to create in a static structure for later X # re-use. X /t[st] := table() X X # We'll call the table entry for the current set dfstn. (It really X # does enable us to do things deterministically.) X dfstn := t[st] X X # Snarf one character at a time from s. X every c := !s do { X X # The state we're in is represented by the set of all possible X # completions before c was read. If we haven't yet seen char X # c in this state, run through the current-possible-completion X # set, popping off the first character of each possible X # completion, and then construct a table which uses these X # initial chars as keys, and makes the completions that are X # possible for each of these characters into the values for X # those keys. X if /dfstn[st] then { X X # To get strings that start with the same char together, X # sort the current string set (st). X l := sort(st) X newtbl := table() X old_chr := "" X # Now pop off each member of the sorted string set. Use X # first characters as keys, and then divvy up the full strings X # into sets of strings having the same initial letter. X every str := !l do { X str ? { chr := move(1) | next; str := tab(0) } X if old_chr ~==:= chr then { X strset := set([str]) X insert(newtbl, chr, strset) X } X else insert(strset, str) X } X insert(dfstn, st, newtbl) X } X X # What we've done essentially is to create a table in which X # the keys represent labeled arcs out of the current state, X # and the values represent possible completion sets for those X # paths. What we need to do now is store that table in dfstn X # as the value of the current state-set (i.e. the current X # range of possible completions). Once stored, we can then X # see if there is any arc from the current state (dfstn[st]) X # with the label c (dfstn[st][c]). If so, its value becomes X # the new current state (st), and we cycle around again for X # yet another c. X st := \dfstn[st][c] | fail X if *st = 1 & match(s,!st) X then break X } X X # Eventually we run out of characters in c. The current state X # (i.e. the set of possible completions) can simply be suspended X # one element at a time, with s prefixed to each element. If, for X # instance, st had contained ["hello","help","hear"] at the outset X # and s was equal to "hel", we would now be suspending "hel" || X # !set(["lo","p"]). X suspend s || !st X Xend SHAR_EOF true || echo 'restore of complete.icn 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# X# Makefile for iwinds demos X# X XSHELL = /bin/sh XMAKE = /usr/local/bin/gnumake X X# You may need to change this. XICONC = /usr/icon/v8/bin/icont -u X XSRC = iwinds.icn iolib.icn iscreen.icn getchlib.icn X Xall: demo1 demo2 X Xdemo1: main.icn $(SRC) X $(ICONC) -o demo1 main.icn $(SRC) X Xdemo2: main2.icn $(SRC) X $(ICONC) -o demo2 main2.icn $(SRC) complete.icn X Xclean: X -rm -f demo1 demo2 *~ SHAR_EOF true || echo 'restore of Makefile.dist 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 archive contains a simple windowing package, along with two Xdemos. The first demo (demo1) just draws and manipulates some simple Xwindows. The second demo (demo2) draws a little box in the center of Xthe screen that can be moved around the screen using arrow or vi keys. XIf you want to look at the source code for the demos, look at the Xfiles main.icn and main2.icn. The windowing library is in iwinds.icn. XGeneral termcap interface routines are in iscreen.icn, iolib.icn, and Xgetchlib.icn. X XIf you want to take a look at the demos, just "make -f Makefile.dist". XThen type "./demo1; ./demo2". Make "clean" when you're done. X XSee the docs prepended to iwinds.icn for a description of the whats Xand whys. This very preliminary hack will doubtless contain bugs. XSend reports of them, or any general comments you feel like voicing, Xto me, Richard Goerwitz, at goer@sophist.uchicago.edu. X X-Richard SHAR_EOF true || echo 'restore of README failed' rm -f _shar_wnt_.tmp fi rm -f _shar_seq_.tmp echo You have unpacked the last part exit 0 -- -Richard L. Goerwitz goer%sophist@uchicago.bitnet goer@sophist.uchicago.edu rutgers!oddjob!gide!sophist!goer From icon-group-request@arizona.edu Tue Oct 15 01:50:24 1991 Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Tue, 15 Oct 91 01:50:24 MST Resent-From: icon-group-request@arizona.edu Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by optima.cs.arizona.edu (4.1/15) id AA02392; Tue, 15 Oct 91 01:50:13 MST Received: from ucbvax.Berkeley.EDU by Arizona.edu with PMDF#10282; Tue, 15 Oct 1991 01:49 MST Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA11918; Tue, 15 Oct 91 01:42:10 -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: Tue, 15 Oct 1991 01:49 MST Date: 15 Oct 91 07:35:22 GMT From: midway!quads!goer@handies.ucar.edu (Richard L. Goerwitz) Subject: iwinds, part 2 of 4 Sender: icon-group-request@arizona.edu Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: <19F0A70B38C1071F@Arizona.edu> Message-Id: <1991Oct15.073522.24789@midway.uchicago.edu> X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.edu Organization: University of Chicago ---- Cut Here and feed the following to sh ---- #!/bin/sh # this is iwinds.02 (part 2 of a multipart archive) # do not concatenate these parts, unpack them in order with /bin/sh # file iwinds.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 iwinds.icn' else echo 'x - continuing file iwinds.icn' sed 's/^X//' << 'SHAR_EOF' >> 'iwinds.icn' && X 1 : emphasize() X 2 : underline() X 3 : boldface() X 4 : blink() X default : { X # write(&errout, "mode for ", y, ",", x, " = ", mode) X normal() X } X } X } X X # Turn lower 16 bits of sq.val into a character. 8 bits is X # the usual now, but soon it'll be 16 bits for characters (I X # hope). X return writes(char(iand(sq.val, 65535))) X Xend X X Xprocedure hidew(w) X X # X # Hides window w. X # X local y, x, stdscr_y, stdscr_x, window_square X X w === _mainw & fail # can't hide main window X # window is already hidden if over and under pointers are null X /w.wlist[1][1].over & /w.wlist[1][1].under & fail X X every y := 1 to w.lines do { X every x := 1 to w.cols do { X X # Create a handle for manipulating the current square in w. X window_square := w.wlist[y][x] X X # If the over pointer is nonnull, then we're not on top X # of the stack for position y,x. X if \window_square.over then { X # So link the record underneath (if there is one) to X # the one on top; link the one on top to the one X # underneath (to &null if there isn't one underneath). X (\window_square.under).over := window_square.over X window_square.over.under := window_square.under X } X X # Over pointer is null, but under pointer is not, so the X # square is on-screen at _stdscr.wlist[stdscr_y][stdscr_x]. X # Remove it; make _stdscr.wlist[stdscr_y][stdscr_x] point X # to window_square.under. Set window_square.under.over to X # &null to indicate that it is now on the top of the stack. X else { X window_square.under.over := &null X stdscr_y := y + w.begy - 1 X stdscr_x := x + w.begx - 1 X _stdscr.wlist[stdscr_y][stdscr_x] := window_square.under X if window_square.val ~= window_square.under.val | X window_square.val < 0 X then draw_it(window_square.under, stdscr_y, stdscr_x) X else window_square.val := abs(window_square.val) X } X window_square.over := &null X window_square.under := &null X X # Paranoid check. The topmost member of the stack should X # always have &null as its "over" pointer. X # /(((_stdscr.wlist)[stdscr_y][stdscr_x]).over) | { X # write(&errout,"window:\n", X # (\ximage)(_stdscr.wlist[stdscr_y][stdscr_x].over)) X # exit_prog("hidew", "bizarre stack malformation", 21) X # } X } X } X X return X Xend X X Xprocedure createw(begy, begx, lines, cols, wmode, wchar, border, bmode) X X # X # Creates a new window with the upper left corner at begy,begx, and X # a size of lines,cols, a default mode of wmode, and a default fill X # char of wchar; a border is drawn if border is nonnull. X # X local default_cell, wlist, wlist2, r, c, w, ypos, xpos X X if /(begy | begx | lines | cols) then X exit_prog("createw", "first four arguments must all be nonnull", 31) X X /wmode := 0 # default mode is 0 (normal) X /wchar := " " # default char is a space X # default_cell := -(ishift(wmode,16) + ord(wchar)) X default_cell := -((wmode * 65536) + ord(wchar)) X /border := &null X X # X # Create a lines X cols array of _square() records. X # X every !(wlist := list(lines)) := list(cols) X every !(wlist2 := list(lines)) := list(cols) X # X every r := 1 to lines do X every c := 1 to cols do X wlist[r][c] := _square(default_cell, &null, &null) X X if \border then ypos := xpos := 2 else ypos := xpos := 1 X w := _window(wlist, begy,begx, lines, cols, ypos, xpos, border) X make_border(w, \border, \bmode | wmode) X refreshw(w) X X return w X Xend X X Xprocedure redraw() X X # X # Simple redraw of the entire screen. X # X local r, c X #global LINES, COLS X X # clear() X every r := _stdscr.begy to LINES do { X every c := _stdscr.begx to COLS do { X draw_it(_stdscr.wlist[r][c], r, c) X } X } X X return "screen redrawn" X Xend X X Xprocedure movew(w, begy, begx) X X # X # Moves window w from wherever it is on the screen to begy,begx. X # This routine is slow. Much too slow. There are, I'm sure, a X # lot faster ways (even within Icon), but I didn't happen to think X # of any as I wrote this. X # X X local wlist, wlist2, y, x, w2, window_square X X w === _mainw & fail # can't move main window X X /begy | /begx & X exit_prog("movew","null argument 2 and/or 3!",61) X wlist := w.wlist X wlist2 := list(w.lines) X every (!wlist2) := list(w.cols) X X every y := 1 to w.lines do { X every x := 1 to w.cols do { X window_square := (wlist2[y][x] := copy(wlist[y][x])) X window_square.val := -abs(window_square.val) X window_square.over := &null X window_square.under := &null X } X } X w2 := copy(w) X w2.wlist := wlist2 X w2.begy := begy X w2.begx := begx X refreshw(w2) X X hidew(w) X w.wlist := wlist2 X w.begy := begy X w.begx := begx X X return X Xend X X Xprocedure make_border(w, border, mode) X X local ulc, uc, urc, rc, brc, bc, blc, lc, y, x X X # mode := ishift(\mode, 16) | 0 X mode := (\mode * 65536) | 0 X X if type(border) === ("list"|"string") then { X *border = 8 | exit_prog("make_border", "*border must be 8", 41) X ulc := -(mode + ord(border[1])) X uc := -(mode + ord(border[2])) X urc := -(mode + ord(border[3])) X rc := -(mode + ord(border[4])) X brc := -(mode + ord(border[5])) X bc := -(mode + ord(border[6])) X blc := -(mode + ord(border[7])) X lc := -(mode + ord(border[8])) X } X else { X ulc := -(mode + ord("+")) X uc := -(mode + ord("-")) X urc := -(mode + ord("+")) X rc := -(mode + ord("|")) X brc := -(mode + ord("+")) X bc := -(mode + ord("-")) X blc := -(mode + ord("+")) X lc := -(mode + ord("|")) X } X w.border := [ulc, uc, urc, rc, brc, bc, blc, lc] X X # Now draw in all the appropriate charcters. Be sure to check X # whether the window is big enough! X w.wlist[1][1].val := ulc X every x := 2 to w.cols-1 do { X w.wlist[1][x].val := uc X w.wlist[w.lines][x].val := bc X } X w.wlist[1][w.cols].val := urc X w.wlist[w.lines][w.cols].val := brc X every y := 2 to w.lines-1 do { X w.wlist[y][w.cols].val := rc X w.wlist[y][1].val := lc X } X w.wlist[w.lines][1].val := blc X X return w.border X Xend X X Xprocedure writew(w, s, y, x, mode) X X local begy, begx, maxy, maxx, ypos, xpos, c, stdscr_square, newval X static controls, spaces X initial { X controls := "" X every controls ||:= char((0 to 7) | 9 | 11 | 12 | (14 to 31)) X spaces := repl(" ", *controls) X # write(&errout, image(controls)) X } X X begy := 1 X begx := 1 X maxy := w.lines X maxx := w.cols X ypos := \y | w.ypos X xpos := \x | w.xpos X # see below on mode X X if \w.border then { X # just in case it's forgotten that there's a border, and an X # attempt is made to write to spaces occupied by the border X ypos <= begy & ypos := 2 X ypos >= maxy & ypos := 2 & xpos := 2 X xpos <= begx | xpos >= maxx & xpos := 2 X # reset boundaries to account for the smaller available space X begy +:= 1 X begx +:= 1 X maxy -:= 1 X maxx -:= 1 X } X X begy <= ypos <= maxy | begx <= xpos <= maxx | X exit_prog("writew", "coordinate out of range: "||ypos||","||xpos, 51) X # Reposition the cursor. X iputs(igoto(getval("cm"), xpos + w.begx - 1, ypos + w.begy - 1)) X X s := map(s, controls, spaces) X # write(&errout, image(s)) X # mode := ishift(\mode, 16) X mode := (\mode * 65536) X every c := !s do { X X # write(&errout, image(c)) X if any('\n\r', c) then { X ypos +:= 1 X xpos := begx - 1 X } else { X if c == "\b" then { X (begx <= (xpos <- (xpos - 1))) | next X writew(w, " ", ypos, xpos, mode, "immediate") X iputs(igoto(getval("cm"), xpos + w.begx - 1, ypos + w.begy- 1)) X next X } X # write(&errout, X # "old char cell ",radcon(w.wlist[ypos][xpos].val,10,2)) X stdscr_square := w.wlist[ypos][xpos] X newval := X (\mode | iand(abs(w.wlist[ypos][xpos].val),2147418112))+ ord(c) X if stdscr_square.val < 0 | stdscr_square.val ~= newval then { X stdscr_square.val := -newval X if /stdscr_square.over then X draw_it(stdscr_square, ypos+w.begy - 1, xpos+w.begx - 1) X } X else stdscr_square.val := newval X # write(&errout, "mode = ", radcon(\mode,10,2)) X # write(&errout, X # "char cell = ", radcon(w.wlist[ypos][xpos].val, 10, 2)) X } X ypos > maxy & ypos := begy & xpos := begx X xpos < maxx & xpos +:= 1 X } X X w.ypos := ypos X w.xpos := xpos X X return X Xend X X Xprocedure readw(w, y, x, mode) X X # X # Reads a string from window w, at pos y,x within that window, X # echoing the string to the screen. Characters get echoed as X # they are typed. Terminates on a CR or LF & returns the string X # just read (minus the CR/LF). X # X local chr, s X X # Move the cursor to the spot we're to start reading at. X writew(w, "", y, x, mode) X # Check to be sure this square is visible on the screen. X /_stdscr.wlist[y + w.begy - 1][x + w.begx - 1].over | { X write(&errout, "error (readw): square isn't visible") X fail 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 writew(w,"\b",,,mode) X# s := "" X# } X "\b" : { X if *s < 1 then next X writew(w,"\b",,,mode) X s := s[1:-1] X } X default : { X writew(w,chr,,,mode) X s ||:= chr X } X } X } X X Xend X X Xprocedure getchw(w, y, x, mode) X X # X # Reads a character from window w, at pos y,x within that window, X # echoing the character to the screen. X # X local chr, s X X # Move the cursor to the spot we're to start reading at. X writew(w, "", y, x, mode) X X # Check to be sure this square is visible on the screen. X /_stdscr.wlist[y + w.begy - 1][x + w.begx - 1].over | { X write(&errout, "error (getchw): square isn't visible") X fail X } X chr := getch() | fail X writew(w,chr,,,mode) X return chr X Xend X X Xprocedure exit_prog(func, msg, errcode) X X # X # Program termination utility. Prints error message "msg" for X # function "func," resets the terminal, then aborts with exit code X # "errcode." For normal exits, call exit_prog() without any args. X # X # global LINES X X func := " (" || (trim(\func, ': ') || "): ") | ": " X write(&errout, "error", func, \msg) X window("off") X normal(); clear() X iputs(igoto(getval("cm"), 1, LINES-1)) X exit(errcode) # abort program with exit code errcode X Xend SHAR_EOF echo 'File iwinds.icn is complete' && true || echo 'restore of iwinds.icn failed' rm -f _shar_wnt_.tmp fi # ============= iolib.icn ============== if test -f 'iolib.icn' -a X"$1" != X"-c"; then echo 'x - skipping iolib.icn (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp echo 'x - extracting iolib.icn (Text)' sed 's/^X//' << 'SHAR_EOF' > 'iolib.icn' && X######################################################################## X# X# Name: iolib.icn X# X# Title: Icon termlib-type tools for MS-DOS and UNIX X# X# Author: Richard L. Goerwitz (with help from Norman Azadian) X# X# Version: 1.13 X# X######################################################################### X# X# The authors place this and future versions of iolib in the public X# domain. X# X######################################################################### X# X# The following library represents a series of rough functional X# equivalents to the standard Unix low-level termcap routines. It is X# not meant as an exact termlib clone. Nor is it enhanced to take X# care of magic cookie terminals, terminals that use \D in their X# termcap entries, or archaic terminals that require padding. This X# library is geared mainly for use with ANSI and VT-100 devices. X# Note that this file may, in most instances, be used in place of the X# older UNIX-only itlib.icn file. It essentially replaces the DOS- X# only itlibdos routines. For DOS users not familiar with the whole X# notion of generalized screen I/O, I've included extra documentation X# below. Please read it. X# X# The sole disadvantage of this over the old itlib routines is that X# iolib.icn cannot deal with archaic or arcane UNIX terminals and/or X# odd system file arrangements. Note that because these routines X# ignore padding, they can (unlike itlib.icn) be run on the NeXT and X# other systems which fail to implement the -g option of the stty X# command. Iolib.icn is also simpler and faster than itlib.icn. X# X# I want to thank Norman Azadian for suggesting the whole idea of X# combining itlib.icn and itlibdos.icn into one distribution, for X# suggesting things like letting drive specifications appear in DOS X# TERMCAP environment variables, and for finding several bugs (e.g. X# the lack of support for %2 and %3 in cm). Although he is loathe X# to accept this credit, I think he deserves it. X# X######################################################################### X# X# Contents: 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 completely irrelevant for most X# modern terminals, and is supplied here merely for the sake of X# backward compatibility with itlib, a UNIX-only version of these X# routines (one which handles padding on archaic terminals). X# X########################################################################## X# X# Notes for MS-DOS users: X# 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# 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, you could use "ansi-color" instead of X# "ansi-mono," although for compatibility with a broader range of X# users, it would perhaps be better to stick with mono. The purpose X# of setting TERMCAP is to make it possible to determine where the X# termcap database file is located. The termcap file (which should X# have been packed with this library as termcap.dos) is a short X# database of all the escape sequences used by the various terminal X# drivers. Set TERMCAP so that it reflects the location of this file X# (which should be renamed as termcap, for the sake of consistency X# across UNIX and MS-DOS spectra). If desired, you can also try X# using termcap2.dos. Certain games work a lot better using this X# alternate file. To try it out, rename it to termcap, and set X# the environment variable TERMCAP to its location. X# X# Although the authors make no pretense of providing here a X# complete introduction to the format of the termcap database file, X# it will be useful, we believe, to explain a few basic facts about X# how to use this program in conjunction with it. If, say, you want X# to clear the 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# 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 can also write "writes(getval("so") || str || getval("se")), X# but this would make reimplementation for UNIX terminals that X# require padding rather difficult. X# 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# Most 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: UNIX or MS-DOS, co-expressions X# SHAR_EOF true || echo 'restore of iolib.icn failed' fi echo 'End of part 2' echo 'File iolib.icn is continued in part 3' echo 3 > _shar_seq_.tmp exit 0 -- -Richard L. Goerwitz goer%sophist@uchicago.bitnet goer@sophist.uchicago.edu rutgers!oddjob!gide!sophist!goer From icon-group-request@arizona.edu Tue Oct 15 01:50:36 1991 Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Tue, 15 Oct 91 01:50:36 MST Resent-From: icon-group-request@arizona.edu Received: from Arizona.edu (Merlin.Telcom.Arizona.EDU) by optima.cs.arizona.edu (4.1/15) id AA02416; Tue, 15 Oct 91 01:50:24 MST Received: from ucbvax.Berkeley.EDU by Arizona.edu with PMDF#10282; Tue, 15 Oct 1991 01:49 MST Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA11949; Tue, 15 Oct 91 01:42:46 -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: Tue, 15 Oct 1991 01:50 MST Date: 15 Oct 91 07:35:57 GMT From: midway!quads!goer@handies.ucar.edu (Richard L. Goerwitz) Subject: iwinds, part 3 of 4 Sender: icon-group-request@arizona.edu Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: <19F705ACA0223435@Arizona.edu> Message-Id: <1991Oct15.073557.24849@midway.uchicago.edu> X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.edu Organization: University of Chicago References: <1991Oct15.073456.24722@midway.uchicago.edu> ---- Cut Here and feed the following to sh ---- #!/bin/sh # this is iwinds.03 (part 3 of a multipart archive) # do not concatenate these parts, unpack them in order with /bin/sh # file iolib.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 iolib.icn' else echo 'x - continuing file iolib.icn' sed 's/^X//' << 'SHAR_EOF' >> 'iolib.icn' && X# See also: itlib.icn, iscreen.icn X# X########################################################################## X X Xglobal tc_table, isDOS Xrecord true() X X Xprocedure check_features() X X initial { X X if find("UNIX",&features) then X isDOS := &null X else if find("MS-DOS", &features) then X isDOS := 1 X else stop("check_features: OS not (yet?) supported.") X X find("expressi",&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 := 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 DOS or X # UNIX, and, if so, tries to figure out what the current terminal X # type is, checking successively the value of the environment X # variable TERM, and then (under UNIX) the output of "tset -". X # Terminates with an error message if the terminal type cannot be X # ascertained. DOS defaults to "mono." X X local term, tset_output X X check_features() X X if \isDOS then { X term := getenv("TERM") | "mono" X } X else { 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 } 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 the termcap file 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 isFILE, f, getline, line, nm, ent1, ent2, entry X static slash, termcap_names X initial { X if \isDOS then { X slash := "\\" X termcap_names := ["termcap","termcap.dos","termcap2.dos"] X } X else { X slash := "/" X termcap_names := ["/etc/termcap"] X } X } X 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 \isDOS then { X if \termcap_string then { X if termcap_string ? ( X not ((tab(any(&letters)), match(":")) | match(slash)), X pos(1) | tab(find("|")+1), =name) X then { X # if entry ends in tc= then add in the named tc entry X termcap_string ?:= tab(find("tc=")) || X # Recursively fetch the new termcap entry w/ name trimmed. X # Note that on the next time through name won't match the X # termcap environment variable, so getentry() will look for X # a termcap file. X (move(3), getentry(tab(find(":"))) ? X (tab(find(":")+1), tab(0))) X return termcap_string X } X else isFILE := 1 X } X } X else { X if \termcap_string then { X if termcap_string ? ( X not match(slash), pos(1) | tab(find("|")+1), =name) X then { X # if entry ends in tc= then add in the named tc entry X termcap_string ?:= tab(find("tc=")) || X # Recursively fetch the new termcap entry w/ name trimmed. X (move(3), getentry(tab(find(":")), "/etc/termcap") ? X (tab(find(":")+1), tab(0))) X return termcap_string X } X else isFILE := 1 X } X } 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 \isFILE # if find(slash, \termcap_string) X then f := open(\termcap_string) X /f := open(!termcap_names) | X er("getentry","I can't access your termcap file. Read iolib.icn.",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 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, str, decoded_value 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), ="=") then { X # Get rid of null padding information. Iolib can't X # handle it (unlike itlib.icn). Leave star in. It X # indicates a real dinosaur terminal, and will later X # prompt an abort. X str := ="*" | ""; tab(many(&digits)) X decoded_value := Decode(str || tab(find(":"))) X } X else if k := 1(move(2), ="#") X then decoded_value := integer(tab(find(":"))) X else if k := 1(tab(find(":")), pos(-1)) X then decoded_value := true() X else er("maketc_table", "your termcap file has a bad entry",3) X /tc_table[k] := decoded_value X &null 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 local new_s, chr, chr2 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, padding, 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 if padding := integer(tab(any('23'))) X then chr := (="d" | "d") X else 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, \padding, "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 itlib (a UNIX-only version which can handle X # albeit inelegantly) terminals that need padding. 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: iolib can't use terminals that require padding.") X writes(tab(0)) X } X X return X Xend SHAR_EOF echo 'File iolib.icn is complete' && true || echo 'restore of iolib.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.27 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 (usu. = reverse) mode X# boldface() - initiates bold mode X# blink() - initiates blinking mode X# normal() - resets to normal 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# clear_emphasize() - horrible way of clearing the screen to all- X# emphasize mode; necessary for many terminals 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 local i X X normal() X if not iputs(getval("cl")) X then iputs(igoto(getval("cm"),1,1) | getval("ho")) 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 boldface() X X static bold_str, cookie_str X initial { X if bold_str := getval("md") X then cookie_str := repl(getval("le"|"bc") | "\b", getval("mg")) X else { X # One global procedure value substituted for another. X boldface := emphasize X return emphasize() X } X } X X normal() X iputs(\bold_str) X iputs(\cookie_str) X return X Xend X X X Xprocedure blink() X X static blink_str, cookie_str X initial { X if blink_str := getval("mb") X then cookie_str := X repl(getval("le"|"bc") | "\b", getval("mg")) X else { X # One global procedure value substituted for another. X blink := emphasize X return emphasize() X } X } X X normal() X iputs(\blink_str) X iputs(\cookie_str) X return X Xend X X X Xprocedure emphasize() X X static emph_str, cookie_str X initial { X if emph_str := getval("so") X then cookie_str := repl(getval("le"|"bc") | "\b", getval("sg")) X else { X if emph_str := getval("mr") X then cookie_str := repl(getval("le"|"bc") | "\b", getval("mg")) X else if emph_str := getval("us") X then cookie_str := repl(getval("le"|"bc") | "\b", getval("ug")) X } X } X X normal() X iputs(\emph_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("le"|"bc") | "\b", getval("ug")) X } X X normal() X iputs(\underline_str) X iputs(\cookie_str) X return X Xend X X X Xprocedure normal(mode) X X static UN_emph_str, emph_cookie_str, X UN_underline_str, underline_cookie_str, X UN_bold_str, bold_cookie_str X X initial { X X # Find out code to turn off emphasize (reverse video) mode. X if UN_emph_str := getval("se") then X # Figure out how many backspaces we need to erase cookies. X emph_cookie_str := repl(getval("le"|"bc") | "\b", getval("sg")) X X # Finally, figure out how to turn off underline mode. X if UN_underline_str := (UN_emph_str ~== getval("ue")) then X underline_cookie_str := repl(getval("le"|"bc")|"\b", getval("ug")) X X # Figure out how to turn off boldface mode. X if UN_bold_str := X (UN_underline_str ~== (UN_emph_str ~== getval("me"))) then X # Figure out how many backspaces we need to erase cookies. X bold_cookie_str := repl(getval("le"|"bc") | "\b", getval("mg")) X X } X X iputs(\UN_emph_str) & X iputs(\emph_cookie_str) X X iputs(\UN_underline_str) & X iputs(\underline_cookie_str) X X iputs(\UN_bold_str) & X iputs(\bold_cookie_str) X 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 := ""; /s2 := ""; /p := "c" 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 X case p of { X "c" : s := center(s,width) X "l" : s := left(s,width) X "r" : s := right(s,width) 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) 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"))) X iputs(getval("ce")) X normal() X iputs(igoto(getval("cm"), 1, getval("li")-1)) X iputs(getval("ce")) X writes(s[1:getval("co")] | s) X return X Xend X X X Xprocedure clear_underline() X X # Horrible way of clearing the screen to all underline mode, but X # the only apparent way we can do it "portably" using the termcap X # capability database. X X local i X X underline() X iputs(igoto(getval("cm"),1,1)) X if getval("am") then { X underline() X every 1 to (getval("li")-1) * getval("co") do X writes(" ") X } X else { X every i := 1 to getval("li")-1 do { X iputs(igoto(getval("cm"), 1, i)) X underline() X writes(repl(" ",getval("co"))) X } X } X iputs(igoto(getval("cm"),1,1)) X Xend X X X Xprocedure clear_emphasize() X X # Horrible way of clearing the screen to all reverse-video, but X # the only apparent way we can do it "portably" using the termcap X # capability database. X X local i X X emphasize() X iputs(igoto(getval("cm"),1,1)) X if getval("am") then { X emphasize() X every 1 to (getval("li")-1) * getval("co") do X writes(" ") X } X else { X every i := 1 to getval("li")-1 do { X iputs(igoto(getval("cm"), 1, i)) X emphasize() X writes(repl(" ",getval("co"))) X } X } X iputs(igoto(getval("cm"),1,1)) X Xend SHAR_EOF true || echo 'restore of iscreen.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.14 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 SHAR_EOF true || echo 'restore of getchlib.icn failed' fi echo 'End of part 3' echo 'File getchlib.icn is continued in part 4' echo 4 > _shar_seq_.tmp exit 0 -- -Richard L. Goerwitz goer%sophist@uchicago.bitnet goer@sophist.uchicago.edu rutgers!oddjob!gide!sophist!goer From icon-group-request@arizona.edu Tue Oct 15 01:50:51 1991 Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Tue, 15 Oct 91 01:50:51 MST Resent-From: icon-group-request@arizona.edu Received: from Arizona.edu (Maggie.Telcom.Arizona.EDU) by optima.cs.arizona.edu (4.1/15) id AA02442; Tue, 15 Oct 91 01:50:39 MST Received: from ucbvax.Berkeley.EDU by Arizona.edu with PMDF#10282; Tue, 15 Oct 1991 01:49 MST Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA11903; Tue, 15 Oct 91 01:41:50 -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: Tue, 15 Oct 1991 01:50 MST Date: 15 Oct 91 07:34:56 GMT From: midway!quads!goer@handies.ucar.edu (Richard L. Goerwitz) Subject: iwinds, part 1 of 4 Sender: icon-group-request@arizona.edu Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: <19FE5725D8A13A98@Arizona.edu> Message-Id: <1991Oct15.073456.24722@midway.uchicago.edu> X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.edu Organization: University of Chicago I got some interesting comments on the windowing routines, fixed some bugs, and what not. I got several requests for some of the routines these windowing routines need to be linked with. Wrote another little demo (this one showing how the arrow keys can be used). All of this added up to my deciding just to post the entire shell archive. -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 10/15/1991 07:10 UTC by goer@sophist.uchicago.edu # Source directory /u/richard/Iwinds # # 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 # ------ ---------- ------------------------------------------ # 1451 -rw-r--r-- main.icn # 2255 -rw-r--r-- main2.icn # 23574 -r--r--r-- iwinds.icn # 18055 -r--r--r-- iolib.icn # 7069 -r--r--r-- iscreen.icn # 9166 -r--r--r-- getchlib.icn # 5988 -r--r--r-- complete.icn # 380 -rw-r--r-- Makefile.dist # 901 -rw-r--r-- README # 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 # ============= main.icn ============== if test -f 'main.icn' -a X"$1" != X"-c"; then echo 'x - skipping main.icn (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp echo 'x - extracting main.icn (Text)' sed 's/^X//' << 'SHAR_EOF' > 'main.icn' && X# for UNIX - make sure your IPL is fully updated! X# link iwinds, iolib, iscreen, getchlib X X# non-UNIX X# link iwinds, iolib, iscreen (make sure you have getch()) X Xprocedure main() X X # global LINES, COLS (defined in iwinds.icn) X local w, w2, w3, y, x X X # Initiate windowing mode. X window("on") X X # Display a 10x30 window in the upper left corner of the screen. X # Give it a border of spaces in reverse video mode. Fill the box X # with "x" characters in normal mode. X w := createw(1, 1, 10, 30, 0, "x", " ", 1) X X # Now for fun, move the window just created diagonally down, until X # it gets to the bottom of the screen. Be sure not to overrun the X # screen. X x := 1 X every y := 3 to LINES - 10 by 3 do X movew(w, y, x +:= 6) X X # Lay down a small window. X w2 := createw(8, 20, 3, 10, 1) X # Print the word "hello" in it. X writew(w2, "hello", 1, 1) X X # Lay down a window over top of the first one. X w3 := createw(14, 50, 9, 30, 0, ".", " ",1) X X # Move the small window down on top of the other two. X x := 20 X every y := 11 to LINES - 7 by 3 do X movew(w2, y, x +:= 7) X X # Change the message in the little window. X writew(w2, "done!! ", 1, 1, 3) X # Erase the two big windows. X hidew(w3) X hidew(w) X X # Move the little window back up to where it started. X every y := y to 3 by -3 do X movew(w2, y, x -:= 7) X X # Quit. X window("off") X exit_prog() X Xend SHAR_EOF true || echo 'restore of main.icn failed' rm -f _shar_wnt_.tmp fi # ============= main2.icn ============== if test -f 'main2.icn' -a X"$1" != X"-c"; then echo 'x - skipping main2.icn (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp echo 'x - extracting main2.icn (Text)' sed 's/^X//' << 'SHAR_EOF' > 'main2.icn' && Xglobal me X Xprocedure main() X X local command_table, command_set, s, response, tmp X initial { X window("on") X command_table := make_command_table() X command_set := set() X every insert(command_set, key(command_table)) X } X X me := createw(LINES / 2 - 1, COLS / 2 - 4, 3, 8, 0, " ", " ", 1) X X repeat { X s := ""; response := "" X writew(me, " ", 2, 2, 0) X writew(me, "", 2, 2, 0) X while s ||:= getch() do { X tmp := [] X every put(tmp, complete(s, command_set)) X if *tmp > 0 then { X if *tmp = 1 then { X command_table[!tmp]() X s := ""; next X } X else next X } else { X if *s > 1 then { X iputs(getval("vb"|"bl") | "\x07") X break next X } X else { X if any(&digits, s) then { X response ||:= s X writew(me, s,,,0) X s := "" X if *response > 6 then { X iputs(getval("vb"|"bl") | "\x07") X break next X } X next X } X else { X iputs(getval("vb"|"bl") | "\x07") X break next X } X } X } X } X } X X # End windowing mode. X window("off") X Xend X X Xprocedure make_command_table() X X local t X X t := table() X X every insert(t, "y"|getval("K1"|"HM"|"kh"), move_ul) X every insert(t, getval("ku")|"k", move_u) X every insert(t, "u"|getval("K3"|"PU"|"kP"), move_ur) X every insert(t, getval("kr")|"l", move_r) X every insert(t, "n"|getval("K5"|"PD"|"kN"), move_lr) X every insert(t, getval("kd")|"j", move_d) X every insert(t, "b"|getval("K4"|"EN"|"@7"), move_ll) X every insert(t, getval("kl")|"h", move_l) X every insert(t, "\x12", redraw) X X return t X Xend X X Xprocedure move_ul() X movew(me, 1 < me.begy - 1, 1 < me.begx - 1) & X return Xend Xprocedure move_u() X movew(me, 1 < me.begy - 1, me.begx) & X return Xend Xprocedure move_ur() X movew(me, 1 < me.begy - 1, COLS - 7 > me.begx + 1) & X return Xend Xprocedure move_r() X movew(me, me.begy, COLS - 7 > me.begx + 1) & X return Xend Xprocedure move_lr() X movew(me, LINES - 2 > me.begy + 1, COLS - 7 > me.begx + 1) & X return Xend Xprocedure move_d() X movew(me, LINES - 2 > me.begy + 1, me.begx) & X return Xend Xprocedure move_ll() X movew(me, LINES - 2 > me.begy + 1, 1 < me.begx - 1) & X return Xend Xprocedure move_l() X movew(me, me.begy, 1 < me.begx - 1) & X return Xend SHAR_EOF true || echo 'restore of main2.icn failed' rm -f _shar_wnt_.tmp fi # ============= iwinds.icn ============== if test -f 'iwinds.icn' -a X"$1" != X"-c"; then echo 'x - skipping iwinds.icn (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp echo 'x - extracting iwinds.icn (Text)' sed 's/^X//' << 'SHAR_EOF' > 'iwinds.icn' && X############################################################################ X# X# Name: iwinds.icn X# X# Title: windowing routines X# X# Author: Richard L. Goerwitz X# X# Version: 1.5 (a very preliminary version) X# X############################################################################ X# X# This file contains a relatively small windowing package for use on X# UNIX systems with an installed (and updated) Icon Program Library. X# It will probably work under MS-DOS and other such systems as well, X# although you'll need to read the docs for iolib.icn and iscreen.icn X# in the IPL. X# X# Note: This is not a curses clone, and it is very slow. I was just X# trying to decide how a windowing interface might possibly be done X# in Icon (which has no pointers, and hence forces me to use things X# like records and global variables where I'd like to use explicit X# pointers to smaller data types). It's an exercize, and I'd really X# appreciate any advice on how to speed it up. X# X# For those seriously interested in character-based I/O that will work X# using stock terminals, check out the work being done by Iconic Soft- X# ware Inc. They have a curses interface for their Icon interpreter X# that is terminfo based, and runs on most i386 UNIX versions. As of X# this writing, it's in the end stages of beta testing. X# X############################################################################ X# X# This file contains the following routines: X# X# createw(begy, begx, lines, cols, wmode, wchar, border, bmode) X# exit_prog(procname, message, exit_code) X# hidew(w) X# movew(w, begy, begx) X# redraw() X# readw(w, ypos, xpos, mode) X# getchw(w, ypos, xpos, mode) - for no-echo, just use getch() X# window(mode) X# writew(w, s, pos, xpos, mode) X# X# To initiate windowing mode one must call window() with the argu- X# ment "on". To end it, one must call it with the argument "off". X# To "stop" a program while in windowing mode, call exit_prog(), X# using the current function name as arg 1, a diagnostic message as X# arg 2, and an exit code as arg 3. If you don't follow this X# protocol under UNIX, you'll find your terminal locked up in raw X# mode. X# X# To create a window, call createw() with the following arguments, in X# order: 1) the beginning line and 2) the beginning column for the X# upper left-hand square of the window; 3) the number of lines and 4) X# columns the window occupies; if desired, you can specify a default X# mode (5 - where 0 = normal, 1 = reverse video, 2 = underline, and 3 X# = boldface), and a default character (6). You can also specify a X# border (7) and a default mode for the border (8). Note that the X# border argument must be a string or list with 8 members, X# corresponding to the top left, top, top right, right, bottom right, X# bottom, bottom left, and left characters used to form the border. X# If you call it with some other nonnull argument, "+-+|+-+|" will be X# used as the default. X# X# To hide a window on the screen, call hidew(w). If you want to free X# up the storage occupied by a window, hide it, and then set variables X# that point to it to &null. If you are anal-retentive, you can call X# collect(). Hidew() fails if you try to hide _mainw, or try to hide X# an already-hidden window. X# X# The redraw() procedure (no arguments) redraws the entire physical X# screen. Movew(w, y, x) moves window w so that its upper left-hand X# corner is at line y and column x. X# X# Writew(w, s, y, x, mode) writes string s to window w beginning at X# position y,x using mode as the default mode. There is no scroll or X# wordwrap, although writes to the bottom right corner will come back X# around to the upper left corner. I forget why I did things this X# way. X# X# Readw(w, y, x, mode) reads and returns a string, echoing it, while X# it is being typed, to window w, starting at position y,x using mode X# as the default mode. If you want to do non-echoing reads, just use X# getch(). In general, don't read &input using read(), reads(), or X# getche() while in windowing mode. It will look silly on the screen, X# and if you're running under UNIX, the read functions may not work as X# expected (remember, you're in raw mode). X# X############################################################################ X# X# Here's a brief example of how to use this library to do pretty things X# on the screen. It's nothing very complicated - just some simple window X# drawing and moving exercizes, with one window being used for a message. X# X# # for UNIX - make sure your IPL is fully updated! X# link iwinds, iolib, iscreen, getchlib X# X# # non-UNIX X# # link iwinds, iolib, iscreen (make sure you have getch()) X# X# procedure main() X# X# # global LINES, COLS (defined in iwinds.icn) X# local w, w2, w3, y, x X# X# # Initiate windowing mode. X# window("on") X# X# # Display a 10x30 window in the upper left corner of the screen. X# # Give it a border of spaces in reverse video mode. Fill the box X# # with "x" characters in normal mode. X# w := createw(1, 1, 10, 30, 0, "x", " ", 1) X# X# # Now for fun, move the window just created diagonally down, until X# # it gets to the bottom of the screen. Be sure not to overrun the X# # screen. X# x := 1 X# every y := 3 to LINES - 10 by 3 do X# movew(w, y, x +:= 6) X# X# # Lay down a small window. X# w2 := createw(8, 20, 3, 10, 1) X# # Print the word "hello" in it. X# writew(w2, "hello", 1, 1) X# X# # Lay down a window over top of the first one. X# w3 := createw(14, 50, 9, 30, 0, ".", " ",1) X# X# # Move the small window down on top of the other two. X# x := 20 X# every y := 11 to LINES - 7 by 3 do X# movew(w2, y, x +:= 7) X# X# # Change the message in the little window. X# writew(w2, "done!! ", 1, 1, 3) X# # Erase the two big windows. X# hidew(w3) X# hidew(w) X# X# # Move the little window back up to where it started. X# every y := y to 3 by -3 do X# movew(w2, y, x -:= 7) X# X# # Quit. X# window("off") X# exit_prog() X# X# end X# X############################################################################ X# X# Links: itlib or iolib, iscreen, and some implementation of getche() X# X############################################################################ X X# UNIX - link itlib, iscreen, getchlib X X# for debugging purposes X# link ximage, radcon X Xglobal _stdscr, _mainw, isUNIX, COLS, LINES Xrecord _square(val, over, under) Xrecord _window(wlist, begy,begx, lines,cols, ypos,xpos, border) X X Xprocedure window(mode) X X # X # Initiates/ends windowing mode. If arg1 == "on", then windowing X # mode is turned on; "off" does the opposite. Returns a string X # containing the current mode. No arg invocation works the same, X # except that no change occurs in the current mode. X # X static wmode X #global isUNIX X initial { X wmode := "off" X find("UNIX", &features) & isUNIX := "yes" X } X X if /mode | (wmode === mode) X then return wmode X else { X case mode of { X "off" : { X \isUNIX & reset_tty() X normal() X iputs(igoto(getval("cm"), 1, LINES)) X } X "on" : { X \isUNIX & setup_tty() X initscr() X } X default: { X exit_prog("window", "mode arg must be \"on\" or \"off\"", 11) X } X } X } X X return wmode := mode X Xend X X Xprocedure initscr(wmode, wchar, border) X X # X # Creates _stdscr, and the main window which covers the terminal X # screen (unless TERM has am capability, i.e. won't let us write X # to the last column without wrapping; in which case make _stdscr X # one column narrower than the physical screen). X # X X local begy, begx, ypos, xpos, default_cell, wlist, wlist2, r, c, tmp X # global _stdscr, _mainw, COLS, LINES, isUNIX X X \isUNIX & setup_tty() # initializes raw mode (see getchlib.icn) X X # X # Set up default size, position, etc. X # X begy := 1 # initialize variables for a single, blank X begx := 1 # normal-mode window starting at 1,1 that X X LINES := getval("li") # covers the entire screen X COLS := getval("co") X if getval("am") then # don't use last col if wordwrap will X COLS -:= 1 # occur X ypos := 1 X xpos := 1 X /border := &null # main window normally doesn't get a border X X /wmode := 0 # default mode for _mainw is always 0 X /wchar := " " # default char for _mainw is always " " X if 0 < *wchar < 2 X # then default_cell := -(ishift(wmode,16) + ord(wchar)) X then default_cell := -((wmode * 65536) + ord(wchar)) X else exit_prog("initscr", "wchar must be a single char or &null", 41) X X # X # Create a LINES X COLS array of _square() records. X # X every !(wlist := list(LINES)) := list(COLS) X every !(wlist2 := list(LINES)) := list(COLS) X # X # If blank spaces aren't the default, then flag each square for update. X if wmode = 0 & wchar == " " then { X default_cell := abs(default_cell) X clear() X } X # X every r := 1 to LINES do { X every c := 1 to COLS do { X tmp := _square(default_cell, &null, &null) X wlist[r][c] := tmp X wlist2[r][c] := tmp X } X } X _mainw := _window(wlist, begy,begx, LINES,COLS, ypos,xpos, border) X _stdscr := _window(wlist, begy,begx, LINES,COLS, ypos,xpos) X if not (wmode = 0 & wchar == " " & /border) then X refreshw(_mainw) X X return _mainw X Xend X X Xprocedure refreshw(w, dont_foreground) X X # X # Foregrounds & redraws window w on the screen. If dont_foreground X # is nonnull, then only already-visible portions are updated. Parts X # covered by other windows are left alone. X # X local y, x, stdscr_y, stdscr_x, stdscr_square, window_square, oldval X X /w := _mainw # _mainw is the default (covers whole screen) X X every y := 1 to w.lines do { X every x := 1 to w.cols do { X X # Create a handle for manipulating the current square in w. X window_square := w.wlist[y][x] X X # If the window isn't to be foregrounded, and the square isn't X # visible, then skip this square. Go right to the next one. X if \dont_foreground then if \window_square.over then next X X # Calculate this square's position on _stdscr. X stdscr_y := y + w.begy - 1 X stdscr_x := x + w.begx - 1 X X # Create a handle for manipulating the square which previously X # occupied the spot we're about to put the current window square X # into. Drop new square into the old one's spot. X stdscr_square := _stdscr.wlist[stdscr_y][stdscr_x] X _stdscr.wlist[stdscr_y][stdscr_x] := window_square X X # If window w already occupies this square in _stdscr, then X # there's no need to reshuffle the _stdscr structure. If w X # does not occupy this square, though... X if window_square ~=== stdscr_square then { X X # ...check to see if the window is farther down the _stdscr X # stacks; if so, then remove it from the stack... X if \window_square.over then { X (\window_square.under).over := window_square.over X window_square.over.under := window_square.under X } X X # ...then push the old topmost square "down" the stack, and X # finally place the current square on top. X window_square.under := stdscr_square X window_square.over := stdscr_square.over X stdscr_square.over := window_square X # The old square will need to be updated when it's X # uncovered. X oldval := stdscr_square.val X stdscr_square.val := -abs(oldval) X X # Paranoid check. The topmost member of the stack should X # always have &null as its "over" pointer. X # /window_square.over | { X # # write(&errout, "window:\n", (\ximage)(window_square)) X # exit_prog("refreshw", "bizarre stack malformation", 21) X # } X } X X # Update the current square on the screen. Don't bother X # drawing it if the previous one had the same val, and it X # wasn't flagged for update. X if stdscr_square.val ~= window_square.val | X ((\oldval | stdscr_square.val) \ 1) < 0 X then draw_it(window_square, stdscr_y, stdscr_x) X else window_square.val := abs(window_square.val) X oldval := &null X } X } X X return X Xend X X Xprocedure draw_it(sq, y, x) X X # X # Draws square sq on the physical screen at y,x. X # X local mode X static cm, last_mode, last_y, last_x X # global COLS (number of columns in _stdscr) X initial { X cm := getval("cm") X # initialize to impossible values X last_mode := last_y := last_x := -1 X } X X # mask out update flag so this square doesn't get updated again X sq.val := abs(sq.val) X X # If we aren't at the right position already, then reposition the X # cursor manually. X if not (y = last_y & x = (last_x + 1)) then { X # termlib routines put x before y. X iputs(igoto(cm, x, y)) X # If we have to reposition the cursor, reset the mode as well. X # This may not be necessary for most terminals. We'll see. X # last_mode := -1 X } X # record the position we're at X last_y := y; last_x := x X X # mode is recorded in bits 16-31 of sq.val X # mode := iand(ishift(sq.val, -16), 32767) X mode := sq.val / 65536 X # If there's been a mode change since the last square was written, X # or if the cursor's been repositioned, or if we're at the start X # of a line, then reset the mode. X if (last_mode ~=:= mode) | (y = 1) then { X case mode of { X 0 : normal() SHAR_EOF true || echo 'restore of iwinds.icn failed' fi echo 'End of part 1' echo 'File iwinds.icn is continued in part 2' echo 2 > _shar_seq_.tmp exit 0 -- -Richard L. Goerwitz goer%sophist@uchicago.bitnet goer@sophist.uchicago.edu rutgers!oddjob!gide!sophist!goer From icon-group-request@arizona.edu Tue Oct 15 15:39:13 1991 Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Tue, 15 Oct 91 15:39:13 MST Resent-From: icon-group-request@arizona.edu Received: from Arizona.edu (Merlin.Telcom.Arizona.EDU) by optima.cs.arizona.edu (4.1/15) id AA25062; Tue, 15 Oct 91 15:39:11 MST Received: from ucbvax.Berkeley.EDU by Arizona.edu with PMDF#10282; Tue, 15 Oct 1991 15:38 MST Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA08066; Tue, 15 Oct 91 15:11:48 -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: Tue, 15 Oct 1991 15:38 MST Date: 15 Oct 91 11:45:35 GMT From: hsi!mlfarm!rosie!ron@uunet.uu.net (Ronald Florence) Subject: RE: windowing; an exercize Sender: icon-group-request@arizona.edu Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: <8DC053CED4A1012A@Arizona.edu> Message-Id: <1991Oct15.114535.343@mlfarm.com> X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.edu Organization: Maple Lawn Farm, Stonington, CT References: <1991Oct12.182846.10147@midway.uchicago.edu> Richard L. Goerwitz writes: About the speed of the package: I note that the character-based I/O is not the worst bottleneck. Actually, the sample file I posted does a lot of internal optimization (e.g. when a window is [re]drawn, only those squares that need to be updated are actually placed on the screen). The odd thing is that it's the internal machinations that take the time, and not so much the actual interaction with the terminal. I gather you under- stood this, Ron. So I'd just modify your statement that the problem is one of character-based I/O in an interpreted system to say merely that the problem is simply one inherent in interpreted systems. LISP programmers have the same problems when writing systems like emacs (the code for which has to be done largely in C). Emacs is a good model for user interface systems. On some platforms emacs runs under X-windows; on others, it drives character-based I/O. When you hack a lisp function for the editor, you don't have to worry about which interface is in use; emacs takes care of that. I guess what I'd like to see for windowing functions in Icon is a set of interface-independent functions. Just as Richard's excellent termcap code has made character-based Icon code portable between Unix and ms-dos platforms, I wonder if we couldn't draw up a set of high-level windowing functions, with link-time hooks to the choice of 1) a curses-like character-based package; 2) X-windows for Unix platforms; or 3) Windows (or some other interface) for ms-dos systems. The Icon coder could then freely use functions like makewindow(), writewindow(), or movewindow(), without worrying about the low-level interface that actually made and manipulated the windows. Is this just dreaming? I would have said the same thing about portable character-based I/O until I began using Richard's termcap functions. -- Ronald Florence ron@mlfarm.com From icon-group-request@arizona.edu Tue Oct 15 18:00:47 1991 Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Tue, 15 Oct 91 18:00:47 MST Resent-From: icon-group-request@arizona.edu Received: from Arizona.edu (Merlin.Telcom.Arizona.EDU) by optima.cs.arizona.edu (4.1/15) id AA10164; Tue, 15 Oct 91 18:00:45 MST Received: from ucbvax.Berkeley.EDU by Arizona.edu with PMDF#10282; Tue, 15 Oct 1991 18:00 MST Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA13818; Tue, 15 Oct 91 17:43:08 -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: Tue, 15 Oct 1991 18:00 MST Date: 16 Oct 91 00:28:45 GMT From: midway!quads!goer@uunet.uu.net (Richard L. Goerwitz) Subject: RE: windowing; an exercize Sender: icon-group-request@arizona.edu Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: Message-Id: <1991Oct16.002845.8678@midway.uchicago.edu> X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.edu Organization: University of Chicago References: <1991Oct14.001550.21718@mlfarm.com>, <1991Oct14.153712.15751@midway.uchicago.edu>, <1991Oct15.114535.343@mlfarm.com> Ronald Florence writes: >Emacs is a good model for user interface systems. On some platforms >emacs runs under X-windows; on others, it drives character-based I/O. >When you hack a lisp function for the editor, you don't have to worry >about which interface is in use; emacs takes care of that. Yeah, but the Emacs interface is really just a character-based inter- face that's been extended to work in an X environment. When character I/O was all we had, it seemed pretty nice. I use emacs for all program editing still now. It's not slick, though, by recent standards. I use emacs because it's so extensible and understands the syntax of the lang- uages I want to edit (handling parentheses, blocks, comments, etc.) - not because of its interface. I'll bet, Ron, that you use emacs for the same reasons. >I wonder if we couldn't draw up a set of >high-level windowing functions, with link-time hooks to the choice of >1) a curses-like character-based package; 2) X-windows for Unix >platforms; or 3) Windows (or some other interface) for ms-dos systems. >The Icon coder could then freely use functions like makewindow(), >writewindow(), or movewindow(), without worrying about the low-level >interface that actually made and manipulated the windows. I wonder if this is going to be possible, given the drastic differences between bit-mapped and character-based displays. Ron, I'm still waiting around for 16-bit characters and interfaces that are smart enough to understand that not all languages wrap left-to-right. I'm worried that a curses-compatible function set would lock in certain misfeatures that might not be necessary with other systems. Do you have some ideas along these lines? Clinton has mentioned some formal notes on the X<->Icon interface under development. I guess I feel a bit out of this discussion because I just don't have the $ or the space to run a big system like X, and I'm not aware of any toolkits that really do what I'd need anyway (e.g. write Arabic, Greek, English all at once, getting the word- wrap right, and all the ligatures and diacritics as well). I'm still wait- ing for NeXT, which promises that it's going to internationalize its inter- face, and also support Unicode. -- -Richard L. Goerwitz goer%sophist@uchicago.bitnet goer@sophist.uchicago.edu rutgers!oddjob!gide!sophist!goer From cjeffery Tue Oct 15 22:10:56 1991 Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Tue, 15 Oct 91 22:10:56 MST Resent-From: "Clinton Jeffery" Received: from Arizona.edu (Merlin.Telcom.Arizona.EDU) by optima.cs.arizona.edu (4.1/15) id AA04444; Tue, 15 Oct 91 22:10:54 MST Received: from optima.cs.arizona.edu by Arizona.edu with PMDF#10282; Tue, 15 Oct 1991 22:10 MST Received: from cheltenham.cs.arizona.edu by optima.cs.arizona.edu (4.1/15) id AA04383; Tue, 15 Oct 91 22:10:20 MST Received: by cheltenham.cs.arizona.edu; Tue, 15 Oct 91 22:10:19 MST Resent-Date: Tue, 15 Oct 1991 22:10 MST Date: Tue, 15 Oct 91 22:10:19 MST From: "Clinton L. Jeffery" Subject: windowing; an exercize In-Reply-To: Richard L. Goerwitz's message of 16 Oct 91 00:28:45 GMT <1991Oct16.002845.8678@midway.uchicago.edu> Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: Message-Id: <9110160510.AA19981@cheltenham.cs.arizona.edu> X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.edu Ronald Florence posed the question (paraphrased): >I wonder if we could... draw up a set of high-level windowing functions, >with...choice of 1) a curses-like character-based package; 2) X-windows >for Unix platforms; or 3) ...other interfaces Exerpted from an answer by Richard Goerwitz: I wonder if this is going to be possible, given the drastic differences between bit-mapped and character-based displays.... I'm worried that a curses-compatible function set would lock in certain misfeatures that might not be necessary with other systems. Ron's idea is not only possible, it is a good idea, and the implementation would not pose insurmountable difficulties. But *designing* the perfect character-based I/O library is an almost impossible task even if one restricts oneself to the 8-bit character world that Icon lives in. And such a standard is useful only if it is almost universally available (to the Icon world, anyhow) and most folks genuinely like it. From icon-group-request@arizona.edu Wed Oct 16 13:57:32 1991 Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Wed, 16 Oct 91 13:57:32 MST Resent-From: icon-group-request@arizona.edu Received: from Arizona.edu (Merlin.Telcom.Arizona.EDU) by optima.cs.arizona.edu (4.1/15) id AA06017; Wed, 16 Oct 91 13:57:30 MST Received: from ucbvax.Berkeley.EDU by Arizona.edu with PMDF#10282; Wed, 16 Oct 1991 13:56 MST Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA20326; Wed, 16 Oct 91 13:53:10 -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: Wed, 16 Oct 1991 13:57 MST Date: 16 Oct 91 19:51:35 GMT From: snorkelwacker.mit.edu!paperboy!pnh@bloom-beacon.mit.edu (Peter Harbo) Subject: Req project management Icon programs Sender: icon-group-request@arizona.edu Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: <48B7655D54A0FF40@Arizona.edu> Message-Id: X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.edu Organization: Open Software Foundation This is a request for any programs people may have written to determine dependencies between tasks described in an ASCII database (Gantt chart or similar prj management programs welcomed too). From icon-group-request@arizona.edu Thu Oct 17 20:47:32 1991 Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Thu, 17 Oct 91 20:47:32 MST Resent-From: icon-group-request@arizona.edu Received: from Arizona.edu (Merlin.Telcom.Arizona.EDU) by optima.cs.arizona.edu (4.1/15) id AA14464; Thu, 17 Oct 91 20:47:29 MST Received: from ucbvax.Berkeley.EDU by Arizona.edu with PMDF#10282; Thu, 17 Oct 1991 20:46 MST Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA23407; Thu, 17 Oct 91 20:36: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, 17 Oct 1991 20:47 MST Date: 17 Oct 91 22:28:12 GMT From: sun-barr!cs.utexas.edu!qt.cs.utexas.edu!zaphod.mps.ohio-state.edu!caen!uvaarpa!murdoch!aemsun.med.virginia.edu!sdm7g@ames.arc.nasa.gov (Steven D. Majewski) Subject: RE: REXX vs Perl ( vs ICON ? ) Sender: icon-group-request@arizona.edu Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: <4B275618E4A05D38@Arizona.edu> Message-Id: <1991Oct17.222812.21915@murdoch.acc.Virginia.EDU> X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.edu Organization: University of Virginia - Physiology Dept. References: <28F2FAD7.59FB@tct.com>, <1011@cadlab.sublink.ORG>, <*3aHd=d13@cs.psu.edu> In article <*3aHd=d13@cs.psu.edu> flee@cs.psu.edu (Felix Lee) writes: >Both languages are fairly traditionally Pascal/Algol-like, with some >built-in support for string processing. > >Perl has better support for aggregate types (vectors and tables) than >REXX. Both languages lack support for nontrivial data types. > >Perl is more compact for some things, especially string processing, >but Perl's syntax is harder to read and learn. > Is it too much to expect that there is someone capable of adding to this thread a comparison of ICON .vs. ( REXX or PERL ) ? What are the other string-processing type languages out there ( that are rather widely used and somewhat portable and excluding: yacc,lex,awk, SNOBOL (Icon's ancestor).) ? Does J ( descendant of APL ) have any special string processing capabilities ? I know PERL is probably the language of choice on Unix systems because of its very complete interface to system & network functions, but just considering string processing capabilities: What language would you use? ( Programmer time, not run-time, needs to be minimized. Assume that in detail, these are usually one-time problem fixes, but that there will be enough similar variations on a theme to discount (somewhat) learning time.) [ An example of the type of application I'm thinking of: Take text from several format ascii files : refer, bibtex, and ascii dumps from other data-base programs ( typically, lines containing: "field: value" pairs. ), Convert to a canonical punctuation and capitalization, verify values and correct where unambiguous, flag for later correction when ambiguous. Reformat the data to be imported into another database program, possibly splitting single input fields into multiple output fields. Assume there are LOTS of errors in the input data and that we want to minimise human intervention but we can't spend a *lot* of time making the program *too* artificially intelligent. ] ======== "If you have a hammer, find a nail" - George Bush,'91 ========= Steven D. Majewski University of Virginia Physiology Dept. sdm7g@Virginia.EDU Box 449 Health Sciences Center Voice: (804)-982-0831 1600 Jefferson Park Avenue FAX: (804)-982-1616 Charlottesville, VA 22908 From LARSSON@sj03.ts.tele.nokia.fi Fri Oct 18 07:12:57 1991 Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Fri, 18 Oct 91 07:12:57 MST Received: from SJ03.TS.TELE.NOKIA.FI by optima.cs.arizona.edu (4.1/15) id AA06358; Fri, 18 Oct 91 07:12:31 MST Date: Fri, 18 Oct 1991 16:11:53 GMT+0300 From: LARSSON@sj03.ts.tele.nokia.fi (Arne Larsson tel 358-0-5117476 fax 358-0-51044287) Message-Id: <911018161153.20606647@sjclus.tele.nokia.fi> Subject: Icon and windows: a possible solution? To: icon-group@cs.arizona.edu X-Vmsmail-To: INET::"icon-group@cs.arizona.edu" One model for doing Windows with Icon could perhaps be patterned on the methods used in Arity Prolog. The Arity library for Windows (ARITYW.LIB) is a replacement for ARITY.LIB that is used to link Microsoft Windows (R) programs that use Arity/Prolog. Programs linked with the ARITYW.LIB must be run in either standard mode or enhanced mode. Also, programs linked with ARITYW.LIB can only have one instance running at a time. This is an inherent limitation of large model programs in Microsoft Windows. Although it is possible to build dynamic link libraries using Arity/Prolog it is not recommended. This is because the DLL's will have limited utility. In Microsoft Windows, DLL's can have only one instance of its data segments. Therefore unless they are "pure" code and read-only data, they cannot be used by more than one application at a time. Using this library Windows dialogs etc can be specified in a rather 'linguistic' manner: NREV DIALOG LOADONCALL MOVEABLE DISCARDABLE 20, 21, 252, 88 STYLE DS_MODALFRAME | WS_POPUP BEGIN CONTROL "Naive Reverse Benchmark (LIPS)", -1, "static", SS_CENTER | WS_GROUP | WS_CHILD, 0, 9, 252, 9 CONTROL "Length of List: ", -1, "static", SS_RIGHT | WS_GROUP | WS_CHILD, 64, 29, 63, 8 CONTROL "Number of Iterations: ", -1, "static", SS_RIGHT | WS_GROUP | WS_CHILD, 38, 47, 91, 8 CONTROL "", ID_NREV_LEN, "edit", ES_LEFT | WS_BORDER | WS_TABSTOP | WS_CHILD, 151, 27, 25, 11 CONTROL "", ID_NREV_CNT, "edit", ES_LEFT | WS_BORDER | WS_TABSTOP | WS_CHILD, 150, 47, 27, 11 CONTROL "OK", 1, "button", BS_DEFPUSHBUTTON | WS_TABSTOP | WS_CHILD, 82, 68, 38, 12 CONTROL "Cancel", 2, "button", BS_PUSHBUTTON | WS_TABSTOP | WS_CHILD, 139, 68, 38, 12 END NREV2 DIALOG LOADONCALL MOVEABLE DISCARDABLE 24, 19, 228, 95 STYLE DS_MODALFRAME | WS_POPUP BEGIN CONTROL "Naive Reverse Benchmark Results", -1, "static", SS_CENTER | WS_GROUP | WS_CHILD, 0, 1, 228, 8 CONTROL "Length of List: ", -1, "static", SS_RIGHT | WS_GROUP | WS_CHILD, 0, 17, 167, 9 CONTROL "Number of Iterations: ", -1, "static", SS_RIGHT | WS_GROUP | WS_CHILD, 1, 30, 169, 9 CONTROL "Time for Test: ", -1, "static", SS_RIGHT | WS_GROUP | WS_CHILD, 0, 43, 167, 9 CONTROL "Logical Inferences per Second (LIPS): ", -1, "static", SS_RIGHT | WS_GROUP | WS_CHILD, 2, 55, 166, 8 CONTROL "123456789", ID_NREV2_LEN, "static", SS_LEFT | WS_GROUP | WS_CHILD, 170, 17, 50, 8 CONTROL "123456789", ID_NREV2_CNT, "static", SS_LEFT | WS_GROUP | WS_CHILD, 170, 30, 50, 8 CONTROL "123456789", ID_NREV2_TIME, "static", SS_LEFT | WS_GROUP | WS_CHILD, 170, 43, 50, 8 CONTROL "123456789", ID_NREV2_LIPS, "static", SS_LEFT | WS_GROUP | WS_CHILD, 170, 55, 50, 8 CONTROL "OK", 1, "button", BS_DEFPUSHBUTTON | WS_TABSTOP | WS_CHILD, 99, 80, 38, 12 END Resources will be given in .RC files: #include "windows.h" #include "demo.h" #include "demo.dlg" DemoMenu MENU BEGIN POPUP "&File" BEGIN MENUITEM "A&bout...", IDM_ABOUT END POPUP "&Demos" BEGIN MENUITEM "&NREV...", IDM_NREV MENUITEM "&ZEBRA", IDM_ZEBRA MENUITEM "&Dynamic...", IDM_DYNAMIC END POPUP "D&atabase" BEGIN MENUITEM "&Start Torture test",IDM_STARTTORTURE MENUITEM "Sto&p Torture test",IDM_ENDTORTURE,GRAYED END END Thus the program code and the user interface specifications are strictly distinct from each other and kept in separate files. Similar results could possibly be achieved using some standard library, e.g. the Zink Interface Library (which I've heard about but not seen yet). Although I'm definitly not the kind of a wizard, who would be in a position to do all these tricks myself, it seems that the techniques necessary do exist. Best regards, Arne Larsson larsson@sjclus.ts.tele.nokia.fi From iwtqg!nowlin@att.att.com Fri Oct 18 07:32:05 1991 Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Fri, 18 Oct 91 07:32:05 MST Message-Id: <9110181432.AA06934@optima.cs.arizona.edu> Received: from att.att.com by optima.cs.arizona.edu (4.1/15) id AA06934; Fri, 18 Oct 91 07:32:03 MST From: iwtqg!nowlin@att.att.com Date: Fri, 18 Oct 91 09:26 CDT To: att!cs.arizona.edu!icon-group Subject: Re: REXX/Perl/Icon > Date: 17 Oct 91 22:28:12 GMT > From: (Steven D. Majewski) > Subject: RE: REXX vs Perl ( vs ICON ? ) > > In article <*3aHd=d13@cs.psu.edu> flee@cs.psu.edu (Felix Lee) writes: > >Both languages are fairly traditionally Pascal/Algol-like, with some > >built-in support for string processing. > > > >Perl has better support for aggregate types (vectors and tables) than > >REXX. Both languages lack support for nontrivial data types. > > > >Perl is more compact for some things, especially string processing, > >but Perl's syntax is harder to read and learn. > > Is it too much to expect that there is someone capable of adding to this > thread a comparison of ICON .vs. ( REXX or PERL ) ? > ... There was a very good comparison of several languages posted to this group some time ago. I don't remember REXX but Perl and Icon were in there. It was very large and I didn't save it. I imagine it's archived on the U of A machine and you can use ftp to get it. Don't ask me how though. I responded because of your assertion: > I know PERL is probably the language of choice on Unix systems because > of its very complete interface to system & network functions, ... I'm glad you "know" that. I've been using Icon for over six years and working on UNIX for a lot longer. I've found almost nothing that I couldn't do in Icon because I needed a more complete interface to UNIX. There are times I've been forced to use other languages for speed, times that the bean counters have forced me to use one of the "supported" languages, and times that Icon was not the appropriate language for the job. The interface to UNIX has never been a limiting factor. The pipe-open and system calls in Icon provide plenty of UNIX access and flexibility. There are some things that I would like to see added to the UNIX interface but they would force a language that is designed to run on a variety of platforms to incorporate yet another operating system specific wart. I know that there are a LOT of programmers that prefer Icon over other languages for exactly the reason you cited: > ( Programmer time, not run-time, needs to be minimized. Assume that in > detail, these are usually one-time problem fixes, but that there will be > enough similar variations on a theme to discount (somewhat) learning > time.) I'm not presumptuous enough to say Icon is the "language of choice" for any one group of programmers. Although I work on UNIX and it certainly is for me :-) Jerry Nowlin From alex@laguna.metaphor.com Fri Oct 18 13:53:18 1991 Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Fri, 18 Oct 91 13:53:18 MST Received: from relay.metaphor.com by optima.cs.arizona.edu (4.1/15) id AA24092; Fri, 18 Oct 91 13:53:11 MST Received: from laguna.Metaphor.COM by relay.metaphor.com (4.1/SMI-4.1) id AA08768; Fri, 18 Oct 91 13:51:22 PDT Received: by laguna.Metaphor.COM (4.1/SMI-4.0) id AA06420; Fri, 18 Oct 91 13:52:12 PDT Date: Fri, 18 Oct 91 13:52:12 PDT From: alex@laguna.metaphor.com (Bob Alexander) Message-Id: <9110182052.AA06420@laguna.Metaphor.COM> To: icon-group@cs.arizona.edu, sdm7g@virginia.edu Subject: Re: REXX/Perl/Icon Here is a posting from the net (3/91) that y'all will probably find interesting: -------------------------------------------------------------------------- > From icon-group-sender@cs.arizona.edu Sat Mar 30 05:38:29 1991 > Return-Path: > Received: from relay.metaphor.com by laguna.Metaphor.COM (4.0/SMI-4.0) > id AA06677; Sat, 30 Mar 91 05:38:23 PST > Errors-To: icon-group-errors@cs.arizona.edu > Received: from megaron.cs.arizona.edu by relay.metaphor.com (4.1/SMI-4.1) > id AA00378; Sat, 30 Mar 91 05:34:21 PST > Errors-To: icon-group-errors@cs.arizona.edu > Received: by megaron.cs.arizona.edu (5.61/15) > id AA18711; Sat, 30 Mar 91 06:33:57 -0700 > Resent-From: icon-group-request@arizona.edu > Resent-Date: Sat, 30 Mar 1991 06:33 MST > Date: 29 Mar 91 16:22:11 GMT > From: eru!kth.se!sunic!mcsun!ukc!mucs!m1!bevan@bloom-beacon.mit.edu (Stephen J > Bevan) > Subject: Survey Results : Perl vs Icon vs .... (> 500 lines) > Sender: icon-group-request@arizona.edu > Resent-To: icon-group@cs.arizona.edu > To: icon-group@arizona.edu > Resent-Message-Id: > Message-Id: > X-Envelope-To: icon-group@CS.Arizona.EDU > X-Vms-To: icon-group@Arizona.edu > Organization: Department of Computer Science, University of Manchester > Errors-To: icon-group-errors@cs.arizona.edu > Status: RO [Note I've crossposted to all the groups I send my original message to. This was at the request of some of the respondents (sp?)] Here are the results of my question regarding which language to use for writing programs to extract information from files, generate reports ... etc. I initially suggested languages like Perl, Icon, Python ... As part of my original message I said :- > Rather than FTP all of them and wade through the documentation, I was > wondering if anybody has experiences with them that they'd like to > share? I would like to thank the following people for replying :- Dan Bernstein - brnstnd@kramden.acf.nyu.edu Tom Christiansen - tchrist@convex.COM Chris Eich - chrise@hpnmdla.hp.com Richard L. Goerwitz - goer@midway.uchicago.edu Clinton Jeffery - cjeffery@cs.arizona.edu Guido van Rossum - guido@cwi.nl Randal L. Schwartz - merlyn@iWarp.intel.com Peter da Silva - peter@ficc.ferranti.com Alan Thew - QQ11@LIVERPOOL.AC.UK Edward Vielmetti - emv@ox.com ?? - russell@ccu1.aukuni.ac.nz Most of the replies were about Perl, so I didn't learn much about the other languages I suggested (other than very general things). Even though I was originally hoping not to have to ftp any stuff, I ended up getting the source to Python, GAWK, TCL, Icon and the texinfo manual for Perl. To save you going through my list of good and bad points of the languages I looked at, here is the summary of what I see the languages as :- TCL - an embedded language i.e. an extension language for large programs (IMHO only if you haven't got, or don't like, Scheme based ones like ELK). Perl - the de facto UNIX scripting language. You name it, and you can probably cobble a solution together in Perl. Beyond the fact that a lot of people use it, I can see nothing to recommend it. It's a bit like C in that respect. Python - Good prototyping language with a consistent design. It might not have all the low level UNIX stuff built in, but by using modules, its easy to add the necessary things in an ordered way. Icon - the `nearly' language. Well designed language, that never seemed to make it into general use. Seems to cover the ground all the way from AWK type applications to Prolog/Lisp ones. If I wasn't already happy with Scheme, I'd use this for more general programming. I would recommend people at least look at this language. GAWK - simple scripting language. Definitely better than `old' awk. I would only use it if the job were really simple or if something like Python or TCL were not available. Note I wouldn't expect anybody to make a choice on what I say. I suggest you get the source/manuals yourself and have a good long look at the language/implementation before you decide. For the types of things _I_ want to do, it would be a tie between Icon and Python. Having said that, given that I'd have to extend both to cover the sort of things I want to do, I'll probably use Scheme instead (ELK in particular). The reason I didn't just use Scheme in the first place is that I was hoping one of the languages would have all the facilities I want without me having to extend them myself. Before, the summary of the languages themselves, I thought I'd try and list some of the things I was looking for. (Actually, I showed an earlier version of this summary to somebody and they didn't understand some of the terms I was using, so this is my attempt at an explanation). Note that most of the things are to do with structuring the code and alike. This is not the sort of thing you usually worry about when writing small scripts, but I plan to convert and write a number of tools, some of which are around the 1000 LOC mark. For example, I'd like to convert a particular lex/yacc/C program I have into the chosen language. You can skip ahead to the actual summary by searching for SUMMARY. (Well I can do this in GNUS, I don't know about other news readers like rn) Packages/Modules ---------------- These are a mechanism for splitting up the name space so that function name clashes are reduced. Most systems work by declaring a package and then all functions listed from then on are members of that package. You then access the functions using the package prefix, or import the whole package so that you don't have to use the prefix. The following is an example in CommonLisp :- ;;; foo.lsp ;;; bar.lsp (in-package 'foo) (in-package 'bar) (export '(bob)) (export '(bob)) (defun bob (a b) ...) (defun bob (x) ...) ;;; main.lsp (foo:bob 10 20) (bar:bob 3) Packages are not perfect, but they do help. You can get the same effect by declaring implicit package prefixes :- ;;; foo.lsp ;; bar.lsp (defun foo-bob (a b) ...) (defun bar-bob (x) ...) ;; main.lsp (foo-bob 10 30) (bar-bob 4) The advantage of packages over this is that you don't have to use a package prefix in the package itself when you want to call a function. This can be a saving if you have lots of functions in a package, and only a few are exported. Exception Handling ------------------ This is useful for dealing with error that shouldn't happen. e.g. reaching the end of the file when you were looking for some valid data. For example, in CommonLisp :- (defun foo (x y) ... (if (catch 'some-unexpexted-error (bar x y) nil) (handle-the-exception ...) (define bar (a b) ... (if (something-wrong) (throw 'some-unexpected-error t)) ...) Here the function `foo' calls `bar', and if any error occurs whilst processing, it is handled by the exception handler. (The example is a bit primitive as I'm trying to save space). The advantage of this is that you don't have to explicitly pass back all sorts of error codes from your functions to handle unusual errors. It also usually means you won't have so many nested `if's to handle the special cases, therefore, making your code clearer. Records/Tuples/Aggregates/Structs --------------------------------- It's handy to be to define objects that contain certain number of elements. You can then pass these objects around and access the individual bits. For example in CommonLisp :- (defstruct point x y) This declares `point' as a type containing two items called `x' and `y'. Some languages don't name the items, they rely on position instead. I see these as equivalent (assuming you have some sort of pattern matching) Provide/Require --------------- This is a primitive facility for declaring that one package depends on another one. For example in CommonLisp :- ;;; foo.lsp (defun bob (a b) ...) (provide 'foo) ;;; main.lsp (require 'foo) (bob 10 3) The above declares that the file `foo' provides the function `bob' and that the file `main' requires `foo' to be loaded for it to work. So when you load in `main' and `foo' hasn't been loaded, it is automatically loaded by the system. C Interface ----------- How easy is it to call C from the language. Is there a dynamic loading facility i.e. do I have to recompile the program to use some arbitrary C code, or can it load in a .o file at runtime? Arbitrary Restrictions ---------------------- This really applies to the implementations rather than the languages. However, as there is only one implementation for most of the languages I'm looking at, they tend to be synonymous If there is one thing I hate about an [implementation of] a languages its arbitrary restrictions. For example, `the length of the input line must not exceed 80 characters', or "strings must be less than 255 characters long". I can except some initial restrictions if :- 1) they are documented. 2) they will be removed in future versions. Note. I realise that some restrictions are not arbitrary, or at least not under the control of the language implementor e.g. the number of open files under UNIX. SUMMARY ------- If you want to know more about the languages, there follows a brief description of the languages, how to get an implementation and some good and bad points as I see them. Each point is preceded by a character indicating the type of point :- + good point - bad point * just a point to note ! subjective point Other than the `*' items, I guess it is all subjective, however, I've tried to put things that are generally good/bad in `+'/`-' and limit really subjective statements to `!'. TCL - version 4.0 patch level 1 ------------------------------- TCL (Tool Command Language) was developed by John Ousterhout at Berkeley. It started out as a small language that could be embedded in applications. It has now been extended by some people at hackercorp into more of a general purpose shell type programming language. It is described by Peter Da Silva (one of the people who extended it) as :- > TCL is like a text-oriented Lisp, but lets you write algebraic > expressions for simplicity and to avoid scaring people away. The language itself for some reason reminds me of csh even though I can only point to two things (the use of `set' and `$') which a definitely like csh. Unless you have other ideas about what an extension language should look like (e.g. IMO it should be Scheme), then I'd definitely recommend this. It's small, and integrates easily with other C programs (you can even have multiple TCL interpreters in an application!) Version 5.0 is available by anonymous ftp from sprite.berkeley.edu as tk.tar.Z (its part of an X toolkit called Tk). Note, although it has a higher number than the one above, does not include the extensions mentioned above. These will apparently be integrated soon. Version 4.0 pl1 is available by anonymous ftp from media-lab.ai.mit.edu (sorry can't remember the exact path) + exceptions. + packages, called libraries However there is only one name-space. The libraries are used as a way of storing single versions of code rather than as a solution to the name space pollution problem. + provide/require + C interface is excellent. You can easily go TCL->C and C->TCL. - No dynamic loading ability that I'm aware of. - Arbitrary line length limit on `gets' and `scan'. i.e. the commands that read lines from files/strings. I would guess this will go away in the next version. - No records. The main data types are strings/lists/associative arrays + extensive test suite included. ! doesn't look to have been tested on many systems. The above version actually failed to link on a SPARCstation running SunOS 4.1 as the source refers to `strerror'. This has apparently been fixed in patch level 2. + lots of example code included in distribution. + extensive documentation (all in nroff) + Can trace execution. ! To make arguments evaluate, you must enclose them in {} or [] This shouldn't be a problem, except that being used to Lisp like languages I expect to quote constants. ! The extensions though useful, are not seamless. e.g. some string facilities are in the core language and some in the extensions. This might happen when the hackercorp extensions are officially merged with the Berkeley core language and released by Berkeley. + As part of the extensions, you get tclsh. This is a shell which you can type command directly into. + scan contexts. This is sort of regular expressions on files rather than strings. Python - version 0.9.1 ---------------------- Available by anonymous ftp from wuarchive.wustl.edu as pub/python0.9.1.tar.Z or for Europeans via the info server at hp4nl.nluug.nl I couldn't think of a good way to describe this, so I'm blatantly copying the following from the Python tutorial :- Python is a simple, yet powerful programming language that bridges the gap between C and shell programming, and is thus ideally suited for rapid prototyping. Its syntax is put together from constructs borrowed from a variety of other languages; most prominent are influences from ABC, C, Modula-3 and Icon So far so good, here's some more from the tutorial :- Because of its more general data types Python is applicable to a much larger problem domain that Awk or even Perl, yet most simple things are at least as easy in Python as in those languages. i.e. Python seems to be designed for larger tasks than you would undertake using the shell/awk/perl. + packages. + exceptions (based on Modula 2/3 modules) + records (actually tuples. I'm not sure they do everything I want as the documentation is a bit vague in this area) Other main types are lists, sets, tables (associative arrays) + C interface is good. No dynamic linking that I am aware of. - Arbitrary Restrictions line length limit on readline. This has been fixed and I would guess will appear in the next release. + lots of example python programs included. There is even a TCL (version 2ish) interpreter! + Object oriented features. Based on Modula 3 i.e. classes with methods, all of which are virtual (to use a C++ term). * any un caught errors produce a stack trace. + disassembler included + can inspect stack frames via traceback module - no single step or breakpoint facility (maybe in the next release) + functions can return multiple values. * The default output command `print' inserts a space between each field output. ! I don't like the above, or rather I would like the option of not having it done. * Documentation includes tutorial and library reference as TeX files. Both are incomplete, but there is enough in them to be able to write Python code. The reference manual is not yet finished, and is not currently distributed with the source. + Python mode for Emacs. (Its primitive, but its a start) Icon - version 8 ---------------- To quote from one of the Icon books :- Icon is a high-level, general purpose programming language that contains many features for processing nonnumeric data, particularly for textual material consisting of string of characters. Available :- In USA :- ??, consult `archie'. In UK :- I picked up a copy form the sources archive at Imperial College. The JANET address is 00000510200001 - no packages. Everything is in one namespace. However ... - no exceptions. + Object oriented features. An extension to the language called Idol is included. This converts Idol into standard Icon. Idol itself looks (to me) like Smalltalk. + has records. Other types include :- sets, lists, strings, tables + unlimited line length when reading (Note. the newline is discarded) ! The only language that has enough facilities to be able to re-write some of my Lex/Yacc code. + stack trace on error. + C interface is good. Can extend the language by building `personal interpreter'. No dynamic linking. + extensive documentation 9 technical reports in all (PostScript and ASCII) - Unix interface is quite primitive. If you just want to use a command, you can use `callout', anything more complicated requires building a personal interpreter (not as difficult as it may sound) + extensive test suite + Usenet group exists specifically for it - comp.lang.icon - Unless you use Idol, all procedures are at the same level i.e. one scope. - regular expressions not supported. However, in many cases, you can use an Icon functions `find', `match', `many' and `upto' instead. + Can trace execution. * Pascal/C like syntax i.e. uses {} but has a few more keywords than C. + lots of example programs included. + can define your own iterators i.e. your own procedures for iterating through arbitrary structures. + co-expressions. Powerful tool, hard to explain briefly. See chapter 13 of the Icon Programming Language. - co-expressions haven't been implemented on Sun 4s (the type of machine I use) + has an `initial' section in procedures that is only ever executed once and allows you to initialise C like static variables with the result of other functions (unlike C). + arbitrary precision integers. As well as the excellent documentation included in the source, there are two books on Icon available (I skimmed through both of them) :- The Icon Programmming Language Ralph E. Griswold and Madge T. Griswold Prentice Hall 1983 The Implementation of the Icon Programmming Language Ralph E. Griswold and Madge T. Griswold Princeton University Press 1986 The second one is particularly useful if you are considering extending Icon yourself. Appendix E of this book also contains a list of projects that could be undertaken to extend and improve Icon. Here are some projects, that if implemented, would greatly improve the usefulness of Icon :- E.2.4 Add a regular expression data type. Modify the functions find and match to perate appropriately when their first argument is a regular expression. E.2.5 \ All of these suggest extending E.5.4 | the string scanning facilities to E.5.5 / cope with files and strings in a uniform way. E.12.1 Provide a way to load functions (written in C) at runtime Perl ---- Available :- USA :- ??, consult `archie' UK :- Imperial sources archive I received more responses about Perl than anything else, so I that most people already know a lot about the language. Here are some edited highlights from a message I received from Tom Christiansen :- First some good words from Tom :- > ... I shall now reveal my true colors as perl disciple > and perhaps not infrequent evangelist. Perl is without question the > greatest single program to appear to the UNIX community (although it runs > elsewhere too) in the last 10 years. It makes progamming fun again. It's > simple enough to get a quick start on, but rich enough for some very > complex tasks. > ... perl is a strict superset of sed and awk, so much so that s2p and > a2p translators exist for these utilities. You can do anything in > perl that you can do in the shell, although perl is not strictly > speaking a command interpreter. It's more of a programming language. and now some of the low points of Perl. [Note this is only a small part of a long post, that explained a lot of good things about Perl. As most people seem to use/like Perl, I thought I'd highlight some of the things wrong with the language, and what better place to get information than from the designer of the language. Note also that this is from a message dated June 90, so some of it may be out of date.] Larry Wall :- > The basic problem with Perl is that it's not about complex data structures. > Just as spreadsheet programs take a single data structure and try to > cram the whole world into it, so too Perl takes a few simple data structures > and drives them into the ground. This is both a strength and a weakness, > depending on the complexity and structure of the problem. > > The basic underlying fault of Perl is that there isn't a real good way > of building composite structures, or to make one variable refer to a piece > of another variable, without giving an operational definition of it. > > ... In a sense, the problem with Perl is not that it is too > complicated or hard to learn, but that perhaps it is not expressive > enough for the effort you put into learning it. Then again, maybe it > is. Your call. Some people are excited about Perl because, despite > its obvious faults, it lets them get creative. > > There are many things I'd do differently if I were designing Perl from > scratch. It would probably be a little more object oriented. Filehandles > and their associated magical variables would probably be abstract types > of some sort. I don't like the way the use of $`, $&, $' and $ > impact the efficiency of the language. I'd probably consider some kind > of copy-on-write semantics like many versions of BASIC use. The subroutine > linkage is currently somewhat problematical in how efficiently it can > be implemented. And of course there are historical artifacts that wouldn't > be there. I think the above is a vary fair summary of the low points of the language. At one point it says `... perhaps it is not expressive enought for the effort you put into learning it. Then again maybe it is. Your call'. Well _my_ call is that it is not. Note I didn't actually pick up the source to this, just the manual. Consequently I haven't been able to check all the points listed below. + packages. ! Note in the examples that I've seen in comp.lang.perl, people don't seem to use the facility, instead they put everything directly in `main' (i.e. the top level scope) rather than in the local scope. + exceptions + provide/require * C Interface ?? I couldn't find this in the documentation I had. + No arbitrary restrictions + has a source level debugger + Well integrated with Unix (nearly all system calls are built in !) ! However, like Unix, only one name space seems to be used (see above) * C like syntax + source contains texinfo manual. You can always buy the (Camel) book for more information. - no records. Other types lists, strings, tables (associative arrays) * some types have distinct scopes. ! You prefix the name with `@', '$', '%' to indicate which type you want. This is one of the ugliest things I've ever seen. ! Uses lots of short strings to contain often used things e.g. `$_' is the current input, `$.' is current line number. I guess some people must like this, but I prefer names like `input' and `line-number' myself. + includes programs to convert existing awk, find and sed scripts into Perl. + Usenet news group - comp.lang.perl + Perl mode for Emacs. GAWK ---- Available :- USA :- prep.ai.mit.edu, probably other places as well. Consult `archie' UK :- Imperial sources archive. A few points about GNU awk as it seems to fix some of the problems with `old' awk. - no packages - no exceptions - no C interface - no records + allows user defined functions + can read and write to arbitrary files + much more informative error messages than the old awk. From icon-group-request@arizona.edu Fri Oct 18 17:20:01 1991 Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Fri, 18 Oct 91 17:20:01 MST Resent-From: icon-group-request@arizona.edu Received: from Arizona.edu (Maggie.Telcom.Arizona.EDU) by optima.cs.arizona.edu (4.1/15) id AA02934; Fri, 18 Oct 91 17:19:59 MST Received: from ucbvax.Berkeley.EDU by Arizona.edu with PMDF#10282; Fri, 18 Oct 1991 17:19 MST Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA05237; Fri, 18 Oct 91 17:05:50 -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, 18 Oct 1991 17:19 MST Date: 18 Oct 91 15:38:58 GMT From: cis.ohio-state.edu!pacific.mps.ohio-state.edu!linac!midway!quads!goer@ucbvax.berkeley.edu (Richard L. Goerwitz) Subject: RE: Icon and windows: a possible solution? Sender: icon-group-request@arizona.edu Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: Message-Id: <1991Oct18.153858.18585@midway.uchicago.edu> X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.edu Organization: University of Chicago References: <911018161153.20606647@sjclus.tele.nokia.fi> Arne Larsson writes: >One model for doing Windows with Icon could perhaps be patterned on >the methods used in Arity Prolog. > >The Arity library for Windows (ARITYW.LIB) is a replacement for ARITY.LIB >that is used to link Microsoft Windows (R) programs that use Arity/Prolog. > >Programs linked with the ARITYW.LIB must be run in either standard mode >or enhanced mode. > >Also, programs linked with ARITYW.LIB can only have one instance running >at a time. This is an inherent limitation of large model programs in >Microsoft Windows. I think gave the impression that there are no windows for Icon! There are at least three available ways of creating an interface via Icon. Not all are available yet, and I confess that the ones that are are pretty much a single-OS affair. The first is the U of Arizona's own X interface, which is not yet part of the standard Icon distribution, but which we may see by the spring. The second is ISI's 3/486 UNIX curses/ETI interface, which is now in the late stages of beta testing. The third is ProIcon, which runs on a Mac, and can do lots of those nifty Mac tricks, so I am told. Of the three, the X interface will theoretically be available on the largest num- ber of platforms, but will naturally require X. Curses is implemented on many different machines, so theoretically the ISI interface could be ported to more platforms. ISI's implementation is commercial, as is ProIcon. I have not used ProIcon. ISI's interface is fast and can run on stock ter- minals. It seems well suited for commercial applications involving UNIX/ {3,4}86 platforms. It sounds to me as if the Arity-type solution would represent yet another method. Of course, people who are really interested in creating their own solutions can try them out via the Icon extcall mechanism (interpreter). The compiler presumably lets you link in and use any C library calls that you want. (Those interested in the compiler should wait, though, until the next version is out - one fully in sync with the interpreter; the ver- sion on cs.arizona.edu is good, but it's not supposed to be a full-fledged production version, and has a few problems with things like type infer- encing.) The package I posted, incidentally, runs slowly when interpreted. If com- piled using the version of the compiler under development, I'd suspect that it would yield acceptable performance. With the current compiler version, it can only be compiled with all the optimizations turned off. Even in that instance, though, it runs twice as fast as the interpreted "execut- able." Of course, this point might be moot when the new compiler comes out, depending on how the C interface is structured. -- -Richard L. Goerwitz goer%sophist@uchicago.bitnet goer@sophist.uchicago.edu rutgers!oddjob!gide!sophist!goer From icon-group-request@arizona.edu Fri Oct 18 21:36:38 1991 Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Fri, 18 Oct 91 21:36:38 MST Resent-From: icon-group-request@arizona.edu Received: from Arizona.edu (Maggie.Telcom.Arizona.EDU) by optima.cs.arizona.edu (4.1/15) id AA09838; Fri, 18 Oct 91 21:36:36 MST Received: from ucbvax.Berkeley.EDU by Arizona.edu with PMDF#10282; Fri, 18 Oct 1991 21:36 MST Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AB13806; Fri, 18 Oct 91 21:33:29 -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, 18 Oct 1991 21:36 MST Date: 19 Oct 91 03:04:58 GMT From: midway!quads!goer@uunet.uu.net (Richard L. Goerwitz) Subject: RE: REXX/Perl/Icon Sender: icon-group-request@arizona.edu Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: <1B2EDE8A58A05F11@Arizona.edu> Message-Id: <1991Oct19.030458.10611@midway.uchicago.edu> X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.edu Organization: University of Chicago References: <9110182052.AA06420@laguna.Metaphor.COM> Addenda to the 'comparison' posting: Where to get Icon - >In USA :- ??, consult `archie'. >In UK :- I picked up a copy form the sources archive at Imperial College. > The JANET address is 00000510200001 USA - cs.arizona.edu >- no packages. Everything is in one namespace. However ... >- no exceptions. Bzzt. There is a primitive exception handler. You can convert most run- time errors to expression failure by setting &error to a nonzero value. The only problem with this facility is that you must check each expression for such failures. You can't insert an error handler so that it is auto- matically called when a given exception occurs. >+ Object oriented features. > An extension to the language called Idol is included. > This converts Idol into standard Icon. > Idol itself looks (to me) like Smalltalk. >+ has records. Other types include :- sets, lists, strings, tables >+ unlimited line length when reading > (Note. the newline is discarded) >! The only language that has enough facilities to be able to re-write > some of my Lex/Yacc code. >+ stack trace on error. >+ C interface is good. Can extend the language by building `personal > interpreter'. No dynamic linking. >+ extensive documentation > 9 technical reports in all (PostScript and ASCII) >- Unix interface is quite primitive. > If you just want to use a command, you can use `callout', anything > more complicated requires building a personal interpreter (not as > difficult as it may sound) >+ extensive test suite >+ Usenet group exists specifically for it - comp.lang.icon >- Unless you use Idol, all procedures are at the same level > i.e. one scope. >- regular expressions not supported. > However, in many cases, you can use an Icon functions `find', > `match', `many' and `upto' instead. See below. Right linear grammars represent a very limited sub-type of the kinds of grammars one can recognize and parse using string scanning mechanisms of Icon and SNOBOL. Regular expressions really aren't needed in Icon (at least for those who know how to use string scanning). >+ Can trace execution. >* Pascal/C like syntax > i.e. uses {} but has a few more keywords than C. >+ lots of example programs included. >+ can define your own iterators > i.e. your own procedures for iterating through arbitrary structures. >+ co-expressions. Powerful tool, hard to explain briefly. See > chapter 13 of the Icon Programming Language. >- co-expressions haven't been implemented on Sun 4s (the type of > machine I use) They have been implemented since this posting appeared. In fact, when the posting appeared code had actually been posted to the net for Sun4 coexpressions. I don't think it had made it into the distribution, though. >+ has an `initial' section in procedures that is only ever executed > once and allows you to initialise C like static variables with the > result of other functions (unlike C). >+ arbitrary precision integers. Additional projects that would be good for Icon: >E.2.4 Add a regular expression data type. Modify the functions find > and match to perate appropriately when their first argument is a > regular expression. Regular expressions represent a language for representing a very limited grammar type (i.e. right linear grammars), and really don't fit into the much more elegant and powerful Icon string-scanning mechanisms. At best they are an optimization that might be tacked on. Many feel that Icon is big enough without having things tacked on. Of course, some would like to see them anyway, just because there are some fast algorithms available for them, and because they are fairly compact. If support for regular expressions does get added at some point, I sincerely hope that no one will add a new type, or extend the builtin functions to handle yet another type. Just two new functions, findre and matchre, would be enough. >E.2.5 \ All of these suggest extending >E.5.4 | the string scanning facilities to >E.5.5 / cope with files and strings in a uniform way. > >E.12.1 Provide a way to load functions (written in C) at runtime -- -Richard L. Goerwitz goer%sophist@uchicago.bitnet goer@sophist.uchicago.edu rutgers!oddjob!gide!sophist!goer From AL302723@VMTECCHI.BITNET Sun Oct 20 04:08:55 1991 Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Sun, 20 Oct 91 04:08:55 MST Received: from Arizona.edu (Merlin.Telcom.Arizona.EDU) by optima.cs.arizona.edu (4.1/15) id AA27897; Sun, 20 Oct 91 04:08:52 MST Received: from VMTECCHI.CHI.ITESM.MX (MAILER@VMTECCHI) by Arizona.edu with PMDF#10282; Sun, 20 Oct 1991 04:08 MST Received: from VMTECCHI (AL302723) by VMTECCHI.CHI.ITESM.MX (Mailer R2.07) with BSMTP id 7554; Sun, 20 Oct 91 01:58:12 EDT Date: Sun, 20 Oct 91 01:54:33 EDT From: "Mario Camou R." Subject: Icon compiler status... To: icon-group@cs.arizona.edu Message-Id: <911020.015433.EDT.AL302723@VMTECCHI> X-Envelope-To: icon-group@cs.arizona.edu Organization: Instituto Tecnologico de Monterrey, Campus Chihuahua I've been offline for a while (almost a year now). What's the state of the Icon compiler? Has it been ported to MS-DOS? +------------------------------------+--------------------------------+ | Dr. Mangagoras * StarStaff | Mario Camou Riveroll | +------------------------------------+------------+-------------------+ | Internet: |Bitnet: | | al302723%vmtecchi.bitnet@tecmtyvm.mty.itesm.mx | em302723@vmtecchi | +-------------------------------------------------+-------------------+ | Laugh at life....or life will laugh at you | +---------------------------------------------------------------------+ From icon-group-request@arizona.edu Sun Oct 20 05:26:01 1991 Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Sun, 20 Oct 91 05:26:01 MST Resent-From: icon-group-request@arizona.edu Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by optima.cs.arizona.edu (4.1/15) id AA00347; Sun, 20 Oct 91 05:25:58 MST Received: from ucbvax.Berkeley.EDU by Arizona.edu with PMDF#10282; Sun, 20 Oct 1991 05:25 MST Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA05155; Sun, 20 Oct 91 05:18:12 -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: Sun, 20 Oct 1991 05:25 MST Date: 20 Oct 91 08:07:24 GMT From: cis.ohio-state.edu!zaphod.mps.ohio-state.edu!samsung!nstar!towers!yngbld!zeta@ucbvax.berkeley.edu (Gregory Youngblood) Subject: COMM Sender: icon-group-request@arizona.edu Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: <25EB10A138A0F228@Arizona.edu> Message-Id: <2mT401w164w@yngbld.rn.com> X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.edu Organization: The Home Grown BBS I just d/l ed the MSDOS version of the icon interpreter. I haven't run it or anything yet, but am looking forward to getting started on it as soon as possible. One of the first things I'm going to be working on is going to require the use of the comm ports, mainly com1 under MSDOS. I would welcome any and all advice on installing this version on my 386-33, so i can get this up and running so i can start using it as soon as possible. I would also welcome any hints/tricks/help on programming using the comm ports. Thankx Greg REPLIES TO: zeta@yngbld.rn.com The Home Grown BBS 308-237-7501 9600 v.32/v.42bis From @um.cc.umich.edu:Paul_Abrahams@MTS.cc.Wayne.edu Mon Oct 21 06:09:00 1991 Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Mon, 21 Oct 91 06:09:00 MST Received: from mailrus.cc.umich.edu by optima.cs.arizona.edu (4.1/15) id AA00739; Mon, 21 Oct 91 06:08:58 MST Received: from um.cc.umich.edu by mailrus.cc.umich.edu (5.61/1123-1.0) id AA09577; Mon, 21 Oct 91 09:05:11 -0400 Received: from MTS.cc.Wayne.edu by um.cc.umich.edu via MTS-Net; Mon, 21 Oct 91 09:07:48 EDT Date: Mon, 21 Oct 91 09:07:28 EDT From: Paul_Abrahams@mts.cc.wayne.edu To: icon-group@cs.arizona.edu Message-Id: <376109@MTS.cc.Wayne.edu> Subject: Icon versus Awk I'd say that Icon is immeasurably superior to awk for programs of more than a few (say 5) lines. Icon is elegant and powerful, while awk is just a mess. The idea of using juxtaposition to indicate concatenation, for instance, is a leftover from Snobol that Icon very sensibly tossed in the trash. The awk expression syntax is ridiculous---no clear distinction between expressions and statements, yet the two are *not* interchangeable. Why should "close" be a statement while "getline" is an expression? Who knows? The dual use of "<" for redirection and for comparison is madness. And on the semantic level, has anyone figured out how to use "gsub" for any nontrivial useful substitutions? Or how about the wierdnesses of awk function definitions? Yet having said all that: awk is probably the superior language for *really* short programs, if they happen to fit its model. You can't write useful one-liners in Icon, but you can in awk. Nor can you write an Icon program on the command line as you can with awk. I'm not sure where the cutoff is---one line, two lines, five, or ten. Under the cutoff, awk wins; over the cutoff, Icon does. The advantages of Icon, of course, grow as the program gets longer. I'd be interested in postings of *really short* Icon programs that do something more useful than hello-worlding. No fair cramming ten expressions onto one line. Paul Abrahams Abrahams@mts.cc.wayne.edu From iwtqg!nowlin@att.att.com Mon Oct 21 07:03:18 1991 Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Mon, 21 Oct 91 07:03:18 MST Message-Id: <9110211403.AA02167@optima.cs.arizona.edu> Received: from att.att.com by optima.cs.arizona.edu (4.1/15) id AA02167; Mon, 21 Oct 91 07:03:16 MST From: iwtqg!nowlin@att.att.com Date: Sat, 24 Feb 90 21:41 CST To: att!cs.arizona.edu!icon-group Subject: Re: Icon versus Awk > Paul Abrahams writes... > > I'd be interested in postings of *really short* Icon programs that do > something more useful than hello-worlding. No fair cramming ten > expressions onto one line. I use this program frequently to convert UNIX text files to DOS text files by adding carriage returns to the end of each line: procedure main() while write(read(),"\r") end The awk alternative is shorter but no more simple: nawk ' { print $0 "\r" } ' > Yet having said all that: awk is probably the superior language for > *really* short programs, if they happen to fit its model. You can't > write useful one-liners in Icon, but you can in awk. Nor can you write > an Icon program on the command line as you can with awk. I'm not sure You can use contrived one-liners: procedure main() ; while write(read(),"\r") ; end In fact, I have frequently typed in Icon programs this short from the command line using the "- -x" flags. Simple one shot base conversions is an example: icont - -x procedure main() write(16raaa) end 2730 This is about as quick as it gets for simple programs to convert to base 10 unless you have an already written Icon program to do it for you :-) Jerry Nowlin From ralph Mon Oct 21 07:30:59 1991 Date: Mon, 21 Oct 91 07:30:59 MST From: "Ralph Griswold" Message-Id: <9110211430.AA26509@cheltenham.cs.arizona.edu> Received: by cheltenham.cs.arizona.edu; Mon, 21 Oct 91 07:30:59 MST To: icon-group Subject: Icon one-liners Assuming you're not sticking at the necessary procedure wrapper or are willing to accept Jerry Nowlin's format, there is a large class of useful Icon one-liners, of which this is an example: procedure main() every write(numeric(!&input)) end This particular instance of the class filters out lines of a file that are not numeric. Ralph Griswold / Department of Computer Science The University of Arizona / Tucson, AZ 85721 ralph@cs.arizona.edu / uunet!arizona!ralph voice: 602-621-6609 / fax: 602-621-9618 From ralph Mon Oct 21 07:33:54 1991 Date: Mon, 21 Oct 91 07:33:54 MST From: "Ralph Griswold" Message-Id: <9110211433.AA26583@cheltenham.cs.arizona.edu> Received: by cheltenham.cs.arizona.edu; Mon, 21 Oct 91 07:33:54 MST To: icon-group Subject: Icon one-liners Here's a short program by Anthony Hewitt that I particularly like for it's "Iconishness" if not its transparancy. I've resisted putting it on one line. procedure main() write(s := !&input) every write(s ~==:= !&input) end It filters out identical adjacent lines in a file. Ralph Griswold / Department of Computer Science The University of Arizona / Tucson, AZ 85721 ralph@cs.arizona.edu / uunet!arizona!ralph voice: 602-621-6609 / fax: 602-621-9618 From alex@laguna.metaphor.com Mon Oct 21 12:47:29 1991 Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Mon, 21 Oct 91 12:47:29 MST Received: from relay.metaphor.com by optima.cs.arizona.edu (4.1/15) id AA15620; Mon, 21 Oct 91 12:47:27 MST Received: from laguna.Metaphor.COM by relay.metaphor.com (4.1/SMI-4.1) id AA10231; Mon, 21 Oct 91 12:46:36 PDT Received: by laguna.Metaphor.COM (4.1/SMI-4.0) id AA08288; Mon, 21 Oct 91 12:47:29 PDT Date: Mon, 21 Oct 91 12:47:29 PDT From: alex@laguna.metaphor.com (Bob Alexander) Message-Id: <9110211947.AA08288@laguna.Metaphor.COM> To: icon-group@cs.arizona.edu Subject: Making a two-liner into one Here's a proposed improvement on one of Ralph's almost-one-liners (trying to recall the exact text -- I deleted the message): write(s := &input) ---> every write(s ~===:= !&input) every write(s ~==:= !&input) I haven't tested it -- too lazy -- but I think this version is slightly more equal than its predecessor (pun intended). Here's a one-liner I use occasionally to see exactly what is being passed to commands: procedure main(arg) every write(image(!arg)) end -- Bob Alexander Metaphor Computer Systems (415) 961-3600 x751 alex@metaphor.com ====^=== Mountain View, CA ...{uunet}!{decwrl,apple}!metaphor!alex From iwtqg!nowlin@att.att.com Mon Oct 21 13:34:57 1991 Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Mon, 21 Oct 91 13:34:57 MST Message-Id: <9110212034.AA01023@optima.cs.arizona.edu> Received: from att.att.com by optima.cs.arizona.edu (4.1/15) id AA01023; Mon, 21 Oct 91 13:34:54 MST From: iwtqg!nowlin@att.att.com Date: Mon, 21 Oct 91 15:31 CDT To: att!cs.arizona.edu!icon-group Subject: Re: Icon one-liners If you get right down to it and parse an awk script with the kind of syntactical breaks that are typically used for procedural languages like Icon you don't really have one-liners. For example, the one-liners I compared earlier could reasonably be written like this: nawk ' { print $0 "\r" } ' procedure main() ; while write(read(),"\r") ; end or like this: nawk ' { print $0 "\r" } ' procedure main() while write(read(),"\r") end Which uses more lines or characters isn't as important as which one a naive user can grasp without a manual or tutorial. Guess which one gets my vote? Jerry Nowlin From kwalker Mon Oct 21 14:26:50 1991 Received: from gacham.cs.arizona.edu by cheltenham.cs.arizona.edu; Mon, 21 Oct 91 14:26:50 MST Date: Mon, 21 Oct 91 14:26:48 MST From: "Kenneth Walker" Message-Id: <9110212126.AA04784@gacham.cs.arizona.edu> Received: by gacham.cs.arizona.edu; Mon, 21 Oct 91 14:26:48 MST In-Reply-To: <911020.015433.EDT.AL302723@VMTECCHI> To: icon-group Subject: Re: Icon compiler status... > Date: Sun, 20 Oct 91 01:54:33 EDT > From: "Mario Camou R." > > I've been offline for a while (almost a year now). What's the state of the > Icon compiler? Has it been ported to MS-DOS? There is a "pre-release" Unix version of the compiler at about V7.6 of Icon. We have in-house a V8.? version that still needs some work before a public release. Some work has been done under MS-DOS, but the compiler uses a lot of memory. It probably will not be useful on a 640K machine. We think it will be usable on a 386/486 machine in conjunction with a C compiler that has built-in DOS extender. Such a version of the compiler will not be available for a while though. 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 TENAGLIA@mis.mcw.edu Mon Oct 21 14:43:46 1991 Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Mon, 21 Oct 91 14:43:46 MST Received: from mis3.mis.mcw.edu by optima.cs.arizona.edu (4.1/15) id AA04425; Mon, 21 Oct 91 14:43:40 MST Received: from mis.mcw.edu by mis.mcw.edu (PMDF #12252) id <01GC0JH3HOV491VW6Q@mis.mcw.edu>; Mon, 21 Oct 1991 16:45 CST Date: Mon, 21 Oct 1991 16:45 CST From: Chris Tenaglia - 257-8765 Subject: One liners To: icon-group@cs.arizona.edu Message-Id: <01GC0JH3HOV491VW6Q@mis.mcw.edu> X-Organization: Medical College of Wisconsin (Milwaukee, WI) X-Vms-To: IN%"icon-group@cs.arizona.edu" I don't think this could really be considered a one liner, but I have a program I call Igrep/Iawk. | | | +---> icon awk : munge using icon expressions +---------> icon grep : scan using icon expressions They really don't try to emulate awk or grep, but offer an icon substitute, and actually they are the same program. Usage : igrep infile iawk infile outfile When invoked it requests icon expressions which it uses to write, compile, and run another icon program. Whatever is returned is output. There are a nice collection of global variables, and added procedures that I always use. Example 1. return trim(line) #will trim trailing spaces off all the lines in the file Example 2. return right(num,8) || " : " || line #will number all the lines in a file While these are not technically 'one liners' in that they are inserted into another program, they do offer the 'one liner' feeling, and I find it very useful for 'throw away' one time only code. It cleans up all the temporary files when done so I don't get confused by having dozens of discarded tool fragments left over either. 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@MTS.cc.Wayne.edu Mon Oct 21 15:33:31 1991 Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Mon, 21 Oct 91 15:33:31 MST Received: from mailrus.cc.umich.edu by optima.cs.arizona.edu (4.1/15) id AA06653; Mon, 21 Oct 91 15:33:26 MST Received: from um.cc.umich.edu by mailrus.cc.umich.edu (5.61/1123-1.0) id AA09408; Mon, 21 Oct 91 18:29:41 -0400 Received: from MTS.cc.Wayne.edu by um.cc.umich.edu via MTS-Net; Mon, 21 Oct 91 18:32:43 EDT Date: Mon, 21 Oct 91 18:32:10 EDT From: Paul_Abrahams@mts.cc.wayne.edu To: icon-group@cs.arizona.edu Message-Id: <376475@MTS.cc.Wayne.edu> Subject: One-liners Has anyone thought of creating a wrapper for Icon so that you could write something like: iconz 'expr' and cause expr to be executed? The wrapper would: (1) surround expr with procedure(arg)...end (2) call the translator and interpreter That would help to equalize the startup costs of Icon and awk. Of course I wouldn't expect the wrapper to be system-independent. Paul Abrahams abrahams@mts.cc.wayne.edu From ralph Mon Oct 21 16:10:56 1991 Date: Mon, 21 Oct 91 16:10:56 MST From: "Ralph Griswold" Message-Id: <9110212310.AA15609@cheltenham.cs.arizona.edu> Received: by cheltenham.cs.arizona.edu; Mon, 21 Oct 91 16:10:56 MST To: Paul_Abrahams@mts.cc.wayne.edu, icon-group@cs.arizona.edu Subject: Re: One-liners There's such a "wrapper" in the Icon program library -- it takes expressions as input, creates a program, and translates and executes it using system(). It works fine under UNIX on platforms that are fast enough to make the overhead insignificant in real time. Ralph Griswold / Department of Computer Science The University of Arizona / Tucson, AZ 85721 ralph@cs.arizona.edu / uunet!arizona!ralph voice: 602-621-6609 / fax: 602-621-9618 From alex@laguna.metaphor.com Mon Oct 21 17:41:09 1991 Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Mon, 21 Oct 91 17:41:09 MST Received: from relay.metaphor.com by optima.cs.arizona.edu (4.1/15) id AA00233; Mon, 21 Oct 91 17:14:13 MST Received: from laguna.Metaphor.COM by relay.metaphor.com (4.1/SMI-4.1) id AA00530; Mon, 21 Oct 91 17:13:18 PDT Received: by laguna.Metaphor.COM (4.1/SMI-4.0) id AA08868; Mon, 21 Oct 91 17:14:10 PDT Date: Mon, 21 Oct 91 17:14:10 PDT From: alex@laguna.metaphor.com (Bob Alexander) Message-Id: <9110220014.AA08868@laguna.Metaphor.COM> To: icon-group@cs.arizona.edu Subject: Re: One-liners Here's how I do one-liners. This method accepts an Icon expression or a whole program on standard input (UNIX). I use it directly from shells or from within editors such as vi, emacs, or Sun textedit that allow filters to operate on selected text. Using standard input instead of the command line is more convenient since most Icon programs would require that many characters be escaped. I have a similar program for Macontosh Programmer's Workshop which allows selection of text with themouse and execution as an Icon expression/program by menu command or command-key, sort of like Smalltalk. Probably the most frequent use to which I put this is to enter a simple one-liner to see how Icon behaves in certain situations. Or maybe to see how a terminal prints all possible characters: every write(!&cset[33:0])) It's done with an Icon program (iconprog.icn) -- the comments explain it fairly well: -------------------------------------------------------------- # # Filter to facilitate execution of Icon expressions and programs from # within command shells and editors. # # The program checks whether its input stream is an Icon *program*; # i.e. the first token is "procedure" | "link" | "record" | "global". # # If it is a program, it is passed unchanged. If it is not a program, # it is assumed to be an expression, and is encapsulated within the # following program skeleton: # # procedure main() # every write(image({ # --- your expression --- # })) # end # # The following UNIX shell script (Bourne shell) accepts Icon text from # standard input and executes it as a program or an expression as # appropriate. # # # #!/bin/sh # # # # Run Icon program or expression from standard input # # # f=/tmp/Icon$$ # iconprog | icont -s -o $f $* - -x 2>&1 # rm -f $f # procedure main() local space,line,trailer space := ' \t\v\n\r\f' while line := "." ~== read() do line ? { tab(many(space)) if ="#" | pos(0) then write(line) else { if not (=("procedure" | "link" | "record" | "global") & any(space) | pos(0)) then { writes("procedure main(); every write(image({") trailer := "})); end" } write(line) break } } while write("." ~== read()) write(\trailer) end From gudeman Tue Oct 22 17:12:36 1991 Received: from orator.cs.arizona.edu by cheltenham.cs.arizona.edu; Tue, 22 Oct 91 17:12:36 MST Date: Tue, 22 Oct 91 17:12:34 MST From: "David Gudeman" Message-Id: <9110230012.AA00601@orator.cs.arizona.edu> Received: by orator.cs.arizona.edu; Tue, 22 Oct 91 17:12:34 MST To: icon-group Subject: one-liner builder Here is my solution to the problem of conveniently writting and running on-liners in Icon. It has the advantage of allowing you to specify a different input file for Icon (this is just in the shell-script), and it lets you write more complex programs than you probably want to write from the keyboard... Run the following shell script to produce two files, iprog and mkprog.icn. Then run 'icont mkprog' to create mkprog. See the header of iprog for (minimal) documentation. ================================================================ #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh 'iprog' <<'END_OF_FILE' X#!/bin/sh X# X# Usage: iprog [-i input-file] args* X# X# iprog reads an Icon program from standard input. All lines not X# inside a declaration are put into the procedure main(argv). Then X# the Icon program is translated and executed. If the first paramater X# is -i, then the following word is the name of the input file for the X# execution of the Icon program. All other args are put into argv, so X# that the nth arg is referenced in the Icon program as argv[n]. You X# can redirect stdout with '>' as usual, but if you redirect stdin X# with '<', then this is used as the source of the Icon program as X# well as the input to the Icon program. X f=/tmp/icontmp$$ mkprog >$f.icn if test $# = 0 then X icont -s $f -x elif test $1 = -i then X in=$2 X shift 2 X icont -s $f -x $* <$in else X icont -s $f -x $* fi END_OF_FILE if test 807 -ne `wc -c <'iprog'`; then echo shar: \"'iprog'\" unpacked with wrong size! fi chmod +x 'iprog' # end of 'iprog' fi if test -f 'mkprog.icn' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'mkprog.icn'\" else echo shar: Extracting \"'mkprog.icn'\" \(1355 characters\) sed "s/^X//" >'mkprog.icn' <<'END_OF_FILE' X# X# Run this program with X# X# iprog args X# X# where args are the arguments to the result program. Then start X# entering an Icon program. Procedure, global, link, and record X# declarations are collected an put out before main(). Then all the X# other lines are put in procedure main(argv) in the order in which X# they appeared. Access the nth argument with argv[n]. X# X# This program is meant to be run by the shell script 'iprog'. X global decls, exprs X procedure main() X local line X X decls := [] X exprs := [] X X while line := read() do line ? { X case tab(upto(&lcase)) & tab(many(&lcase)) of { X "procedure" : read_proc(line) X "link" : put(decls, line) X "record" : read_rec(line) X "global" : put(decls, line) X } | X put(exprs,line) X } X X every write(!decls) X write("procedure main(argv)") X every write(!exprs) X write("end") end X procedure read_proc(line) X X repeat { X put(decls,line) X if (line == "end") | X (match("end", line, *line - 2) & X any(' \t;}', line, *line - 3)) then { X put(decls,"") X return X } X line := read() | X stop("end-of-file inside a procedure declaration") X } end X procedure read_rec(line) X X repeat { X put(decls,line) X if find(")", line) then { X put(decls,"") X return X } X line := read() | X stop("end-of-file inside a record declaration") X } end END_OF_FILE if test 1355 -ne `wc -c <'mkprog.icn'`; then echo shar: \"'mkprog.icn'\" unpacked with wrong size! fi # end of 'mkprog.icn' fi echo shar: End of shell archive. exit 0 From icon-group-request@arizona.edu Wed Oct 23 19:58:07 1991 Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Wed, 23 Oct 91 19:58:07 MST Resent-From: icon-group-request@arizona.edu Received: from Arizona.edu (Maggie.Telcom.Arizona.EDU) by optima.cs.arizona.edu (4.1/15) id AA04576; Wed, 23 Oct 91 19:58:05 MST Received: from ucbvax.Berkeley.EDU by Arizona.edu with PMDF#10282; Wed, 23 Oct 1991 19:57 MST Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA18786; Wed, 23 Oct 91 19:43:53 -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: Wed, 23 Oct 1991 19:57 MST Date: 21 Oct 91 19:51:18 GMT From: agate!spool.mu.edu!munnari.oz.au!comp.vuw.ac.nz!waikato.ac.nz!aukuni.ac.nz!russell@ucbvax.berkeley.edu (Russell J Fulton;ccc032u) Subject: Comparisions of Perl, Rexx and Icon. Sender: icon-group-request@arizona.edu Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: Message-Id: <1991Oct21.195118.29345@ccu1.aukuni.ac.nz> X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.edu Organization: University of Auckland, New Zealand. I have read the recent discussions about Perl, Rexx and Icon with interest. I have, at different times used all 3 languages and have found all 3 very useful. Rather than try a comprehensive comparison I would like to focus on one or two point raised by others. (Sorry I can't acknowledge you since I am working from memory and do not have the original articles to hand.) As well as some purely personal reflections. One initial point I wish to make is that in *my* view both Rexx and Perl are specifically designed to interface directly with the operating system (or in the case of Rexx other programs as well eg. Xedit ). Icon was designed as general purpose programming language. This brings me to the issue of "UNIX and Perl". I use both Perl and Icon on UNIX now. Perl's access to most of the UNIX system calls makes it invaluable for programming system administration utilities or doing one off system jobs. Perl's regular expressions are usually quite adequate for matching filenames etc. and are easier to use than the much more powerful tools that Icon provides. These features combined with the find.pl package make writing disk management software a breeze. I also use Perl for jobs that I would have previously use C particularly for doing prototyping. As a general purpose programming language I prefer Icon. It is much leaner and cleaner than Perl, which I can only describe as baroque. There is one feature that Icon has over Perl in my experience. Both tables and arrays may contain items of arbitrary type in Icon but in Perl Associative arrays (Perl's tables) can only hold scalars. I have fallen over this several times in Perl and have ended up writing the job in Icon instead. As for Rexx, I used it for several year on an IBM VM system (we went to UNIX about 2 years ago so my view may be somewhat out of date) and my view of it is almost certainly coloured by the fact that it was such an enormous improvement over the EXEC (1 & 2) that we had before. I liked Rexx, it was reasonably simple and straight forward and had all the basic tool that one need to write simple scripts. What is lacked was any data structures. It did have some limited pattern matching. I know that IBM stripped some features out of the original implementation when they released. (I saw the manual for the pre release version that was running in the local IBM offices and was quite disappointed when I found that the features we missing in the official release.) If Rexx came out today for our UNIX system I would not bother with it I would much rather use Icon or Perl because their authors are dedicated to producing tools that are useful to people. Rexx is controlled by IBM which, contrary to popular belief, does not make computers or software, they make money and everything they do is influenced by this. Someone In marketing probably decided that the particular features in Rexx threatened some other IBM product and so out they went. As with most things it is a case of 'horses for courses'. Icon is great as a general purpose programming language. It is portable and has enough of an interface to the operating system for most purposes. Perl on the other hand is an excellent tool for the UNIX systems admin. It is also quite adequate as a general purpose programming language and in fact I tend to use it more than Icon because I am more familiar with it even though I prefer Icon as a language. If I had access to Icon, Perl and Rexx on the same system I probably would not bother with Rexx. The other two do more and do it better. If I had to choose one on a UNIX system then the choice would depend on my role. As a systems administrator I would choose Perl and as a general user I would choose Icon. Cheers, Russell. -- Russell Fulton, Computer Center, University of Auckland, New Zealand. From icon-group-request@arizona.edu Wed Oct 23 23:45:22 1991 Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Wed, 23 Oct 91 23:45:22 MST Resent-From: icon-group-request@arizona.edu Received: from Arizona.edu (Merlin.Telcom.Arizona.EDU) by optima.cs.arizona.edu (4.1/15) id AA11696; Wed, 23 Oct 91 23:45:20 MST Received: from ucbvax.Berkeley.EDU by Arizona.edu with PMDF#10282; Wed, 23 Oct 1991 23:44 MST Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA26039; Wed, 23 Oct 91 23:36:20 -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: Wed, 23 Oct 1991 23:45 MST Date: 21 Oct 91 20:04:24 GMT From: hsi!mlfarm!rosie!ron@uunet.uu.net (Ronald Florence) Subject: pipes.icn Sender: icon-group-request@arizona.edu Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: <1AFCE085202010C2@Arizona.edu> Message-Id: <1991Oct21.200424.28953@mlfarm.com> X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.edu Organization: Maple Lawn Farm, Stonington, CT Icon is remarkably portable, but I still find that features I assume are not present on all implementations. Pipes.icn is an effort at portability between systems with pipes and those without. Typical usages: procedure mail_errors() # code to gather errors in a list, which comes out something like: error_list := [ "You wrote it wrong.", "You screwed up the data.", "The presentation is unclear." ] # use pipeout() to write it to a comand, here "mail" to the author pipeout(error_list, "mail ron@mlfarm.com") end procedure list_dir() # the command to list a directory is system-dependent if find("UNIX", &features) then dir_cmd := "ls" else if find("MS-DOS", &features) then dir_cmd := "dir /w" else stop("Don't know how to list a directory on your system.") # use pipein to list the Icon source every write(pipein(dir_cmd ||" *.icn")) end Pipes.icn could use some error-trapping. We don't have an ms-dos machine to test it. Ronald Florence ron@mlfarm.com -----------------------------[pipes.icn]-------------------------- # pipes.icn # imitates pipes # ron@mlfarm.com, 21 Oct 1991 # # This is a modest effort at portability. Unix implementations of # Icon have the ability to read from and write to pipes. Pipeout() # and pipein() are an effort to duplicate this functionality for # systems without pipes, like ms-dos. Both functions could do with # some error-trapping, especially in the ms-dos versions. My # experience with the system function is that it returns 0 (success) # on ms-dos machines even when command.com cannot find the command, so # I'm at a loss how to trap errors. # write "what" (a list) to command "cmd" procedure pipeout(what, cmd) static real_pipes initial real_pipes := find("pipes", &features) p := (\real_pipes & open(cmd, "wp")) | open(tfn := tempname(), "w") every write(p, !what) if \real_pipes then return close(p) else { cmd ||:= " < " || tfn status := system(cmd) remove(tfn) return status } end # read from command "cmd" procedure pipein(cmd) static real_pipes initial real_pipes := find("pipes", &features) if \real_pipes then p := open(cmd ||" 2> /dev/null" , "rp") else { p := open(tfn := tempname(), "w") system(cmd || " > " || tfn) close(p) p := open(tfn) } suspend !p /real_pipes & remove(tfn) end # Richard Goerwitz's ever-useful generator. procedure tempname() every temp_name := "pipe." || right(1 to 999,3,"0") do { close(open(temp_name)) & next suspend \temp_name } end --------------------------------[eof]----------------------------- -- Ronald Florence ron@mlfarm.com From shack Thu Oct 24 23:07:50 1991 Received: from caslon.cs.arizona.edu by cheltenham.cs.arizona.edu; Thu, 24 Oct 91 23:07:50 MST Date: Thu, 24 Oct 91 23:07:48 -0700 From: "David Shackelford" Message-Id: <9110250607.AA09717@caslon.cs.arizona.edu> Received: by caslon.cs.arizona.edu; Thu, 24 Oct 91 23:07:48 -0700 To: icon-group Subject: Icon for OS/2 2.0 I have been trying to port Icon v8 to OS/2 version 2.0 (beta) and have managed to get it to compile without errors. The translator runs on .icn files and produces what seem to be reasonable .icx files, but when I try to run the interpreter it gives me an error message: System error at line 1 in once.icn unimplemented opcode: 7602243 (0x00740043) Given lots of time to work on the problem I might be able to puzzle this out, but my class load doesn't leave me a lot of time. Is there a simple explanation for what would cause this? I suspect it is a problem with my C compiler, which is MSC 6.? with 32-bit flat memory model. Where should I look to find the opcodes for .icx files? Thanks for your help/suggestions/comments/... Dave | shack@cs.arizona.edu From icon-group-request@arizona.edu Fri Oct 25 03:43:36 1991 Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Fri, 25 Oct 91 03:43:36 MST Resent-From: icon-group-request@arizona.edu Received: from Arizona.edu (Merlin.Telcom.Arizona.EDU) by optima.cs.arizona.edu (4.1/15) id AA13720; Fri, 25 Oct 91 03:43:33 MST Received: from ucbvax.Berkeley.EDU by Arizona.edu with PMDF#10282; Fri, 25 Oct 1991 03:43 MST Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA25372; Fri, 25 Oct 91 03:29:21 -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, 25 Oct 1991 03:43 MST Date: 22 Oct 91 16:43:11 GMT From: micro-heart-of-gold.mit.edu!wupost!uwm.edu!linac!convex!usenet@bloom-beacon.mit.edu (Tom Christiansen) Subject: RE: Comparisions of Perl, Rexx and Icon. Sender: icon-group-request@arizona.edu Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: <0570EF54562022BA@Arizona.edu> Message-Id: <1991Oct22.164311.24870@convex.com> X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.edu Organization: CONVEX Software Development, Richardson, TX References: <1991Oct21.195118.29345@ccu1.aukuni.ac.nz> From the keyboard of russell@ccu1.aukuni.ac.nz (Russell J Fulton;ccc032u): :Both tables and arrays may contain items of arbitrary type in Icon but in :Perl Associative arrays (Perl's tables) can only hold scalars. :I have fallen over this several times in Perl and have ended up :writing the job in Icon instead. If the truth be known, while it is indeed the case that arrays and tables in perl can only hold scalar values, there happens to be a special kind of scalar value you can use to circumvent this restriction. This special scalar is a reference to the symbol table (read: pointer). Using these, the determined program can synthesize arbitrarily complex data types. This is discussed in question number 17 of the perl FAQ. As it says there, however, you really have to want to do so badly, as it is notationally cumbersome at best. --tom From icon-group-request@arizona.edu Fri Oct 25 07:17:54 1991 Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Fri, 25 Oct 91 07:17:54 MST Resent-From: icon-group-request@arizona.edu Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by optima.cs.arizona.edu (4.1/15) id AA20250; Fri, 25 Oct 91 07:17:52 MST Received: from ucbvax.Berkeley.EDU by Arizona.edu with PMDF#10282; Fri, 25 Oct 1991 07:17 MST Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA02781; Fri, 25 Oct 91 07:06:33 -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, 25 Oct 1991 07:17 MST Date: 22 Oct 91 16:57:58 GMT From: agate!spool.mu.edu!caen!uvaarpa!murdoch!aemsun.med.virginia.edu!sdm7g@ucbvax.berkeley.edu (Steven D. Majewski) Subject: RE: REXX/Perl/Icon Sender: icon-group-request@arizona.edu Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: <2362428EF020E0A4@Arizona.edu> Message-Id: <1991Oct22.165758.3137@murdoch.acc.Virginia.EDU> X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.edu Organization: University of Virginia - Physiology Dept. References: <9110181432.AA06934@optima.cs.arizona.edu> In article <9110181432.AA06934@optima.cs.arizona.edu> nowlin@iwtqg.UUCP writes: > >I responded because of your assertion: > >> I know PERL is probably the language of choice on Unix systems because >> of its very complete interface to system & network functions, ... > >I'm glad you "know" that. I've been using Icon for over six years and >working on UNIX for a lot longer. I've found almost nothing that I >couldn't do in Icon because I needed a more complete interface to UNIX. >There are times I've been forced to use other languages for speed, times >that the bean counters have forced me to use one of the "supported" >languages, and times that Icon was not the appropriate language for the >job. The interface to UNIX has never been a limiting factor. The >pipe-open and system calls in Icon provide plenty of UNIX access and >flexibility. > > ... > ... > >I'm not presumptuous enough to say Icon is the "language of choice" for any >one group of programmers. Although I work on UNIX and it certainly is for >me :-) > >Jerry Nowlin By "Language of choice" I did not mean any qualitative judgement. I should have said "de facto LofCh". ( We all know de facto standards just happen to be a historically contingent choice :-) Qualitatively, I would judge ICON superior to PERL. It is more powerful and cleaner. I haven't done any extensive programming in either. ( I just downloaded and built the Icon interpreted yesterday! ) but from looking at both, I think I would choose ICON for any large project. De-Facto: PERL just happened to be the (almost) right think in the right place at the right time ( at the right price! ) and found a market. I don't have any statistics, but I would venture my opinion that it is more widely used than ICON. ( Again, no qualitative judgement implied: BASIC is more popular than both combined. ) I would be *HAPPY* to hear other-wise, but PERL seems to be ubiquitous in the unix world. ( It is installed on all of the University machines here at UVA. ). In fact the void it filled was for a "standard" ( and ubiquitous ) language to replace what was being done awkwardly with a combination of shell-scripts/awk/sed /et.al. ( Could have been worse: what if Unix had come bundled with BASIC :-o) The inclusion of interfaces to just about all of the unix utilities made PERL the "de facto language of choice" for sys-admin type tasks where that is a major part of the problem. ( Sure, you can use a generic "system" call or write some "glue" routines, but most of these types of jobs are done in a hurry by harried sys-admins - "quick and dirty" by definition. ) Larry Wall has admitted that there are things he would have done differently in PERL if he could start over. But I don't believe he was trying to design Yet-Another-Language, so much as get a job done. Ralph Griswold, on the other had, had quite a bit of experience with language design and implementation before he developed ICON. It shows. The language has spread from sys-admin tasks to more general purpose type programming. That, I would credit mostly to its availability. I would say that PERL is to AWK what ICON is to SNOBOL. Which is another reason for PERL's success: All unix programmers ( and some users ) are familiar with the Unix/awk/shell/grep style of regular expressions. Again, not a qualitative judgement, but familiarity breeds faster learning curves. BTW: Since the problem I described has a minimal "unix-interface" component, ICON will probably be *my* "language of choice" ! Sorry for the cross-posting, but I missed this thread 'cause I was looking for followups in comp.lang.misc. Maybe we can re-join these threads on languages for (mainly) string processing problems in comp.lang.misc ? ======== "If you have a hammer, find a nail" - George Bush,'91 ========= Steven D. Majewski University of Virginia Physiology Dept. sdm7g@Virginia.EDU Box 449 Health Sciences Center Voice: (804)-982-0831 1600 Jefferson Park Avenue FAX: (804)-982-1616 Charlottesville, VA 22908 From TENAGLIA@mis.mcw.edu Fri Oct 25 07:40:24 1991 Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Fri, 25 Oct 91 07:40:24 MST Received: from MIS3.MIS.MCW.EDU by optima.cs.arizona.edu (4.1/15) id AA20782; Fri, 25 Oct 91 07:40:21 MST Received: from mis.mcw.edu by mis.mcw.edu (PMDF #12252) id <01GC5PU8PMTS9AMENT@mis.mcw.edu>; Fri, 25 Oct 1991 09:41 CST Date: Fri, 25 Oct 1991 09:41 CST From: Chris Tenaglia - 257-8765 Subject: REXX,ICON,PERL To: icon-group@cs.arizona.edu Message-Id: <01GC5PU8PMTS9AMENT@mis.mcw.edu> X-Organization: Medical College of Wisconsin (Milwaukee, WI) X-Vms-To: IN%"icon-group@cs.arizona.edu" It sounds like PERL has made a solid foothold in unix sys admin. I guess I must have been the exception. At my prior position as both unix (sunos, xenix, & zsUnix) and vax/vms sys admin I used icon extensively as a tool builder. I hadn't even heard of perl. The thing I liked about icon was that it was easy to learn and use even though my language of choice had been BASIC at the time. I could never get the hang of C, Pascal, or Fortran with all their data types. I also liked it because as a sys admin for both unix and vms, and as a support person for PCs I liked a tool that was consistent and available for all worlds. Chris Tenaglia (System Manager) | "The past explained, Medical College of Wisconsin | the future fortold, 8701 W. Watertown Plank Rd. | the present largely appologized for." Milwaukee, WI 53226 | Organon to The Doctor (414)257-8765 | tenaglia@mis.mcw.edu, mcwmis!tenaglia From icon-group-request@arizona.edu Fri Oct 25 09:02:07 1991 Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Fri, 25 Oct 91 09:02:07 MST Resent-From: icon-group-request@arizona.edu Received: from Arizona.edu (Hopey.Telcom.Arizona.EDU) by optima.cs.arizona.edu (4.1/15) id AA23592; Fri, 25 Oct 91 09:02:04 MST Received: from ucbvax.Berkeley.EDU by Arizona.edu with PMDF#10282; Fri, 25 Oct 1991 09:01 MST Received: by ucbvax.Berkeley.EDU (5.63/1.42) id AA06817; Fri, 25 Oct 91 08:51:59 -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, 25 Oct 1991 09:01 MST Date: 22 Oct 91 18:50:36 GMT From: dog.ee.lbl.gov!pasteur!agate!spool.mu.edu!uwm.edu!mrsvr.UUCP!hewitt@ucbvax.berkeley.edu (Anthony V. Hewitt) Subject: Makefiles for Icon Sender: icon-group-request@arizona.edu Resent-To: icon-group@cs.arizona.edu To: icon-group@arizona.edu Resent-Message-Id: <31EF2F90B6201935@Arizona.edu> Message-Id: X-Envelope-To: icon-group@CS.Arizona.EDU X-Vms-To: icon-group@Arizona.edu Organization: GE Medical Systems, Milwaukee, WI I've been finding it awkward to manage my icon programs even with make; there are many targets in my ~/icon directory and it's hard to be sure that the makefile is up to date (particularly when I get lazy). This is not very fancy Icon but I've found it automates the process quite nicely; it assumes that you have make. If you're not running Unix, I can only tell you that there are versions of make available for DOS and VMS (Borland and Microsoft bundle one with their DOS C compilers, I think). What follows four files: newsuffixes.icn, icondepend.icn and the makefiles for the program directory and the procedures directory. I don't expect this to trash your source but just the same it would be prudent to have a current backup copy before you do this for the first time. You should start in your prog directory by using icont on the two .icn files and then "make clobber", then "make". In the progs makefile, you may well have to change the definition of PROCSDIR, which currently assumes that procs is a subdirectory of progs (not true for the Icon Programmers Library, for example). If you're using the Icon compiler, you'll have to make some changes to icondepend - it would be cleanest to make it refer to a macro in make, say "$(ICONT"), rather than hardwire the string "icont". ############################################################################ # # Name: newsuffixes.icn # # Title: Replace filename suffixes # # Author: Anthony V. Hewitt # # Date: August 21, 1991 # ############################################################################ # Take a list of filenames, one per line, and output them with new suffixes # The first arg is the old suffix; each new suffix outputs a line for each # file that has a suffix matching the old suffix. # if the input to "newsuffixes .icn .u1 .u2" is "foo.icn\nbar.junk", # the output is # foo.u1 # foo.u2 # The application I had in mind was to put at the top of the procs makefile: # all: # make `ls *.icn | newsuffixes .icn .u1 .u2` # This removes one source of error from the makefile, since in no longer needs # a complete list of .u[12] files as dependencies for "all" # If the find fails, nothing is output. This is intentional, but one # could argue that it would be more useful to pass such a filename # unmodified. # Note that new suffixes may have the value ''; e.g. in the progs makefile, # all: # make `ls *.icn | newsuffixes .icn ''` # Old suffixes may not have the value '', since that case seems to have no # useful interpretation. procedure main(args) (*args > 1) | stop("syntax newsuffixes old new [new . . .]") (*(oldsuffix := pop(args)) > 0) | stop("zero-length old suffix is not meaningful") every write(|read() ? tab(find(oldsuffix)), !args) end ********************************************************************** ############################################################################ # # Name: icondepend.icn # # Title: Parse an icon source to produce a make rule # # Author: Anthony V. Hewitt # # Date: September 11, 1991 # ############################################################################ # args are the filenames of the targets to be processed; # standard input is a newline-separated list of the filenames # (including the path) of the dependency candidates. # Usage: # Typically: # ls [./*.icn] procsdir/*.icn [procsdir1/*.icn...] | # newsuffixes .icn .u1 | # icondepend foo [...] # writes to the standard output make-format dependencies for foo # e.g if foo.icn contains a statement "link a, b" # with a.icn and b.icn present in procsdir, the output of icondepend is # foo: foo.icn procsdir/a.u1 procsdir/b.u1 # icont $(ICONFLAGS) foo.icn # In a makefile # %: %.icn FORCE # ls $(PROCSDIR)/*.icn | newsuffixes .icn .u1 | icondepend $@ >>makerules # $(MAKE) $@ # will create, if necessary, a rule for a target that has # a corresponding icon source file. # It is assumed that good practice guarantees that each filename is unique # in the list of dependencies (though not necessarily in IPATH) # even though there may be multiple directories. # It is also assumed that the link statements do not include hardcoded paths, # since this makes nonportable code. procedure main(args) library := table() words := &ascii -- '\t ,"' every s := |read() do library[reverse(reverse(s) ? tab(upto('/')))] := s every target := !args do { source := open(sourcename := (target ? tab(upto('.') | 0) || ".icn")) s := "" every t := (getline(source) ? (tab(match("link")), tab(0))) do { if *t = 0 then t := "," # a hack, I admit s ||:= t while (s[-1] == ",") do s ||:= getline(source) } writes(target, ": ", sourcename) s ? { while tab(upto(words)) do { t := tab(many(words)) every writes(" ",\library[t || (".u1" | ".u2")]) } } write("\n\ticont $(ICONFLAGS) ",sourcename) } end procedure getline(source) while (s := (trim(|read(source)) ? tab(upto('#')|0))) do (*s > 0, suspend reverse(trim(reverse(s)))) end ********************************************************************** # Makefile for Icon programs PROCSDIR = ./procs # Let's be safe .SUFFIXES: all: $(MAKE) `ls *.icn | newsuffixes .icn ''` %.u1: FORCE cd $(@D) ; $(MAKE) $(@F) $(*F).u2 %: %.icn FORCE ls $(PROCSDIR)/*.icn | newsuffixes .icn .u1 | icondepend $@ >>makerules $(MAKE) $@ FORCE: include makerules clean: cd $(PROCSDIR); $(MAKE) clobber clobber: clean -mv newsuffixes $(HOME)/bin -mv icondepend $(HOME)/bin -$(RM) makerules touch makerules -$(RM) `ls *.icn | newsuffixes .icn ''` ********************************************************************** # Makefile for Icon procedures ICONFLAGS = -uc # Let's be safe .SUFFIXES: all: $(MAKE) `ls *.icn | newsuffixes .icn .u1 .u2` %.u1 %.u2: %.icn FORCE ls ./*.icn | newsuffixes .icn .u1 .u2 | icondepend $@ >>makerules $(MAKE) $@ FORCE: include makerules clobber: -$(RM) makerules touch makerules -$(RM) *.u1 *.u2 -- ------------------------------------------------------------------------------ Anthony V. Hewitt Phone 414 548-5170 (GE Dialcom 8*320-5170) Senior Physicist General Electric Company Fax 414 548-5197 (8*320-5197) P.O.Box 414, W-641 Milwaukee, WI 53201 Internet: hewitta@aslpet.med.ge.com ------------------------------------------------------------------------------ From whm@sunquest.com Fri Oct 25 11:28:26 1991 Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Fri, 25 Oct 91 11:28:26 MST Received: from ALPHA.SUNQUEST.COM by optima.cs.arizona.edu (4.1/15) id AA29544; Fri, 25 Oct 91 11:28:16 MST Received: from sunquest.sunquest.com by ALPHA.SUNQUEST.COM with SMTP; Fri, 25 Oct 1991 11:28:10 -0700 (MST) Received: by sunquest.sunquest.com (4.1/SMI-4.1) id AA22221; Fri, 25 Oct 91 11:28:24 MST Date: Fri, 25 Oct 91 11:28:24 MST From: whm@sunquest.com (Bill Mitchell) Message-Id: <9110251828.AA22221@sunquest.sunquest.com> To: icon-group@cs.arizona.edu Subject: perl I watched perl from a distance for quite a while and then figuring that there must be something to it, I read part one of a three-part series on it in Unix/World or Unix Review. Actually, it was more like the first two-thirds of part one because I got disgusted and quit. It seemed like there were just too many special cases and irregularities. I got the feeling that I'd have to be constantly thumbing through the O'Reilly book whenever I wrote a program. I suppose I'll end up learning perl sooner or later, but I've been largely able to avoid serious shell programming by using Icon instead, so maybe I'll be able to avoid perl as well. Maybe what we need is an Idol framework for doing shell script type stuff. -------------------------------------------------------------------- Bill Mitchell whm@sunquest.com Sunquest Information Systems sunquest!whm@arizona.edu 930 N. Finance Center Dr. {arizona,uunet}!sunquest!whm Tucson, AZ, 85710 sunquest!whm@uunet.uu.net 602-885-7700 From mitch@rock.csd.sgi.com Fri Oct 25 14:02:23 1991 Received: from optima.cs.arizona.edu by cheltenham.cs.arizona.edu; Fri, 25 Oct 91 14:02:23 MST Received: from sgi.sgi.com (SGI.COM) by optima.cs.arizona.edu (4.1/15) id AA05931; Fri, 25 Oct 91 14:02:21 MST Received: from rock.csd.sgi.com by sgi.sgi.com via SMTP (911016.SGI/910110.SGI) for icon-group@cs.arizona.edu id AA24292; Fri, 25 Oct 91 13:48:04 -0700 Received: by rock.csd.sgi.com (911016.SGI/910805.SGI) for @sgi.sgi.com:icon-group@cs.arizona.edu id AA12133; Fri, 25 Oct 91 13:48:00 -0700 Date: Fri, 25 Oct 91 13:48:00 -0700 From: mitch@rock.csd.sgi.com (Tom Mitchell) Message-Id: <9110252048.AA12133@rock.csd.sgi.com> To: icon-group@cs.arizona.edu In-Reply-To: Bill Mitchell's message of Fri, 25 Oct 91 11:28:24 MST <9110251828.AA22221@sunquest.sunquest.com> Subject: perl Date: Fri, 25 Oct 91 11:28:24 MST From: whm@sunquest.com (Bill Mitchell) I watched perl from a distance for quite a while and then figuring that there must be something to it,..... Actually, it was more like the first two-thirds of part one because I got disgusted and quit. It seemed like there were just too many special cases and irregularities. I got the feeling that I'd have to be constantly thumbing through the O'Reilly book whenever I wrote a program. Bill's observations have a lot of value. Perl is full of irregularities because it is a collection of functionality from at least five different tools. In the man page Larry Wall says: "It combines (in the author's opinion, anyway) some of the best features of C, sed, awk, and sh, so people familiar with those languages should have little difficulty with it. (Language historians will also notesome vestiges of csh, Pascal, and even BASIC-PLUS.)" Most unix tools are built with any of the set of tools in a standard Unix. Perl avoids bouncing from tool to tool by including the functionality withing the language. It is the rare unix shell (sh) novice that understands that "[" is a link to /bin/test and that 'sh' cannot test for the simplest things. Nor can 'sh' do arithmetic on strings. Again 'sh' programs must invoke an external utility 'expr' to do arithmetic and arithmetic comparisons on the strings shell understands. This is the same corner that modern 'elegent' languages (Modula II) found themselves in when users discovered that no 'standard' library of tools/functions is available. You want to use the language, but there is no foundation tool set to begin with. Larry avoided this functionality library problem by rolling all things in to the language and his library. Thumbing through the O'Reiley book is a tad simpler than fumbling through a stack of disjoint unix man pages because the book is unified in its table of contents and index. From the Unix users side, perl is a simplification. From the language designer side it is a tad grungy. Hmmm... what if perl had 'generators' :-)