home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.cs.arizona.edu
/
ftp.cs.arizona.edu.tar
/
ftp.cs.arizona.edu
/
icon
/
newsgrp
/
group91c.txt
< prev
next >
Wrap
Internet Message Format
|
1991-10-25
|
456KB
From ralph Thu Jun 13 12:10:02 1991
Date: Thu, 13 Jun 91 12:10:02 MST
From: "Ralph Griswold" <ralph>
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: <E0973FC608202EC0@Arizona.edu>
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: <E9800F2ACC801412@Arizona.edu>
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: <k7p5qcINNs2f@iraun1.ira.uka.de>
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: <k7p5qcINNs2f@iraun1.ira.uka.de>
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: <k7uh36INNi8u@iraun1.ira.uka.de>
X-Envelope-To: icon-group@CS.Arizona.EDU
X-Vms-To: icon-group@Arizona.edu
Organization: University of Karlsruhe, FRG
References: <k7p5qcINNs2f@iraun1.ira.uka.de>,
<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: <A374EBC40E804602@Arizona.edu>
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: <C02455424060CE3A@Arizona.edu>
Message-Id: <167724@felix.UUCP>
X-Envelope-To: icon-group@CS.Arizona.EDU
X-Vms-To: icon-group@Arizona.edu
References: <k7p5qcINNs2f@iraun1.ira.uka.de>
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: <C8CD9AB80060D283@Arizona.edu>
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: <k7uh36INNi8u@iraun1.ira.uka.de>
X-Envelope-To: icon-group@CS.Arizona.EDU
X-Vms-To: icon-group@Arizona.edu
Organization: University of Karlsruhe, FRG
References: <k7p5qcINNs2f@iraun1.ira.uka.de>,
<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: <wgg@cs.washington.edu>
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: <F41042AF4A80A0B1@Arizona.edu>
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 <tim@ksr.com>
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 <grin>).
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 <grin>. 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 <grin>.
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: <BFFCBF5ADA200AB9@Arizona.edu>
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<grin>-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<grin>-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" <gmt>
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 <gmt@cs.arizona.edu>
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: <FB0209F044001EA7@Arizona.edu>
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 <pmoore@cix.compulink.co.uk> 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 <grin>):
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 <grin>.
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" <kwalker>
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 <tim@ksr.com>
>
>...
> 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" <kwalker>
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 <tim@ksr.com>
>
> 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 <tim@ksr.com>
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 <grin> 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 <grin>), 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 <grin>, 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 <grin>.
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 <grin>, 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 <grin>.
> 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 <smile> ...
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 <grin>.
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: <E7D4885BBCC00213@Arizona.edu>
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 <tim@ksr.com>
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 <grin>)
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" <grin>), 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 <tim@ksr.com>
> [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<grin>-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 <LSADENIEMI@cc.helsinki.fi>
Subject: Icon Version 8 for VMS
To: icon-group@cs.arizona.edu, LSADENIE@kruuna.helsinki.fi
Message-Id: <B051EE544028AE45@hylk.Helsinki.FI>
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 <grin>. 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 <grin>? 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: <B2714998064050A3@Arizona.edu>
Message-Id: <HAROLDT.91Aug28130249@paralandra.yorku.ca>
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 <TENAGLIA@mis.mcw.edu>
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" <cheyenne>
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: <kcl2n5INNb47@iraun1.ira.uka.de>
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" <ralph>
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: <D7FD9FD442C002B1@Arizona.edu>
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: <A4FBB11ED2A01AC0@Arizona.edu>
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: <PANNAIYA.91Sep18175706@chama.nmsu.edu>
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" <ralph>
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 <ralph@cs.arizona.edu>
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.91Sep18175706@chama.nmsu.edu>
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: <BC1012F4C6A0BEB7@Arizona.edu>
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 <return>.
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: <E7C7EFD02EC0E391@Arizona.edu>
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: <J1Lq02w164w@ersys.edmonton.ab.ca>
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: <A3EA97D95AA09C1A@Arizona.edu>
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" <cjeffery>
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" <cjeffery@cs.arizona.edu>
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: <AF1AD8990022361F@Arizona.edu>
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: <A1875850B4A0F8BF@Arizona.edu>
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" <cjeffery>
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" <cjeffery@cs.arizona.edu>
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: <C479DD2734A10ABD@Arizona.edu>
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: <PNH.91Oct16155135@pmin24.osf.org>
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: <icon-group-sender@cs.arizona.edu>
> 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: <E198C3D4FC6051A9@Arizona.edu>
> Message-Id: <BEVAN.91Mar29162211@panda.cs.man.ac.uk>
> 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 $<digit>
> 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: <F753F423EEA046A3@Arizona.edu>
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." <AL302723@VMTECCHI.BITNET>
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
<EOF>
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" <ralph>
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" <ralph>
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" <kwalker>
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." <AL302723@VMTECCHI.BITNET>
>
> 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 <TENAGLIA@mis.mcw.edu>
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" <ralph>
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" <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 <file", e.g.. If this archive is complete, you
# will see the following message at the end:
# "End of shell archive."
# Contents: iprog mkprog.icn
# Wrapped by gudeman@orator on Tue Oct 22 17:08:55 1991
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'iprog' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'iprog'\"
else
echo shar: Extracting \"'iprog'\" \(807 characters\)
sed "s/^X//" >'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: <FB3B30DFC0801643@Arizona.edu>
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.
<rj_fulton@aukuni.ac.nz>
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" <shack>
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 <TENAGLIA@mis.mcw.edu>
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: <HEWITT.91Oct22135036@argus.gemed.com>
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' :-)