link abkform
May 2, 2001; Robert J. Alexander
See also: bkutil.icn, pbkform.icn
This file is in the public domain.
Procedures set to read and write HP95LX appointment book (.abk) files. Notes: 1. Files created by the Appointment Book application may contain some padding following the last field of some data records. Hence, the RecordLength field must be used to determine the start of the next record. Appointment book files created by other programs need not have any padding. 2. ApptState has several bit fields. Only bit 0 is meaningful to software processing an appointment book file. Bit 0 being set or cleared corresponds to the alarm being enabled or disabled, respectively. Programs creating Appointment book files should clear all bits, except perhaps bit 0. 3. ToDoState has two one-bit bit fields. Bit 0 being set or cleared corresponds to carry forward being enabled or disabled for this todo item, respectively. Bit 1 being set or cleared corresponds to the doto being checked off or not checked off, respectively. 4. Appointment and ToDo texts are each limited to a maximum of 27 characters. 5. Note text is limited to a maximum of 11 lines of 39 characters per line (not counting the line terminator).
[ Summary entry | Source code ]
procedure Set_OS: set global OS features procedure Basename: obtain base filename procedure Pathname: obtain path of filename procedure getidxname: obtain index from datafile name procedure Strip: remove chars from string
link adjuncts
June 21, 2000; Richard L. Goerwitz
See also: gettext.icn, idxtext,icn
This file is in the public domain.
Pretty mundane stuff. Set_OS(), Basename(), Pathname(), Strip(), and a utility for creating index filenames.
[ Summary entry | Source code ]
link adlutils
January 3, 1994; Ralph E. Griswold
This file is in the public domain.
Procedures used by programs that process address lists: nextadd() get next address writeadd(add) write address get_country(add) get country get_state(add) get state (U.S. addresses only) get_city(add) get city (U.S. addresses only) get_zipcode(add) get ZIP code (U.S. addresses only) get_lastname(add) get last name get_namepfx(add) get name prefix get_title(add) get name title format_country(s) format country name
[ Summary entry | Source code ]
link allof
April 28, 1990; Robert J. Alexander
Requires: co-expressions
This file is in the public domain.
allof{expr1,expr2} -- Control operation that performs iterative conjunction. Iterative conjunction permits a conjunction expression to be built at run time which supports full backtracking among the created terms of the expression. The computed expression can be of arbitrary length, and is built via an iterative loop in which one term is appended to the expression (as if connected with a "&" operator) per iteration. Expr1 works like the control expression of "every-do"; it controls iteration by being resumed to produce all of its possible results. The allof{} expression produces the outcome of conjunction of all of the resulting instances of expr2. For example: global c ... pattern := "ab*" "abcdef" ? { allof { c := !pattern , if c == "*" then move(0 to *&subject - &pos + 1) else =c } & pos(0) } This example will perform a wild card match on "abcdef" against pattern "ab*", where "*" in a pattern matches 0 or more characters. Since pos(0) will fail the first time it is evaluated, the allof{} expression will be resumed just as a conjunction expression would, and backtracking will propagate through all of the instances of expr2; the expression will ultimately succeed (as its conjunctive equivalent would). Note that, due to the scope of variables in co-expressions, variables shared between expr1 and expr2 must have global scope, hence c in the above example must be global. The allof{} procedure models Icon's expression evaluation mechanism in that it explicitly performs backtracking. The author of this procedure knows of no way to invoke Icon's built-in goal directed evaluation to perform conjunction of a arbitrary number of computed expressions (suggestions welcome).
[ Summary entry | Source code ]
link allpat
May 14, 1996; Ralph E. Griswold
Requires:
This file is in the public domain.
[ Summary entry | Source code ]
link ansi
August 14, 1996; Ralph E. Griswold and Richard Goerwitz
This file is in the public domain.
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).
[ Summary entry | Source code ]
link apply
March 4, 1995; Ralph E. Griswold
This file is in the public domain.
This procedure applies a list of functions to an argument. An example is apply([integer, log], 10) which is equivalent to integer(log(10)).
[ Summary entry | Source code ]
link argparse
November 14, 1991; Ralph E. Griswold
This file is in the public domain.
argparse(s) parses s as if it were a command line and puts the components in in a list, which is returned. At present, it does not accept any escape conventions.
[ Summary entry | Source code ]
link array
April 30, 1993; Ralph E. Griswold
This file is in the public domain.
create_array([lbs], [ubs], value) creates a n-dimensional array with the specified lower bounds, upper bounds, and with each array element having the specified initial value. ref_array(A, i1, i2, ...) references the i1-th i2-th ... element of A.
[ Summary entry | Source code ]
link asciinam
August 14, 1996; Robert J. Alexander
This file is in the public domain.
asciiname(s) returns the mnemonic name of the single unprintable ASCII character s.
[ Summary entry | Source code ]
procedure base64encode: encode a string into base 64 (MIME) procedure base64decode: decode a string from base 64 (MIME)
link base64
May 2, 2001; David A. Gamey
This file is in the public domain.
Descriptions: base64encode( s1 ) : s2 returns the base64 encoding of a string s1 base64decode( s1 ) : s2 returns the base64 decoding of a string s1 fails if s1 isn't base64 encoded references: MIME encoding Internet RFC 2045
[ Summary entry | Source code ]
procedure basename: base name of file
link basename
September 22, 1998; Ralph E. Griswold
Contributor: Charles Shartsis
This file is in the public domain.
This procedure is based on the UNIX basename(1) utility. It strips off any path information and removes the specified suffix, if present. If no suffix is provided, the portion of the name up to the first "." is returned. It should work under UNIX, MS-DOS, and the Macintosh.
[ Summary entry | Source code ]
procedure pack: pack values into a string procedure unpack: unpack values from string
link binary
August 14, 1996; Robert J. Alexander
This file is in the public domain.
This is a collection of procedures that support conversion of Icon data elements to and from binary data formats. The purpose is to facilitate dealing with binary data files. The procedures can be used individually or via the "control" procedures pack() and unpack(). ____________________________________________________________ The individual conversion functions are prefixed by either "pack_" or "unpack_" and are identified in comments by their format character(s). The "pack_" procedures convert from Icon to binary and take a single argument: the value to be converted. The "unpack_" procedures convert from binary to Icon and usually take no parameters -- they are executed within a string-scanning context and scan the necessary amount from the &subject string. Some of the "unpack_" functions take a parameter that specifies the length of the output string. The individual conversion procedures are minimally commented, but their action is apparent from their procedure names and the documentation of the pack() and unpack() procedures. The control procedures pack() and unpack() take a format string that controls conversions of several values (similar to the "printf" C library function). pack() and unpack() are patterned after the Perl (programming language) functions of the same names, and are documented below. pack(template,value1,...) : packed_binary_string ------------------------------------------------ This procedure packs the "values" into a binary structure, returning the string containing the structure. The elements of any lists in the "value" parameters are processed individually as if they were "spliced" into the "value" parameter list. The "template" is a sequence of characters that give the order and type of values, as follows" (using C language terminology): a An ascii string, will be null padded (unstripped for unpack()). A An ascii string, will be space padded (trailing nulls and spaces will be stripped for unpack()). b A bit string, low-to-high order. B A bit string, high-to-low order. h A hexadecimal string, low-nybble-first. H A hexadecimal string, high-nybble-first. c A signed char value. C An unsigned char value. s A signed short value. S An unsigned short value. i A signed int value. I An unsigned int value. l A signed long value. L An unsigned long value. n A short in "network" order (big-endian). N A long in "network" order (big-endian). v A short in "vax" order (little-endian). V A long in "vax" order (little-endian). f A single-precision float in IEEE Motorola format. d A double-precision float in IEEE Motorola format. e An extended-precision float in IEEE Motorola format 80-bit. E An extended-precision float in IEEE Motorola format 96-bit. x Skip forward a byte (null-fill for pack()). X Back up a byte. @ Go to absolute position (null-fill if necessary for pack()). u A uu-encoded/decoded string. Each letter may optionally be followed by a number which gives a count. Together the letter and the count make a field specifier. Letters and numbers can be separated by white space which will be ignored. Types A, a, B, b, H, and h consume one value from the "value" list and produce a string of the length given as the field-specifier-count. The other types consume "field-specifier-count" values from the "value" list and append the appropriate data to the packed string. unpack(template,string) : value_list ------------------------------------ This procedure does the reverse of pack(): it takes a string representing a structure and expands it out into a list of values. The template has mostly the same format as for pack() -- see pack(), above. Endianicity of integers ----------------------- Integer values can be packed and unpacked in either big-endian (Motorola) or little-endian (Intel) order. The default is big-endian. Procedures pack_little_endian() and pack_big_endian() set the mode for future packs and unpacks. Size of ints ------------ The "i" (signed int) and "I" (unsigned int) types can pack and unpack either 16-bit or 32-bit values. 32-bit is the default. Procedures pack_int_as_short() and pack_int_as_long() change the mode for future packs and unpacks.
[ Summary entry | Source code ]
link bincvt
October 16, 1996; Robert J. Alexander
This file is in the public domain.
unsigned() -- Converts binary byte string into unsigned integer. Detects overflow if number is too large. This procedure is normally used for processing of binary data read from a file. raw() -- Puts raw bits of characters of string s into an integer. If the size of s is less than the size of an integer, the bytes are put into the low order part of the integer, with the remaining high order bytes filled with zero. If the string is too large, the most significant bytes will be lost -- no overflow detection. This procedure is normally used for processing of binary data read from a file. rawstring() -- Creates a string consisting of the raw bits in the low order "size" bytes of integer i. This procedure is normally used for processing of binary data to be written to a file.
[ Summary entry | Source code ]
procedure binop: apply binary operation
link binop
July 15, 1995; Ralph E. Griswold
This file is in the public domain.
This procedure applies a binary operation to a list of arguments. For example, binop("+", 1, 2, 3) returns 6.
[ Summary entry | Source code ]
link bitint
May 25, 1994; Ralph E. Griswold
This file is in the public domain.
int2bit(i) produces a string with the bit representation of i. bit2int(s) produces an integer corresponding to the bit representation i.
[ Summary entry | Source code ]
link bitstr
August 14, 1996; Robert J. Alexander
See also: bitstrm.icn
This file is in the public domain.
Procedures for working with strings made up of numeric values represented by strings of an arbitrary number of bits, stored without regard to character boundaries. In conjunction with the "large integers" feature of Icon, this facility can deal with bitstring segments of arbitrary size. If "large integers" are not supported, bitstring segments (i.e. the nbits parameter of BitStringGet and BitStringPut) wider that the integer size of the platform are likely to produce incorrect results. ____________________________________________________________ Usage of BitStringPut, by example: record bit_value(value, nbits) ... bitString := BitString("") while value := get_new_value() do # loop to append to string BitStringPut(bitString, value.nbits, value.value) resultString := BitStringPut(bitString) # output any buffered bits Note the interesting effect that BitStringPut(bitString), as well as producing the complete string, pads the buffered string to an even character boundary. This can be dune during construction of a bit string if the effect is desired. The "value" argument defaults to zero. ____________________________________________________________ Usage of BitStringGet, by example: record bit_value(value, nbits) ... bitString := BitString(string_of_bits) while value := BitStringGet(bitString, nbits) do # do something with value BitStringGet fails when too few bits remain to satisfy a request. However, if bits remain in the string, subsequent calls with fewer bits requested may succeed. A negative "nbits" value gets the value of the entire remainder of the string, to the byte boundary at its end.
[ Summary entry | Source code ]
link bitstrm
August 14, 1996; Robert J. Alexander
See also: bitstr.icn
This file is in the public domain.
Procedures for reading and writing integer values made up of an arbitrary number of bits, stored without regard to character boundaries. ____________________________________________________________ Usage of BitStreamWrite, by example: record bit_value(value, nbits) ... BitStreamWrite() #initialize while value := get_new_value() do # loop to output values BitStreamWrite(outfile, value.nbits, value.value) BitStreamWrite(outfile) # output any buffered bits Note the interesting effect that BitStreamWrite(outproc), as well as outputting the complete string, pads the output to an even character boundary. This can be dune during construction of a bit string if the effect is desired. The "value" argument defaults to zero. ____________________________________________________________ Usage of BitStreamRead, by example: BitStreamRead() while value := BitStreamRead(infile, nbits) do # do something with value BitStringRead fails when too few bits remain to satisfy a request.
[ Summary entry | Source code ]
link bkutil
August 14, 1996; Robert J. Alexander
See also: abkform.icn, pbkform.icn
This file is in the public domain.
Utility procedures for HP95LX phone book and appointment book processing.
[ Summary entry | Source code ]
link bold
March 25, 2002; Ralph E. Griswold
This file is in the public domain.
These procedures produce text with interspersed characters suit- able for printing to produce the effect of boldface (by over- striking) and underscoring (using backspaces). bold(s) bold version of s uscore(s) underscored version of s
[ Summary entry | Source code ]
procedure b01: complement pattern procedure b0110: "xor" of two patterns procedure b1000: "and" of two patterns procedure b1110: "or" of two patterns
link boolops
June 26, 2002; Ralph E. Griswold
This file is in the public domain.
Limitation: Assumes square patterns.
[ Summary entry | Source code ]
link bufread
March 11,1995; Charles A. Shartsis
This file is in the public domain.
Synopsis: bufopen(s) Open a file name s for buffered read and lookahead bufread(f) Read the next line from file f bufnext(f, n) Return the next nth record from file f without changing the next record to be read by bufread bufclose(f) Close file f ____________________________________________________________ These procedures provide a mechanism for looking ahead an arbitrary number of records in an open file while still keeping track of the logical current record and end-of-file. Although similar in intent to the procedures in buffer.icn, these procedures are used differently. The procedures bufopen, bufread, and bufclose were designed to closely mirror the built-in open, read, and close. A code segment like file := open("name", "r") | stop("open failed") while line := read(file) do { ...process current line... } close(file) can be changed to the following with no difference in behavior: file := bufopen("name", "r") | stop("open failed") while line := bufread(file) do { ...process current line... } bufclose(file) However in addition to processing the current line, one may also process subsequent lines BEFORE they are logically read: file := bufopen("name", "r") | stop("open failed") while line := bufread(file) do { ...process current line... line := bufnext(file,1) # return next line ...process next line... line := bufnext(file,2) # return 2nd next line ...process 2nd next line... ...etc... } bufclose(file) In the code above, calls to bufnext do not affect the results of subsequent bufread's. The bufread procedure always steps through the input file a line at a time without skipping lines whether or not bufnext is called. ____________________________________________________________ Here is a more detailed description of the procedures: bufopen(s) ========== Produces a file resulting from opening s for reading ("r" option), but fails if the file cannot be opened. if s is missing or the value of s is &null, then standard input is opened and &input is returned. Unlike the Icon open function, bufopen() can and must be called prior to any call to bufread or bufnext involving standard input. Unlike named files, only one buffered standard input may be open at any given time. Default: s &null (indicates &input should be opened for buffered reading) Errors (from open): 103 s not string Errors (new): Attempt to open standard input when currently open bufread(f) ========== Produces a string consisting of the next line from f, but fails on end of file. Calls to bufnext do not affect the results of subsequent bufread's. The procedure bufread always steps through a file a line at a time without skipping lines. The procedure bufread fails when a logical end of file is reached, i.e., when the physical end of file has been reached AND the internal buffer is empty. Default: f &input Errors: f is not a file f not opened for buffered reads (includes &input) bufnext(f, n) ============= Produces a string consisting of the nth next line from f after the current line. It fails when the physical end of file has been reached. Default: f &input n 1 (the next line after the current one) Errors: f is not a file f not opened for buffered reads (includes &input) n not convertible to integer n not positive bufclose(f) =========== Produces f after closing it. Standard input must be closed before it can be reopened using bufopen. If standard input is closed, all lines read using bufnext are lost when it is reopened. In general, there is no practical reason to bufclose and then bufopen standard input. One may want to bufclose standard input to release its internal buffer for garbage collection. Default: f &input Errors (from close): 105 f not file
[ Summary entry | Source code ]
procedure Cal_Init: initialize calendar globals procedure Cal_IsLeapYear: determine if year is leap procedure Cal_IsDST: determines if seconds (local) is DST procedure Cal_NthWeekdayTo gets seconds of nth specified weekday of month procedure Cal_DateLineToSe convert &dateline to seconds procedure Cal_DateToSec: convert &date to seconds procedure Cal_SecToDate: convert seconds to &date procedure Cal_SecToDateLin convert seconds to &dateline procedure Cal_SecToUnixDat convert seconds to UNIX time procedure Cal_ClockToSec: convert &date to seconds procedure Cal_SecToClock: convert seconds to &clock
link calendar
March 25, 2002; Robert J. Alexander
See also: datetime.icn, datefns.icn
This file is in the public domain.
Procedures in this file supersede several procedures in datetime.icn. ____________________________________________________________ Setting up ---------- You will probably want to set a platform environment variable "Cal_TimeZone" to an appropriate local time zone ID string before using this library. Look at the time zone data at the end of this source file and choose an ID for your locale. Common ones for USA are "PST", "MST", "CST", and "EST", although there are more specific ones such as "America/Arizona" that handle special rules. If environment variables are not supported for your platform or your implementation of Icon, explicitly specify the default time zone in your program: e.g. Cal_CurrentTimeZone := Cal_GetTimeZone("PST"). If your system uses a base year for date calculation that is different from 1970, your can specify it in an environment variable "Cal_DateBaseYear" or set it directly in the global variable by the same name. Unix and Windows use the library's default value of 1970, but Macintosh used to use 1984 (I'm not sure if Apple have yet seen fit to conform to the 1970 quasi-standard). This setting doesn't matter unless you want your "seconds" values to be the same as your system's. GMT and local time ------------------ GMT (Greenwich Mean Time) is a universal time standard (virtually equivalent to "Coordinated Universal Time" (UTC), except for some millisecond differences). Time forms ---------- There are two fundamental date/time forms supported by this library: a form in which computation is easy (the "seconds" form) and a form in which formatting is easy (the "calendar record" form). - Seconds -- the time is be represented as an integer that is the number of seconds relative to the beginning of Cal_DateBaseYear, GMT. Cal_DateBaseYear is usually 1970, but can be changed). The "seconds" form is a universal time, independent of locale. - Cal_Rec -- a "calendar record", which has fields for date and time components: year, month, day, hour, minutes, seconds,and day-of-week. The "Cal_Rec" form is usually in terms of local time, including accounting for daylight savings time according to local rules. Notes ----- - Several procedures have a final "timeZone" parameter. In those procedures the timeZone parameter is optional and, if omitted, Cal_CurrentTimeZone is used. - The time zone table and list consume around 30KB that can be "freed" by setting both Cal_TimeZoneTable and Cal_TimeZoneList to &null. Procedures Cal_GetTimeZoneTable() and Cal_GetTimeZoneList() will re-create the structures and assign them back to their globals. For many applications, those structures are no longer needed after program initialization. - The global variables are automatically initialized by the Cal_ procedures. However, if you want to use the globals before using any procedures, they must be explicitly initialized by calling Cal_Init(). - Time zone records in the time zone structures should be viewed as read-only. If you want to make temporary changes to the fields, copy() the time zone record. Global variables ---------------- The following global variables are useful in date and time operations (R/O means please don't change it): - Cal_SecPerMin - (R/O) Seconds per minute. - Cal_SecPerHour - (R/O) Seconds per hour. - Cal_SecPerDay - (R/O) Seconds per day. - Cal_SecPerWeek - (R/O) Seconds per week. - Cal_MonthNames - (R/O) List of month names. - Cal_DayNames - (R/O) List of day names. - Cal_CurrentTimeZone - Current default time zone record -- can be changed at any time. Initialized to the time zone whose ID is in environment variable "Cal_TimeZone" if set, or to GMT. - Cal_TimeZoneGMT - (R/O) The GMT time zone record. Can be used as a timeZone parameter to "turn off" conversion to or from local. - Cal_DateBaseYear - The base year from which the "seconds" form is calculated, initialized to the value of environment variable "Cal_DateBaseYear" if set, or 1970 (the year used by both Unix and MS-Windows) - Cal_TimeZoneTable - A table of time zones keyed by the time zone's ID string - Cal_TimeZoneList - A list of time zones ordered by increasing offset from GMT Initialization procedure ------------------------ Cal_Init() Initializes global variables. Called implicitly by the Cal_ procedures. Cal_Rec (calendar record) procedures ------------------------------------ Cal_Rec(year,month,day,hour,min,sec,weekday) =20 Cal_Rec record constructor. All values are integers in customary US usage (months are 1-12, weekdays are 1-7 with 1 -> Sunday) Cal_SecToRec(seconds,timeZone) Converts seconds to a Cal_Rec, applying conversion rules of "timeZone". To suppress conversion, specify timeZone = Cal_TimeZoneGMT. Cal_RecToSec(calRec,timeZone) Converts a Cal_Rec to seconds, applying conversion rules of "timeZone". To suppress conversion, specify timeZone = Cal_TimeZoneGMT. Time zone procedures -------------------- Cal_GetTimeZone(timeZoneName) Gets a time zone given a time zone ID string. Fails if a time zone for the given ID cannot be produced. Cal_GetTimeZoneList() Returns the tine zone list that is the value of Cal_TimeZoneList, unless that global has been explicitly set to &null. If the global is null, a new list is built, assigned to Cal_TimeZoneList, and returned. Cal_GetTimeZoneTable() Returns the tine zone table that is the value of Cal_TimeZoneTable, unless that global has been explicitly set to &null. If the global is null, a new table is built, assigned to Cal_TimeZoneTable, and returned. In building the table, Cal_GetTimeZoneList() is called so global variable Cal_TimeZoneList is also set. Date/time calculation procedures -------------------------------- Cal_LocalToGMTSec(seconds,timeZone) Converts seconds from local to GMT using the rules of timeZone. Cal_GMTToLocalSec(seconds,timeZone) Converts seconds from GMT to local using the rules of timeZone. Cal_IsLeapYear(year) Returns the number of seconds in a day if year is a leap year, otherwise fails. Cal_LeapYearsBetween(loYear,hiYear) Returns the count of leap years in the range of years n where loYear <= n < hiYear. Cal_IsDST(seconds,timeZone) Returns the DST offset in hours if seconds (local time) is in the DST period, otherwise fails. Cal_NthWeekdayToSec(year,month,weekday,n,fromDay) Returns seconds of nth specified weekday of month, or fails if no such day. This is mainly an internal procedure for DST calculations, but might have other application. Date/time formatting procedures ------------------------------- Cal_DateLineToSec(dateline,timeZone) Converts a date in something like Icon's &dateline format (Wednesday, February 11, 1998 12:00 am) to "seconds" form. Cal_DateToSec(date,timeZone) Converts a date string in something like Icon &date format (1998/02/11) to "seconds" form. Cal_SecToDate(seconds,timeZone) Converts "seconds" form to a string in Icon's &date format (1998/02/11). Cal_SecToDateLine(seconds,timeZone) Converts "seconds" form to a string in Icon's &dateline format (Wednesday, February 11, 1998 12:00 am). Cal_SecToUnixDate(seconds,timeZone) Converts "seconds" form to a string in typical UNIX date/time format (Jan 14 10:24 1991). Time-only formatting procedures ------------------------------- Cal_ClockToSec(seconds) Converts a time in the format of &clock (19:34:56) to seconds past midnight. Cal_SecToClock(seconds) Converts seconds past midnight to a string in the format of &clock (19:34:56).
[ Summary entry | Source code ]
link calendat
March 25, 2002; Ralph E. Griswold
This file is in the public domain.
calendat(j) return a record with the month, day, and year corresponding to the Julian Date Number j. ____________________________________________________________ Acknowledgement: This procedure is based on an algorithm given in "Numerical Recipes; The Art of Scientific Computing"; William H. Press, Brian P. Flannery, Saul A. Teukolsky. and William T. Vetterling; Cambridge University Press, 1986.
[ Summary entry | Source code ]
link calls
March 6, 2008; Ralph E. Griswold
This file is in the public domain.
These procedures deal with procedure invocations that are encapsulated in records.
[ Summary entry | Source code ]
link capture
March 25, 2002; David A. Gamey
This file is in the public domain.
Capture is initially called by the user with one argument, the open file to contain the echoed output. Then it places itself and several shadow procedures between all calls to write, writes & stop. The user never need call capture again. Subsequently, during calls to write, writes, and stop, the appropriate shadow procedure gains control and calls capture internally. Capture then constructs a list of only those elements that direct output to &output and calls the original builtin function via the saved name. Upon return the shadow routine calls the the original builtin function with the full list. A series of uncaptured output functions have been added to allow output to be directed only to &output. These are handy for placing progress messages and other comforting information on the screen. Example: otherfile := open(...,"w") capfile := capture(open(filename,"w")) write("Hello there.",var1,var2," - this should be echoed", otherfile,"This should appear once in the other file only") uncaptured_writes("This will appear once only.") every i := 1 to 10000 do if ( i % 100 ) = 0 then uncaptured_writes("Progress is ",i,"\r") close(capfile) close(otherfile) ____________________________________________________________ Notes: 1. stop must be handled specially in its shadow function 2. capture is not designed to be turned off 3. This may be most useful in systems other than Unix (i.e. that don't have a "tee" command) 4. Display has not been captured because a) display is usually a debugging aid, and capture was originally intended to capture screen output to a file where a record or audit trail might be required b) the display output would be 'down a level' showing the locals at the display_capture_ level, although the depth argument could easily be incremented to adjust for this c) write, writes, and stop handle arguments the same way 5. An alternative to having two calls would be to have capture call the desired procedure with : push(&output,x) ; return p!(y ||| x ) While this would remove the complexity with stop it would probably be slower ____________________________________________________________ History: 10Jun94 - D.Gamey - added uncaptured i/o routines 05Oct94 - D.Gamey - temporarily suspend tracing 20Oct94 - D.Gamey - fix no output for f(&null) - eliminated global variable and select procedure
[ Summary entry | Source code ]
procedure project: project a list of coordinates procedure invp: return inversion of projection procedure sbsize: calculate scalebar size procedure rectp: define rectangular projection procedure pptrans: define planar projective transformation procedure utm: define UTM projection procedure compose: define composite projection
link cartog
February 19, 2003; Gregg M. Townsend and William S. Evans
This file is in the public domain.
These procedures project geographic coordinates. rectp(x1, y1, x2, y2, xm, ym) defines a rectangular projection. pptrans(L1, L2) defines a planar projective transformation. utm(a, f) defines a latitude/longitude to UTM projection. project(p, L) projects a list of coordinates. invp(p) returns the inverse of projection p. compose(p1, p2, ...) creates a composite projection. ____________________________________________________________ rectp(x1, y1, x2, y2, xm, ym) returns a rectangular projection in which the point (x1, y1) maps to (x2, y2). If xm is specified, distances in the projected coordinate system are scaled by xm. If ym is also specified, xm scales x values while ym scales y values. ____________________________________________________________ pptrans(L1, L2) returns a planar projective transform that maps the four points in L1 to the four points in L2. Each of the two lists contains 8 coordinates: [x1, y1, x2, y2, x3, y3, x4, y4]. ____________________________________________________________ utm(a, f) returns a projection from latitude and longitude to Universal Transverse Mercator (UTM) representation. The reference ellipsoid is specified by a, the equatorial radius in metres, and f, the flattening. Alternatively, f can be omitted with a specifying a string, such as "Clarke66"; if a is also omitted, "WGS84" is used. See ellipsoid() in geodat.icn for the list of possible strings. The input list contains signed numeric values: longitude and latitude, in degrees, in that order (x before y). The output list contains triples: an integer zone number followed by real-valued UTM x and y distances in metres. No "false easting" is applied. UTM conversions are valid between latitudes 72S and 84N, except for those portions of Norway where the UTM grid is irregular. ____________________________________________________________ project(p, L) applies a projection, reading a list of coordinates and returning a new list of transformed coordinates. ____________________________________________________________ invp(p) returns the inverse of projection p, or fails if no inverse projection is available. ____________________________________________________________ compose(p1, p2, ..., pn) returns the projection that is the composition of the projections p1, p2, ..., pn. The composition applies pn first. ____________________________________________________________ sbsize(p, x, y, u, maxl) calculates a scale bar size for use with projection p at input coordinates (x, y). Given u, the size of an unprojected convenient unit (meter, foot, mile, etc.) at (x, y), sbsize() returns the maximum "round number" N such that -- N is of the form i * 10 ^ k for i in {1,2,3,4,5} -- the projected length of the segment (x, y, x + N * u, y) does not exceed maxl ____________________________________________________________ UTM conversion algorithms are based on: Map Projections: A Working Manual John P. Snyder U.S. Geological Survey Professional Paper 1395 Washington: Superintendent of Documents, 1987 Planar projective transformation calculations come from: Computing Plane Projective Transformations (Method 1) Andrew Zisserman, Robotics Research Group, Oxford in CVOnline (R. Fisher, ed.), found 22 February 2000 at: http://www.dai.ed.ac.uk/CVonline/LOCAL_COPIES/EPSRC_SSAZ/node11.html
[ Summary entry | Source code ]
procedure anycl: Caseless version of any() procedure balcl: Caseless version of bal() procedure findcl: Caseless version of find() procedure manycl: Caseless version of many() procedure matchcl: Caseless version of match() procedure uptocl: Caseless version of upto()
link caseless
August 19, 1996; Nevin J. Liber
This file is in the public domain.
These procedures are analogous to the standard string-analysis functions except that uppercase letters are considered equivalent to lowercase letters. anycl(c, s, i1, i2) succeeds and produces i1 + 1, provided map(s[i1]) is in cset(map(c)) and i2 is greater than i1. It fails otherwise. balcl(c1, c2, c3, s, i1, i2) generates the sequence of integer positions in s preceding a character of cset(map(c1)) in map(s[i1:i2]) that is balanced with respect to characters in cset(map(c2)) and cset(map(c3)), but fails if there is no such position. findcl(s1, s2, i1, i2) generates the sequence of integer positions in s2 at which map(s1) occurs as a substring in map(s2[i1:i2]), but fails if there is no such position. manycl(c, s, i1, i2) succeeds and produces the position in s after the longest initial sequence of characters in cset(map(c)) within map(s[i1:i2]). It fails if map(s[i1]) is not in cset(map(c)). matchcl(s1, s2, i1, i2) produces i1 + *s1 if map(s1) == map(s2[i1+:=*s1]) but fails otherwise. uptocl(c, s, i1, i2) generates the sequence of integer positions in s preceding a character of cset(map(c)) in map(s[i1:i2]). It fails if there is no such position. Defaults: s, s2 &subject i1 &pos if s or s2 is defaulted; otherwise 1 i2 0 c1 &cset c2 '(' c3 ')' Errors: 101 i1 or i2 not integer 103 s or s1 or s2 not string 104 c or c1 or c2 or c3 not cset
[ Summary entry | Source code ]
link codeobj
March 25, 2002; Ralph E. Griswold
Requires: co-expressions
This file is in the public domain.
These procedures provide a way of storing Icon values as strings and retrieving them. The procedure encode(x) converts x to a string s that can be converted back to x by decode(s). These procedures handle all kinds of values, including structures of arbitrary complexity and even loops. For "scalar" types -- null, integer, real, cset, and string -- decode(encode(x)) === x For structures types -- list, set, table, and record types -- decode(encode(x)) is, for course, not identical to x, but it has the same "shape" and its elements bear the same relation to the original as if they were encoded and decode individually. No much can be done with files, functions and procedures, and co-expressions except to preserve type and identification. The encoding of strings and csets handles all characters in a way that it is safe to write the encoding to a file and read it back. No particular effort was made to use an encoding of value that minimizes the length of the resulting string. Note, however, that as of Version 7 of Icon, there are no limits on the length of strings that can be written out or read in. ____________________________________________________________ The encoding of a value consists of four parts: a tag, a length, a type code, and a string of the specified length that encodes the value itself. The tag is omitted for scalar values that are self-defining. For other values, the tag serves as a unique identification. If such a value appears more than once, only its tag appears after the first encoding. There is, therefore, a type code that distinguishes a label for a previously encoded value from other encodings. Tags are strings of lowercase letters. Since the tag is followed by a digit that starts the length, the two can be distinguished. The length is simply the length of the encoded value that follows. The type codes consist of single letters taken from the first character of the type name, with lower- and uppercase used to avoid ambiguities. Where a structure contains several elements, the encodings of the elements are concatenated. Note that the form of the encoding contains the information needed to separate consecutive elements. Here are some examples of values and their encodings: x encode(x) ------------------------------------------------------- 1 "1i1" 2.0 "3r2.0" &null "0n" "\377" "4s\\377" '\376\377' "8c\\376\\377" procedure main "a4pmain" co-expression #1 (0) "b0C" [] "c0L" set() "d0S" table("a") "e3T1sa" L1 := ["hi","there"] "f11L2shi5sthere" A loop is illustrated by L2 := [] put(L2,L2) for which x encode(x) ------------------------------------------------------- L2 "g3L1lg" Of course, you don't have to know all this to use encode and decode.
[ Summary entry | Source code ]
link colmize
June 15, 1990; Robert J. Alexander
This file is in the public domain.
colmize() -- Arrange data into columns. Procedure to arrange a number of data items into multiple columns. Items are arranged in column-wise order, that is, the sequence runs down the first column, then down the second, etc. This procedure goes to great lengths to print the items in as few vertical lines as possible.
[ Summary entry | Source code ]
link complete
August 14, 1996; Richard L. Goerwitz
This file is in the public domain.
complete(s,st) completes a s relative to a set or list of strings, st. Put differently, complete() lets you supply a partial string, s, and get back those strings in st that s is either equal to or a substring of. ____________________________________________________________ Lots of command interfaces allow completion of partial input. Complete() simply represents my personal sentiments about how this might best be done in Icon. If you strip away the profuse comments below, you end up with only about thirty lines of actual source code. I have arranged things so that only that portion of an automaton which is needed to complete a given string is actually created and stored. Storing automata for later use naturally makes complete() eat up more memory. The performance gains can make it worth the trouble, though. If, for some reason, there comes a time when it is advisable to reclaim the space occupied by complete's static structures, you can just call it without arguments. This "resets" complete() and forces an immediate garbage collection. Example code: commands := ["run","stop","quit","save","load","continue"] while line := read(&input) do { cmds := list() every put(cmds, complete(line, commands)) case *cmds of { 0 : input_error(line) 1 : do_command(cmds[1]) default : display_possible_completions(cmds) } etc... More Iconish methods might include displaying successive alternatives each time the user presses the tab key (this would, however, require using the nonportable getch() routine). Another method might be to use the first string suspended by complete(). NOTE: This entire shebang could be replaced with a slightly slower and much smaller program suggested to me by Jerry Nowlin and Bob Alexander. procedure terscompl(s, st) suspend match(s, p := !st) & p end This program will work fine for lists with just a few members, and also for cases where s is fairly large. It will also use much less memory.
[ Summary entry | Source code ]
procedure strcpx: convert string to complex number procedure cpxstr: return complex number as string procedure cpxadd: complex add procedure cpxsub: complex subtract procedure cpxmul: complex multiply procedure cpxdiv: complex divide procedure cpxconj: complex conjugate procedure cpxabs: complex absolute value
link complex
May 26, 2010; Ralph E. Griswold
This file is in the public domain.
The following procedures perform operations on complex numbers. complex(r,i) create complex number with real part r and imaginary part i cpxabs(z) compute absolute value of complex number z cpxadd(z1, z2) add complex numbers z1 and z2 cpxconj(z) compute conjugate of complex number z cpxdiv(z1, z2) divide complex number z1 by complex number z2 cpxmul(z1, z2) multiply complex number z1 by complex number z2 cpxsub(z1, z2) subtract complex number z2 from complex number z1 cpxstr(z) convert complex number z to string representation strcpx(s) convert string representation s of complex number to complex number
[ Summary entry | Source code ]
procedure Directive: Wrapper to build directive specification procedure ReadDirectives: Builds icon data structures from a config file procedure Directive_table_ build table of sets: action key value(s) procedure Directive_table: build table: action key value procedure Directive_set: build set: action value(s) procedure Directive_list: build list: action value(s) procedure Directive_value: build value: action value procedure Directive_exists build existence flag: action procedure Directive_ignore quietly ignore any directive procedure Directive_warnin flag directive with a warning
link conffile
March 25, 2002; David A. Gamey
Thanks to Clint Jeffery for suggesting the Directive wrapper and making defining a specification much cleaner looking and easier! ____________________________________________________________ This file is in the public domain. ____________________________________________________________ Description: At Some point certain procedures become indispensable. Anyone who has used 'options' from the Icon program library will probably agree. I found a need to be able to quickly, change the format and interpretation of a set of configuration and rules files. And so, I hope this collection of procedures will become similarly indispensable. Directive( p1, p2, i1, i2 ) : r1 returns a specification record for a table required by ReadDirectives p1 is the build procedure used to extract the data from the file. The table below describes the build procedures and the default minimum and maximum number of arguments for each. If the included procedures don't meet your needs then you can easily add your own and still use Directive to build the specification. build procedure minargs maxargs Directive_table_of_sets 2 - Directive_table 2 - Directive_value 1 1 Directive_set 1 - Directive_list 1 - < user defined > 1 - Directive_exists 0 0 Directive_ignore 0 - Directive_warning 0 - p2 is an edit procedure that allows you to preprocess the data or null i1 is the minimum number of arguments for this directive, default is 1 i2 is the maximum number of arguments for this directive Run-time Errors: - 123 if p1 isn't a procedure - 123 if p2 isn't null or a procedure - 101 if i1, i2 aren't integers and not ( 0 <= i1 <= i2 ) after defaults ReadDirectives( l1, t1, s1, s2, c1, c2, p1 ) : t2 returns a table containing parsed directives for the specified file l1 is a list of file names or open files, each element of l1 is tried in turn until a file is opened or an open file is encountered. For example: [ "my/rules", "/etc/rules", &input ] t1 is a table of specifications for parsing and handling each directive s1 the comment character, default "#" s2 the continuation character, default "_" c1 the escape character, default "\" c2 the cset of whitespace, default ' \b\t\v\f\r' p1 stop | an error procedure to be called, fail if null t2 is a table containing the parsed results keyed by tag Notes: - the special key "*file*" is a list containing the original text of input file with interspersed diagnostic messages. - the comment, escape, continuation and whitespace characters must not overlap (unpredictable) - the end of a directive statement will forcibly close an open quote (no warning) - the end of file will forcibly close a continuation (no warning) Run-time Errors: - 103, 104, 107, 108, 500 500 errors occur if: - arguments are too big/small - the specification table is improper Directive file syntax: - blank lines are ignored - all syntactic characters are parameterized - everything after a comment character is ignored (discarded) - to include a comment character in the directive, precede it with an escape - to continue a directive, place a continue character at the end of the line (before comments) - trailing whitespace is NOT ignored in continuations - quoted strings are supported, - to include a quote within a quoted string, precede the enclosed quote with an escape Usage: -- Config file, example: -- # comment line var1 "This string, w/o quotes, will be in cfgspec[\"var\"]" cset1 "abcdefffffffffffff" # type of quotes isn't important int1 12345 lcase1 "Hello There THIs iS CasE inSENsITive" list1 one two three _ # continues four five one three zero set1 one one one two three 3 'a b c' # one two three 3 'a b c' table1 k1 v1 table1 k2 v2 t/set1 key1 v1 v2 v3 v4 t/set1 key2 v5 v6 t/set1 key3 "1 2 \#3" # comment warn1 this will produce _ a warning -- Coding example: -- # 1. Define a specification table using Directive. # Directive has four fields: # - the procedure to handle the tag # - an optional edit procedure to preprocess the data # - the minimum number of values following the tag, # default is dependent on the &null is treated as 0 # - the maximum number of values following the tag, # &null is treated as unlimited # The table's keys are the directives of the configuration file # The default specification should be either warning of ignore cfgspec := table( Directive( Directive_warning ) ) cfgspec["var1"] := Directive( Directive_value ) cfgspec["cset1"] := Directive( Directive_value, cset ) cfgspec["int1"] := Directive( Directive_value, integer ) cfgspec["lcase1"] := Directive( Directive_value, map ) cfgspec["list1"] := Directive( Directive_list ) cfgspec["set1"] := Directive( Directive_set ) cfgspec["table1"] := Directive( Directive_table ) cfgspec["t/set1"] := Directive( Directive_table_of_sets ) # 2. Read, parse and build a table based upon the spec and the file cfg := ReadDirectives( ["my.conf",&input], cfgspec ) # 3. Process the output write("Input:\n") every write(!cfg["*file*"]) write("\nBuilt:\n") every k :=key(cfg) do if k ~== "*file*" then write(k, " := ",ximage(cfg[k])) -- Output: -- Input: # comment line var1 "This string, w/o quotes, will be in cfgspec[\"var\"]" cset1 "abcdefffffffffffff" # type of quotes isn't important int1 12345 lcase1 "Hello There THIs iS CasE inSENsITive" list1 one two three _ # continues four five one three zero set1 one one one two three 3 'a b c' # one two three 3 'a b c' table1 k1 v1 table1 k2 v2 t/set1 key1 v1 v2 v3 v4 t/set1 key2 v5 v6 t/set1 key3 "1 2 \#3" # comment warn This will produce a _ warning -- Directive isn't defined in specification. Built: set1 := S1 := set() insert(S1,"3") insert(S1,"a b c") insert(S1,"one") insert(S1,"three") insert(S1,"two") cset1 := 'abcdef' t/set1 := T4 := table(&null) T4["key1"] := S2 := set() insert(S2,"v1") insert(S2,"v2") insert(S2,"v3") insert(S2,"v4") T4["key2"] := S3 := set() insert(S3,"v5") insert(S3,"v6") T4["key3"] := S4 := set() insert(S4,"1 2 #3") list1 := L12 := list(8) L12[1] := "one" L12[2] := "two" L12[3] := "three" L12[4] := "four" L12[5] := "five" L12[6] := "one" L12[7] := "three" L12[8] := "zero" lcase1 := "hello there this is case insensitive" int1 := 12345 var1 := "This string, w/o quotes, will be in cfgspec[\"var\"]" table1 := T3 := table(&null) T3["k1"] := "v1" T3["k2"] := "v2"
[ Summary entry | Source code ]
procedure converge: continued-fraction convergents
link converge
June 7, 2000; Ralph E. Griswold
This file is in the public domain.
This procedure produces continued-fraction convergents from a list of partial quotients.
[ Summary entry | Source code ]
procedure exbase10: convert base 10 to arbitrary base procedure inbase10: convert arbitrary base to base 10 procedure radcon: convert between bases
link convert
March 19, 1998; Ralph E. Griswold
This file is in the public domain.
exbase10(i, j) converts base-10 integer i to base j. inbase10(s, i) convert base-i integer s to base 10. radcon(s, i, j) convert base-i integer s to base j. There are several other procedures related to conversion that are not yet part of this module.
[ Summary entry | Source code ]
link core
August 4, 2000; Gregg M. Townsend
This file is in the public domain.
Links to core modules of the basic part of the library, as defined in the Icon Language book (3/e, p.179) and Graphics book (p.47).
[ Summary entry | Source code ]
procedure created: number of structures created
link created
March 25, 2002; Ralph E. Griswold
This file is in the public domain.
This program returns the number of structures of a given type that have been created.
[ Summary entry | Source code ]
link currency
September 21, 1993; Robert J. Alexander
This file is in the public domain.
currency() -- Formats "amount" in standard American currency format. "amount" can be a real, integer, or numeric string. "width" is the output field width, in which the amount is right adjusted. The returned string will be longer than "width" if necessary to preserve significance. "minus" is the character string to be used for negative amounts (default "-"), and is placed to the right of the amount.
[ Summary entry | Source code ]
link curves
March 25, 2002; Ralph E. Griswold
This file is in the public domain.
This file links procedure files that generate traces of points on various plain curves. The first two parameters determine the defining position of the curve: x x coordinate y y coordinate The meaning of "definition position" depends on the curve. In some cases it is the position at which plotting starts. In others, it is a "center" for the curve. The next arguments vary and generally refer to parameters of the curve. There is no practical way to describe these here. If they are not obvious, the best reference is A Catalog of Special Plane Curves, J. Dennis Lawrence, Dover Publications, Inc., New York, 1972. This book, which is in print at the time of this writing, is a marvelous source of information about plane curves and is inexpensive as well. The trailing parameters give the number of steps and the end points (generally in angles) of the curves: steps number of points, default varies lo beginning of plotting range, default varies hi end of plotting range, default varies Because of floating-point roundoff, the number of steps may not be exactly the number specified. Note: Some of the curves may be "upside down" when plotted on coordinate systems in which the y axis increases in a downward direction. Caution: Some of these procedures generate very large values in portions of their ranges. These may cause run-time errors when used in versions of Icon prior to 8.10. One work-around is to turn on error conversion in such cases. Warning: The procedures that follow have not been tested thoroughly. Corrections and additions are most welcome. These procedures are, in fact, probably most useful for the parametric equations they contain.
[ Summary entry | Source code ]
link datefns
August 14, 1995; Charles Hethcoat
This file is in the public domain.
datefns.icn - a collection of date functions Adaptor: Charles L Hethcoat III June 12, 1995 Taken from various sources as attributed below. All date and calendar functions use the "date_rec" structure defined below. Note: I adapted the procedures "julian" and "unjulian" sometime in 1994 from "Numerical Recipes in C." Some time later I discovered them (under slightly different names) in Version 9 of the Icon Library (Ralph Griswold, author). I am including mine for what they are worth. That'll teach me to wait!
[ Summary entry | Source code ]
procedure ClockToSec: convert &date to seconds procedure DateLineToSec: convert &dateline to seconds procedure DateToSec: convert &date to seconds procedure SecToClock: convert seconds to &clock procedure SecToDate: convert seconds to &date procedure SecToDateLine: convert seconds to &dateline procedure SecToUnixDate: convert seconds to UNIX time procedure IsLeapYear: determine if year is leap procedure calendat: Julian date procedure date: date in natural English procedure dayoweek: day of the week procedure full13th: full moons on Friday 13ths procedure julian: Julian date procedure pom: phase of moon procedure saytime: time in natural English procedure walltime: time since midnight
link datetime
August 9, 2000; Robert J. Alexander and Ralph E. Griswold
See also: datefns.icn
This file is in the public domain.
Notes: - the default value for function parameters named "hoursFromGmt" is the value of global variable "HoursFromGmt" if nonnull, or environment variable "HoursFromGmt" if set, or 0. - The base year from which the "seconds" representation of a date is calculated is by default 1970 (the ad hoc standard used by both Unix and MS-Windows), but can be changed by either setting the global variable "DateBaseYear" or environment variable "DateBaseYear". - There are some procedures not mentioned in this summary that are useful: DateRecToSec(), SecToDateRec(). See the source code for details. ClockToSec(seconds) converts a time in the format of &clock to seconds past midnight. DateLineToSec(dateline,hoursFromGmt) converts a date in &dateline format to seconds since start of dateBaseYear. DateToSec(date,hoursFromGmt) converts a date string in Icon &date format (yyyy/mm/dd) to seconds past DateBaseYear. SecToClock(seconds) converts seconds past midnight to a string in the format of &clock. SecToDate(seconds,hoursFromGmt) converts seconds past DateBaseYear to a string in Icon &date format (yyyy/mm/dd). SecToDateLine(seconds,hoursFromGmt) produces a date in the same format as Icon's &dateline. SecToUnixDate(seconds,hoursFromGmt) returns a date and time in typical UNIX format: Jan 14 10:24 1991. IsLeapYear(year) succeeds if year is a leap year, otherwise fails. calendat(j) returns a record with the month, day, and year corresponding to the Julian Date Number j. date() natural date in English. dayoweek(day, month, year) produces the day of the week for the given date. Note carefully the parameter order. full13th(year1, year2) generates records giving the days on which a full moon occurs on Friday the 13th in the range from year1 though year2. julian(m, d, y) returns the Julian Day Number for the specified month, day, and year. pom(n, phase) returns record with the Julian Day number of fractional part of the day for which the nth such phase since January, 1900. Phases are encoded as: 0 - new moon 1 - first quarter 2 - full moon 3 - last quarter# GMT is assumed. saytime() computes the time in natural English. If an argument is supplied it is used as a test value to check the operation the program. walltime() produces the number of seconds since midnight. Beware wrap-around when used in programs that span midnight. ____________________________________________________________ Acknowledgement: Some of these procedures are based on an algorithm given in "Numerical Recipes; The Art of Scientific Computing"; William H. Press, Brian P. Flannery, Saul A. Teukolsky, and William T. Vetterling;# Cambridge University Press, 1986.
[ Summary entry | Source code ]
procedure ddfopen: open DDF file procedure ddfread: read DDF record procedure ddfclose: close DDF file
link ddfread
August 2, 2001; Gregg M. Townsend
This file is in the public domain.
These procedures read DDF files ("Data Descriptive Files", ISO standard 8211) such as those specified by the US Geological Survey's "Spatial Data Transfer Standard" for digital maps. ISO8211 files from other sources may contain additional data encodings not recognized by these procedures. ddfopen(filename) opens a file and returns a handle. ddfdda(handle) returns a list of header records. ddfread(handle) reads the next data record. ddfclose(handle) closes the file. ____________________________________________________________ ddfopen(filename) opens a DDF file, decodes the header, and returns an opaque handle for use with subsequent calls. It fails if any problems are encountered. Instead of a filename, an already-open file can be supplied. ____________________________________________________________ ddfdda(handle) returns a list of records containing data from the Data Descriptive Area (DDA) of the file header. Each record contains the following fields: tag DDR entry tag control field control data name field name labels list of field labels format data format The records may also contain other fields used internally. ____________________________________________________________ ddfread(handle) reads the next data record from the file. It returns a list of lists, with each sublist containing a tag name followed by the associated data values, already decoded according to the specification given in the header. ____________________________________________________________ ddfclose(handle) closes a DDF file.
[ Summary entry | Source code ]
link dif
August 14, 1996; Robert J. Alexander
This file is in the public domain.
dif(stream, compare, eof, group) generates a sequence of differences between an arbitrary number of input streams. Each result is returned as a list of diff_recs, one for each input stream, with each diff_rec containing a list of items that differ and their position in the input stream. The diff_rec type is declared as: record diff_rec(pos,diffs) dif() fails if there are no differences, i.e. it produces an empty result sequence. ____________________________________________________________ For example, if two input streams are: a b c d e f g h a b d e f i j the output sequence would be: [diff_rec(3,[c]),diff_rec(3,[])] [diff_rec(7,[g,h]),diff_rec(6,[i,j]) The arguments to dif(stream,compare,eof,group) are: stream A list of data objects that represent input streams from which dif will extract its input "records". The elements can be of several different types which result in different actions, as follows: Type Action =========== ============================= file file is "read" to get records co-expression co-expression is activated to get records list records are "gotten" (get()) from the list diff_proc a record type defined in "dif" to allow a procedure (or procedures) suppled by dif's caller to be called to get records. Diff_proc has two fields, the procedure to call and the argument to call it with. Its definition looks like this: record diff_proc(proc,arg) Optional arguments: compare Item comparison procedure -- succeeds if "equal", otherwise fails (default is the identity "===" comparison). The comparison must allow for the fact that the eof object (see next) might be an argument, and a pair of eofs must compare equal. eof An object that is distinguishable from other objects in the stream. Default is &null. group A procedure that is called with the current number of unmatched items as its argument. It must return the number of matching items required for file synchronization to occur. Default is the formula Trunc((2.0 * Log(M)) + 2.0) where M is the number of unmatched items.
[ Summary entry | Source code ]
procedure digitcnt: count digits in file
link digitcnt
July 15, 1995; Ralph E. Griswold
This file is in the public domain.
This procedure counts the number of each digit in a file and returns a ten-element list with the counts.
[ Summary entry | Source code ]
procedure do_od: Dijkstra's do_od construct procedure if_fi: Dijkstra's if_fi construct
link dijkstra
December 9, 2003; Frank J. Lhota
This file is in the public domain.
The procedures do_od and if_fi implement the "do ... od" and "if ... fi" control structures used in the book "A Discipline of Programming" by Edsger W. Dijkstra. This book uses a programming language designed to delay implementation details, such as the order in which tests are performed. Dijkstra's programming language uses two non-ASCII characters, a box and a right arrow. In the following discussion, the box and right arrow characters are represented as "[]" and "->" respectively. The "if ... fi" control structure is similar to multi-branch "if" statements found in many languages, including the Bourne shell (i.e. the "if / elif / fi" construct). The major difference is that in Dijkstra's notation, there is no specified order in which the "if / elif" tests are performed. The "if ... fi" structure has the form if Guard1 -> List1 [] Guard2 -> List2 [] Guard3 -> List3 ... [] GuardN -> ListN fi where Guard1, Guard2, Guard3 ... GuardN are boolean expressions, and List1, List2, List3 ... ListN are lists of statements. When this "if ... fi" statement is performed, the guard expressions are evaluated, in some order not specified by the language, until one of the guard expressions evaluates to true. Once a true guard is found, the list of statements following the guard is evaluated. It is a fatal error for none of the guards in an "if ... fi" statement to be true. The "do ... od" control is a "while" loop structure, but with multiple loop conditions, in style similar to "if ... fi". The form of a Dijkstra "do" statement is do Guard1 -> List1 [] Guard2 -> List2 [] Guard3 -> List3 ... [] GuardN -> ListN od where Guard1, Guard2, Guard3 ... GuardN are boolean expressions, and List1, List2, List3 ... ListN are lists of statements. To perform this "do ... od" statement, the guard expressions are evaluated, in some order not specified by the language, until either a guard evaluates to true, or all guards have been evaluated as false. - If all the guards are false, we exit the loop. - If a guard evaluates to true, then the list of statements following this guard is performed, and then we loop back to perform this "do ... od" statement again. The procedures if_fi{} and do_od{} implement Dijkstra's "if ... fi" and "do ... od" control structures respectively. In keeping with Icon conventions, the guard expressions are arbitrary Icon expressions. A guard is considered to be true precisely when it succeeds. Similarly, a statement list can be represented by a single Icon expression. The Icon call if_fi{ Guard1, List1, Guard2, List2, ... GuardN, ListN } suspends with each result produced by the expression following the true guard. If none of the guards succeed, runerr() is called with an appropriate message. Similarly, the Icon call do_od{ Guard1, List1, Guard2, List2, ... GuardN, ListN } parallels the "do ... od" statement. As long as at least one guard succeeds, another iteration is performed. When all guards fail, we exit the loop and do_od fails. The test section of this file includes a guarded command implementation of Euclid's algorithm for calculating the greatest common denominator. Unlike most implementations of Euclid's algorithm, this version handles its parameters in a completely symmetrical fashion.
[ Summary entry | Source code ]
link divide
March 29, 2000; Ralph E. Griswold
Requires: Large integer arithmetic, potentially
This file is in the public domain.
Doesn't get the decimal point. Not sure what the padding does; to study.
[ Summary entry | Source code ]
link ebcdic
August 14, 1996; Alan Beale
This file is in the public domain.
These procedures assist in use of the ASCII and EBCDIC character sets, regardless of the native character set of the host: Ascii128() Returns a 128-byte string of ASCII characters in numerical order. Ascii128() should be used in preference to &ascii for applications which might run on an EBCDIC host. Ascii256() Returns a 256-byte string representing the 256- character ASCII character set. On an EBCDIC host, the order of the second 128 characters is essentially arbitrary. Ebcdic() Returns a 256-byte string of EBCDIC characters in numerical order. AsciiChar(i) Returns the character whose ASCII representation is i. AsciiOrd(c) Returns the position of the character c in the ASCII collating sequence. EbcdicChar(i) Returns the character whose EBCDIC representation is i. EbcdicOrd(c) Returns the position of the character c in the EBCDIC collating sequence. MapEtoA(s) Maps a string of EBCDIC characters to the equivalent ASCII string, according to a plausible mapping. MapAtoE(s) Maps a string of ASCII characters to the equivalent EBCDIC string, according to a plausible mapping. Control(c) Returns the "control character" associated with the character c. On an EBCDIC host, with $ representing an EBCDIC character with no 7-bit ASCII equivalent, Control("$") may not be identical to "\^$", as translated by ICONT (and neither result is particularly meaningful). ____________________________________________________________ Notes: There is no universally accepted mapping between ASCII and EBCDIC. See the SHARE Inc. publication "ASCII and EBCDIC Character Set and Code Issues in Systems Application Architecture" for more information than you would ever want to have on this subject. The mapping of the first 128 characters defined below by Ascii128() is the most commonly accepted mapping, even though it probably is not exactly like the mapping used by your favorite PC to mainframe file transfer utility. The mapping of the second 128 characters is quite arbitrary, except that where an alternate translation of ASCII char(n) is popular, this translation is assigned to Ascii256()[n+129]. The behavior of all functions in this package is controlled solely by the string literals in the _Eascii() procedure. Therefore you may modify these strings to taste, and still obtain consistent results, provided that each character appears exactly once in the result of _Eascii(). Yes, it's really true that the EBCDIC "\n" (NL, char(16r15)) is not the same as "\l" (LF, char(16r25)). How can that be? "Don't blame me, man, I didn't do it."
[ Summary entry | Source code ]
procedure echo: interpolate variables and print
link echo
February 9, 2010; Charles L Hethcoat III and Carl Sturtivant
This file is in the public domain.
echo() substitutes global variables for occurrences of $name in &subject, and writes the result to standard output. ____________________________________________________________ Background: String "interpolation", as used in Perl, Tcl, Bash, and so on, involves a special notation used within a string that causes the value of a variable to be inserted into the string at runtime. A common notation for this is a dollar sign, e. g. "The price is $price pfennig." If a variable named "price" has the value 10, then on output the string becomes "The price is 10 pfennig." Interpolation is lacking in Icon, so we must use the fussier syntax of an Icon write() procedure: write("The price is ", price, "pfennig."). Here is a slightly more complex example, assuming variables `price' = 10, `article' == "thimble", and `currency' == "pfennig": write("The price of a ", article, " is ", price, " ", currency, ".") This can be annoying and error-prone if we must use many such strings in a program. The echo() procedure provides a very nice solution for Icon programmers. Compare the preceding write() call to this: "The price of a $article is $price $currency" ? echo() Is this not much simpler? Both examples will print out the string "The price of a thimble is 10 pfennig." but interpolation with echo() greatly reduces the low-level syntactic requirements (and reduces the number of characters to type from 68 to 54). It is much easier to write, read, and check. If many such lines of code are needed, the difference adds up. Consider, for example, how this would pay off if your program needs to generate hundreds of lines of HTML or PostScript. ____________________________________________________________ Usage: A string to be printed with interpolated values should be set up in a scanning environment, using echo() as the scanning procedure, as in "foo$variable" ? echo(). Here is an actual example for testing: link echo global month, day, year procedure main() month := "February" day := 30 year := 2010 "Free beer on $month $day, $year." ? echo() end Assuming echo.icn has been compiled with the -c option beforehand, compiling, linking, and running this program produces the string "Free beer on February 30, 2010." on standard output. ____________________________________________________________ Notes: Since there is no way for any Icon procedure to discover the values of any another procedure's local variables, all variables to be used via the echo() procedure must be global. This restriction ought not to be too serious for smaller programs, or even longer ones if they are of simple construction. But it may be a limitation for sophisticated Icon programming projects. You will have to be the judge. If x is a global variable with value 10, "x" ? echo() prints "x" "$x" ? echo() prints "10" "$$x" ? echo() prints "$x" "$$$x" ? echo() prints "$10" "$$$$x" ? echo() prints "$$x" "$$$$$x" ? echo() prints "$$10" and so on. The rule is: take dollar signs off in pairs from the left. Each pair prints ONE literal dollar sign on the output. If there were an odd number of dollar signs to begin with, then one will be left over, and this will print the value of the variable (10). If there were an even number to begin with, then none are left, and a literal "x" is printed. There is an extended notation that helps disambiguate some usage scenarios. Here are some examples: "${x}" is the same as $x. "${x}:" is the same as $x:. "${x}${y}" is the same as $x$y. However, "${x}avier" is NOT the same as $xavier! Can you see why? You may use any variable names you like. There are no restrictions. echo() uses no global variable names of its own, but receives the string it interpolates in a string scanning environment. ____________________________________________________________ Using echo() on a larger scale , with input from a generator: global time, date, save, wombats link echo procedure main() time := &clock date := &date save := ?100000 wombats := 22 "It is now $time on $date and you have savings of $$$save." | "The number of wombats is $wombats." | "It is now ${time} on ${date} and you have ${wombats} wombats." | "There is no global variable named \"$foo\"." | "This does not work: It is now ${&clock}." | "" | "The previous input line printed an empty output line." ? echo() end Because echo() always fails (in the Icon sense), evaluation of a | b | c | d ? echo() will group as (a | b | c | d) ? echo() because of operator precedence, and the left-hand expression produces _a_ first, which is assigned to &subject. Then echo() is evaluated -- and fails. This makes the whole expression fail, so Icon backtracks to the first expression, resumes its evaluation to produce its second value b, which is assigned to &subject and then echo() is called, which fails, and so forth, until all possibilities are exhausted. ____________________________________________________________ Taking input from a template file: You can create a template file (with $-strings in it) and use an Icon program to read it and write it out to standard output. Your main Icon program will supply the needed variable values for the $-strings in the template. As an example, suppose your program will generate a hundred business cards for you as a PostScript file. You have a template file named template.ps with $-strings such as $firstname, $lastname, $address, $companyname, and so on --- all embedded in it at the proper places. Your main program will read this template and substitute the actual name and address information. This is one way your program can read template.ps and pass it to echo(): ... firstname := "Joe" lastname := "Smith" # ... etc. ... reads("template.ps",1000000) ? echo() ... When this is run, your customized business cards appear on standard output. ____________________________________________________________ This trick relies upon concatenation having a higher precedence than alternation: "................" || "................" || "................" | "................" || "................" | "................" || "................" ? echo() This prints out three messages, one specified on three lines, one on two, and one on two. The alternations fix the newlines provided at the end of each message by echo(). &subject is the empty string if it's unassigned. So echo() called without ? will under those circumstances print a blank line.
[ Summary entry | Source code ]
link empgsup
May 30, 1993; Ralph E. Griswold
This file is in the public domain.
This procedure is called by timing programs produced by empg. It a "delta" timing value used to adjust timings.
[ Summary entry | Source code ]
link emptygen
December 5, 1995; Ralph E. Griswold
This file is in the public domain.
This program is designed to be linked with the output of the meta- translator. As given here, they produce an identity translation. Modifications can be made to effect different translations. The procedures here are just wrappers. This file is a skeleton that can be used as a basis for code-generation procedures. ____________________________________________________________ Bug: The invocable declaration is not handled properly. "invocable all" will get by, but some other forms produce syntax errors. The problem is in the meta-translator itself, not in this program.
[ Summary entry | Source code ]
procedure equiv: compare values for equivalence
link equiv
February 20, 1996; Ralph E. Griswold
This file is in the public domain.
equiv(s,y) compare arbitrary structures x and y ____________________________________________________________ The procedure equiv() tests for the "equivalence" of two values. For types other than structures, it does the same thing as x1 === x2. For structures, the test is for "shape". For example, equiv([],[]) succeeds. It handles loops, but does not recognize them as such. For example, given L1 := [] L2 := [] put(L1,L1) put(L2,L1) equiv(L1,L2) succeeds. The concept of equivalence for tables and sets is not quite right if their elements are themselves structures. The problem is that there is no concept of order for tables and sets, yet it is impractical to test for equivalence of their elements without imposing an order. Since structures sort by "age", there may be a mismatch between equivalent structures in two tables or sets. Note: The procedures equiv and ldag have a trailing argument that is used on internal recursive calls; a second argument must not be supplied by the user.
[ Summary entry | Source code ]
link escape
April 16, 1993; William H. Mitchell
Contributors: Ralph E. Griswold and Alan Beale
This file is in the public domain.
The procedure escape(s) produces a string in which Icon quoted literal escape conventions in s are replaced by the corresponding characters. For example, escape("\\143\\141\\164") produces the string "cat".
[ Summary entry | Source code ]
link escapesq
May 13, 1994; Robert J. Alexander
This file is in the public domain.
Procedure kit for dealing with escape sequences in Icon character string representations. Note that Icon escape sequences are very similar to C escapes, so this works for C strings, too. escapeseq() -- a matching procedure for Icon string escape sequences escchar() -- produces the character value of an Icon string escape sequence escape() -- converts a string with escape sequences (as in Icon string representation) to the string it represents with escape quotedstring() -- matching routine for a quoted string.
[ Summary entry | Source code ]
link eval
March 3, 1996; Ralph E. Griswold
This file is in the public domain.
This procedure analyzes a string representing an Icon function or procedure call and evaluates the result. Operators can be used in functional form, as in "*(2,3)". This procedure cannot handle nested expressions or control structures. It assumes the string is well-formed. The arguments can only be Icon literals. Escapes, commas, and parentheses in strings literals are not handled. In the case of operators that are both unary and binary, the binary form is used.
[ Summary entry | Source code ]
procedure evallist: list of values generated by Icon expression
link evallist
July 15, 1995; Ralph E. Griswold
Requires: system(), /tmp, pipes
This file is in the public domain.
This procedure takes an expression, produces a program encapsulating it, and puts the results written by the program in a list. It is called as evallist(expr, n, ucode, ...) where expr is an expression (normally a generator), n is the maximum size of the list, and the trailing arguments are ucode files to link with the expression.
[ Summary entry | Source code ]
link eventgen
May 23, 1996; Ralph E. Griswold
This file is in the public domain.
This program is designed to be linked with the output of the meta-variant translator. It is designed to insert event-reporting code in Icon programs. ____________________________________________________________ Bug: The invocable declaration is not handled properly. "invocable all" will get by, but some other forms produce syntax errors. The problem is in the meta-variant translator itself, not in this program.
[ Summary entry | Source code ]
link everycat
April 25, 1992; Ralph E. Griswold
This file is in the public domain.
everycat(x1, x2, ...) generates the concatenation of every string from !x1, !x2, ... . For example, if first := ["Mary", "Joe", "Sandra"] last := ["Smith", "Roberts"] then every write(everycat(first, " ", last)) writes Mary Smith Mary Roberts Joe Smith Joe Roberts Sandra Smith Sandra Roberts Note that x1, x2, ... can be any values for which !x1, !x2, ... produce strings or values convertible to strings. In particular, in the example above, the second argument is a one-character string " ", so that !" " generates a single blank.
[ Summary entry | Source code ]
procedure pfl2str: pattern-form to plain string procedure pfl2pwl: pattern form to Painter expression procedure pfl2gxp: pattern form to generating expression procedure pwl2pfl: Painter expression to pattern form
link expander
May 2, 2001; Ralph E. Griswold
This file is in the public domain.
pfl2str(pattern) expands pattern-form expressions, which have the form [<expr><op><expr>] to the corresponding string. The value of <op> determines the operation to be performed. pfl2gxp(pattern) expands pattern-form expressions into generators that, when compiled and evaluated, produce the corresponding string. pfl2pwl(pattern) converts pattern-form expressions to Painter's weaving language.
[ Summary entry | Source code ]
procedure exprfile: pipe for Icon expression procedure exec_expr: execute expression in lists procedure plst2pstr: convert program list to string procedure pstr2plst: convert program string to list procedure ucode: create ucode file
link exprfile
August 5, 1997; Ralph E. Griswold
Requires: system(), pipes, /tmp
This file is in the public domain.
exprfile(exp, link, ...) produces a pipe to a program that writes all the results generated by exp. The trailing arguments name link files needed for the expression. exprfile() closes any previous pipe it opened and deletes its temporary file. Therefore, exprfile() cannot be used for multiple expression pipes. If the expression fails to compile, the global expr_error is set to 1; otherwise 0. exec_expr(expr_list, links[]) generates the results of executing the expression contained in the lists expr_list with the specified links. plst2pstr(L) converts the list of Icon programs lines in L to a string with separating newlines. pstr2plst(s) converts the string of Icon program lines (separated by newlines) to a list of lines. ucode(file) produces a ucode file from the Icon program in file.
[ Summary entry | Source code ]
procedure divisors: generate the divisors of n procedure divisorl: return list of divisors of n procedure factorial: return n! (n factorial) procedure factors: return list of factors procedure genfactors: generate prime factors of integer procedure gfactorial: generalized factorial procedure pfactors: primes that divide integer procedure ispower: test for integer power procedure isprime: test for primality procedure nxtprime: next prime beyond n procedure prdecomp: prime decomposition procedure prime: generate primes procedure primel: primes from list procedure primorial: product of primes procedure sfactors: return factors in string form procedure squarefree: test for square-free number
link factors
January 23, 2002; Ralph E. Griswold and Gregg M. Townsend
Requires: Large-integer arithmetic; prime.lst for primel() and primorial().
This file is in the public domain.
This file contains procedures related to factorization and prime numbers. divisors(n) generates the divisors of n. divisorl(n) returns a list of the divisors of n. factorial(n) returns n!. It fails if n is less than 0. factors(i, j) returns a list containing the prime factors of i limited to maximum value j; default, no limit. genfactors(i, j) like factors(), except factors are generated as they are found. gfactorial(n, i) generalized factorial; n x (n - i) x (n - 2i) x ... ispower(i, j) succeeds and returns root if i is k^j isprime(n) succeeds if n is a prime. nxtprime(n) returns the next prime number beyond n. pfactors(i) returns a list containing the primes that divide i. prdecomp(i) returns a list of exponents for the prime decomposition of i. prime() generates the primes. primel() generates the primes from a precompiled list. primorial(i,j) product of primes j <= i; j defaults to 1. sfactors(i, j) as factors(i, j), except output is in string form with exponents for repeated factors squarefree(i) succeeds if the factors of i are distinct ____________________________________________________________ Notes: Some of these procedures are not fast enough for extensive work. Factoring is believed to be a hard problem. factors() should only be used for small numbers.
[ Summary entry | Source code ]
link fastfncs
December 26, 1995; Ralph E. Griswold
See also: iterfncs.icn, memrfncs.icn, recrfncs.icn
This file is in the public domain.
These procedures implement integer-valued using the fastest method known to the author. "Fastest" does not mean "fast". acker(i, j) Ackermann's function fib(i) Fibonacci sequence g(k, i) Generalized Hofstader nested recurrence q(i) "Chaotic" sequence robbins(i) Robbins numbers
[ Summary entry | Source code ]
link feval
June 8, 1994; Ralph E. Griswold
This file is in the public domain.
This procedure analyzes a string representing an Icon function or procedure call and evaluates the result. It assumes the string is well-formed. The arguments can only be Icon literals. Escapes, commas, and parentheses in strings literals are not handled.
[ Summary entry | Source code ]
link filedim
April 30, 1993; Ralph E. Griswold
This file is in the public domain.
filedim(s, p) computes the number of rows and maximum column width of the file named s. The procedure p, which defaults to detab, i applied to each line. For example, to have lines left as is, use filedim(s, 1)
[ Summary entry | Source code ]
link filenseq
May 2, 2001; David A. Gamey
Requires: MS-DOS or another congenial operating system
This file is in the public domain.
This procedure is useful when you need to create the next file in a series of files (such as successive log files). Usage: fn := nextseqfilename( ".", "$", "log") returns the (non-existent) filename next in the sequence .\$*.log (where the * represents 1, 2, 3, ...) or fails
[ Summary entry | Source code ]
procedure filesize: file size
link filesize
July 9, 1998; Ralph E. Griswold
This file is in the public domain.
filesize(s) returns the number of characters in the file named s; it fails if s cannot be opened.
[ Summary entry | Source code ]
link findre
March 3, 1996; Richard L. Goerwitz
This file is in the public domain.
DESCRIPTION: findre() is like the Icon builtin function find(), except that it takes, as its first argument, a regular expression pretty much like the ones the Unix egrep command uses (the few minor differences are listed below). Its syntax is the same as find's (i.e. findre(s1,s2,i,j)), with the exception that a no- argument invocation wipes out all static structures utilized by findre, and then forces a garbage collection. ____________________________________________________________ (For those not familiar with regular expressions and the Unix egrep command: findre() offers a simple and compact wildcard-based search system. If you do a lot of searches through text files, or write programs which do searches based on user input, then findre is a utility you might want to look over.) IMPORTANT DIFFERENCES between find and findre: As noted above, findre() is just a find() function that takes a regular expression as its first argument. One major problem with this setup is that it leaves the user with no easy way to tab past a matched substring, as with s ? write(tab(find("hello")+5)) In order to remedy this intrinsic deficiency, findre() sets the global variable __endpoint to the first position after any given match occurs. Use this variable with great care, preferably assigning its value to some other variable immediately after the match (for example, findre("hello [.?!]*",s) & tmp := __endpoint). Otherwise, you will certainly run into trouble. (See the example below for an illustration of how __endpoint is used). IMPORTANT DIFFERENCES between egrep and findre: findre utilizes the same basic language as egrep. The only big difference is that findre uses intrinsic Icon data structures and escaping conven- tions rather than those of any particular Unix variant. Be care- ful! If you put findre("\(hello\)",s) into your source file, findre will treat it just like findre("(hello)",s). If, however, you enter '\(hello\)' at run-time (via, say, findre(!&input,s)), what Icon receives will depend on your operating system (most likely, a trace will show "\\(hello\\)"). ____________________________________________________________ BUGS: Space has essentially been conserved at the expense of time in the automata produced by findre(). The algorithm, in other words, will produce the equivalent of a pushdown automaton under certain circumstances, rather than strive (at the expense of space) for full determinism. I tried to make up a nfa -> dfa converter that would only create that portion of the dfa it needed to accept or reject a string, but the resulting automaton was actually quite slow (if anyone can think of a way to do this in Icon, and keep it small and fast, please let us all know about it). Note that under version 8 of Icon, findre takes up negligible storage space, due to the much improved hashing algorithm. I have not tested it under version 7, but I would expect it to use up quite a bit more space in that environment. IMPORTANT NOTE: Findre takes a shortest-possible-match approach to regular expressions. In other words, if you look for "a*", findre will not even bother looking for an "a." It will just match the empty string. Without this feature, findre would perform a bit more slowly. The problem with such an approach is that often the user will want to tab past the longest possible string of matched characters (say tab((findre("a*|b*"), __endpoint)). In circumstan- ces like this, please just use something like: s ? { tab(find("a")) & # or use Arb() from the IPL (patterns.icn) tab(many('a')) tab(many('b')) } or else use some combination of findre and the above. ____________________________________________________________ REGULAR EXPRESSION SYNTAX: Regular expression syntax is complex, and yet simple. It is simple in the sense that most of its power is concentrated in about a dozen easy-to-learn symbols. It is complex in the sense that, by combining these symbols with characters, you can represent very intricate patterns. I make no pretense here of offering a full explanation of regular expressions, their usage, and the deeper nuances of their syntax. As noted above, this should be gleaned from a Unix manual. For quick reference, however, I have included a brief summary of all the special symbols used, accompanied by an explanation of what they mean, and, in some cases, of how they are used (most of this is taken from the comments prepended to Jerry Nowlin's Icon-grep command, as posted a couple of years ago): ^ - matches if the following pattern is at the beginning of a line (i.e. ^# matches lines beginning with "#") $ - matches if the preceding pattern is at the end of a line . - matches any single character + - matches from 1 to any number of occurrences of the previous expression (i.e. a character, or set of paren- thesized/bracketed characters) * - matches from 0 to any number of occurrences of the previous expression \ - removes the special meaning of any special characters recognized by this program (i.e if you want to match lines beginning with a "[", write ^\[, and not ^[) | - matches either the pattern before it, or the one after it (i.e. abc|cde matches either abc or cde) [] - matches any member of the enclosed character set, or, if ^ is the first character, any nonmember of the enclosed character set (i.e. [^ab] matches any character _except_ a and b). () - used for grouping (e.g. ^(abc|cde)$ matches lines consist- ing of either "abc" or "cde," while ^abc|cde$ matches lines either beginning with "abc" or ending in "cde") ____________________________________________________________ EXAMPLE program: procedure main(a) while line := !&input do { token_list := tokenize_line(line,a[1]) every write(!token_list) } end procedure tokenize_line(s,sep) tmp_lst := [] s ? { while field := tab(findre(sep)|0) & mark := __endpoint do { put(tmp_lst,"" ~== field) if pos(0) then break else tab(mark) } } return tmp_lst end The above program would be compiled with findre (e.g. "icont test_prg.icn findre.icn") to produce a single executable which tokenizes each line of input based on a user-specified delimiter. Note how __endpoint is set soon after findre() succeeds. Note also how empty fields are excluded with "" ~==, etc. Finally, note that the temporary list, tmp_lst, is not needed. It is included here merely to illustrate one way in which tokens might be stored. Tokenizing is, of course, only one of many uses one might put findre to. It is very helpful in allowing the user to construct automata at run-time. If, say, you want to write a program that searches text files for patterns given by the user, findre would be a perfect utility to use. Findre in general permits more compact expression of patterns than one can obtain using intrinsic Icon scanning facilities. Its near complete compatibility with the Unix regexp library, moreover, makes for greater ease of porting, especially in cases where Icon is being used to prototype C code.
[ Summary entry | Source code ]
link ftype
March 10, 1998; Ralph E. Griswold
Requires: UNIX
This file is in the public domain.
This procedure returns the file identification produced by file(1).
[ Summary entry | Source code ]
link fullimag
May 23, 1996; Robert J. Alexander
This file is in the public domain.
fullimage() -- enhanced image()-type procedure that outputs all data contained in structured types. The "level" argument tells it how far to descend into nested structures (defaults to unlimited).
[ Summary entry | Source code ]
link gauss
September 19, 1991; Stephen B. Wampler
This file is in the public domain.
gauss_random(x, f) produces a Gaussian distribution about the value x. The value of f can be used to alter the shape of the Gaussian distribution (larger values flatten the curve...)
[ Summary entry | Source code ]
link gdl
May 2, 2001; Richard L. Goerwitz
Requires: UNIX or MS-DOS
This file is in the public domain.
Gdl returns a list containing everything in a directory (whose name must be passed as an argument to gdl). Nothing fancy. I use this file as a template, modifying the procedures according to the needs of the program in which they are used.
[ Summary entry | Source code ]
link gdl2
August 14, 1995; Richard L. Goerwitz and Charles Shartsis
Requires: UNIX or MS-DOS
This file is in the public domain.
Gdl returns a list containing everything in a directory (whose name must be passed as an argument to gdl). Nothing fancy. I use this file as a template, modifying the procedures according to the needs of the program in which they are used. NOTE: MSDOS results are all in lower case Modifications: 1) Fixed MSDOS routines. 2) Added gdlrec which does same thing as gdl except it recursively descends through subdirectories. May choose which Unix utility to use by passing in method parameter. See below.
[ Summary entry | Source code ]
procedure gedload: load GEDCOM data from file f procedure gedwalk: generate GEDCOM tree nodes in preorder procedure gedsub: find subrecords procedure gedval: find subrecord values procedure gedref: find referenced nodes procedure gedfnf: get first name first procedure gedlnf: get last name first procedure gednmf: format name procedure geddate: get canonical date procedure gedyear: get year procedure gedfind: find individual by name
link gedcom
March 25, 2002; Gregg M. Townsend
This file is in the public domain.
These procedures read and interpret GEDCOM files, a standard format for genealogy databases. ____________________________________________________________ gedload(f) loads GEDCOM data from file f and returns a gedcom record containing the following fields: tree root of tree of gednode records id table of labeled nodes, indexed by @ID@ fam list of FAM nodes (marriages) ind list of INDI nodes (individuals) The tree is composed of gednode records R containing these fields: level level id ID (label), including @...@ delimiters tag tag data data lnum line number parent parent node in tree ref referenced node, if any sub sub-entry list hcode unique hashcode, if INDI node gedwalk(tree) generates the nodes of the tree in preorder. Three procedures find descendants of a node based on a sequence of identifying tag strings: gedsub(R, tag...) generates subnodes specified by tag sequence gedval(R, tag...) generates data values of those subnodes gedref(R, tag...) generates nodes referenced by those subnodes Three procedures extract a person's name from an INDI record: gedfnf(R) produces "John Quincy Adams" form gedlnf(R) produces "Adams, John Quincy" form gednmf(R,f) produces an arbitrary format, substituting prefix, firstname, lastname, suffix for "P", "F", "L", "S" (respectively) in f geddate(R) finds the DATE subnode of a node and returns a string of at least 12 characters in a standard form such as "11 Jul 1767" or "abt 1810". It is assumed that the input is in English. gedyear(R) returns the year from the DATE subnode of a node. gedfind(g,s) generates the individuals under gedcom record g that are named by s, a string of whitespace-separated words. gedfind() generates each INDI node for which every word of s is matched by either a word of the individual's name or by the birth year. Matching is case-insensitive.
[ Summary entry | Source code ]
link gen
April 30, 1993; Ralph E. Griswold
This file is in the public domain.
These procedures are for use with code produced by a meta-variant translator. As given here, they produce an identity translation. Modifications can be made to effect variant translations.
[ Summary entry | Source code ]
link gener
March 25, 2002; Ralph E. Griswold
This file is in the public domain.
These procedures generate sequences of results. days() days of the week. hex() sequence of hexadecimal codes for numbers from 0 to 255 label(s,i) sequence of labels with prefix s starting at i multii(i, j) sequence of i * j i's months() months of the year octal() sequence of octal codes for numbers from 0 to 255 star(s) sequence consisting of the closure of s starting with the empty string and continuing in lexical order as given in s
[ Summary entry | Source code ]
procedure arandseq: arithmetic sequence with random intervals procedure arithseq: arithmetic sequence procedure beatty1seq: Beatty sequence 1 procedure beatty2seq: Beatty sequence 2 procedure catlnseq: generalized Catalan sequence procedure chaosseq: Hofstadter's chaotic sequence procedure connellseq: generalized Connell sequence procedure chexmorphseq: sequence of centered hexamorphic numbers procedure cfseq: continued-fraction sequence procedure eisseq: EIS A sequence procedure factseq: factorial sequence procedure fareyseq: Farey fraction sequence procedure fareydseq: Farey fraction denominator sequence procedure fareynseq: Farey fraction numerator sequence procedure fareyn1seq: Farey fraction numerator sequence, 1-based procedure fibseq: generalized Fibonacci sequence procedure fileseq: sequence from file procedure figurseq: sequence of figurate numbers procedure friendseq: random friendly sequence procedure geomseq: geometric sequence procedure hailseq: hailstone sequence procedure irepl: repeated sequence procedure linrecseq: synonym for lrrcseq procedure lrrcseq: linear recurrence sequence procedure meanderseq: generate meandering characters procedure mthueseq: Morse-Thue sequence procedure mthuegseq: generalized Morse-Thue sequence procedure multiseq: sequence of repeated integers procedure ngonalseq: sequence of polygonal numbers procedure nibonacciseq: n-valued Fibonacci generalization procedure partitseq: sequence of integer partitions procedure pellseq: generalized Pell sequence procedure perrinseq: perrin sequence procedure polyseq: sequence of polynomial evaluations procedure primeseq: sequence of prime numbers procedure powersofseq: powers procedure powerseq: powers sequence procedure rabbitseq: rabbit sequence procedure ratsseq: reverse add and then sort sequence procedure signaseq: signature sequence procedure spectseq: spectral sequence procedure srpseq: generate square-root palindrome procedure versumseq: generalized reversed-sum sequence procedure versumopseq: versum sequence with operator procedure vishwanathseq: random variation on Fibonacci sequence procedure zebra: black and white bands
link genrfncs
March 4, 2003; Ralph E. Griswold
Requires: co-expressions
This file is in the public domain.
These procedures generate sequences of results. arandseq(i, j) arithmetic sequence starting at i with randomly chosen increment between 1 and j arithseq(i, j) arithmetic sequence starting at i with increment j beatty1seq() Beatty's first sequence i * &phi beatty2seq() Beatty's second sequence i * &phi ^ 2 catlnseq(i) sequence of generalized Catalan numbers cfseq(i, j) continued-fraction sequence for i / j chaosseq() chaotic sequence chexmorphseq() sequence of centered hexamorphic numbers connellseq(p) generalized Connell sequence dietzseq(s) Dietz sequence for polynomial dressseq(i) dress sequence with increment i, default 1 (Schroeder) eisseq(i) EIS A sequence for i factseq() factorial sequence fareyseq(i, k) Farey fraction sequence; k = 0, the default, produces numerator sequence; k = 1 produces denominator sequence fibseq(i, j, k, m) generalized Fibonacci sequence (Lucas sequence) with initial values i and j and additive constant k. If m is supplied, the results are produced mod m. figurseq(i) series of ith figurate number fileseq(s, i) generate from file s; if i is null, lines are generated. Otherwise characters, except line terminators. friendseq(k) generate random friendly sequence from k values, 1 to k (in a friendly sequence, successive terms differ by 1). geomseq(i, j) geometric sequence starting at i with multiplier j hailseq(i) hailstone sequence starting at i irepl(i, j) j instances of i lindseq(f, i) generate symbols from L-system in file f; i if present overrides the number of generations specified in the L-system. logmapseq(k, x) logistic map lrrcseq(L1, L2) generalized linear recurrence with constant coefficients; L1 is a list of initial terms, L2 is a list of coefficients for n previous values, where n = *L2 meanderseq(s, n) sequences of all characters that contain all n-tuples of characters from s mthueseq() Morse-Thue sequence mthuegseq(i) Morse-Thue sequence for base i multiseq(i, j, k) sequence of (i * j + k) i's ngonalseq(i) sequence of the ith polygonal number nibonacciseq(values[]) generalized Fibonacci sequence that sums the previous n terms, where n = *values. partitseq(i, j, k) sequence of integer partitions of i with minimum j and maximum k pellseq(i, j, k) generalized Pell's sequence starting with i, j and using multiplier k perrinseq() Perrin sequence polyseq(coeff[]) polynomial in x evaluated for x := seq() primeseq() the sequence of prime numbers powerseq(i) sequence n ^ i, n = 1, 2, 3, 4, ... powersofseq(i) sequence i ^ n, n = 1, 2, 3, 4, ...n rabbitseq() rabbit sequence ratsseq(i) versumseq() with sort signaseq(r) signature sequence of r spectseq(r) spectral sequence integer(i * r), i - 1, 2, 3, ... srpseq(n, m) palindromic part of the continued-fraction sequence for sqrt(n^2+m) versumseq(i, j) generalized sequence of added reversed integers with seed i (default 196) and increment j (default 0) versumopseq(i, p) procedure p (default 1) applied to versumseq(i) vishwanathseq() random variation on Fibonacci sequence zebra(values[]) zebra colors, alternating 2 and 1, for number of times given by successive values
[ Summary entry | Source code ]
procedure geodat: define geodetic conversion procedure nadcon: define NAD data conversion procedure molodensky: define geodetic conversion procedure ellipsoid: return [a, 1/f] for named ellipsoid
link geodat
July 31, 2000; William S. Evans and Gregg M. Townsend
This file is in the public domain.
These procedures provide "projections" that convert among geodetic datums, which relate locations on the earth's surface to longitude and latitude coordinates. As measurement techniques improve, newer datums typically give slightly different values from older ones. The values returned here are used with the project() procedure of cartog.icn. geodat(s1, s2) defines a geodetic datum conversion. molodensky() performs an algorithmic datum conversion. nadcon(s1, s2) uses data files for more precise conversion. ellipsoid(s) return the parameters of the named ellipsoid. ____________________________________________________________ geodat(f, t) returns a projection from longitude and latitude in datum f to longitude and latitude in datum t. f and t are strings. If f and t equal "NAD83", "NAD27", "HARN", or "HPGN", geodat returns a nadcon projection. Failing that, geodat returns a molodensky projection. The input to the projection is a list of signed numeric values, angles measured in degrees, with each pair representing one location; longitude precedes latitude. The output is a list with the same form and length as the input list. ____________________________________________________________ nadcon(f, t) returns a projection from longitude and latitude in datum f to longitude and latitude in datum t. The strings f and t must each be one of "NAD83", "NAD27", "HARN", or "HPGN". The projection uses our implementation of the National Oceanic and Atmospheric Administration's (NOAA's) North American Datum Conversion Utility (NADCON); for more information, see http://www.ngs.noaa.gov/TOOLS/Nadcon/Nadcon.html nadcon() requires data grid (.loa and .laa) files, which must be found in the current directory or along the space-separated path given by the environment variable DPATH. These files can be downloaded from: http://www.cs.arizona.edu/icon/ftp/data/nadcon/ ftp://ftp.cs.arizona.edu/icon/data/nadcon/ The projection's input and output are lists of signed numbers. Output is properly rounded and so may not agree exactly with the equivalent NOAA programs. ____________________________________________________________ molodensky(dx, dy, dz, ain, fin, aout, fout) returns a projection from input longitude and latitude to output longitude and latitude. The projection uses the standard Molodensky transformation. The input datum is specified by an ellipsoid with parameters ain, the equatorial radius in metres, and fin, the flattening; and by three shift values dx, dy, and dz. The output datum is specified by an ellipsoid with parameters aout and fout. If dz is null, then dx and dy are interpreted as the names of an input and output datum. The names are the ID codes specified in NIMA TR 8350.2. The projection's input and output are lists of signed numbers. ____________________________________________________________ ellipsoid(s) return a list [a, 1/f] containing the defining parameters of the standard ellipsoid model named s; a is the equatorial radius and 1/f is the flattening factor. Names are listed in the code; the default is "WGS84". ____________________________________________________________ Ellipsoid and datum parameters are from: Department of Defense World Geodetic System 1984 National Imagery and Mapping Agency Technical Report TR8350.2 Third Edition, Amendment 1 (3 January 2000) ftp://ftp.nima.mil/pub/gg/tr8350.2/
[ Summary entry | Source code ]
link getchlib
May 2, 2001; Richard L. Goerwitz
Requires: UNIX
This file is in the public domain.
Implementing getch() is a much, much more complex affair under UNIX than it is under, say, MS-DOS. This library represents one, solution to the problem - one which can be run as a library, and need not be compiled into the run-time system. Note that it will not work on all systems. In particular, certain Suns (with a screwy stty command) and the NeXT 1.0 OS (lacking the -g option for stty) do not run getchlib properly. See the bugs section below for workarounds. Four basic utilities are included here: getch() - waits until a keystroke is available & returns it without displaying it on the screen getche() - same as getch() only with echo getse(s) - like getche() only for strings. The optional argument s gives getse() something to start with. Use this if, say, you want to read single characters in cbreak mode, but get more input if the character read is the first part of a longer command. If the user backspaces over everything that has been input, getse() fails. Returns on \r or \n. reset_tty() - absolutely vital routine for putting the cur- rent tty line back into cooked mode; call it before exiting or you will find yourself with a locked-up terminal; use it also if you must temporarily restore the terminal to cooked mode Note that getse() *must* be used in place of read(&input) if you are planning on using getch() or getche(), since read(&input) assumes a tty with "sane" settings. Warning: The routines below do not do any sophisticated output processing. As noted above, they also put your tty line in raw mode. I know, I know: "Raw is overkill - use cbreak." But in a world that includes SysV, one must pick a lowest common denomi- nator. And no, icanon != cbreak. BUGS: These routines will not work on systems that do not imple- ment the -g option for the stty command. The NeXT workstation is an example of such a system. Tisk, tisk. If you are on a BSD system where the network configuration makes stty | more impossible, then substitute /usr/5bin/stty (or whatever your system calls the System V stty command) for /bin/stty in this file. If you have no SysV stty command online, then you can try replacing every instance of "stty -g 2>&1" below with "stty -g 2>&1 1> /dev/tty" or something similar. ____________________________________________________________ Example program: The following program is a simple file viewer. To run, it needs to be linked with itlib.icn, iscreen.icn, and this file (getchlib.icn). procedure main(a) # Simple pager/file searcher for UNIX systems. Must be linked # with itlib.icn and iscreen.icn. local intext, c, s # Open input file intext := open(a[1],"r") | { write(&errout,"Can't open input file.") exit(1) } # Initialize screen clear() print_screen(intext) | exit(0) # Prompt & read input repeat { iputs(igoto(getval("cm"), 1, getval("li"))) emphasize() writes("More? (y/n or /search):") write_ce(" ") case c := getche() of { "y" : print_screen(intext) | break " " : print_screen(intext) | break "n" : break "q" : break "/" : { iputs(igoto(getval("cm"), 1, getval("li"))) emphasize() writes("Enter search string:") write_ce(" ") pattern := GetMoreInput() /pattern | "" == pattern & next # For more complex patterns, use findre() (IPL findre.icn) if not find(pattern, s := !intext) then { iputs(igoto(getval("cm"), 1, getval("li"))) emphasize() write_ce("String not found.") break } else print_screen(intext, s) | break } } } reset_tty() write() exit(0) end procedure GetMoreInput(c) local input_string static BS initial BS := getval("bc") | "\b" /c := "" if any('\n\r', chr := getch()) then return c else { chr == BS & fail writes(chr) input_string := getse(c || chr) | fail if any('\n\r', input_string) then fail else (return input_string) } end procedure print_screen(f,s) if /s then begin := 1 # Print top line, if one is supplied else { iputs(igoto(getval("cm"), 1, 1)) write_ce(s ? tab(getval("co") | 0)) begin := 2 } # Fill the screen with lines from f; clear and fail on EOF. every i := begin to getval("li") - 1 do { iputs(igoto(getval("cm"), 1, i)) if not write_ce(read(f) ? tab(getval("co") | 0)) then { # Clear remaining lines on the screen. every j := i to getval("li") do { iputs(igoto(getval("cm"), 1, j)) iputs(getval("ce")) } iputs(igoto(getval("cm"), 1, i)) fail } } return end procedure write_ce(s) normal() iputs(getval("ce")) | writes(repl(" ",getval("co") - *s)) writes(s) return end
[ Summary entry | Source code ]
link getkeys
May 2, 2001; Richard L. Goerwitz
Requires: UNIX (maybe MS-DOS; untested)
See also: gettext.icn
This file is in the public domain.
Getkeys(FNAME) generates all keys in FNAME in order of occurrence. See gettext.icn for a description of the requisite file structure for FNAME.
[ Summary entry | Source code ]
link getmail
August 19, 1996; Charles Shartsis
Requires: Icon Version 9 or greater
This file is in the public domain.
The getmail procedure reads a Unix/Internet type mail folder and generates a sequence of records, one per mail message. It fails when end-of-file is reached. Each record contains the message header and message text components parsed into separate record fields. The entire uninterpreted message (header and text) are also stored in the record. See the description of message_record below. The argument to getmail is either the name of a mail folder or the file handle for a mail folder which has already been opened for reading. If getmail is resumed after the last message is generated, it closes the mail folder and returns failure. If getmail generates an incomplete sequence (does not close the folder and return failure) and is then restarted (not resumed) on the same or a different mail folder, the previous folder file handle remains open and inaccessible. This may be a problem if done repeatedly since there is usually an OS-imposed limit on number of open file handles. Safest way to use getmail is using one of the below forms: message := message_record() every message := !getmail("folder_name") do { process message ... } message := message_record() coex := create getmail("folder_name") while message := @coex do { process message ... } Note that if message_record's are stored in a list, the records may be sorted by individual components (like sender, _date, _subject) using sortf function in Icon Version 9.0.
[ Summary entry | Source code ]
link getpaths
August 14, 1996; Richard L. Goerwitz
Requires: UNIX or MS-DOS
This file is in the public domain.
Suspends, in turn, the paths supplied as args to getpaths(), then all paths in the PATH environment variable. A typical invocation might look like: open(getpaths("/usr/local/lib/icon/procs") || filename) Note that getpaths() will be resumed in the above context until open succeeds in finding an existing, readable file. Getpaths() can take any number of arguments.
[ Summary entry | Source code ]
procedure gettext: search database by indexed term procedure get_offsets: binary search of index procedure sequential_searc brute-force database search
link gettext
May 2, 2001; Richard L. Goerwitz
This file is in the public domain.
Gettext() and associated routines allow the user to maintain a file of KEY/value combinations such that a call to gettext(KEY, FNAME) will produce value. Gettext() fails if no such KEY exists. Returns an empty string if the key exists, but has no associated value in the file, FNAME. The file format is simple. Keys belong on separate lines, marked as such by an initial colon+colon (::). Values begin on the line following their respective keys, and extend up to the next colon+colon-initial line or EOF. E.g. ::sample.1 or: ::sample.1 ::sample.2 Notice how the key above, sample.1, has :: prepended to mark it out as a key. The text you are now reading represents that key's value. To retrieve this text, you would call gettext() with the name of the key passed as its first argument, and the name of the file in which this text is stored as its second argument (as in gettext("sample.1","tmp.idx")). ::next.key etc... For faster access, an indexing utility is included, idxtext. Idxtext creates a separate index for a given text-base file. If an index file exists in the same directory as FNAME, gettext() will make use of it. The index becomes worthwhile (at least on my system) after the text- base file becomes longer than 5 kilobytes. Donts: 1) Don't nest gettext text-base files. 2) In searches, surround phrases with spaces or tabs in key names with quotation marks: "an example" 3) Don't modify indexed files in any way other than to append additional keys/values (unless you want to re-index). This program is intended for situations where keys tend to have very large values, and use of an Icon table structure would be unwieldy. BUGS: Gettext() relies on the Icon runtime system and the OS to make sure the last text/index file it opens gets closed. ____________________________________________________________ Invoke set_OS() before first call to gettext() or sequential_search() Tested with UNIX, OS/2, DOS, DOS-386, ProIcon
[ Summary entry | Source code ]
link gobject
July 22, 1997; Ralph E. Griswold
This file is in the public domain.
These declarations are provided for representing geometrical objects as records.
[ Summary entry | Source code ]
procedure read_graph: read graph procedure write_graph: write graph procedure closure: transitive closure of graph
link graphpak
May 2, 2001; Ralph E. Griswold
This file is in the public domain.
The procedures here use sets to represent directed graphs. See The Icon Programming Language, second edition, pp. 195-198. A value of type "graph" has two components: a list of nodes and a two-way lookup table. The nodes in turn contain pointers to other nodes. The two-way table maps a node to its name and vice-versa. Graph specifications are give in files in which the first line is a white-space separated list of node names and subsequent lines give the arcs, as in Tucson Phoenix Bisbee Douglas Flagstaff Tucson->Phoenix Tucson->Bisbee Bisbee->Bisbee Bisbee->Douglas Douglas->Phoenix Douglas->Tucson
[ Summary entry | Source code ]
procedure stypes: types of structure elements
link hetero
April 19, 1996; Ralph E. Griswold
This file is in the public domain.
[ Summary entry | Source code ]
link hexcvt
June 7, 1994; Robert J. Alexander
This file is in the public domain.
hex(s) -- Converts string of hex digits into an integer. hexstring(i,n,lc) -- Returns a string that is the hexadecimal representation of the argument. If n is supplied, a minimum of n digits appear in the result; otherwise there is no minimum, and negative values are indicated by a minus sign. If lc is non-null, lowercase characters are used instead of uppercase.
[ Summary entry | Source code ]
link hostname
April 30, 1993; Richard L. Goerwitz
Requires: UNIX, pipes
This file is in the public domain.
This procedure determines the name of the current host. It takes no arguments. Aborts with an error message if the necessary commands are not found. Geared specifically for UNIX machines.
[ Summary entry | Source code ]
procedure htchunks: generate chunks of HTML file procedure htrefs: generate references from HTML file procedure httag: extract name of HTML tag procedure htvals: generate values in HTML tag procedure urlmerge: merge URLs procedure canpath: put path in canonical form
link html
April 26, 2005; Gregg M. Townsend
This file is in the public domain.
These procedures parse HTML files: htchunks(f) generates the basic chunks -- tags and text -- that compose an HTML file. htrefs(f) generates the tagname/keyword/value combinations that reference other files. These procedures process strings from HTML files: httag(s) extracts the name of a tag. htvals(s) generates the keyword/value pairs from a tag. urlmerge(base,new) interprets a new URL in the context of a base. canpath(s) puts a path in canonical form ____________________________________________________________ htchunks(f) generates the HTML chunks from file f. It returns strings beginning with <!-- for unclosed comments (legal comments are deleted) < for tags (will end with ">" unless unclosed at EOF) anything else for text At this level entities such as & are left unprocessed and all whitespace is preserved, including newlines. ____________________________________________________________ htrefs(f) extracts file/url references from within an HTML file and generates a string of the form tagname keyword value for each reference. A single space character separates the three fields, but if no value is supplied for the keyword, no space follows the keyword. Tag and keyword names are always returned in upper case. Quotation marks are stripped from the value, but note that the value can contain spaces or other special characters (although by strict HTML rules it probably shouldn't). A table in the code determines which fields are references to other files. For example, with <IMG>, SRC= is a reference but WIDTH= is not. The table is based on the HTML 4.0 standard: http://www.w3.org/TR/REC-html40/ ____________________________________________________________ httag(s) extracts and returns the tag name from within an HTML tag string of the form "<tagname...>". The tag name is returned in upper case. ____________________________________________________________ htvals(s) generates the tag values contained within an HTML tag string of the form "<tagname kw=val kw=val ...>". For each keyword=value pair beyond the tagname, a string of the form keyword value is generated. One space follows the keyword, which is returned in upper case, and quotation marks are stripped from the value. The value itself can be an empty string. For each keyword given without a value, the keyword is generated in upper case with no following space. Parsing is somewhat tolerant of errors. ____________________________________________________________ urlmerge(base,new) interprets a full or partial new URL in the context of a base URL, returning the combined URL. Here are some examples of applying urlmerge() with a base value of "http://www.vcu.edu/misc/sched.html" and a new value as given: new result ------------- ------------------- #tuesday http://www.vcu.edu/misc/sched.html#tuesday bulletin.html http://www.vcu.edu/misc/bulletin.html ./results.html http://www.vcu.edu/misc/results.html images/rs.gif http://www.vcu.edu/misc/images/rs.gif ../ http://www.vcu.edu/ /greet.html http://www.vcu.edu/greet.html file:a.html file:a.html ____________________________________________________________ canpath(s) returns the canonical form of a file path by squeezing out components such as "./" and "dir/../".
[ Summary entry | Source code ]
link ibench
March 23, 2002; Ralph E. Griswold
This file is in the public domain.
Procedures to support benchmarking of Icon programs: Init__(prog) initialize for benchmarking Term__() terminate benchmarking Allocated__() get amounts allocated Collections__() get collections Regions__() get regions Signature__() show program/environment information Storage__() get storage Time__() show elapsed time Display__(data,name) show information ____________________________________________________________ The code to be timed is bracketed by calls to Init__(name) and Term__(), where name is used for tagging the results. The typical usage is: procedure main() [declarations] Init__(name) . . . Term__() end If the environment variable OUTPUT is set, program output is not suppressed. If the environment variable NOBENCH is set, benchmarking is not performed (and OUTPUT has no effect). This allows a program that links ibench to run in the ordinary way.
[ Summary entry | Source code ]
link ichartp
August 3, 2000; Richard L. Goerwitz
Requires: co-expressions
This file is in the public domain.
General: Ichartp implements a simple chart parser - a slow but easy-to-implement strategy for parsing context free grammars (it has a cubic worst-case time factor). Chart parsers are flexible enough to handle a lot of natural language constructs. They also lack many of the troubles associated with empty and left-recursive derivations. To obtain a parse, just create a BNF file, obtain a line of input, and then invoke parse_sentence(sentence, bnf_filename, start-symbol). Parse_sentence suspends successive edge structures corresponding to possible parses of the input sentence. There is a routine called edge_2_tree() that converts these edges to a more standard form. See the stub main() procedure for an example of how to make use of all these facilities. ____________________________________________________________ Implementation details: The parser itself operates in bottom-up fashion, but it might just as well have been coded top-down, or for that matter as a combination bottom-up/top-down parser (chart parsers don't care). The parser operates in breadth-first fashion, rather than walking through each alternative until it is exhausted. As a result, there tends to be a pregnant pause before any results appear, but when they appear they come out in rapid succession. To use a depth-first strategy, just change the "put" in "put(ch.active, new_e)" to read "push." I haven't tried to do this, but it should be that simple to implement. BNFs are specified using the same notation used in Griswold & Griswold, and as described in the IPL program "pargen.icn," with the following difference: All metacharacters (space, tab, vertical slash, right/left parends, brackets and angle brackets) are converted to literals by prepending a backslash. Comments can be include along with BNFs using the same notation as for Icon code (i.e. #-sign). ____________________________________________________________ Gotchas: Pitfalls to be aware of include things like <L> ::= <L> | ha | () (a weak attempt at a laugh recognizer). This grammar will accept "ha," "ha ha," etc. but will suspend an infinite number of possible parses. The right way to do this sort of thing is <L> ::= ha <S> | ha, or if you really insist on having the empty string as a possibility, try things like: <S> ::= () | <LAUGHS> <LAUGHS> ::= ha <LAUGHS> | ha Of course, the whole problem of infinite parses can be avoided by simply invoking the parser in a context where it is not going to be resumed, or else one in which it will be resumed a finite number of times. ____________________________________________________________ Motivation: I was reading Byte Magazine (vol. 17:2 [February, 1992]), and ran into an article entitled "A Natural Solution" (pages 237-244) in which a standard chart parser was described in terms of its C++ implementation. The author remarked at how his optimizations made it possible to parse a 14-word sentence in only 32 seconds (versus 146 for a straight Gazdar-Mellish LISP chart parser). 32 seconds struck me as hardly anything to write home about, so I coded up a quick system in Icon to see how it compared. This library is the result. I'm quite sure that this code could be very much improved upon. As it stands, its performance seems as good as the C++ parser in BYTE, if not better. It's hard to tell, though, seeing as I have no idea what hardware the guy was using. I'd guess a 386 running DOS. On a 386 running Xenix the Icon version beats the BYTE times by a factor of about four. The Icon compiler creates an executable that (in the above environment) parses 14-15 word sentences in anywhere from 6 to 8 seconds. Once the BNF file is read, it does short sentences in a second or two. If I get around to writing it, I'll probably use the code here as the basic parsing engine for an adventure game my son wants me to write. ____________________________________________________________ Here's a sample BNF file (taken, modified, from the BYTE Magazine article mentioned above). Note again the conventions a) that nonterminals be enclosed in angle brackets & b) that overlong lines be continued by terminating the preceding line with a backslash. Although not illustrated below, the metacharacters <, >, (, ), and | can all be escaped (i.e. can all have their special meaning neutralized) with a backslash (e.g. \<). Comments can also be included using the Icon #-notation. Empty symbols are illegal, so if you want to specify a zero-derivation, use "()." There is an example of this usage below. <S> ::= <NP> <VP> | <S> <CONJ> <S> <VP> ::= <VP> <CONJ> <VP> | <IV> ( () | <PP> ) | \ <TV> ( <NP> | <NP> <PP> | <NP> <VP> | <REL> <S> ) <NP> ::= <DET> ( <NP> | <ADJ> <NP> | <ADJ> <NP> <PP> | <NP> <PP> ) | \ <ADJ> <NP> | <N> | <N> <CONJ> <N> | \ <NP> <CONJ> <NP> <PP> ::= <P> ( <NP> | <ADJ> <NP> ) | <PP> <CONJ> <PP> <ADJ> ::= <ADJ> <CONJ> <ADJ> <CONJ> ::= and <DET> ::= the | a | his | her <NP> ::= her | he | they <N> ::= nurse | nurses | book | books | travel | arrow | arrows | \ fortune | fortunes | report <ADJ> ::= outrageous | silly | blue | green | heavy | white | red | \ black | yellow <IV> ::= travel | travels | report | see | suffer <TV> ::= hear | see | suffer <P> ::= on | of <REL> ::= that ____________________________________________________________ Addendum: Sometimes, when writing BNFs, one finds oneself repeatedly writing the same things. In efforts to help eliminate the need for doing this, I've written a simple macro facility. It involves one reserved word: "define." Just make sure it begins a line. It takes two arguments. The first is the macro. The second is its expansion. The first argument must not contain any spaces. The second, however, may. Here's an example: define <silluq-clause> ( <silluq-phrase> | \ <tifcha-silluq-clause> | \ <zaqef-silluq-clause> \ )
[ Summary entry | Source code ]
link identgen
August 3, 2000; Ralph E. Griswold
This file is in the public domain.
This program is designed to be linked with the output of the meta- translator. As given here, they produce an identity translation. Modifications can be made to effect different translations. ____________________________________________________________ Bug: The invocable declaration is not handled properly. "invocable all" will get by, but some other forms produce syntax errors. The problem is in the meta-translator itself, not in this program.
[ Summary entry | Source code ]
link identity
September 2, 1991; Ralph E. Griswold
This file is in the public domain.
This procedure produces an "identity" value for types that have one.
[ Summary entry | Source code ]
link ifncs
September 28, 1996; Ralph E. Griswold
See also: iftrace.icn
This file is in the public domain.
These are procedure wrappers for use in Icon function tracing. Don't let the apparent recursion fool you.
[ Summary entry | Source code ]
procedure iftrace: trace built-in functions
link iftrace
July 14, 1997; Stephen B. Wampler
Contributor: Ralph E. Griswold
This file is in the public domain.
These procedures provide tracing for Icon functions by using procedure wrappers to call the functions. iftrace(fncs[]) sets tracing for a list of function names. ____________________________________________________________ Note: The functions that can be traced and their procedure wrappers should be organized and coordinated to assure consistency and to allow for extended function repertoire.
[ Summary entry | Source code ]
link image
May 2, 2001; Michael Glass, Ralph E. Griswold, and David Yost
This file is in the public domain.
The procedure Image(x,style) produces a string image of the value x. The value produced is a generalization of the value produced by the Icon function image(x), providing detailed information about structures. The value of style determines the formatting and order of processing: 1 indented, with ] and ) at end of last item (default) 2 indented, with ] and ) on new line 3 puts the whole image on one line 4 as 3, but with structures expanded breadth-first instead of depth-first as for other styles. ____________________________________________________________ Tags are used to uniquely identify structures. A tag consists of a letter identifying the type followed by an integer. The tag letters are L for lists, R for records, S for sets, and T for tables. The first time a structure is encountered, it is imaged as the tag followed by a colon, followed by a representation of the structure. If the same structure is encountered again, only the tag is given. An example is a := ["x"] push(a,a) t := table() push(a,t) t[a] := t t["x"] := [] t[t] := a write(Image(t)) which produces T1:[ "x"->L1:[], L2:[ T1, L2, "x"]->T1, T1->L2] On the other hand, Image(t,3) produces T1:["x"->L1:[],L2:[T1,L2,"x"]->T1,T1->L2] Note that a table is represented as a list of entry and assigned values separated by ->. ____________________________________________________________ Problem: The procedure here really is a combination of an earlier version and two modifications to it. It should be re-organized to combine the presentation style and order of expansion. Bug: Since the table of structures used in a call to Image is local to that call, but the numbers used to generate unique tags are static to the procedures that generate tags, the same structure gets different tags in different calls of Image.
[ Summary entry | Source code ]
link inbits
November 3, 1991; Richard L. Goerwitz
See also: outbits.icn
This file is in the public domain.
This procedure, inbits(), re-imports data converted into writable form by outbits(). See the file outbits.icn for all the whys and hows.
[ Summary entry | Source code ]
procedure indices: generate indices
link indices
June 2, 1998; Ralph E. Griswold
This file is in the public domain.
indices(spec, last) produces a list of the integers given by the specification spec, which is a common separated list of either positive integers or integer spans, as in "1,3-10, ..." If last is specified, it it used for a span of the form "10-". In an integer span, the low and high values need not be in order. For example, "1-10" and "10-1" are equivalent. Similarly, indices need not be in order, as in "3-10, 1, ..." And empty value, as in "10,,12" is ignored. indices() fails if the specification is syntactically erroneous or if it contains a value less than 1.
[ Summary entry | Source code ]
link inserts
September 7, 1990; Robert J. Alexander
This file is in the public domain.
inserts() -- Inserts values into a table in which the same key can have more than one value (i.e., duplicate keys). The value of each element is a list of inserted values. The table must be created with default value &null.
[ Summary entry | Source code ]
link intstr
April 2, 1990; Robert J. Alexander
This file is in the public domain.
intstr() -- Creates a string consisting of the raw bits in the low order "size" bytes of integer i. This procedure is normally used for processing of binary data to be written to a file. Note that if large integers are supported, this procedure still will not work for integers larger than the implementation defined word size due to the shifting in of zero-bits from the left in the right shift operation.
[ Summary entry | Source code ]
procedure ClearOut: remove contents of output buffer procedure DOS_FileParts: parse DOSfile name procedure Flush: flush output buffer procedure GetBack: get back line written procedure LookAhead: look at next line procedure PutBack: put back line read procedure Read: read a line in buffered mode procedure ReadAhead: read ahead procedure Write: write in buffered mode procedure components: get components of file name procedure dopen: open file on DPATH procedure dosdir: process DOS directory procedure dosdirlist: get list of DOS directory procedure dosfiles: DOS file names procedure dosname: convert file name to DOS format procedure dpath: full path to file on DPATH procedure exists: test file existence procedure directory: succeed if name is a directory procedure fcopy: copy file procedure filelist: get list of files procedure filetext: read file into list procedure getdrive: get current DOS drive procedure getwd: get DOS working directory procedure pathfind: find file on path procedure pathload: load C function from $FPATH procedure readline: assemble backslash-continued lines procedure splitline: split line into pieces procedure suffix: find suffix of file name procedure tail: find tail of file name procedure tempfile: get temporary file procedure tempname: get temporary file name
link io
June 5, 2013; Ralph E. Griswold
Contributors: Paul Abrahams, Bob Alexander, Will Evans, David A. Gamey,
Richard L. Goerwitz, Will Menagarini, Charles Shartsis,
Carl Sturtivant, and Gregg Townsend.
Requires: Appropriate operating system for procedures used. Some
require loadfunc().
This file is in the public domain.
They provide facilities for handling input, output, and files. There are other modules in the Icon program library that deal with input and output. They are not included here because they conflict with procedures here or each other. ____________________________________________________________ File copying: fcopy(fn1, fn2) copies a file named fn1 to file named fn2. ____________________________________________________________ File existence: exists(name) succeeds if name exists as a file but fails otherwise. directory(name) succeeds if name exists as a directory but fails otherwise. ____________________________________________________________ File lists: filelist(s,x) returns a list of the file names that match the specification s. If x is nonnull, any directory is stripped off. At present it only works for UNIX. Users of other platforms are invited to add code for their platforms. ____________________________________________________________ Reading and writing files: filetext(f) reads the lines of f into a list and returns that list readline(file) assembles backslash-continued lines from the specified file into a single line. If the last line in a file ends in a backslash, that character is included in the last line read. splitline(file, line, limit) splits line into pieces at first blank after the limit, appending a backslash to identify split lines (if a line ends in a backslash already, that's too bad). The pieces are written to the specified file. ____________________________________________________________ Buffered input and output: ClearOut() remove contents of output buffer without writing Flush() flush output buffer GetBack() get back line writen LookAhead() look ahead at next line PutBack(s) put back a line Read() read a line ReadAhead(n) read ahead n lines Write(s) write a line ____________________________________________________________ Path searching: dopen(s) opens and returns the file s on DPATH. dpath(s) returns the path to s on DPATH. Both fail if the file is not found. pathfind(fname, path) returns the full path of fname if found along the list of directories in "path", else fails. If no path is given, getenv("DPATH") is the default. As is customary in Icon path searching, "." is prepended to the path. pathload(fname, entry) calls loadfunc() to load entry from the file fname found on the function path. If the file or entry point cannot be found, the program is aborted. The function path consists of the current directory, then getenv("FPATH"), to which iconx automatically appends the directory containing the standard libcfunc.so file. ____________________________________________________________ Parsing file names: suffix() parses a hierarchical file name, returning a 2-element list: [prefix,suffix]. E.g. suffix("/a/b/c.d") -> ["/a/b/c","d"] tail() parses a hierarchical file name, returning a 2-element list: [head,tail]. E.g. tail("/a/b/c.d") -> ["/a/b","c.d"]. components() parses a hierarchical file name, returning a list of all directory names in the file path, with the file name (tail) as the last element. For example, components("/a/b/c.d") -> ["/","a","b","c.d"]. ____________________________________________________________ Temporary files: tempfile(prefix, suffix, path, len) produces a "temporary" file that can be written. The name is chosen so as not to overwrite an existing file. The prefix and suffix are prepended and appended, respectively, to a randomly chosen number. They default to the empty string. The path is prepended to the file name; its default is "." The randomly chosen number is fit into a field of len (default 8) by truncation or right filling with zeros as necessary. It is the user's responsibility to remove the file when it is no longer needed. tempname(prefix, suffix, path, len) produces the name of a temporary file. ____________________________________________________________ DOS helpers: dosdir(diropts) generates records of type dirinfo for each file found in the directory, failing when no more files are available, as in every dirent := dosdir("*.*") do .... known problems: When used to traverse directories and sub-directories in nested every loops it doesn't work as expected - requires further investigation. Bypass by building lists of the subdirectories to be traversed. dosdirlist( dpath, dpart2, infotab ) returns a list containing the qualified file names for files in dpath and matching file patterns and/or options specified in dpart2. For example, dirlist := dosdirlist( "..", "*.* /o:n /a:r-d" ) returns a list of all read-only-non-directory files in the parent directory on a MS-DOS compatible system. If the optional infotab is specified, (1) it must be a table or a run time error will result (2) the contents of the table will be updated as follows a dirinfo record will be created for each filename (3) the filename will be the key to the table For example, t := table() dirlist := dosdirlist( "..", "*.* /o:n /a:r-d", t ) maxsize := 0 ; every maxsize <:= t[!dirlist].size calculates the maximum size of the files. dosfiles(pfn) accepts a DOS filename possibly containing wildcards. The filename can also include a drive letter and path. If the filename ends in "\" or ":", "*.*" is appended. The result sequence is a sequence of the filenames corresponding to pfn. dosname(s) converts a file name by truncating to the MS-DOS 8.3 format. Forward slashes are converted to backslashes and all letters are converted to lower case. Every disk drive on a MS-DOS system has a "working directory", which is the directory referred to by any references to that drive that don't begin with a backslash (& so are either direct references to that working directory, or paths relative to it). There is also 1 "current drive", & its working directory is called the "current working directory". Any paths that don't explicitly specify a drive refer to the current drive. For example, "name.ext" refers to the current drive's working directory, aka the current working directory; "\name.ext" refers to the current drive's root directory; & "d:name.ext" refers to the working directory on d:. It's reasonable to want to inquire any of these values. The CD command displays both, in the form of a complete path to the current working directory. However, passing such a path to either CD or the Icon function chdir() doesn't change to that dir on that drive; it changes that drive's working directory to the specified path without changing the current drive. The command to change the current drive is the system() function of a command consisting of just the drive letter followed by ":". This affects the design of inquiry functions. They could be implemented with system( "CD >" || ( name := tempname() ) ) & read(open(name)), but because this requires a slow disk access (which could fail on a full disk) it's unacceptable to need to do that *twice*, once for the drive & again for the dir; so if that strategy were used, it'd be necessary to return a structure containing the current drive & the working directory. That structure, whether table, list, or string, would then need to be either indexed or string-scanned to get the individual values, making the code cumbersome & obscure. It's much better to have 2 separate inquiry functions, 1 for each value; but for this to be acceptably efficient, it's necessary to forgo the disk access & implement the functions with interrupts. getdrive() returns the current drive as a lowercase string with the ":". getwd("g") getwd("g:") return the working directory on drive g:, or fail if g: doesn't exist. getwd() returns the current working directory. getwd(...) always returns lowercase. It prepends the relevant drive letter with its colon; that's harmless in a chdir(), & useful in an open(). DOS_FileParts(s) takes a DOS file name and returns a record containing various representations of the file name and its components. The name given is returned in the fullname field. Fields that cannot be determined are returned as empty strings.
[ Summary entry | Source code ]
link iolib
August 14, 1996; Richard L. Goerwitz (with help from Norman Azadian)
Requires: UNIX or MS-DOS, co-expressions
See also: itlib.icn, iscreen.icn
This file is in the public domain.
The following library represents a series of rough functional equivalents to the standard UNIX low-level termcap routines. It is not meant as an exact termlib clone. Nor is it enhanced to take care of magic cookie terminals, terminals that use \D in their termcap entries, or archaic terminals that require padding. This library is geared mainly for use with ANSI and VT-100 devices. Note that this file may, in most instances, be used in place of the older UNIX-only itlib.icn file. It essentially replaces the DOS- only itlibdos routines. For DOS users not familiar with the whole notion of generalized screen I/O, I've included extra documentation below. Please read it. The sole disadvantage of this over the old itlib routines is that iolib.icn cannot deal with archaic or arcane UNIX terminals and/or odd system file arrangements. Note that because these routines ignore padding, they can (unlike itlib.icn) be run on the NeXT and other systems which fail to implement the -g option of the stty command. Iolib.icn is also simpler and faster than itlib.icn. I want to thank Norman Azadian for suggesting the whole idea of combining itlib.icn and itlibdos.icn into one distribution, for suggesting things like letting drive specifications appear in DOS TERMCAP environment variables, and for finding several bugs (e.g. the lack of support for %2 and %3 in cm). Although he is loathe to accept this credit, I think he deserves it. ____________________________________________________________ Contents: setname(term) Use only if you wish to initialize itermlib for a terminal other than what your current environment specifies. "Term" is the name of the termcap entry to use. Normally this initialization is done automatically, and need not concern the user. getval(id) Works something like tgetnum, tgetflag, and tgetstr. In the spirit of Icon, all three have been collapsed into one routine. Integer valued caps are returned as integers, strings as strings, and flags as records (if a flag is set, then type(flag) will return "true"). Absence of a given capability is signalled by procedure failure. igoto(cm,destcol,destline) - NB: default 1 offset (*not* zero)! Analogous to tgoto. "Cm" is the cursor movement command for the current terminal, as obtained via getval("cm"). Igoto() returns a string which, when output via iputs, will cause the cursor to move to column "destcol" and line "destline." Column and line are always calculated using a *one* offset. This is far more Iconish than the normal zero offset used by tgoto. If you want to go to the first square on your screen, then include in your program "iputs(igoto(getval("cm"),1,1))." iputs(cp,affcnt) Equivalent to tputs. "Cp" is a string obtained via getval(), or, in the case of "cm," via igoto(getval("cm"),x,y). Affcnt is a count of affected lines. It is completely irrelevant for most modern terminals, and is supplied here merely for the sake of backward compatibility with itlib, a UNIX-only version of these routines (one which handles padding on archaic terminals). ____________________________________________________________ Notes for MS-DOS users: There are two basic reasons for using the I/O routines contained in this package. First, by using a set of generalized routines, your code will become much more readable. Secondly, by using a high level interface, you can avoid the cardinal programming error of hard coding things like screen length and escape codes into your programs. To use this collection of programs, you must do two things. First, you must add the line "device=ansi.sys" (or the name of some other driver, like zansi.sys, nansi.sys, or nnansi.sys [=new nansi.sys]) to your config.sys file. Secondly, you must add two lines to your autoexec.bat file: 1) "set TERM=ansi-mono" and 2) "set TERMCAP=\location\termcap." The purpose of setting the TERM variable is to tell this program what driver you are using. If you have a color system, you could use "ansi-color" instead of "ansi-mono," although for compatibility with a broader range of users, it would perhaps be better to stick with mono. The purpose of setting TERMCAP is to make it possible to determine where the termcap database file is located. The termcap file (which should have been packed with this library as termcap.dos) is a short database of all the escape sequences used by the various terminal drivers. Set TERMCAP so that it reflects the location of this file (which should be renamed as termcap, for the sake of consistency across UNIX and MS-DOS spectra). If desired, you can also try using termcap2.dos. Certain games work a lot better using this alternate file. To try it out, rename it to termcap, and set the environment variable TERMCAP to its location. Although the authors make no pretense of providing here a complete introduction to the format of the termcap database file, it will be useful, we believe, to explain a few basic facts about how to use this program in conjunction with it. If, say, you want to clear the screen, add the line, iputs(getval("cl")) to your program. The function iputs() outputs screen control sequences. Getval retrieves a specific sequence from the termcap file. The string "cl" is the symbol used in the termcap file to mark the code used to clear the screen. By executing the expression "iputs(getval("cl"))," you are 1) looking up the "cl" (clear) code in the termcap database entry for your terminal, and the 2) outputting that sequence to the screen. Some other useful termcap symbols are "ce" (clear to end of line), "ho" (go to the top left square on the screen), "so" (begin standout mode), and "se" (end standout mode). To output a boldfaced string, str, to the screen, you would write - iputs(getval("so")) writes(str) iputs(getval("se")) You can also write "writes(getval("so") || str || getval("se")), but this would make reimplementation for UNIX terminals that require padding rather difficult. It is also heartily to be recommended that MS-DOS programmers try not to assume that everyone will be using a 25-line screen. Most terminals are 24-line. Some 43. Some have variable window sizes. If you want to put a status line on, say, the 2nd-to-last line of the screen, then determine what that line is by executing "getval("li")." The termcap database holds not only string-valued sequences, but numeric ones as well. The value of "li" tells you how many lines the terminal has (compare "co," which will tell you how many columns). To go to the beginning of the second-to-last line on the screen, type in: iputs(igoto(getval("cm"), 1, getval("li")-1)) The "cm" capability is a special capability, and needs to be output via igoto(cm,x,y), where cm is the sequence telling your computer to move the cursor to a specified spot, x is the column, and y is the row. The expression "getval("li")-1" will return the number of the second-to-last line on your screen.
[ Summary entry | Source code ]
link iscreen
May 2, 2001; Richard L. Goerwitz
Requires: UNIX
See also: boldface.icn
This file is in the public domain.
This file contains some rudimentary screen functions for use with itlib.icn (termlib-like routines for Icon). clear() - clears the screen (tries several methods) emphasize() - initiates emphasized (usu. = reverse) mode boldface() - initiates bold mode blink() - initiates blinking mode normal() - resets to normal mode message(s) - displays message s on 2nd-to-last line underline() - initiates underline mode status_line(s,s2,p) - draws status line s on the 3rd-to-last screen line; if s is too short for the terminal, s2 is used; if p is nonnull then it either centers, left-, or right-justi- fies, depending on the value, "c," "l," or "r." clear_emphasize() - horrible way of clearing the screen to all- emphasize mode; necessary for many terminals
[ Summary entry | Source code ]
link iterfncs
May 2, 2001; Ralph E. Griswold
See also: fastfncs.icn, memrfncs.icn, and recrfncs.icn
This file is in the public domain.
These procedures implement commonly referenced ``text-book'' recursively defined functions, but using iteration. acker(i, j) Ackermann's function fib(i, j) Generalized Fibonacci (Lucas) sequence
[ Summary entry | Source code ]
link itlib
September 2, 2010; Richard L. Goerwitz
Contributor: Clinton L. Jeffery
Requires: UNIX, co-expressions
See also: iscreen.icn, iolib.icn, itlibdos.icn
This file is in the public domain.
The following library represents a series of rough functional equivalents to the standard UNIX low-level termcap routines. They are not meant as exact termlib clones. Nor are they enhanced to take care of magic cookie terminals, terminals that use \D in their termcap entries, or, in short, anything I felt would not affect my normal, day-to-day work with ANSI and vt100 terminals. There are some machines with incomplete or skewed implementations of stty for which itlib will not work. See the BUGS section below for work- arounds. ____________________________________________________________ setname(term) Use only if you wish to initialize itermlib for a terminal other than what your current environment specifies. "Term" is the name of the termcap entry to use. Normally this initialization is done automatically, and need not concern the user. getval(id) Works something like tgetnum, tgetflag, and tgetstr. In the spirit of Icon, all three have been collapsed into one routine. Integer valued caps are returned as integers, strings as strings, and flags as records (if a flag is set, then type(flag) will return "true"). Absence of a given capability is signalled by procedure failure. igoto(cm,destcol,destline) - NB: default 1 offset (*not* zero)! Analogous to tgoto. "Cm" is the cursor movement command for the current terminal, as obtained via getval("cm"). Igoto() returns a string which, when output via iputs, will cause the cursor to move to column "destcol" and line "destline." Column and line are always calculated using a *one* offset. This is far more Iconish than the normal zero offset used by tgoto. If you want to go to the first square on your screen, then include in your program "iputs(igoto(getval("cm"),1,1))." iputs(cp,affcnt) Equivalent to tputs. "Cp" is a string obtained via getval(), or, in the case of "cm," via igoto(getval("cm"),x,y). Affcnt is a count of affected lines. It is only relevant for terminals which specify proportional (starred) delays in their termcap entries. ____________________________________________________________ BUGS: I have not tested these routines much on terminals that require padding. These routines WILL NOT WORK if your machine's stty command has no -g option (tisk, tisk). This includes 1.0 NeXT workstations, and some others that I haven't had time to pinpoint. If you are on a BSD box, try typing "sh -c 'stty -g | more'" it may be that your stty command is too clever (read stupid) to write its output to a pipe. The current workaround is to replace every in- stance of /bin/stty with /usr/5bin/stty (or whatever your system calls the System V stty command) in this file. If you have no SysV stty command online, try replacing "stty -g 2>&1" below with, say, "stty -g 2>&1 1> /dev/tty." If you are using mainly modern ter- minals that don't need padding, consider using iolib.icn instead of itlib.icn.
[ Summary entry | Source code ]
link itlibdos
August 14, 1996; Richard L. Goerwitz
Requires: MS-DOS, coexpressions
See also: iscreen.icn, iolib.icn, itlib.icn
This file is in the public domain.
The following library represents a series of rough functional equivalents to the standard UNIX low-level termcap routines. They are not meant as exact termlib clones. Nor are they enhanced to take care of magic cookie terminals, terminals that use \D in their termcap entries, or, in short, anything I felt would not affect my normal, day-to-day work with ANSI and vt100 terminals. At this point I'd recommend trying iolib.icn instead of itlibdos.icn. Iolib is largely DOS-UNIX interchangeable, and it does pretty much every- thing itlibdos.icn does. ____________________________________________________________ Notes on the MS-DOS version: There are two basic reasons for using the I/O routines contained in this package. First, by using a set of generalized routines, your code will become much more readable. Secondly, by using a high level interface, you can avoid the cardinal programming error of hard coding things like screen length and escape codes into your programs. To use this collection of programs, you must do two things. First, you must add the line "device=ansi.sys" (or the name of some other driver, like zansi.sys, nansi.sys, or nnansi.sys [=new nansi.sys]) to your config.sys file. Secondly, you must add two lines to your autoexec.bat file: 1) "set TERM=ansi-mono" and 2) "set TERMCAP=\location\termcap." The purpose of setting the TERM variable is to tell this program what driver you are using. If you have a color system, use "ansi-color" instead of "ansi-mono," and if you are using nansi or zansi instead of vanilla ansi, use one of these names instead of the "ansi" (e.g. "zansi-mono"). The purpose of setting TERMCAP is to make it possible to determine where the termcap file is located. The termcap file (which should have been packed with this library as termcap.dos) is a short database of all the escape sequences used by the various terminal drivers. Set TERMCAP so that it reflects the location of this file (which should be renamed as termcap, for the sake of consistency with the UNIX version). Naturally, you must change "\location\" above to reflect the correct path on your system. With some distributions, a second termcap file may be included (termcap2.dos). Certain games work a lot better using this alternate file. To try it out, rename it to termcap, and set TERMCAP to its location. Although I make no pretense here of providing here a complete introduction to the format of the termcap database file, it will be useful, I think, to explain a few basic facts about how to use this program in conjunction with it. If, say, you want to clear the screen, add the line, iputs(getval("cl")) to your program. The function iputs() outputs screen control sequences. Getval retrieves a specific sequence from the termcap file. The string "cl" is the symbol used in the termcap file to mark the code used to clear the screen. By executing the expression "iputs(getval("cl"))," you are 1) looking up the "cl" (clear) code in the termcap database entry for your terminal, and the 2) outputting that sequence to the screen. Some other useful termcap symbols are "ce" (clear to end of line), "ho" (go to the top left square on the screen), "so" (begin standout mode), and "se" (end standout mode). To output a boldfaced string, str, to the screen, you would write - iputs(getval("so")) writes(str) iputs(getval("se")) You could write "writes(getval("so") || str || getval("se")), but this would only work for DOS. Some UNIX terminals require padding, and iputs() handles them specially. Normally you should not worry about UNIX quirks under DOS. It is in general wise, though, to separate out screen control sequences, and output them via iputs(). It is also heartily to be recommended that MS-DOS programmers try not to assume that everyone will be using a 25-line screen. Some terminals are 24-line. Some 43. Some have variable window sizes. If you want to put a status line on, say, the 2nd-to-last line of the screen, then determine what that line is by executing "getval("li")." The termcap database holds not only string-valued sequences, but numeric ones as well. The value of "li" tells you how many lines the terminal has (compare "co," which will tell you how many columns). To go to the beginning of the second-to-last line on the screen, type in: iputs(igoto(getval("cm"), 1, getval("li")-1)) The "cm" capability is a special capability, and needs to be output via igoto(cm,x,y), where cm is the sequence telling your computer to move the cursor to a specified spot, x is the column, and y is the row. The expression "getval("li")-1" will return the number of the second-to-last line on your screen.
[ Summary entry | Source code ]
link itokens
March 3, 1996; Richard L. Goerwitz
Requires: coexpressions
This file is in the public domain.
This file contains itokens() - a utility for breaking Icon source files up into individual tokens. This is the sort of routine one needs to have around when implementing things like pretty printers, preprocessors, code obfuscators, etc. It would also be useful for implementing cut-down implementations of Icon written in Icon - the sort of thing one might use in an interactive tutorial. Itokens(f, x) takes, as its first argument, f, an open file, and suspends successive TOK records. TOK records contain two fields. The first field, sym, contains a string that represents the name of the next token (e.g. "CSET", "STRING", etc.). The second field, str, gives that token's literal value. E.g. the TOK for a literal semicolon is TOK("SEMICOL", ";"). For a mandatory newline, itokens would suspend TOK("SEMICOL", "\n"). Unlike Icon's own tokenizer, itokens() does not return an EOFX token on end-of-file, but rather simply fails. It also can be instructed to return syntactically meaningless newlines by passing it a nonnull second argument (e.g. itokens(infile, 1)). These meaningless newlines are returned as TOK records with a null sym field (i.e. TOK(&null, "\n")). NOTE WELL: If new reserved words or operators are added to a given implementation, the tables below will have to be altered. Note also that &keywords should be implemented on the syntactic level - not on the lexical one. As a result, a keyword like &features will be suspended as TOK("CONJUNC", "&") and TOK("IDENT", "features").
[ Summary entry | Source code ]
procedure itrcline: generate trace messages in file
link itrcline
July 14, 1997; Ralph E. Griswold
This file is in the public domain.
itrcline(f) generates lines from the file f that are Icon trace messages. It can, of course, be fooled.
[ Summary entry | Source code ]
procedure ivalue: convert string to Icon value
link ivalue
October 12, 1996; Ralph E. Griswold
This file is in the public domain.
This procedure turns a string from image() into the corresponding Icon value. It can handle integers, real numbers, strings, csets, keywords, structures, and procedures. For the image of a structure, it produces a result of the correct type and size, but any values in the structure are not likely to be correct, since they are not encoded in the image. For procedures, the procedure must be present in the environment in which ivalue() is evaluated. This generally is true for built-in procedures (functions). All keywords are supported even if image() does not produce a string of the form "&name" for them. The values produced for non-constant keywords are, of course, the values they have in the environment in which ivalue() is evaluated. ivalue() also can handle non-local variables (image() does not produce these), but they must be present in the environment in which ivalue() is evaluated.
[ Summary entry | Source code ]
link jumpque
May 9, 1992; Ralph E. Griswold
This file is in the public domain.
jumpque(queue, y) moves y to the head of the queue if it is in queue but just adds y to the head of the queue if it is not already in the queue. A copy of queue is returned; the argument is not modified.
[ Summary entry | Source code ]
procedure kmap: map letter with modifier key to lowercase
link kmap
July 15, 1995; Ralph E. Griswold
This file is in the public domain.
This procedure maps uppercase letters and the control modifier key in combination with letters into the corresponding lowercase letters. It is intended for use with graphic applications in which the modifier keys for shift and control are encoded in keyboard events.
[ Summary entry | Source code ]
link labeler
April 9, 1993; Gregg M. Townsend
This file is in the public domain.
This procedure produces a new label in sequence each time it's called. The labels consist of all possible combinations of the characters given in the argument the first time it is called. See star(s) in gener.icn for a generator that does the same thing (and much more concisely). ____________________________________________________________ Increment a counter and convert to a label.
[ Summary entry | Source code ]
link lastc
March 25, 2002; David A. Gamey
This file is in the public domain.
Descriptions: lastc( c, s, i1, i2 ) : i3 succeeds and produces i1, provided either - i1 is 1, or - s[i1 - 1] is in c and i2 is greater than i1 defaults: same as for any errors: same as for any findp( c, s1, s2, i1, i2 ) : i3, i4, ..., in generates the sequence of positions in s2 at which s1 occurs provided that: - s2 is preceded by a character in c, or is found at the beginning of the string i1 & i2 limit the search as in find defaults: same as for find errors: same as for find & lastc findw( c1, s1, c2, s2, i1, i2 ) : i3, i4, ..., in generates the sequence of positions in s2 at which s1 occurs provided that: - s2 is preceded by a character in c1, or is found at the beginning of the string; and - s2 is succeeded by a character in c2, or the end of the string i1 & i2 limit the search as in find defaults: same as for find errors: same as for find & lastc
[ Summary entry | Source code ]
link lastname
June 21, 2000; Ralph E. Griswold
This file is in the public domain.
Produces the last name of a name in conventional form. Obviously, it doesn't work for every possibility.
[ Summary entry | Source code ]
link lcseval
May 23, 1996; Ralph E. Griswold
Requires: large integers
This file is in the public domain.
rcseval(a, c, m) evaluates the constants used in a linear congruence recurrence for generating a sequence of pseudo-random numbers. a is the multiplicative constant, c is the additive constant, and m is the modulus. Any line of output starting with asterisks indicates a problem. See Donald E. Knuth, "Random Numbers" in The Art of Computer Programming, Vol. 2, Seminumerical Algorithms, Addison-Wesley, Reading, Massachusetts, 1969, pp. 1-160. ____________________________________________________________ Deficiency: The modulus test for a assumes m is a power of 2.
[ Summary entry | Source code ]
link levensht
August 25, 2010; Jeremy N. Cowgar
This file is in the public domain.
The procedure levenshtein(s1, s2) returns the minimum number of edit operations needed to transform string s1 into s2. Examples: levenshtein("day", "may") produces 1 levenshtein("cat", "dog") produces 3 Now, those are easy examples, but consider: levenshtein("Saturday", "Sunday") produces 3 Yes, 3. Delete "a" and "t" from Saturday (Surday), then change the "r" to an "n", and you have Sunday!
[ Summary entry | Source code ]
procedure lindgen: rewrite L-system procedure lindgenx: rewrite L-system
link lindgen
April 5, 1998; Ralph E. Griswold
This file is in the public domain.
lindgen() assumes a "full" mapping table; lindgenx() does not. Note that the first argument is a single character. At the top level it might be called as lindgen(!axiom, rewrite, gener)
[ Summary entry | Source code ]
link lindstrp
March 25, 2002; Ralph E. Griswold
This file is in the public domain.
Lindenmayer systems are usually are interpreted as specifications for drawing plant-like objects, fractals, or other geometric designs. This procedure illustrates that L-systems can be interpreted in other ways -- as striped patterns, for example. The procedure is called as lindstrp(prod, band_tbl) where prod is a "production" that is interpreted as being a sequence of one-character symbols, and band_tbl is a table with these symbols as keys whose corresponding values are specifications for bands of the form "color:width". An example of a table for the symbols A, B, and C is: band_tbl := table() band_tbl["A"] := "blue:3" band_tbl["B"] := "red:10" band_tbl["C"] := "black:5" With a table default of null, as above, symbols in prod that are not table keys are effectively ignored. Other table defaults can be used to produce different behaviors for such symbols. An example of a production is: "ABCBABC" The result is a string of band specifications for the striped pattern represented by prod. It can be converted to an image by using strplang.icn, but graphics are not necessary for the use of this procedure itself. One thing this procedure is useful for is developing an understanding of how to construct L-systems for specific purpose: L-systems for plant-like objects and fractals are require specialized knowledge and are difficult to construct, while stripes are simple enough for anyone to understand and develop L-systems for. ____________________________________________________________ See also linden.icn and lindsys.icn.
[ Summary entry | Source code ]
link list2tab
May 21, 1992; Ralph E. Griswold
See also: tab2list.icn, tab2rec.icn, rec2tab.icn
This file is in the public domain.
This procedure writes a list as a tab-separated string. Carriage returns in files are converted to vertical tabs.
[ Summary entry | Source code ]
procedure file2lst: create list from lines in file procedure imag2lst: convert limage() output to list procedure l_Bscan: begin list scanning procedure l_Escan: end list scanning procedure l_any: any() for list scanning procedure l_bal: bal() for list scanning procedure l_find: find() for list scanning procedure l_many: many() for list scanning procedure l_match: match() for list scanning procedure l_move: move() for list scanning procedure l_pos: pos() for list scanning procedure l_tab: tab() for list scanning procedure l_upto: upto() for list scanning procedure llayer: interleave lists with layering procedure lcompact: compact sequence procedure lclose: close open palindrome procedure lcomb: list combinations procedure ldecollate: list decollation procedure ldelete: delete specified list elements procedure ldupl: list term duplication procedure lequiv: compare lists for equivalence procedure levate: elevate values procedure lextend: list extension procedure lfliph: list horizontal flip (reversal) procedure lflipv: list vertical flip procedure limage: list image procedure lcollate: generalized list collation procedure lconstant: test list for all terms equal procedure lindex: generate indices for items matching x procedure linterl: list interleaving procedure llpad: list padding at left procedure lrunup: list run up procedure lrundown: list run up procedure lltrim: list left trimming procedure lmap: list mapping procedure lresidue: list residue procedure lpalin: list palindrome procedure lpermute: list permutations procedure lreflect: list reflection procedure lremvals: remove values from list procedure lrepl: list replication procedure lreverse: list reverse procedure lrotate: list rotation procedure lrpad: list right padding procedure lrtrim: list right trimming procedure lshift: shift list terms procedure lst2str: convert list to string procedure lswap: list element swap procedure lunique: keep only unique list elements procedure lmaxlen: size of largest list entry procedure lminlen: size of smallest list entry procedure sortkeys: extract keys from sorted list procedure sortvalues: extract values from sorted list procedure str2lst: list from string
link lists
March 5, 2003; Ralph E. Griswold
Contributor: Richard L. Goerwitz
This file is in the public domain.
file2lst(s) create list from lines in file imag2lst(s) convert limage() output to list l_Bscan(e1) begin list scanning l_Escan(l_OuterEnvir, e2) end list scanning l_any(l1,l2,i,j) any() for list scanning l_bal(l1,l2,l3,l,i,j bal() for list scanning l_find(l1,l2,i,j) find() for list scanning l_many(l1,l2,i,j) many() for list scanning l_match(l1,l2,i,j) match() for list scanning l_move(i) move() for list scanning l_pos(i) pos() for list scanning l_tab(i) tab() for list scanning l_upto(l1,l2,i,j) upto() for list scanning lclose(L) close open palindrome lcomb(L,i) list combinations lcompact(L) compact list, mapping out missing values ldecollate(I, L) list decollation ldelete(L, spec) list deletion ldupl(L, i) list term duplication lequiv(L1, L2) list equivalence levate(L, m, n) list elevation lextend(L, i) list extension lfliph(L) list horizontal flip (reversal) lflipv(L) list vertical flip limage(L) unadorned list image lindex(L, x) generate indices of L whose values are x lcollate(L1, L2, ...) list collation; like linterl() except stops on short list lconstant(L) succeeds and returns element if all are the same linterl(L1, L2) list interleaving llayer(L1, L2, ...) layer and interleave L1, L2, ... llpad(L, i, x) list padding at left lltrim(L, S) list left trimming lmap(L1,L2,L3) list mapping lpalin(L, x) list palindrome lpermute(L) list permutations lreflect(L, i) returns L concatenated with its reversal to produce palindrome; the values of i determine "end conditions" for the reversal: 0 omit first and last elements; default 1 omit first element 2 omit last element 3 don't omit element lremvals(L, x1, x2, ...) remove values from list lrepl(L, i) list replication lresidue(L, m, i) list residue lreverse(L) list reverse lrotate(L, i) list rotation lrpad(L, i, x) list right padding lrundown(L1, L2, L3) list run down lrunup(L1, L2, L3) list run up lrtrim(L, S) list right trimming lshift(L, i) shift list terms lst2str(L) string from concatenated values in L lswap(L) list element swap lunique(L) keep only unique list elements lmaxlen(L, p) returns the size of the largest value in L. If p is given, it is applied to each string as as a "length" procedure. The default for p is proc("*", 1). lminlen(L, p) returns the size of the smallest value in L. If p is given, it is applied to each string as as a "length" procedure. The default for p is proc("*", 1). sortkeys(L) returns list of keys from L, where L is the result of sorting a table with option 3 or 4. sortvalues(L) return list of values from L, where L is the result of sorting a table with option 3 or 4. str2lst(s, i) creates list with i-character lines from s. The default for i is 1. ____________________________________________________________ About List Mapping The procedure lmap(L1,L2,L3) maps elements of L1 according to L2 and L3. This procedure is the analog for lists of the built-in string-mapping function map(s1,s2,s3). Elements in L1 that are the same as elements in L2 are mapped into the corresponding ele- ments of L3. For example, given the lists L1 := [1,2,3,4] L2 := [4,3,2,1] L3 := ["a","b","c","d"] then lmap(L1,L2,L3) produces a new list ["d","c","b","a"] Lists that are mapped can have any kinds of elements. The operation x === y is used to determine if elements x and y are equivalent. All cases in lmap are handled as they are in map, except that no defaults are provided for omitted arguments. As with map, lmap can be used for transposition as well as substitution. Warning: If lmap is called with the same lists L2 and L3 as in the immediately preceding call, the same mapping is performed, even if the values in L2 and L3 have been changed. This improves performance, but it may cause unexpected effects. This ``caching'' of the mapping table based on L2 and L3 can be easily removed to avoid this potential problem. ____________________________________________________________ About List Scanning by Richard L. Goerwitz PURPOSE: String scanning is terrific, but often I am forced to tokenize and work with lists. So as to make operations on these lists as close to corresponding string operations as possible, I've implemented a series of list analogues to any(), bal(), find(), many(), match(), move(), pos(), tab(), and upto(). Their names are just like corresponding string functions, except with a prepended "l_" (e.g. l_any()). Functionally, the list routines parallel the string ones closely, except that in place of strings, l_find and l_match accept lists as their first argument. L_any(), l_many(), and l_upto() all take either sets of lists or lists of lists (e.g. l_tab(l_upto([["a"],["b"],["j","u","n","k"]])). Note that l_bal(), unlike the builtin bal(), has no defaults for the first four arguments. This just seemed appropriate, given that no precise list analogue to &cset, etc. occurs. The default subject for list scans (analogous to &subject) is l_SUBJ. The equivalent of &pos is l_POS. Naturally, these variables are both global. They are used pretty much like &subject and &pos, except that they are null until a list scanning expression has been encountered containing a call to l_Bscan() (on which, see below). Note that environments cannot be maintained quite as elegantly as they can be for the builtin string-scanning functions. One must use instead a set of nested procedure calls, as explained in the _Icon Analyst_ 1:6 (June, 1991), p. 1-2. In particular, one cannot suspend, return, or otherwise break out of the nested procedure calls. They can only be exited via failure. The names of these procedures, at least in this implementation, are l_Escan and l_Bscan. Here is one example of how they might be invoked: suspend l_Escan(l_Bscan(some_list_or_other), { l_tab(10 to *l_SUBJ) & { if l_any(l1) | l_match(l2) then old_l_POS + (l_POS-1) } }) Note that you cannot do this: l_Escan(l_Bscan(some_list_or_other), { l_tab(10 to *l_SUBJ) & { if l_any(l1) | l_match(l2) then suspend old_l_POS + (l_POS-1) } }) Remember, it's no fair to use suspend within the list scanning expression. l_Escan must do all the suspending. It is perfectly OK, though, to nest well-behaved list scanning expressions. And they can be reliably used to generate a series of results as well. ____________________________________________________________ Here's another simple example of how one might invoke the l_scan routines: procedure main() l := ["h","e","l","l","o"," ","t","t","t","h","e","r","e"] l_Escan(l_Bscan(l), { hello_list := l_tab(l_match(["h","e","l","l","o"])) every writes(!hello_list) write() # Note the nested list-scanning expressions. l_Escan(l_Bscan(l_tab(0)), { l_tab(l_many([[" "],["t"]]) - 1) every writes(!l_tab(0)) write() }) }) end The above program simply writes "hello" and "there" on successive lines to the standard output. ____________________________________________________________ PITFALLS: In general, note that we are comparing lists here instead of strings, so l_find("h", l), for instance, will yield an error message (use l_find(["h"], l) instead). The point at which I expect this nuance will be most confusing will be in cases where one is looking for lists within lists. Suppose we have a list, l1 := ["junk",[["hello"]," ",["there"]],"!","m","o","r","e","junk"] and suppose, moreover, that we wish to find the position in l1 at which the list [["hello"]," ",["there"]] occurs. If, say, we assign [["hello"]," ",["there"]] to the variable l2, then our l_find() expression will need to look like l_find([l2],l1) ____________________________________________________________ Extending scanning to lists is really very difficult. What I think (at least tonight) is that scanning should never have been restricted to strings. It should have been designed to operate on all homogenous one-dimensional arrays (vectors, for you LISPers). You should be able, in other words, to scan vectors of ints, longs, characters - any data type that seems useful. The only question in my mind is how to represent vectors as literals. Extending strings to lists goes beyond the bounds of scanning per-se. This library is therefore something of a stab in the dark.
[ Summary entry | Source code ]
link longstr
June 1, 1991; Jerry Nowlin
Contributors: Stephen B. Wampler, Kenneth Walker, Bob Alexander,
and Richard E. Goerwitz
This file is in the public domain.
longstr(l,s,i,j) works like any(), except that instead of taking a cset as its first argument, it takes instead a list or set of strings (l). Returns i + *x, where x is the longest string in l for which match(x,s,i,j) succeeds. Fails if no match occurs. Defaults: s &subject i &pos if s is defaulted, otherwise 1 j 0 Errors: The only manual error-checking that is done is to test l to be sure it is, in fact, a list or set. Errors such as non- string members in l, and non-integer i/j parameters, are caught by the normal Icon built-in string processing and sub- scripting mechanisms.
[ Summary entry | Source code ]
link lrgapprx
September 14, 1995; Ralph E. Griswold
This file is in the public domain.
This procedure produces an approximate of an integer value in the form n.nx10^n. It is primarily useful for large integers.
[ Summary entry | Source code ]
link lstfncs
April 23, 2001; Ralph E. Griswold
This file is in the public domain.
Links: genrfncs, numbers
[ Summary entry | Source code ]
procedure seqterp: interpret L-system output
link lterps
September 30, 2001; Ralph E. Griswold
This file is in the public domain.
Links: numbers
[ Summary entry | Source code ]
link lu
August 14, 1996; Ralph E. Griswold
This file is in the public domain.
lu_decomp(M, I) performs LU decomposition on the square matrix M using the vector I. Both M and I are modified in the process. The value returned is +1 or -1 depending on whether the number of row interchanges is even or odd. lu_decomp() is used in combination with lu_back_sub() to solve linear equations or invert matrices. lu_decomp() fails if the matrix is singular. lu_back_sub(M, I, B) solves the set of linear equations M x X = B. M is the matrix as modified by lu_decomp(). I is the index vector produced by lu_decomp(). B is the right-hand side vector and return with the solution vector. M and I are not modified by lu_back_sub() and can be used in successive calls of lu_back_sub() with different Bs. ____________________________________________________________ Acknowledgement: These procedures are based on algorithms given in "Numerical Recipes; The Art of Scientific Computing"; William H. Press, Brian P. Flannery, Saul A. Teukolsky. and William T. Vetterling; Cambridge University Press, 1986.
[ Summary entry | Source code ]
procedure makelsys: make L-system from list procedure readlsys: make L-system from a file
link makelsys
January 23, 1999; Ralph E. Griswold
This file is in the public domain.
These procedures coverts a list corresponding to an L-System into an L-System record. See lindsys.icn for documentation about format. See linden.dat for an example of input data. See also linden.icn for a graphics version.
[ Summary entry | Source code ]
link mapbit
December 5, 1995; Ralph E. Griswold
This file is in the public domain.
The procedure mapbit(s) produces a string of zeros and ones corresponding to the bit patterns for the characters of s. For example, mapbit("Axe") produces "010000010111100001100101".
[ Summary entry | Source code ]
link mapstr
March 3, 1996; Richard L. Goerwitz
This file is in the public domain.
Mapstrs(s, l1, l2) works like map(), except that instead of taking ordered character sequences (strings) as arguments 2 and 3, it takes ordered string sequences (lists). Suppose, for example, you wanted to bowdlerize a string by replacing the words "hell" and "shit" with "heck" and "shoot." You would call mapstrs as follows: mapstrs(s, ["hell", "shit"], ["heck", "shoot"]) In order to achieve reasonable speed, mapstrs creates a lot of static structures, and uses some extra storage. If you want to replace one string with another, it is overkill. Just use the IPL replace() routine (in strings.icn). If l2 is longer than l1, extra members in l2 are ignored. If l1 is longer, however, strings in l1 that have no correspondent in l2 are simply deleted. Mapstr uses a longest-possible-match approach, so that replacing ["hellish", "hell"] with ["heckish", "heck"] will work as one would expect.
[ Summary entry | Source code ]
link matchlib
September 2, 1991; Ralph E. Griswold
See also: parsgen.icn
This file is in the public domain.
These procedures perform low-level "lexical" matching for recursive-descent pattern matchers. rb_() match right bracket lb_() match left bracket rp_() match right parenthesis lp_() match left parenthesis vb_() match vertical bar nl_() match newline empty_() match empty string
[ Summary entry | Source code ]
procedure binocoef: binomial coefficient procedure cosh: hyperbolic cosine procedure sinh: hyperbolic sine procedure tanh: hyperbolic tanh
link math
December 26, 1995; Ralph E. Griswold
Requires: Large integer arithmetic for binocoef(n, k) for all but small
values of n and k.
This file is in the public domain.
binocoef(n, k) produces the binomial coefficient n over k. It fails unless 0 <= k <= n. cosh(r) produces the hyperbolic cosine of r. sinh(r) produces the hyperbolic sine of r. tanh(r) produces the hyperbolic tangent of r.
[ Summary entry | Source code ]
link matrix
December 2, 2000; Stephen B. Wampler and Ralph E. Griswold
This file is in the public domain.
This file contains procedures for matrix manipulation.
[ Summary entry | Source code ]
link matrix2
November 1, 2005; Arthur C. Eschenlauer
This file is in the public domain.
transpose_matrix(M) : L - produces a matrix R that is the transpose of M: R[j][i] = M[i][j] numeric_matrix(M) : L - produces a matrix R that is a copy of M except each element has been subjected to the numeric(x) function; if numeric fails for any element, numeric_matrix fails: R[i][j] = numeric(M[i][j]) scale_matrix(M,mult) : L - produces a new matrix R each of whose elements is mult times larger than its peer in M: R[i][j] := mult * M[i][j] scale_matrix(mult,M) : L - is a synonym for scale_matrix(M,mult). floor_matrix(M,min) : L - produces a matrix R that is a copy of M except each element is increased to min if necessary: R[i][j] := min <= M[i][j] | min floor_matrix(min,M) : L - is a synonym for floor_matrix(M,min). ceil_matrix(M,max) : L - produces a matrix R that is a copy of M except each element is increased to max if necessary: R[i][j] := max <= M[i][j] | max ceil_matrix(max,M) : L - is a synonym for ceil_matrix(M,max). sumsquares_matrix(M) : n - produces the sum of the squares of all terms in a matrix sum(for every i,j) (M[i][j])^2 sumsquaresdiff_matrix(M1,M2) : n - produces the sum of the squares of all terms in the difference between two matrices sum(for every i,j) (M1[i][j] - M2[i][j])^2 normalize_rows(M,t) : L - produce a row-scaled matrix such that, for every row i, the sum of the values in all columns is 1 R[i][j] /:= sum(for every J) M[i][J] t is a required minimum magnitude for row sums to avoid divide-by-zero errors normalize_rows(t,M) : L - synonym for normalize_rows(M,t) normalize_columns(M,t) : L - produce a column-scaled matrix such that, for every column i, the sum of the values in all rows is 1 such that their sum is 1 R[i][j] /:= sum(for every I) M[I][j] t is a required minimum magnitude for column sums to avoid divide-by-zero errors normalize_columns(t,M) : L - synonym for normalize_columns(M,t) sprintf_matrix(f,M) - produces a matrix R of strings whose elements are formatted (by the IPL sprintf routine) from the elements of M: R[i][j] := sprintf(f,M[i,j])
[ Summary entry | Source code ]
procedure memlog: log memory usage
link memlog
August 14, 1996; Gregg M. Townsend
This file is in the public domain.
memlog(f) writes a message to file f recording the current memory usage in the string and block regions. For each, three figures are written: amount in use, amount reserved, and number of collections. memlog does not perturb the figures: it requires no allocation itself. f defaults to &output. memlog() returns the total current usage.
[ Summary entry | Source code ]
link memrfncs
February 4, 1995; Ralph E. Griswold
See also: fastfncs, iterfncs.icn, and recrfncs.icn
This file is in the public domain.
These procedures implement commonly referenced ``text-book'' recursively defined functions using memory to avoid redundant calls. acker(i, j) Ackermann's function fib(i) Fibonacci sequence q(i) "Chaotic" sequence
[ Summary entry | Source code ]
procedure mixsort: mixed-case string sorting
link mixsort
August 30, 1996; Ralph E. Griswold
This file is in the public domain.
This procedure sorts tables like sort(T, i), except that the keys that are strings are sorted with case mixed. That is, keys such as "Volvo" and "voluntary" come out sorted "voluntary" followed by "Volvo" as if it were "volvo" instead (assuming ASCII). If a string appears in two case forms, as in "Volvo" and "volvo", one key is lost. At present, this procedure applies only to keys (i = 1 or 3). It could be extended to handle values (i = 2 or 3).
[ Summary entry | Source code ]
link models
May 1, 1993; Ralph E. Griswold
This file is in the public domain.
These procedures model built-in Icon functions. Their purpose is primarily pedagogical. See Icon Analyst 11, pp. 5-7.
[ Summary entry | Source code ]
link morse
June 26, 1990; Ralph E. Griswold, modified by Rich Morin
This file is in the public domain.
This procedure converts the string s to its Morse code equivalent. The version used is known both as International Morse Code and as Continental Code, and is used by radio amateurs (hams).
[ Summary entry | Source code ]
link mset
January 3, 1994; Jan P. de Ruiter
This file is in the public domain.
The idea of the mset type is that no two identical data-structures can be present in a set, where identity is defined as "containing the same elements". Definitions implicit in the procedure same_value(..,..): TYPE IDENTITY TEST all types === and if this test fails... integer = real = cset, string == record all fields have same value list all elements are the same, including ordering table same keys, and every key has the same associated value set contain the same elements
[ Summary entry | Source code ]
link namepfx
September 2, 1991; Ralph E. Griswold
This file is in the public domain.
Produces the "name prefix" from a name in standard form -- omitting any title, but picking up the first name and any initials. There are a lot more titles that should be added to this list. Obviously, it can't always produce the "correct" result.
[ Summary entry | Source code ]
link nestlist
November 1, 2005; Arthur C. Eschenlauer
This file is in the public domain.
Procedure s_list(L) produces a string-representation of a nested list. Procedure l_list(s) produces a nested list from s, its string representation. ____________________________________________________________ # demo for reading nested numeric array from a string, e.g., # [1,[2,3,[4]],[[5]]] procedure main( ) local line, m, i while line := read( ) do if m := l_list( line ) then write( s_list( m ) ) end
[ Summary entry | Source code ]
procedure ngrams: n-grams with count procedure ngramset: n-grams set
link ngrams
March 20, 1998; Ralph E. Griswold
This file is in the public domain.
The procedure ngrams(s, n, c, t) generates a tabulation of the n-grams in the specified string. If c is non-null, it is used as the set of characters from which n-grams are taken (other characters break n-grams). The default for c is the upper- and lowercase letters. If t is non-null, the tabulation is given in order of frequency; otherwise in alphabetical order of n-grams. For backward compatibility, the first argument may be a file, in which case, it is read to provide the string.
[ Summary entry | Source code ]
link noncase
May 2, 2001; Robert J. Alexander
This file is in the public domain.
Kit of case-independent versions of Icon's built-in string-analysis procedures.
[ Summary entry | Source code ]
procedure adp: additive digital persistence procedure adr: additive digital root procedure amean: arithmetic mean procedure ceil: ceiling procedure commas: insert commas in number procedure decimal: decimal expansion of rational procedure decipos: position decimal point procedure digred: sum digits of integer repeated to one digit procedure digroot: digital root procedure digprod: product of digits procedure digsum: sum of digits procedure distseq: generate low to high nonsequentially procedure div: real division procedure fix: format real number procedure floor: floor procedure frn: format real number procedure gcd: greatest common divisor procedure gcdl: greatest common divisor of list procedure gmean: geometric mean procedure hmean: harmonic mean procedure large: detect large integers procedure lcm: least common multiple procedure lcml: least common multiple of list procedure mantissa: mantissa (fractional part) procedure max: maximum value procedure mdp: multiplicative digital persistence procedure mdr: multiplicative digital root procedure min: minimum value procedure mod1: modulus for 1-based integers procedure npalins: palindromic numbers procedure qmean: quadratic mean procedure residue: residue for j-based integers procedure roman: convert integer to Roman numeral procedure round: round real procedure sigma: synonym for digroot() procedure sign: sign procedure spell: spell integer in American English procedure sum: sum of numbers procedure trunc: truncate real procedure unroman: convert Roman numeral to integer
link numbers
March 17, 2014; Ralph E. Griswold
Contributors: Robert J. Alexander, Richard Goerwitz
Tim Korb, Gregg M. Townsend, David Gamey, Steve Wampler
This file is in the public domain.
These procedures deal with numbers in various ways: adp(i) additive digital persistence of i adr(i) additive digital root of i (same as digred()) amean ! L returns arithmetic mean of numbers in L. ceil(r) returns nearest integer to r away from 0. commas(s) inserts commas in s to separate digits into groups of three. decimal(i, j) decimal expansion of i / j; terminates when expansion terminates or the end of a recurring period is reached. The format of the returned value is <integer>.<seq>, where <seq> is a string a decimal digits if the expansion is finite but <pre>[<recurr>] if it is not, where <pre> is a string of decimal digits (possibly empty) before the recurring part. decipos(r, i, j) positions decimal point at i in real number r in field of width j. digprod(i) product of digits of i digred(i) reduction of number by adding digits until one digit is reached. digroot(i) same as digred(). digsum(i) sum of digits in i. distseq(i, j) generates i to j in distributed order. div(i, j) produces the result of real division of i by j. fix(i, j, w, d) formats i / j as a real (floating-point) number in a field of width w with d digits to the right of the decimal point, if possible. j defaults to 1, w to 8, and d to 3. If w is less than 3 it is set to 3. If d is less than 1, it is set to 1. The function fails if j is 0 or if the number cannot be formatted. floor(r) nearest integer to r toward 0. frn(r, w, d) format real number r into a string with d digits after the decimal point; a result narrower than w characters is padded on the left with spaces. Fixed format is always used; there is no exponential notation. Defaults: w 0, d 0 gcd(i, j) returns greatest common divisor of abs(i) and abs(j). gcdl ! L returns the greatest common divisor of the integers in list L. gmean ! L returns geometric mean of numbers in L. hmean ! L returns harmonic mean of numbers in L. large(i) succeeds if i is a large integer but fails otherwise. lcm(i, j) returns the least common multiple of i and j. lcml ! L returns the least common multiple of the integers in the list L. mantissa(r) mantissa (fractional part) of r. max ! L produces maximum of numbers in L. mdp(i) multiplicative digital persistence of i mdr(i) multiplicative digital root of i min ! L produces minimum of numbers in L. mod1(i, m) residue for 1-based indexing. npalins(n) generates palindromic n-digit numbers. qmean ! L returns quadratic mean (RMS) of numbers in L. residue(i, m, j) residue for j-based indexing. roman(i) converts i to Roman numerals. round(r) returns nearest integer to r. sigma(i) synonym for digroot(i) sign(r) returns sign of r. spell(i) spells out i in American English. sum ! L sum of numbers in list L trunc(r) returns nearest integer to r toward 0 unroman(s) converts Roman numerals to integers.
[ Summary entry | Source code ]
link openchk
March 14, 1995; David A. Gamey
This file is in the public domain.
Usage: OpenCheck() Subsequent opens and closes will write diagnostic information to &errout Useful for diagnosing situations where many files are opened and closed and there is a possibility that some files are not always being closed.
[ Summary entry | Source code ]
link opnames
December 2, 1991; Ralph E. Griswold
This file is in the public domain.
opnames() produces a table that maps virtual-machine instruction numbers to instruction names.
[ Summary entry | Source code ]
link opsyms
July 10, 1992; Ralph E. Griswold
This file is in the public domain.
opsyms() produces a table that maps virtual-machine instruction numbers for operators to operator symbols. The suffixes 1 and 2 are used for symbols that have both a unary and binary meaning.
[ Summary entry | Source code ]
link options
May 5, 2000; Robert J. Alexander and Gregg M. Townsend
This file is in the public domain.
options(arg, optstring,errproc) removes command options from the argument list of an Icon main procedure, returning a table of option values. ____________________________________________________________ options(arg,optstring,errproc) -- Get command line options. This procedure separates and interprets command options included in the main program argument list. Option names and values are removed from the argument list and returned in a table. On the command line, options are introduced by a "-" character. An option name is either a single printable character, as in "-n" or "-?", or a string of letters, numbers, and underscores, as in "-geometry". Valueless single-character options may appear in combination, for example as "-qtv". Some options require values. Generally, the option name is one argument and the value appears as the next argument, for example "-F file.txt". However, with a single-character argument name (as in that example), the value may be concatenated: "-Ffile.txt" is accepted as equivalent. Options may be freely interspersed with non-option arguments. An argument of "-" is treated as a non-option. The special argument "--" terminates option processing. Non-option arguments are returned in the original argument list for interpretation by the caller. An argument of the form @filename (a "@" immediately followed by a file name) causes options() to replace that argument with arguments retrieved from the file "filename". Each line of the file is taken as a separate argument, exactly as it appears in the file. Arguments beginning with - are processed as options, and those starting with @ are processed as nested argument files. An argument of "--" causes all remaining arguments IN THAT FILE ONLY to be treated as non-options (including @filename arguments). The parameters of options(arg,optstring,errproc) are: arg the argument list as passed to the main procedure. optstring a string specifying the allowable options. This is a concatenation, with optional spaces between, of one or more option specs of the form -name% where - introduces the option name is either a string of alphanumerics (any of a-z, A-Z, 0-9, and _) or any single printable character % is one of the following flag characters: ! No value is required or allowed : A string value is required + An integer value is required . A real value is required The leading "-" may be omitted for a single-character option. The "!" flag may be omitted except when needed to terminate a multi-character name. Thus, the following optstrings are equivalent: "-n+ -t -v -q -F: -geometry: -silent" "n+tvqF:-geometry:-silent" "-silent!n+tvqF:-geometry:" If "optstring" is omitted any single letter is assumed to be valid and require no data. errproc a procedure which will be called if an error is is detected in the command line options. The procedure is called with one argument: a string describing the error that occurred. After errproc() is called, options() immediately returns the outcome of errproc(), without processing further arguments. Already processed arguments will have been removed from "arg". If "errproc" is omitted, stop() is called if an error is detected. A table is returned containing the options that were specified. The keys are the specified option names. The assigned values are the data values following the options converted to the specified type. A value of 1 is stored for options that accept no values. The table's default value is &null. Upon return, the option arguments are removed from arg, leaving only the non-option arguments.
[ Summary entry | Source code ]
link outbits
November 3, 1991; Richard L. Goerwitz
See also: inbits.icn
This file is in the public domain.
In any number of instances (e.g. when outputting variable-length characters or fixed-length encoded strings), the programmer must fit variable and/or non-byte-sized blocks into standard 8-bit bytes. Outbits() performs this task. Pass to outbits(i, len) an integer i, and a length parameter (len), and outbits will suspend byte-sized chunks of i converted to characters (most significant bits first) until there is not enough left of i to fill up an 8-bit character. The remaining portion is stored in a buffer until outbits() is called again, at which point the buffer is combined with the new i and then output in the same manner as before. The buffer is flushed by calling outbits() with a null i argument. Note that len gives the number of bits there are in i (or at least the number of bits you want preserved; those that are discarded are the most significant ones). A trivial example of how outbits() might be used: outtext := open("some.file.name","w") l := [1,2,3,4] every writes(outtext, outbits(!l,3)) writes(outtext, outbits(&null,3)) # flush buffer List l may be reconstructed with inbits() (see inbits.icn): intext := open("some.file.name") l := [] while put(l, inbits(intext, 3)) Note that outbits() is a generator, while inbits() is not.
[ Summary entry | Source code ]
link packunpk
May 2, 2001; C. Tenaglia (modified by Richard L. Goerwitz)
This file is in the public domain.
Integers written directly as strings occupy much more space than they need to. One easy way to shrink them a bit is to "pack" them, i.e. convert each decimal digit into a four-byte binary code, and pack these four-bit chunks into eight-bit characters, which can be written to a file. Interestingly, packing decimal strings in this manner lends itself to unpacking by treating each character as a base-10 integer, and then converting it to base-16. Say we have an input string "99." Pack() would convert it to an internal representation of char(16*9 + 9), i.e. char(153). Unpack would treat this char(153) representation as a base-10 integer, and convert it to base 16 (i.e. 10r153 -> 16r99). The 99 is, of course, what we started with. Note that two unpack routines are provided here: The first, by Tanaglia, utilizes convert.icn from the IPL. The second, by Goerwitz, does not. They utilize very different methods, but both amount to basically the same thing. Goerwitz's routine returns an integer, though, and has no "width" argument.
[ Summary entry | Source code ]
link parscond
March 31, 1992; Ralph E. Griswold
See also: parsgen.icn
This file is in the public domain.
Procedure to condense a parse tree produced by the output of pargen.icn and produce the string that was parsed. The necessary record declaration is provided by the program with which is linked.
[ Summary entry | Source code ]
link partit
December 5, 1995; Ralph E. Griswold
This file is in the public domain.
partit(i, min, max) generates, as lists, the partitions of i; that is the ways that i can be represented as a sum of positive integers with minimum and maximum values. partcount(i, min, max) returns just the number of partitions. fibpart(i) returns a list of Fibonacci numbers that is a partition of i.
[ Summary entry | Source code ]
procedure pascal: Pascal triangle
link pascal
August 3, 2000; Ralph E. Griswold
Requires: large integers
This file is in the public domain.
This procedure writes numeric triangles as "carpets". The argument determines the number of rows written, default 16.
[ Summary entry | Source code ]
procedure PascalsTriangle: Pascal triangle row
link pascltri
August 7, 1997; Erik Eid
This file is in the public domain.
The procedure, when invoked by a call to PascalsTriangle(n), returns the nth row of Pascal's Triangle in list form. Pascal's Triangle is a mathematical structure in which each element of a row is the sum of the two elements directly above it. The first few levels are: Row 1: 1 Triangle stored as: [[1], 2: 1 1 [1, 1], 3: 1 2 1 [1, 2, 1], 4: 1 3 3 1 [1, 3, 3, 1], 5: 1 4 6 4 1 [1, 4, 6, 4, 1]] For example, PascalsTriangle(4) would return the list [1, 3, 3, 1]. The procedure fails if n is not an integer or if it is less than one.
[ Summary entry | Source code ]
link patch
June 18, 1990; Rich Morin
Requires: co-expressions
This file is in the public domain.
This procedure produces a sequence of edited items, reading a source stream (from) and a stream of difference records (diffs), as generated by dif.icn. An optional parameter (rev) causes the edits to be made in reverse. This allows an old stream to be regenerated from a new stream and an appropriate stream of difference records. The original patch(1) utility was written by Larry Wall, and is used widely in the UNIX community. See also diffu.icn and patchu.icn, the utility program versions of dif.icn and patch.icn. Usage: patch(old, diff) # patch old to new via diff patch(new, diff, rev) # patch new to old via diff
[ Summary entry | Source code ]
link patterns
June 10, 1988; Ralph E. Griswold
This file is in the public domain.
These procedures provide procedural equivalents for most SNOBOL4 patterns and some extensions. Procedures and their pattern equivalents are: Any(s) ANY(S) Arb() ARB Arbno(p) ARBNO(P) Arbx(i) ARB(I) Bal() BAL Break(s) BREAK(S) Breakx(s) BREAKX(S) Cat(p1,p2) P1 P2 Discard(p) /P Exog(s) \S Find(s) FIND(S) Len(i) LEN(I) Limit(p,i) P \ i Locate(p) LOCATE(P) Marb() longest-first ARB Notany(s) NOTANY(S) Pos(i) POS(I) Replace(p,s) P = S Rpos(i) RPOS(I) Rtab(i) RTAB(I) Span(s) SPAN(S) String(s) S Succeed() SUCCEED Tab(i) TAB(I) Xform(f,p) F(P) The following procedures relate to the application and control of pattern matching: Apply(s,p) S ? P Mode() anchored or unanchored matching (see Anchor and Float) Anchor() &ANCHOR = 1 if Mode := Anchor Float() &ANCHOR = 0 if Mode := Float In addition to the procedures above, the following expressions can be used: p1() | p2() P1 | P2 v <- p() P . V (approximate) v := p() P $ V (approximate) fail FAIL =s S (in place of String(s)) p1() || p2() P1 P2 (in place of Cat(p1,p2)) Using this system, most SNOBOL4 patterns can be satisfactorily transliterated into Icon procedures and expressions. For example, the pattern SPAN("0123456789") $ N "H" LEN(*N) $ LIT can be transliterated into (n <- Span('0123456789')) || ="H" || (lit <- Len(n)) Concatenation of components is necessary to preserve the pattern-matching properties of SNOBOL4. Caveats: Simulating SNOBOL4 pattern matching using the procedures above is inefficient.
[ Summary entry | Source code ]
link patword
December 2, 1995; Kenneth Walker
This file is in the public domain.
The procedure patword(s) returns a letter pattern in which each different character in s is assigned a letter. For example, patword("structural") returns "abcdebdcfg".
[ Summary entry | Source code ]
link pbkform
August 14, 1996; Robert J. Alexander
See also: pbkutil.icn, abkform.icn
This file is in the public domain.
Icon procedure set to read and write HP95LX phone book (.pbk) files. ____________________________________________________________ HP 95LX Phone Book File Format The HP 95LX Phone Book file is structured as a file identification record, followed by a variable number of phone book data records, and terminated by an end of file record. Each data record contains the information for one phone book entry. The format of these phone book records is described below. In the descriptions, the type <int> refers to a two byte integer stored least significant byte first, the type <char> refers to a one byte integer, and the type <ASCII> refers to a string of ASCII characters. HP 95LX Phone Book File Identification Record: Byte Offset Name Type Contents 0 ProductCode int -2 (FEh, FFh) 2 ReleaseNum int 1 (01h, 00h) 4 FileType char 3 (03h)
[ Summary entry | Source code ]
procedure AddTabbyPDCO: PDCO to add tabby to treadling procedure AllparAER: PDAE for parallel evaluation with repeats procedure AltPDCO: PDCO to model alternation procedure BinopPDCO: PDCO to apply binary operation to sequences procedure CFapproxPDCO: PDCO for continued-fraction approximations procedure ComparePDCO: PDCO to compare sequences procedure ComplintPDCO: PDCO to generate integers not in sequence procedure CondPDCO: PDCO for generalized Lisp conditional procedure CumsumPDCO: PDCO to produce cumulative sum procedure CycleparAER: PDAE for parallel evaluation with cycling procedure DecimatePDCO: PDCO to decimate sequence procedure DecimationPDCO: PDCO to create decimation sequence procedure DecollatePDCO: PDCO to decollate sequence procedure DeltaPDCO: PDCO to generate difference sequence procedure ElevatePDCO: PDCO to elevate sequence procedure EveryPDCO: PDCO to model iteration procedure ExtendSeqPDCO: PDCO to extend sequence procedure ExtractAER: PDAE to extract values procedure FifoAER: PDAE for reversal of lifo evaluation procedure GaltPDCO: PDCO to concatenate sequences procedure GconjPDCO: PDCO for generalized conjunction procedure HistoPDCO: histogram procedure IncreasingPDCO: PDCO to filter out non-increasing values procedure IndexPDCO: PDCO to select terms by position procedure InterPDCO: PDCO to interleave sequences procedure LcondPDCO: PDCO for Lisp conditional procedure LengthPDCO: PDCO to produce length of sequence procedure LifoAER: PDAE for standard lifo evaluation procedure LimitPDCO: PDCO to model limitation procedure ListPDCO: list from sequence procedure LowerTrimPDCO: lower trimming procedure MapPDCO: PDCO to map values procedure OddEvenPDCO: PDCO to force odd/even sequence procedure PalinPDCO: PDCO to produce palindromic sequence procedure ParallelPDCO: synonym for Inter procedure ParallelAER: PDAE for parallel evaluation procedure PatternPalinPDCO PDCO to produce pattern palindrome procedure PeriodPDCO: PDCO for periodic part of sequence procedure PermutePDCO: PDCO for permutations procedure PivotPDCO: PDCO to generate pivot points procedure RandomPDCO: PDCO to generate from sequences at random procedure RepaltPDCO: PDCO to model repeated alternation procedure ReducePDCO: PDCO to reduce sequence using binary operation procedure RepeatPDCO: PDCO to repeat sequence procedure RemoveDuplPDCO: PDCO for remove duplicate values in a sequence procedure ReplPDCO: PDCO to replicate values in a sequence procedure ResumePDCO: PDCO to model limited iteration procedure ReversePDCO: PDCO to reverse sequence procedure RotatePDCO: PDCO to rotate sequence procedure SelfreplPDCO: PDCO to produce multiple of values in sequence procedure SeqlistPDCO: PDCO to return list of values procedure SimpleAER: PDAE for simple evaluation procedure SkipPDCO: PDCO to skip terms procedure SmodPDCO: generalized modular reduction procedure SpanPDCO: fill in gaps in integer sequences procedure SumlimitPDCO: PDCO to sum sequence to a limit procedure TrinopPDCO: PDCO to apply trinary operator to sequences procedure UndulantPDCO: PDCO to produce undulant procedure UniquePDCO: PDCO to filter out duplication values procedure UnopPDCO: PDCO to apply unary operation to sequence procedure UpperTrimPDCO: upper sequence trimming procedure ValrptPDCO: synonym for Repl procedure WobblePDCO: PDCO to produce sequence values alternately
link pdco
March 4, 2003; Ralph E. Griswold and Robert J. Alexander
Requires: co-expressions
This file is in the public domain.
These procedures use co-expressions to used to model the built-in control structures of Icon and also provide new ones. AddTabbyPDCO{e, i} adds tabby to treadling sequence AllparAER{e1,e2, ...} parallel evaluation with last result used for short sequences AltPDCO{e1,e2} models e1 | e2 BinopPDCO{op,e1,e2} produces the result of applying op to e1 and e2 CFapproxPDCO{e} produce sequence of approximations for the continued-fraction sequence e ComparePDCO{e1,e2} compares result sequences of e1 and e2 ComplintPDCO{e} produces the integers not in e CondPDCO{e1,e2, ...} models the generalized Lisp conditional CumsumPDCO{e} generates the cumulative sum of the terms of e CycleparAER{e1,e2, ...} parallel evaluation with shorter sequences re-evaluated DecimatePDCO{e1, e2} "decimate" e1 by deleting e2-numbered terms (e2 is assumed to be an increasing sequence). DecimationPDCO{e} produce a decimation sequence from e1 by deleting even-valued terms and replacing odd-valued terms by their position. DecollatePDCO{e, i} decollate e according to parity of i DeltaPDCO{e1} produces the difference of the values in e1 ElevatePDCO{e1, m, n} elevate e1 mod n to n values EveryPDCO{e1,e2} models every e1 do e2 ExtendSeqPDCO{e1,i} extends e1 to i results ExtractAER{e1,e2, ...} extract results of even-numbered arguments according to odd-numbered values FifoAER{e1,e2, ...} reversal of lifo evaluation FriendlyPDCO{m, k, e3} friendly sequence starting at k shaft mod m GaltPDCO{e1,e2, ...} produces the results of concatenating the sequences for e1, e2, ... GconjPDCO{e1,e2,...} models generalized conjunction: e1 & e2 & ... The programmer-defined control operation above shows an interesting technique for modeling conjunction via recursive generative procedures. HistoPDCO{e,i} generates histogram for e limited to i terms; default 100. IncreasingPDCO{e} filters out non-increasing values in integer sequence IndexPDCO{e1,e2} produce e2-th terms from e1 InterPDCO{e1,e2, ...} produces results of e1, e2, ... alternately LcondPDCO{e1,e2, ...} models the Lisp conditional LengthPDCO{e} returns the length of e LifoAER{e1,e2, ...} models standard Icon "lifo" evaluation LimitPDCO{e1,e2} models e1 \ e2 ListPDCO{e,i} produces a list of the first i results from e LowerTrimPDCO{e} lower trim MapPDCO{e1,e2} maps values of e1 in the order they first appear to values of e2 (as needed) OddEven{e} forces odd/even sequence PalinPDCO{e} x produces results of concatenating the sequences for e and then its reverse. ParallelPDCO{e1,e2, ...} synonym for InterPDCO{e1, e2, ...} ParallelAER{e1,e2, ...} parallel evaluation terminating on shortest sequence PatternPalinPDCO{e, i} produces pattern palindrome. If i is given, e is truncated to length i. PeriodPDCO{e, i} generates the periodic part of e; i values are used to find the period PermutePDCO{e1,e2} permutes each n-subsequence of e1 by the n positional values in lists from e2. If a list does not consist of all the integers in the range 1 to n, "interesting" things happen (see the use of map() for transpositions). PivotPDCO{e, m} produces pivot points from e % m; m default 100 PosDiffPDCO{e1,e2} produces positions at which e1 and e2 differ PositionsPDCO{e, i} generates the positions at which i occurs in e. RandomPDCO{e1,e2, ...} produces results of e1, e2, ... at random ReducePDCO{op, x, e} "reduces" the sequence e by starting with the value x and repetitively applying op to the current value and values from e. RemoveDuplPDCO{e} removes duplicate adjacent values. RepaltPDCO{e} models |e RepeatPDCO{e1, e2} repeats the sequence for e1 e2 times ReplPDCO{e1,e2} replicates each value in e1 by the corresponding integer value in e2. ResumePDCO{e1,e2,e3} models every e1 \ e2 do e3 ReversePDCO{e, i} produces the results of e in reverse order. If i is given, e is truncated to i values. RotatePDCO(e, i) rotates the sequence for e left by i; negative i rotates to the right SelfreplPDCO{e1,i} produces e1 * i copies of e1 SeqlistPDCO{e1, i} produce list with first i values of e1; i defaults to all values SimpleAER{e1,e2, ...} simple evaluation with only success or failure SkipPDCO{e1,e2} generate e1 skipping each e2 terms SmodPDCO{e1,e2} reduce terms in e1 (shaft) modulus e2 SpanPDCO{e,m} fill in between consecutive (integer) values in e % m; m default 100 SumlimitPDCO{e, i, j} produces values of e until their sum exceeds i. Values less than j are discarded. TrinopPDCO{op,e2,e2,e3} produces the result of applying op to e1, e2, and e3 UndulantPDCO{e} produces the undulant for e. UniquePDCO{e} produces the unique results of e in the order they first appear UnopPDCO{e1,e2} produces the result of applying e1 to e2 UpperTrimPDCO{e} upper trim ValrptPDCO{e1,e2} synonym for ReplPDCO WobblePDCO{e} produces e(1), e(2), e(1), e(2), e(3), e(2), ... Comments: Because of the handling of the scope of local identifiers in co-expressions, expressions in programmer-defined control operations cannot communicate through local identifiers. Some constructions, such as break and return, cannot be used in argu- ments to programmer-defined control operations.
[ Summary entry | Source code ]
procedure Sqrt: rational approximate to square root procedure rat2cf: continued fraction sequence for rational procedure cfapprox: continued-fraction approximation procedure dec2rat: convert repeating decimal to rational procedure rat2dec: decimal expansion of rational procedure repeater: find repeat in sequence procedure seqimage: sequence image
link periodic
June 10, 2001; Ralph E. Griswold
Requires: Large-integer arithmetic
This file is in the public domain.
Sqrt(i, j) produces a rational approximation to the square root of i with j iterations of the half-way method. j defaults to 5.
[ Summary entry | Source code ]
procedure multireduce: multi-reduction permutation procedure permperiod: period of permutation procedure cycles: permutation cycles procedure mutate: mutate sequence
link permutat
June 10, 2001; Ralph E. Griswold
This file is in the public domain.
Links: lists, seqops
[ Summary entry | Source code ]
link phoname
June 10, 1988; Thomas R. Hicks
This file is in the public domain.
This procedure generates the letter combinations corresponding to the digits in a telephone number. Warning: The number of possibilities is very large. This procedure should be used in a context that limits or filters its output.
[ Summary entry | Source code ]
procedure plural: produce plural of word
link plural
July 15, 1995; Ralph E. Griswold
This file is in the public domain.
This procedure produces the plural form of a singular English noun. The procedure here is rudimentary and does not work in all cases.
[ Summary entry | Source code ]
procedure str2poly: convert string to polynomial procedure polyadd: add polynomials procedure polymod: polynomial modular reduction procedure polysub: subtract polynomials procedure polymul: multiply polynomials procedure polyexp: exponentiate polynomial procedure poly2str: polynomial to string procedure polydiff: polynomial differentiation procedure polyintg: polynomial integration procedure peval: string polynomial simplification procedure poper: find polynomial operation procedure pform: polynomial formation procedure poly2profile: polynomial to profile sequence procedure poly2profilelen: polynomial to profile sequence
link polynom
October 1, 2001; Ralph E. Griswold
This file is in the public domain.
The format for strings omits symbols for multiplication and exponentiation. For example, 3*a^2 is entered as 3a2. A polynomial is represented by a table in which each term, such as 3xy, the xy is # a key and the corresponding value is the coefficient, 3 in this case. If a variable is raised to a power, such as x^3, the key is the product of the individual variables, xxx in this case.
[ Summary entry | Source code ]
link polyseq
September 19, 2001; Ralph E. Griswold
This file is in the public domain.
The procedure poly2seq(str) generates the Dietz sequence for the polynomial str. See Ada Dietz, "Algebraic Expressions in Handweaving".
[ Summary entry | Source code ]
link polystuf
May 23, 1994; Erik Eid
This file is in the public domain.
These procedures are for creating and performing operations on single- variable polynomials (like ax^2 + bx + c). poly (c1, e1, c2, e2, ...) - creates a polynomial from the parameters given as coefficient-exponent pairs: c1x^e1 + c2x^e2 + ... is_zero (n) - determines if n = 0 is_zero_poly (p) - determines if a given polynomial is 0x^0 poly_add (p1, p2) - returns the sum of two polynomials poly_sub (p1, p2) - returns the difference of p1 - p2 poly_mul (p1, p2) - returns the product of two polynomials poly_eval (p, x) - finds the value of polynomial p when evaluated at the given x. term2string (c, e) - converts one coefficient-exponent pair into a string. poly_string (p) - returns the string representation of an entire polynomial.
[ Summary entry | Source code ]
link popen
September 28, 1992; Ronald Florence
This file is in the public domain.
Contents: popen(command, mode) mode == "w" writes to a pipe mode == "r" reads from a pipe pclose(pipe) On systems without real pipes (ms-dos), popen and pclose imitate pipes; pclose must be called after popen. The code should run faster on ms-dos if dir in tempfile() points to a directory on a virtual disk. On systems with real pipes, popen & pclose open and close a pipe.
[ Summary entry | Source code ]
procedure pq: create priority queue procedure pqget: remove first priority queue element procedure pqgen: generate priority queue elements procedure pqput: insert priority queue element
link pqueue
May 3, 2001; William S. Evans and Gregg M. Townsend
This file is in the public domain.
These procedures manipulate priority queues. pq(L) returns a priority queue containing the elements in L. L is a list (or table or set) of pqelem records, each containing a data and priority field. If L is &null, pq() returns an empty priority queue. pqget(Q) returns and removes the highest priority element from Q. Q is a priority queue returned by pq(). pqput(Q, e) adds element e (a pqelem record) to Q. pqgen(Q) generates the elements in Q in priority order. pqelem(d, p) constructs a record with data d and priority p. ____________________________________________________________ Priority queues are implemented as heaps. Heaps are implemented as lists in the usual fashion.
[ Summary entry | Source code ]
link printcol
August 14, 1996; Robert J. Alexander
This file is in the public domain.
This procedure deals with with the problem of printing tabular data where the total width of items to be printed is wider than the page. Simply allowing the data to wrap to additional lines often produces marginally readable output. This procedure facil- itates printing such groups of data as vertical columns down the page length, instead of as horizontal rows across the page. That way many, many fields can be printed neatly. The programming of such a transformation can be a nuisance. This procedure does much of the work for you, like deciding how many items can fit across the page width and ensuring that entire items will be printed on the same page without page breaks (if that service is requested). ____________________________________________________________ For example, suppose we have a list of records we would like to print. The record is defined as: record rec(item1,item2,item3,...) Also suppose that lines such as Field 1 Field 2 Field 3 ... ------- ------- ------- --- Record 1 item1 item2 item3 ... Record 2 item1 item2 item3 ... are too long to print across the page. This procedure will print them as: TITLE ===== Record 1 Record 2 ... -------- -------- --- Field 1 item1 item1 ... Field 2 item2 item2 ... Field 3 item3 item3 ... The arguments are: items: a co-expression that produces a sequence of items (usually structured data objects, but not necessarily) for which data is to be printed. fields: a list of procedures to produce the field's data. Each procedure takes two arguments. The procedure's action depends upon what is passed in the first argument: header Produces the row heading string to be used for that field (the field name). width Produces the maximum field width that can be produced (including the column header). Other Produces the field value string for the item passed as the argument. The second argument is arbitrary data from the procedures with each invocation. The data returned by the first func- tion on the list is used as a column heading string (the item name). title: optional. pagelength: if null (omitted) page breaks are ignored. linelength: default 80. auxdata: auxiliary arbitrary data to be passed to the field procedures -- see `fields', above.
[ Summary entry | Source code ]
link printf
February 13, 2006; William H. Mitchell
Contributors: Cheyenne Wills, Phillip Lee Thomas,
Michael Glass, Gregg M. Townsend
This file is in the public domain.
This procedure behaves somewhat like the standard printf. Supports d, e, s, o, and x formats like printf. An "r" format prints real numbers in a manner similar to that of printf's "f". Though "e" differs from printf in some details, it always produces exponential format. Left or right justification and field width control are provided as in printf. %s, %r, and %e handle precision specifications.
[ Summary entry | Source code ]
link prockind
January 4, 1994; Ralph E. Griswold
This file is in the public domain.
prockind(p) produces a code for the kind of the procedure p as follows: "p" (declared) procedure "f" (built-in) function "o" operator "c" record constructor It fails if p is not of type procedure.
[ Summary entry | Source code ]
link procname
May 2, 2001; Ralph E. Griswold
This file is in the public domain.
procname(p, x) produces the name of a procedure from a procedure value. Here, the term "procedure" includes functions, operators, and record constructors. If x is null, the result is derived from image() is a relatively straightforward way. In the case of operators, the number of arguments is appended to the operator symbol. If x is nonnull, the result is put in a form that resembles an Icon expression. procname() fails if p is not of type procedure.
[ Summary entry | Source code ]
link progary
April 30, 1993; Ralph E. Griswold
This file is in the public domain.
This procedure creates an array with one element for each program token. The program is read from file. The initial value of each element is value.
[ Summary entry | Source code ]
procedure epsheader: write PostScript header procedure psprotect: escape special PostScript characters
link pscript
February 21, 2003; Gregg M. Townsend
This file is in the public domain.
This file contains procedures for writing PostScript output explicitly, as contrasted with the procedures in psrecord.icn that write PostScript as a side effect of normal graphics calls. epsheader(f, x, y, w, h, flags) writes an Encapsulated PostScript file header and initializes the PostScript coordinate system. psprotect(s) adds escapes to protect characters that are special in PostScript strings, notably parentheses and backslash. ____________________________________________________________ epsheader(f, x, y, w, h, flags) aids the creation of an Encapsulated PostScript file by writing a header. An EPS file can either be incorporated as part of a larger document or sent directly to a PostScript printer. Epsheader() writes the first portion of the PostScript output to file f; the calling program then generates the rest. It is the caller's responsibility to ensure that the rest of the file conforms to the requirements for EPS files as documented in the PostScript Reference Manual, second edition. (x,y,w,h) specify the range of coordinates that are to be used in the generated PostScript code. Epsheader() generates PostScript commands that center this region on the page and clip anything outside it. If the flags string contains the letter "r" and abs(w) > abs(h), the coordinate system is rotated to place the region in "landscape" mode. The generated header also defines an "inch" operator that can be used for absolute measurements as shown in the example below. Usage example: f := open(filename, "w") | stop("can't open ", filename) epsheader(f, x, y, w, h) write(f, ".07 inch setlinewidth") write(f, x1, " ", y1, " moveto ", x2, " ", y2, " lineto stroke") ... write(f, "showpage") ____________________________________________________________ psprotect(s) adds a backslash character before each parenthesis or backslash in s. These characters are special in PostScript strings. The characters \n \r \t \b \f are also replaced by escape sequences, for readability, although this is not required by PostScript.
[ Summary entry | Source code ]
procedure pt2coord: convert point to coordinate procedure coord2pt: convert coordinate to path procedure negpt: negative of point procedure pteq: test point equality procedure getpts: make point list from coordinate file
link ptutils
March 25, 2002; Ralph E. Griswold
This file is in the public domain.
These procedures provide various operations on 3-dimensional objects in 3-space.
[ Summary entry | Source code ]
procedure choose: set of k integers in [1..n] procedure rand_num: random number generator procedure rand_int: model ?i procedure randomize: randomize procedure randrange: random number in range procedure randrangeseq: random sequence in range procedure randseq: generate &random procedure rng: random number generator procedure shuffle: shuffle
link random
April 11, 2014; Ralph E. Griswold and Gregg M. Townsend
This file is in the public domain.
This file contains procedures related to pseudo-random numbers. choose(k, n) produces a set of k distinct integers in [1..n] rand_num() is a linear congruential pseudo-random number generator. Each time it is called, it produces another number in the sequence and also assigns it to the global variable random. With no arguments, rand_num() produces the same sequence(s) as Icon's built-in random-number generator. Arguments can be used to get different sequences. The global variable random serves the same role that &random does for Icon's built-in random number generator. rand_int(i) produces a randomly selected integer in the range 1 to i. It models ?i for positive i. randomize() sets &random to a "random" value, using /dev/urandom if available, otherwise based on the date and time. randrange(min, max) produces random number in the range min <= i <= max. randrangeseq(i, j) generates the integers from i to j in random order. randseq(seed) generates the values of &random, starting at seed, that occur as the result of using ?x. rng(a, c, m, x) generates a sequence of numbers using the linear congruence method. With appropriate parameters, the result is a pseudo-random sequence. The default values produce the sequence used in Icon. shuffle(x) shuffles the elements of x
[ Summary entry | Source code ]
procedure addrat: sum of rationals procedure divrat: divide rationals. procedure medrat: form rational mediant procedure mpyrat: multiply rationals procedure negrat: negative of rational procedure rat2real: floating-point approximation of rational procedure rat2str: convert rational to string procedure ratred: reduce rational to lowest terms procedure real2rat: convert to rational with precision p procedure reciprat: reciprocal of rational procedure subrat: difference of rationals
link rational
June 10, 2001; Ralph E. Griswold
Contributor: Gregg M. Townsend
This file is in the public domain.
These procedures perform arithmetic on rational numbers (fractions): addrat(r1,r2) Add rational numbers r1 and r2. divrat(r1,r2) Divide rational numbers r1 and r2. medrat(r1,r2) Form mediant of r1 and r2. mpyrat(r1,r2) Multiply rational numbers r1 and r2. negrat(r) Produce negative of rational number r. rat2real(r) Produce floating-point approximation of r rat2str(r) Convert the rational number r to its string representation. real2rat(v,p) Convert real to rational with precision p. The default precision is 1e-10. (Too much precision gives huge, ugly factions.) reciprat(r) Produce the reciprocal of rational number r. str2rat(s) Convert the string representation of a rational number (such as "3/2") to a rational number. subrat(r1,r2) Subtract rational numbers r1 and r2.
[ Summary entry | Source code ]
procedure read_cpt: convert numerical carpet to matrix
link readcpt
August 7, 1997; Ralph E. Griswold
See also: writecpt.icn
This file is in the public domain.
This procedure reads a "carpet" file and returns a corresponding matrix.
[ Summary entry | Source code ]
link readtbl
May 2, 2001; Richard L. Goerwitz
This file is in the public domain.
This file is part of the strpsgml package. It does the job of read- ing option user-created mapping information from a file. The purpose of this file is to specify how each code in a given input text should be translated. Each line has the form: SGML-designator start_code end_code where the SGML designator is something like "quote" (without the quota- tion marks), and the start and end codes are the way in which you want the beginning and end of a <quote>...<\quote> sequence to be transla- ted. Presumably, in this instance, your codes would indicate some set level of indentation, and perhaps a font change. If you don't have an end code for a particular SGML designator, just leave it blank.
[ Summary entry | Source code ]
link reassign
May 2, 2001; David A. Gamey
This file is in the public domain.
Descriptions: ReAssign( s ) : s2 Replaces sequences of \n in s with the corresponding parenthesis groups from the last regular expression match/find (if one exists). Special characters: \n use nth parenthesis group \\ escaped \ \n.i nth group followed by a number
[ Summary entry | Source code ]
link rec2tab
July 6, 2002; Ralph E. Griswold
This file is in the public domain.
This procedure writes fields of a record as tab-separated string. Carriage returns in files are converted to vertical tabs. (Works for lists too.)
[ Summary entry | Source code ]
link recog
May 29, 1993; Ralph E. Griswold
See also: pargen.icn
This file is in the public domain.
This procedure serves as a main procedure for the output of recognizers.
[ Summary entry | Source code ]
procedure field: return name of field R[i] procedure fieldnum: return index of field R.s procedure movecorr: move corresponding record fields
link records
November 4, 2002; Ralph E. Griswold and Gregg M. Townsend
Contributor: Paul Abrahams
This file is in the public domain.
field(R, i) returns the name of the ith field of R. fieldnum(R, s) returns the index of the field named s in record R. movecorr(R1, R2) copies values from the fields of record R1 into fields of the same names (if any) in record R2, and returns R2.
[ Summary entry | Source code ]
link recrfncs
December 5, 1995; Ralph E. Griswold
See also: fastfncs.icn, iterfncs.icn, and memrfncs.icn
This file is in the public domain.
These procedures implement commonly referenced ``text-book'' recursively defined functions. acker(i, j) Ackermann's function fib(i) Fibonacci sequence g(k, i) generalized Hofstader nested recurrence q(i) chaotic sequence
[ Summary entry | Source code ]
link recurmap
February 17, 1995; Ralph E. Griswold
This file is in the public domain.
This procedure maps a recurrence declaration of the form f(i): if expr11 then expr12 if expr21 then expr22 ... else expr The declaration if passed to recurmap() in the form of a list. The result is returned as a string constituting an Icon procedure declaration. into an Icon procedure that compute corresponding values. At present there is no error checking and the most naive form of code is generated.
[ Summary entry | Source code ]
link reduce
January 14, 1995; Ralph E. Griswold
This file is in the public domain.
reduce(op, init, args[]) applies the binary operation op to all the values in args, using init as the initial value. For example, reduce("+", 1, args[]) produces the sum of the values in args.
[ Summary entry | Source code ]
procedure RePat: regular expression pattern list procedure ReMatch: position past regular expression matched procedure ReFind: position where regular expression matched
link regexp
May 19, 1996; Robert J. Alexander
This file is in the public domain.
This is a kit of procedures to deal with UNIX-like regular expression patterns. These procedures are interesting partly because of the "recursive suspension" (or "suspensive recursion" :-) technique used to simulate conjunction of an arbitrary number of computed expressions (see notes, below). The public procedures are: ReMatch(pattern,s,i1,i2) : i3,i4,...,iN ReFind(pattern,s,i1,i2) : i3,i4,...,iN RePat(s) : pattern list ____________________________________________________________ ReMatch() produces the sequence of positions in "s" past a substring starting at "i1" that matches "pattern", but fails if there is no such position. Similar to match(), but is capable of generating multiple positions. ReFind() produces the sequence of positions in "s" where substrings begin that match "pattern", but fails if there is no such position. Similar to find(). Each position is produced only once, even if several possible matches are possible at that position. "pattern" can be either a string or a pattern list -- see RePat(), below. Default values of s, i1, and i2 are handled as for Icon's built-in string scanning procedures such as match(). ____________________________________________________________ RePat(s) : L Creates a pattern element list from pattern string "s", but fails if the pattern string is not syntactically correct. ReMatch() and ReFind() will automatically convert a pattern string to a pattern list, but it is faster to do the conversion explicitly if multiple operations are done using the same pattern. An additional advantage to compiling the pattern separately is avoiding ambiguity of failure caused by an incorrect pattern and failure to match a correct pattern. ____________________________________________________________ ReCaseIndependent() : n ReCaseDependent() : n Set mode for case-independent or case-dependent matching. The initial mode is case-dependent. ____________________________________________________________ Accessible Global Variables After a match, the strings matched by parenthesized regular expressions are left in list "Re_ParenGroups", and can be accessed by subscripting in using the same number as the \N construct. If it is desired that regular expression format be similar to UNIX filename generation patterns but still retain the power of full regular expressions, make the following assignments prior to compiling the pattern string: Re_ArbString := "*" # Defaults to ".*" The sets of characters (csets) that define a word, digits, and white space can be modified. The following assignments can be made before compiling the pattern string. The character sets are captured when the pattern is compiled, so changing them after pattern compilation will not alter the behavior of matches unless the pattern string is recompiled. Re_WordChars := 'whatever you like' # Defaults to &letters ++ &digits ++ "_" Re_Digits := &digits ++ 'ABCDEFabcdef' # Defaults to &digits Re_Space := 'whatever you like' # Defaults to ' \t\v\n\r\f' These globals are normally not initialized until the first call to RePat(), and then only if they are null. They can be explicitly initialized to their defaults (if they are null) by calling Re_Default(). ____________________________________________________________ Characters compiled into patterns can be passed through a user-supplied filter procedure, provided in global variable Re_Filter. The filtering is done before the characters are bound into the pattern. The filter proc is passed one argument, the string to filter, and it must return the filtered string as its result. If the filter proc fails, the string will be used unfiltered. The filter proc is called with an argument of either type string (for characters in the pattern) or cset (for character classes [...]). Filtering is done only as the pattern is compiled. Any filtering of strings to be matched must be explicitly done. ____________________________________________________________ By default, individual pattern elements are matched in a "leftmost- longest-first" sequence, which is the order observed by perl, egrep, and most other regular expression matchers. If the order of matching is not important a performance improvement might be seen if pattern elements are matched in "shortest-first" order. The following global variable setting causes the matcher to operate in leftmost-shortest- first order. Re_LeftmostShortest := 1 ____________________________________________________________ In the case of patterns containing alternation, ReFind() will generally not produce positions in increasing order, but will produce all positions from the first term of the alternation (in increasing order) followed by all positions from the second (in increasing order). If it is necessary that the positions be generated in strictly increasing order, with no duplicates, assign any non-null value to Re_Ordered: Re_Ordered := 1 If the Re_Ordered option is chosen, there is a *small* penalty in efficiency in some cases, and the co-expression facility is required in your Icon implementation. ____________________________________________________________ Regular Expression Characters and Features Supported The regular expression format supported by procedures in this file model very closely those supported by the UNIX "egrep" program, with modifications as described in the Perl programming language definition. Following is a brief description of the special characters used in regular expressions. In the description, the abbreviation RE means regular expression. c An ordinary character (not one of the special characters discussed below) is a one-character RE that matches that character. \c A backslash followed by any special character is a one- character RE that matches the special character itself. Note that backslash escape sequences representing non-graphic characters are not supported directly by these procedures. Of course, strings coded in an Icon program will have such escapes handled by the Icon translator. If such escapes must be supported in strings read from the run-time environment (e.g. files), they will have to be converted by other means, such as the Icon Program Library procedure "escape()". . A period is a one-character RE that matches any character. [string] A non-empty string enclosed in square brackets is a one- character RE that matches any *one* character of that string. If, the first character is "^" (circumflex), the RE matches any character not in the remaining characters of the string. The "-" (minus), when between two other characters, may be used to indicate a range of consecutive ASCII characters (e.g. [0-9] is equivalent to [0123456789]). Other special characters stand for themselves in a bracketed string. * Matches zero or more occurrences of the RE to its left. + Matches one or more occurrences of the RE to its left. ? Matches zero or one occurrences of the RE to its left. {N} Matches exactly N occurrences of the RE to its left. {N,} Matches at least N occurrences of the RE to its left. {N,M} Matches at least N occurrences but at most M occurrences of the RE to its left. ^ A caret at the beginning of an entire RE constrains that RE to match an initial substring of the subject string. $ A currency symbol at the end of an entire RE constrains that RE to match a final substring of the subject string. | Alternation: two REs separated by "|" match either a match for the first or a match for the second. () A RE enclosed in parentheses matches a match for the regular expression (parenthesized groups are used for grouping, and for accessing the matched string subsequently in the match using the \N expression). \N Where N is a digit in the range 1-9, matches the same string of characters as was matched by a parenthesized RE to the left in the same RE. The sub-expression specified is that beginning with the Nth occurrence of "(" counting from the left. E.g., ^(.*)\1$ matches a string consisting of two consecutive occurrences of the same string. ____________________________________________________________ Extensions beyond UNIX egrep The following extensions to UNIX REs, as specified in the Perl programming language, are supported. \w Matches any alphanumeric (including "_"). \W Matches any non-alphanumeric. \b Matches only at a word-boundary (word defined as a string of alphanumerics as in \w). \B Matches only non-word-boundaries. \s Matches any white-space character. \S Matches any non-white-space character. \d Matches any digit [0-9]. \D Matches any non-digit. \w, \W, \s, \S, \d, \D can be used within [string] REs. ____________________________________________________________ Notes on computed conjunction expressions by "suspensive recursion" A conjunction expression of an arbitrary number of terms can be computed in a looping fashion by the following recursive technique: procedure Conjunct(v) if <there is another term to be appended to the conjunction> then suspend Conjunct(<the next term expression>) else suspend v end The argument "v" is needed for producing the value of the last term as the value of the conjunction expression, accurately modeling Icon conjunction. If the value of the conjunction is not needed, the technique can be slightly simplified by eliminating "v": procedure ConjunctAndProduceNull() if <there is another term to be appended to the conjunction> then suspend ConjunctAndProduceNull(<the next term expression>) else suspend end Note that <the next term expression> must still remain in the suspend expression to test for failure of the term, although its value is not passed to the recursive invocation. This could have been coded as suspend <the next term expression> & ConjunctAndProduceNull() but wouldn't have been as provocative. Since the computed conjunctions in this program are evaluated only for their side effects, the second technique is used in two situations: (1) To compute the conjunction of all of the elements in the regular expression pattern list (Re_match1()). (2) To evaluate the "exactly N times" and "N to M times" control operations (Re_NTimes()).
[ Summary entry | Source code ]
link repetit
February 25, 2003; Ralph E. Griswold
This file is in the public domain.
This procedure returns the length of the smallest range of values that repeat in a list. For example, if L := [1, 2, 3, 1, 2, 3, 1, 2, 3] repetit(L) returns 3. If there is no repetition, repetit() returns the length of the list.
[ Summary entry | Source code ]
link revadd
May 2, 2001; Ralph E. Griswold
Requires: Large integer arithmetic
This file is in the public domain.
This procedure is designed to help explore the number-theory problem in which an integer is added to its (digit) reversal until a palindrome appears. It is unknown if this process terminates for all integers. For example, for 196, it appears not to, but no proof, to our knowledge, exists for nontermination. The radix used is important. For bases that are powers of 2, it can be proved that there are integers for which the process does not terminate in a palindrome.
[ Summary entry | Source code ]
link rewrap
March 3, 1996; Richard L. Goerwitz
See also: wrap.icn
This file is in the public domain.
The procedure rewrap(s,i), included in this file, reformats text fed to it into strings < i in length. Rewrap utilizes a static buffer, so it can be called repeatedly with different s arguments, and still produce homogenous output. This buffer is flushed by calling rewrap with a null first argument. The default for argument 2 (i) is 70. ____________________________________________________________ Here's a simple example of how rewrap could be used. The following program reads the standard input, producing fully rewrapped output. procedure main() every write(rewrap(!&input)) write(rewrap()) end Naturally, in practice you would want to do things like check for in- dentation or blank lines in order to wrap only on a paragraph-by para- graph basis, as in procedure main() while line := read(&input) do { if line == "" then { write("" ~== rewrap()) write(line) } else { if match("\t", line) then { write(rewrap()) write(rewrap(line)) } else { write(rewrap(line)) } } } end Fill-prefixes can be implemented simply by prepending them to the output of rewrap: i := 70; fill_prefix := " > " while line := read(input_file) do { line ?:= (f_bit := tab(many('> ')) | "", tab(0)) write(fill_prefix || f_bit || rewrap(line, i - *fill_prefix)) etc. Obviously, these examples are fairly simplistic. Putting them to actual use would certainly require a few environment-specific modifications and/or extensions. Still, I hope they offer some indication of the kinds of applications rewrap might be used in. Note: If you want leading and trailing tabs removed, map them to spaces first. Rewrap only fools with spaces, leaving tabs intact. This can be changed easily enough, by running its input through the Icon detab() function.
[ Summary entry | Source code ]
link rng
June 11, 1994; Ralph E. Griswold
Requires: large integers
See also: lcseval.icn
This file is in the public domain.
This procedure generates a sequence of numbers using the linear congruence method. With appropriate parameters, the result is a pseudo-random sequence. The default values produce the sequence used in Icon.
[ Summary entry | Source code ]
link sandgen
November 19, 1997; Ralph E. Griswold
This file is in the public domain.
This program is designed to be linked with the output of the meta- translator. These procedures produce "evaluation sandwiches" so that program execution can be monitored. See "Evaluation Sandwiches", Icon Analyst 6, pp. 8-10, 1991. ____________________________________________________________ Bug: The invocable declaration is not handled properly. "invocable all" will get by, but some other forms produce syntax errors. The problem is in the meta-translator itself, not in this program.
[ Summary entry | Source code ]
procedure slashbal: bal() with escapes procedure slashupto: upto() with escapes procedure slshupto: upto() with escapes procedure snapshot: snapshot of string scanning procedure balq: bal() with quote escaping. procedure balqc: balq() with comment escaping procedure limatch: matching items in list
link scan
May 2, 2001; Richard L. Goerwitz, David A. Gamey, and Ralph E. Griswold
Contributors: Randal L. Schwartz and Cheyenne Wills
This file is in the public domain.
This module contains procedures related to string scanning: balq(c1, c2, c3, c4, c5, s, i1, i2) like bal() with quoting from characters in c5. balqc(c1, c2, c3, c4, c5, s1, s2, s3, i1, i2) like balq() with the addition that balanced characters within "comments", as delimited by the strings s1 and s2, are also excluded from balancing. In addition, if s1 is given and s2 limatch(L, c) matches items in list L delimited by characters in c slashbal(c1, c2, c3, s, i, j) like bal() with escape processing slashupto(c, s, i, j) like upto() with escape processing slshupto() synonym for slashupto() snapshot(title, len) snapshot of string scanning with optional title and maximum length. More extensive documentation proceeds each procedure. ____________________________________________________________ Richard L. Goerwitz: I am often frustrated at bal()'s inability to deal elegantly with the common \backslash escaping convention (a way of telling Unix Bourne and C shells, for instance, not to interpret a given character as a "metacharacter"). I recognize that bal()'s generic behavior is a must, and so I wrote slashbal() to fill the gap. Slashbal behaves like bal, except that it ignores, for purposes of balancing, any c2/c3 char which is preceded by a backslash. Note that we are talking about internally represented backslashes, and not necessarily the backslashes used in Icon string literals. If you have "\(" in your source code, the string produced will have no backslash. To get this effect, you would need to write "\\(." BUGS: Note that, like bal() (v8), slashbal() cannot correctly handle cases where c2 and c3 intersect. Note also that older ver- sions of this routine counted from the beginning of the string, instead of from i. This feature came to be regarded as a bug when put into actual use (especially when I realized that bal() doesn't work this way).
[ Summary entry | Source code ]
link scanmodl
May 30, 1993; Ralph E. Griswold
This file is in the public domain.
These procedures model string scanning: e1 ? e2 -> Escan(Bscan(e1, e2) See Icon Analyst 6, pp. 1-2.
[ Summary entry | Source code ]
link scanset
June 4, 1993; Robert J. Alexander
This file is in the public domain.
Procedure to set up for user-written string-scanning procedures that are in the spirit of Icon's built-ins. The values passed are the s, i1, i2 parameters which are the last three arguments to all Icon scanning functions (such as upto(c,s,i1,i2)). scan_setup() supplies any appropriate defaults and returns needed values. The value returned is a "scan_setup_result" record consisting of two values: 1. The substring of s to be scanned (ss). 2. The size of the substring of s that precedes the substring to be scanned (offset). scan_setup() fails if i1 or i2 is out of range with respect to s. The user-written procedure can then match in the string ss to compute the position within ss appropriate to the scan (p). The value returned (or suspended) to the caller is p + offset (the position within the original string, s). For example, the following function finds two words separated by spaces: procedure two_words(s,i1,i2) local x,p x := scan_setup(s,i1,i2) | fail # fail if out of range x.ss ? suspend { tab(upto(&letters)) & pos(1) | (move(-1) & tab(any(~&letters))) & p := &pos & # remember starting position tab(many(&letters)) & tab(many(' ')) & tab(many(&letters)) & p + x.offset # return position in original s } end
[ Summary entry | Source code ]
link segment
June 10, 1988; William H. Mitchell
This file is in the public domain.
These procedures segment a string s into consecutive substrings consisting of characters that respectively do/do not occur in c. segment(s,c) generates the substrings, while seglist produces a list of the segments. For example, segment("Not a sentence.",&letters) generates "Not" " " "a" " " "sentence" "." while seglist("Not a sentence.",&letters) produces ["Not"," ","a","sentence","."]
[ Summary entry | Source code ]
link senten1
August 14, 1996; Peter A. Bigot
This file is in the public domain.
sentence(f) generates the English sentences encountered in a file. ____________________________________________________________ The following rules describe what a 'sentence' is. * A sentence begins with a capital letter. * A sentence ends with one or more of '.!?', subject to other constraints. * If a period is immediately followed by: - a digit - a letter - one of ',;:' it is not a sentence end. * If a period is followed (with intervening space) by a lower case letter, it is not a sentence end (assume it's part of an abbreviation). * The sequence '...' does not end a sentence. The sequence '....' does. * If a sentence end character appears after more opening parens than closing parens in a given sequence, it is not the end of that particular sentence. (I.e., full sentences in a parenthetical remark in an enclosing sentence are considered part of the enclosing sentence. Their grammaticality is in question, anyway.) (It also helps with attributions and abbreviations that would fail outside the parens.) * No attempt is made to ensure balancing of double-quoted (") material. * When scanning for a sentence start, material which does not conform is discarded. * Corollary: Quotes or parentheses which enclose a sentence are not considered part of it. * An end-of-line on input is replaced by a space unless the last character of the line is 'a-' (where 'a' is any letter), in which case the hyphen is deleted. * Leading and trailing space (tab, space, newline) chars are removed from each line of the input. * If a blank line is encountered on input while scanning a sentence, the scan is aborted and search for a new sentence begins (rationale: ignore section and chapter headers separated from text by newlines). * Most titles before names would fail the above constraints. They are special-cased. * This does NOT handle when a person uses their middle initial. To do so would rule out sentences such as 'It was I.', Six of one, half-dozen of the other--I made my choice. * Note that ':' does not end a sentence. This is a stylistic choice, and can be modified by simply adding ':' to sentend below.
[ Summary entry | Source code ]
link sentence
August 14, 1996; Richard L. Goerwitz
Requires: co-expressions
This file is in the public domain.
sentence(f) - suspends sentences from file f A lot of grammatical and stylistic analysis programs are predicated on the notion of a sentence. For instance, some programs count the number of words in each sentence. Other count the number and length of clauses. Still others pedantically check for sentence-final par- ticles and prepositions. This procedure, sentence(), is supposed to be used as a filter for ASCII text files, suspending everything that looks remotely like a sentence in them. ____________________________________________________________ BUGS: Cannot correctly parse sentences with constructs like "R. L. Goerwitz" in them. The algorithm can be much improved simply by checking to see if the word after the period is in /usr/dict/words or whatever your system dictionary file is. If it isn't, then it's likely not to be the beginning of a sentence (this also is not in- fallible, naturally).
[ Summary entry | Source code ]
link seqfncs
September 30, 2001; Ralph E. Griswold
This file is in the public domain.
Links: genrfncs, lterps, math, numbers, partit, pdco, seqops, strings, convert
[ Summary entry | Source code ]
link seqimage
June 20, 1997; Ralph E. Griswold
This file is in the public domain.
The procedure Seqimage{e,i,j} produces a string image of the result sequence for the expression e. The first i results are printed. If i is omitted, there is no limit. If there are more than i results for e, ellipses are provided in the image after the first i. If j is specified, at most j results from the end of the sequence are printed after the ellipses. If j is omitted, only the first i results are produced. For example, the expressions Seqimage{1 to 12} Seqimage{1 to 12,10} Seqimage{1 to 12,6,3} produce, respectively, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12} {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, ...} {1, 2, 3, 4, 5, 6, ..., 10, 11, 12} Warning: If j is not omitted and e has an infinite result sequence, Seqimage{} does not terminate.
[ Summary entry | Source code ]
procedure copyl: copy list of lists procedure get_scollate: find collation in sequence procedure get_splace: find motif along a path in sequence procedure get_srepeat: find repeat in sequence procedure is_scompact: test sequence for compactness procedure remod: handle modulus procedure sbinop: binary operation on terms procedure sbound: compute sequence upper bound FIX! procedure scollate: sequence term collation procedure scompress: compact sequence procedure sconcat: concatenate sequences procedure sconcatp: concatenate sequences as pattern procedure sconstant: test for constant sequence procedure scpal: closed sequence palindrome procedure sdecimate: decimate sequence procedure sdecollate: sequence decollation procedure sdelta: sequence delta procedure sdirection: sequence delta "direction" procedure sextend: extend sequence procedure sground: ground sequence to i procedure shaft_period: shaft period procedure simage: string image of sequence procedure simageb: bracketed sequence image procedure sinit: initialize sequence operations procedure sintermix: sequence intermixing procedure slayer: layer sequences procedure slength: compute sequence length procedure slocate: sequences of first positions of terms procedure smap: map terms in sequence procedure smin: compute sequence lower bound FIX procedure smissing: missing terms in sequence BOGUS?? procedure smod: modular reduction procedure smutate: mutation procedure snormal: normalize sequence procedure sopal: create open sequence palindrome procedure sorder: positions of first occurrence procedure sparity: adjust parity procedure speriod: period of sequence procedure splace: place motif along a path procedure splacep: place motif along a path procedure splaceg: generalized motifs along a path procedure spositions: positions of values in sequence procedure spromote: promote term to sequence procedure srandom: random selection procedure sreflecth: reflect sequence horizontally procedure sreflectv: reflect sequence vertically procedure sremdupl: remove duplicate adjacent terms procedure ssplitdupl: split duplicate adjacent terms procedure srepeat: repeat sequence procedure srotatev: rotate sequence vertically procedure srun: create connected runs procedure sscale: scale terms in sequence procedure sscollate: entire sequence collation procedure sselect: select terms from sequence procedure sshift: shift terms sequence procedure sundulate: make undulating sequence procedure sunmod: modular expansion procedure sunop: unary operation on terms procedure sbefriend: make a sequence friendly procedure connect: connect friends procedure wander: friendly meander
link seqops
March 4, 2003; Ralph E. Griswold
Requires: Courage.
This file is in the public domain.
These procedures perform operations related to T-Sequences and to analyze T-Sequences. ____________________________________________________________ copyl(xargs[]) copy list of lists eval_tree(n) evaluate expression tree expression_tree(n) create expression tree fragment(s, i, p, arg) get_analysis(s) analyze sequence get_scollate(s) analyze for collation get_splace(s) analyze for motif along a path get_srepeat(s) analyze for repeat get_srun(s) analyze for run get_sruns(s) analyze for simple runs is_scompact(x) test sequence for compactness pimage(x) remod(s, p) sanalout() output analysis sanalysis(x) over-all analysis sbefriend(x, p) befriend sequence sbinop(op, xargs[]) binary operation on terms sbound(xargs[]) compute sequence upper bound FIX! scollate(xargs[]) sequence collation scompress(xargs[]) compact sequence sconcat(xargs[]) concatenate sequences sconcatp(xargs[]) concatenate sequences, pattern style scpal(xargs[]) closed sequence palindrome sdecimate(xargs[]) decimate sequence sdecollate(order, x) decollate sequence sdelta(x) get delta sequence sdirection(x) "direction" of delta(x) sequiv(x1, x2) test sequence equivalence sextend(xargs[]) extend sequence sflatten(x) flatten nested sequence sground(s, i) ground sequence to i shaft_period(x1, x2) shaft period simage(x, limit) string image of sequence sinit() initialize sequence operations sintermix(xargs[]) intermix sequences slayer(xargs[]) layer sequences slength(x) compute sequence length slocate(xargs[]) sequences of first positions of terms smap(xargs[]) map terms in sequence smin(xargs[]) compute sequence lower bound FIX smissing(x) missing terms in sequence BOGUS?? smod(xargs[]) modular reduction smutate(xargs[]) mutation snormal(x) normalize sequence sopal(xargs[]) create open sequence palindrome sorder(x) positions of first occurrence sparity(xargs[]) adjust parity speriod(s, i) sequence period splace(xargs[]) place motif along a path splaceg(xargs[]) generalized motifs along a path splacep(xargs[]) place motif along a path ssplitdupl(xargs[]) split duplicate adjacent terms spositions(x1, x2) shaft positions spromote(x) promote term to sequence srandom(x) random selection sreflecth(xargs[]) reflect sequence horizontally sreflectr(xargs[]) sreflectv(xargs[]) reflect sequence vertically sremdupl(xargs[]) remove duplicate adjacent terms srepeat(xargs[]) repeat sequence srepl(xargs[]) replicate sequence terms srotatev(xargs[]) rotate sequence vertically srun(xargs[]) create connected run sruns(xargs[]) create simple runs sscale(xargs[]) scale terms in sequence sscollate(xargs[]) collate entire sequences sselect(xargs[]) select terms from sequence sshift(x, i) shift terms sequence sundulate(x) make undulating sequence sunmod(x) modular expansion sunop(op, xargs[]) unary operation on terms walk_tree(n, tree_list, tree_ptrs, depth) walk expression tree
[ Summary entry | Source code ]
procedure serial: structure serial number
link serial
April 19, 1996; Ralph E. Griswold
This file is in the public domain.
Procedure to return the serial number of a structure.
[ Summary entry | Source code ]
link sername
June 27, 1997; Ralph E. Griswold
This file is in the public domain.
sername(p, s, n, i) produces a series of names of the form p<nnn>s. If n is given it determines the number of digits in <nnn>. If i is given it resets the sequence to start with i. <nnn> is an right-adjusted integer padded with zeros. Ordinarily, the arguments only are given on the first call. Subsequent calls without arguments give the next name. For example, sername("image", ".gif", 3, 0) produces "image000.gif", and subsequently, sername() produces "image001.gif", image002.gif", and so on. The defaults, if sername() is first called without any arguments is as for the call sername("file", 3, 0, ""). If any argument changes on subsequent calls, all non-null arguments are reset.
[ Summary entry | Source code ]
procedure cset2set: set of characters procedure pairset: set of table pairs procedure domain: domain of table procedure range: range of table procedure inverse: inverse of table function procedure seteq: set equivalence procedure setlt: set inclusion procedure simage: string image of set
link sets
August 7, 1999; Alan Beale
Contributor: Ralph E. Griswold
This file is in the public domain.
cset2set(c) returns a set that contains the individual characters in cset c. domain(T) returns the domain of the function defined by the table T. inverse(T, x) returns the inverse of the function defined by the table T. If x is null, it's the functional inverse. If x is an empty list, it's the relational inverse. If x is an empty set, it the relational inverse, but with each table member as a set instead of a list. pairset(T) converts the table T to an equivalent set of ordered pairs. range(T) returns the range of the function defined by the table T. seteq(S1, S2) tests equivalence of sets S1 and S2. setlt(S1, S2) tests inclusion of set S1 in S2. simage(S) string image of set
[ Summary entry | Source code ]
procedure showtbl: show table contents
link showtbl
March 25, 2002; Ralph E. Griswold
This file is in the public domain.
showtbl(title, tbl, sort_type, limit, sort_order, posit, w1, w2, gutter, f1, f2) displays tbl according to the arguments given. The arguments are: position name meaning default/alternative 1 title heading title "" 2 tbl table to be shown 3 sort_type type of sorting "ref"/"val" 4 limit lines of table output essentially infinite 5 sort_order increasing/decreasing "incr"/"decr" 6 posit first column "val"/"ref" 7 w1 width of 1st column 10 8 w2 width of 2nd column 10 9 gutter width between columns 3 10 f1 function of 1st column left 11 f2 function of 2nd column right showtbl() returns a record with the first element being a count of the size of the table and the second element the number of lines written. ____________________________________________________________ This procedure just grew. It needs rewriting. And it has far too many arguments. ____________________________________________________________ Deficiencies: Several features are not yet implemented. sort_order and posit have no effect. In the case of sort_type "val", the sorting order is decreasing.
[ Summary entry | Source code ]
link shquote
December 30, 1993; Robert J. Alexander
This file is in the public domain.
The following procedures are useful for writing Icon programs that generate shell commands. Certain characters cannot appear in the open in strings that are to be interpreted as "words" by command shells. This family of procedures assists in quoting such strings so that they will be interpreted as single words. Quoting characters are applied only if necessary -- if strings need no quoting they are returned unchanged. shquote(s1, s2, ..., sN) : s -- Produces a string of words s1, s2, ..., sN that are properly separated and quoted for the Bourne Shell (sh). cshquote(s1, s2, ..., sN) : s -- Produces a string of words s1, s2, ..., sN that are properly separated and quoted for the C-Shell (csh). mpwquote(s1, s2, ..., sN) : s -- Produces a string of words s1, s2, ..., sN that are properly separated and quoted for the Macintosh Programmer's Workshop shell (MPW Shell). dequote(s1,s2) : s3 -- Produces the UNIX-style command line word s1 with any quoting characters removed. s2 is the escape character required by the shell (s2 defaults the the usual UNIX escape character, the backslash "\\").
[ Summary entry | Source code ]
link signed
April 2, 1990; Robert J. Alexander
This file is in the public domain.
signed(s,n) -- Puts raw bits of characters of string s into an integer. The value is taken as signed. If large integers are supported, this routine will work for integers of arbitrary size. If large integers are not supported, the following are true: If the size of s is the same as or greater than the size of an integer in the Icon implementation, the result will be negative or positive depending on the value of the integer's sign bit. If the size of s is less than the size of an integer, the bytes are put into the low order part of the integer, with the remaining high order bytes filled with sign bits (the high order bit of the first character of the string). If the string is too large, the most significant bytes will be lost. This procedure is normally used for processing of binary data read from a file.
[ Summary entry | Source code ]
procedure sortff: sort on multiple fields procedure sortgen: generate by different sorting orders procedure sortt: sort to produce list of records
link sort
September 10, 1998; Bob Alexander, Richard L. Goerwitz, and Ralph E. Griswold
This file is in the public domain.
isort(x, p) customized sort in which procedure p is used for comparison. sortff(L, fields[]) like sortf(), except takes an unlimited number of field arguments. sortgen(T, m) generates sorted output in a manner specified by m: "k+" sort by key in ascending order "k-" sort by key in descending order "v+" sort by value in ascending order "v-" sort by value in descending order sortt(T, i) like sort(T, i) but produces a list of two-element records instead of a list of two-element lists. ____________________________________________________________ Customizable sort procedure for inclusion in Icon programs. isort(x,keyproc,y) Argument x can be any Icon data type that is divisible into elements by the unary element generation (!) operator. The result is a list of the objects in sorted order. The default is to sort elements in their natural, Icon-defined order. However, an optional parameter (keyproc) allows a sort key to be derived from each element, rather than the default of using the element itself as the key. Keyproc can be a procedure provided by the caller, in which case the first argument to the key procedure is the item for which the key is to be computed, and the second argument is isort's argument y, passed unchanged. The keyproc must produce the extracted key. Alternatively, the keyproc argument can be an integer, in which case it specifies a subscript to be applied to each item to produce a key. Keyproc will be called once for each element of structure x.
[ Summary entry | Source code ]
link sortt
August 20, 1998; Ralph E. Griswold
Requires: Version 9
This file is in the public domain.
This program sorts a table in the manner of sort(T, i) but produces a list of two-element records instead of a list of two-element lists
[ Summary entry | Source code ]
link soundex
July 14, 1989; Cheyenne Wills
This file is in the public domain.
This procedure produces a code for a name that tends to bring together variant spellings. See Donald E. Knuth, The Art of Computer Programming, Vol.3; Searching and Sorting, pp. 391-392.
[ Summary entry | Source code ]
link soundex1
April 30, 1993; John David Stone
This file is in the public domain.
When names are communicated by telephone, they are often transcribed incorrectly. An organization that has to keep track of a lot of names has a need, therefore, for some system of representing or encoding a name that will mitigate the effects of transcription errors. One idea, originally proposed by Margaret K. Odell and Robert C. Russell, uses the following encoding system to try to bring together occurrences of the same surname, variously spelled: Encode each of the letters of the name according to the following equivalences: a, e, h, i, o, u, w, y -> * b, f, p, v -> 1 c, g, j, k, q, s, x, z -> 2 d, t -> 3 l -> 4 m, n -> 5 r -> 6 If any two adjacent letters have the same code, change the code for the second one to *. The Soundex representation consists of four characters: the initial letter of the name, and the first three digit (non-asterisk) codes corresponding to letters after the initial. If there are fewer than three such digit codes, use all that there are, and add zeroes at the end to make up the four-character representation.
[ Summary entry | Source code ]
link speedo
March 25, 2002; Robert J. Alexander
This file is in the public domain.
speedo -- a "percentage complete" graphic indicator for command-line-oriented user interfaces. This is a general facility that can function for anything, and a specific implementation for input files. The general implementation consists of two procedures: SpeedoNew -- Starts a speedo SpeedoValue -- Sets a new value for the speedo (non-decreasing) See FileSpeedo for an example of using the general facility. FileSpeedo is especially for input files. Here is how to use it, by example: f := open("input_file") | stop("!!!") FileSpeedo(f,75,&errout) # Start a file speedo, specifying # length and output file while read(f) do { FileSpeedo(f) # Keep it updated while reading file ... } FileSpeedo() # Finish up
[ Summary entry | Source code ]
link spin
November 25, 1996; Mark Otto
Contributor: Ralph E. Griswold
This file is in the public domain.
This little procedure came from a discussion about how to produce a spinning cursor. The argument, if supplied, limits the number of cycles.
[ Summary entry | Source code ]
link statemap
March 25, 2002; Ralph E. Griswold
This file is in the public domain.
This procedure produces a "two-way" table to map state names (in the postal sense) to their postal abbreviations and vice-versa. The list is done in two parts with auxiliary procedures so that this procedure can be used with the default constant-table size for the translator and linker.
[ Summary entry | Source code ]
link step
April 6, 1993; Ralph E. Griswold
This file is in the public domain.
step(r1, r2, r3) generates real values from r1 to r2 in increments of r3 (default 1.0). It is the real equivalent of i to j by k. If r2 is null, the sequence is infinite and is the real equivalent of seq(). Beware the usual problems of floating-point precision.
[ Summary entry | Source code ]
link str2toks
March 3, 1996; Richard L. Goerwitz
This file is in the public domain.
str2toks: cset x string x integer x integer -> strings (c, s, i, j) -> s1, s2, ... Suspends portions of s[i:j] delimited by characters in c. The usual defaults for s, i, and j apply, although str2toks is not meant as a primitive scanning function (note that it suspends strings, and not integer positions). Defaults: c ~(&letters ++ &digits) s &subject i &pos if s is defaulted, otherwise 1 j 0 Basically, this file is just a very simple piece of code wrapped up with some sensible defaults, and isolated in its own procedure. ____________________________________________________________ Example: "hello, how are ya?" ? every write(str2toks()) The above expression would write to &output, on successive lines, the words "hello", "how", "are", and finally "ya" (skipping the punctuation). Naturally, the beginning and end of the line count as delimiters. Note that if i > 1 or j < *s+1 some tokens may end up appearing truncated. Normally, one should simply use the defaults for i and j - and for s as well when inside a scanning expression.
[ Summary entry | Source code ]
procedure cat: concatenate strings procedure charcnt: character count procedure collate: string collation procedure comb: character combinations procedure compress: character compression procedure coprefix: find common prefix of strings procedure cosuffix: find common suffix of strings procedure csort: lexically ordered characters procedure decollate: string decollation procedure deletec: delete characters procedure deletes: delete string procedure diffcnt: number of different characters procedure extend: extend string procedure fchars: characters in order of frequency procedure interleave: interleave strings procedure ispal: test for palindrome procedure maxlen: maximum string length procedure meander: meandering strings procedure multicoll: collate strings in list procedure ochars: first appearance unique characters procedure odd_even: odd-even numerical string procedure palins: palindromes procedure permutes: generate string permutations procedure pretrim: pre-trim string procedure reflect: string reflection procedure replace: string replacement procedure replacem: multiple string replacement procedure replc: replicate characters procedure rotate: string rotation procedure schars: lexical unique characters procedure scramble: scramble string procedure selectp: select characters procedure slugs: generate s in chunks of size <= n procedure starseq: closure sequence procedure strcnt: substring count procedure substrings: generate substrings procedure transpose: transpose characters procedure words: generate words from string
link strings
May 8, 2002; Ralph E. Griswold
This file is in the public domain.
These procedures perform operations on strings. cat(s1, s2, ...) concatenates an arbitrary number of strings. charcnt(s, c) returns the number of instances of characters in c in s. collate(s1, s2) collates the characters of s1 and s2. For example, collate("abc", "def") produces "adbecf". comb(s, i) generates the combinations of characters from s taken i at a time. compress(s, c) compresses consecutive occurrences of charac- ters in c that occur in s; c defaults to &cset. coprefix(s1, s2, ...) produces the common prefix of its arguments: the longest initial substring shared by all, which may be the empty string. cosuffix(s1, s2, ...) produces the common suffix of its arguments: the longest trailing substring shared by all, which may be the empty string. csort(s) produces the characters of s in lexical order. decollate(s, i) produces a string consisting of every other character of s. If i is odd, the odd-numbered characters are selected, while if i is even, the even-numbered characters are selected. The default value of i is 1. deletec(s, c) deletes occurrences of characters in c from s. deletep(s, L) deletes all characters at positions specified in L. deletes(s1, s2) deletes occurrences of s2 in s1. diffcnt(s) returns count of the number of different characters in s. extend(s, n) replicates s to length n. fchars(s) returns characters of s in order of decreasing frequency interleave(s1, s2) interleaves characters s2 extended to the length of s1 with s1. ispal(s) succeeds and returns s if s is a palindrome maxlen(L, p) returns the length of the longest string in L. If p is given, it is applied to each string as as a "length" procedure. The default for p is proc("*", 1). meander(s, n) produces a "meandering" string that contains all n-tuples of characters of s. multicoll(L) returns the collation of the strings in L. ochars(s) produces the unique characters of s in the order that they first appear in s. odd_even(s) inserts values in a numerical string so that adjacent digits follow an odd-even pattern. palins(s, n) generates all the n-character palindromes from the characters in s. permutes(s) generates all the permutations of the string s. pretrim(s, c) trims characters from beginning of s. reflect(s1, i, s2) returns s1 concatenated s2 and the reversal of s1 to produce a palindroid; the values of i determine "end conditions" for the reversal: 0 pattern palindrome; the default 1 pattern palindrome with center duplicated 2 true palindrome with center not duplicated 3 true palindrome with center duplicated s2 defaults to the empty string, in which case the result is a full palindrome replace(s1, s2, s3) replaces all occurrences of s2 in s1 by s3; fails if s2 is null. replacem(s, ...) performs multiple replacements in the style of of replace(), where multiple argument pairs may be given, as in replacem(s, "a", "bc", "d", "cd") which replaced all "a"s by "bc"s and all "d"s by "cd"s. Replacements are performed one after another, not in parallel. replc(s, L) replicates each character of c by the amount given by the values in L. rotate(s, i) rotates s i characters to the left (negative i produces rotation to the right); the default value of i is 1. schars(s) produces the unique characters of s in lexical order. scramble(s) scrambles (shuffles) the characters of s randomly. selectp(s, L) selects characters of s that are at positions given in L. slugs(s, n, c) generates column-sized chunks (length <= n) of string s broken at spans of cset c. Defaults: n 80 c ' \t\r\n\v\f' Example: every write("> ", slugs(msg, 50)) starseq(s) sequence consisting of the closure of s starting with the empty string and continuing in lexical order as given in s strcnt(s1, s2) produces a count of the number of non-overlapping times s1 occurs in s2; fails is s1 is null substrings(s, i, j) generates all the substrings of s with lengths from i to j, inclusive; i defaults to 1, j to *s transpose(s1, s2, s3) transposes s1 according to label s2 and transposition s3. words(s, c) generates the "words" from the string s that are separated by characters from the cset c, which defaults to ' \t\r\n\v\f'.
[ Summary entry | Source code ]
link strip
June 3, 1991; Richard L. Goerwitz
This file is in the public domain.
strip(s,c) - strip characters c from string s
[ Summary entry | Source code ]
link stripcom
March 3, 1996; Richard L. Goerwitz
This file is in the public domain.
Strip commented-out portion of a line of Icon code. Fails on lines which, either stripped or otherwise, come out as an empty string. ____________________________________________________________ BUGS: Can't handle lines ending in an underscore as part of a broken string literal, since stripcom is not intended to be used on sequentially read files. It simply removes comments from indi- vidual lines.
[ Summary entry | Source code ]
link stripunb
May 2, 2001; Richard L. Goerwitz
This file is in the public domain.
This routine strips material from a line which is unbalanced with respect to the characters defined in arguments 1 and 2 (unbalanced being defined as bal() defines it, except that characters preceded by a backslash are counted as regular characters, and are not taken into account by the balancing algorithm). One little bit of weirdness I added in is a table argument. Put simply, if you call stripunb() as follows, stripunb('<','>',s,&null,&null,t) and if t is a table having the form, key: "bold" value: outstr("\e[2m", "\e1m") key: "underline" value: outstr("\e[4m", "\e1m") etc. then every instance of "<bold>" in string s will be mapped to "\e2m," and every instance of "</bold>" will be mapped to "\e[1m." Values in table t must be records of type output(on, off). When "</>" is encountered, stripunb will output the .off value for the preceding .on string encountered.
[ Summary entry | Source code ]
link tab2list
January 3, 1994; Ralph E. Griswold
See also: list2tab.icn, tab2rec.icn, rec2tab.icn
This file is in the public domain.
This procedure to takes tab-separated strings and inserts them into a list. Vertical tabs in strings are converted to carriage returns. (Works for lists too.)
[ Summary entry | Source code ]
link tab2rec
July 6, 2002; Ralph E. Griswold
This file is in the public domain.
This procedure to takes tab-separated strings and inserts them into fields of a record. Vertical tabs in strings are converted to carriage returns. (Works for lists too.)
[ Summary entry | Source code ]
procedure tblunion: table union procedure tblinter: table intersection procedure tbldiff: table difference procedure tblinvrt: table inversion procedure tbldflt: table default procedure twt: two-way table procedure keylist: list of keys in table procedure tbleq: table equivalence procedure vallist: list of table values procedure valset: set of table values
link tables
August 20, 1996; Ralph E. Griswold
Contributor: Alan Beale
This file is in the public domain.
keylist(T) produces list of keys in table T. kvallist(T) produces values in T ordered by sorted order of keys. tbleq(T1, T2) tests equivalences of tables T1 amd T2. tblunion(T1, T2) approximates T1 ++ T2. tblinter(T1, T2) approximates T1 ** T2. tbldiff(T1, T2) approximates T1 -- T2. tblinvrt(T) produces a table whose keys are T's values and whose values are T's keys. tbldflt(T) produces the default value for T. twt(T) produces a two-way table based on T. vallist(T) produces list of values in table T. ____________________________________________________________ For the operations on tables that mimic set operations, the correspondences are only approximate and do not have the mathematical properties of the corresponding operations on sets. For example, table "union" is not symmetric or transitive. Where there is potential asymmetry, the procedures "favor" their first argument. All the procedures that return tables return new tables and do not modify their arguments.
[ Summary entry | Source code ]
link tclass
August 14, 1996; Ralph E. Griswold
This file is in the public domain.
tclass(x) returns "atomic" or "composite" depending on the type of x.
[ Summary entry | Source code ]
link title
March 25, 2002; Ralph E. Griswold
This file is in the public domain.
This procedure produces the "title" of a name, as "Mr." from "Mr. John Doe". The process is imperfect.
[ Summary entry | Source code ]
link titleset
September 2, 1991; Ralph E. Griswold
This file is in the public domain.
This procedure produces a set of strings that commonly appear as titles in names. This set is (necessarily) incomplete.
[ Summary entry | Source code ]
link tokgen
May 23, 1996; Ralph E. Griswold
This file is in the public domain.
These procedures are for use with code produced by a meta-translator. The result of linking these procedures with a program translated by standard the meta-translator and executing the result is a tabulation of the tokens in the program. ____________________________________________________________ Bug: The invocable declaration is not handled properly. "invocable all" will get by, but some other forms produce syntax errors. The problem is in the meta-translator itself, not in this program.
[ Summary entry | Source code ]
procedure depth: depth of tree procedure ldag: construct dag from string procedure ltree: construct tree from string procedure stree: construct string from tree procedure tcopy: tree copy procedure teq: tree equivalence procedure visit: visit nodes of tree
link trees
December 27, 1995; Ralph E. Griswold
This file is in the public domain.
depth(t) compute maximum depth of tree t ldag(s) construct a dag from the string s ltree(s) construct a tree from the string s stree(t) construct a string from the tree t tcopy(t) copy tree t teq(t1,t2) compare trees t1 and t2 visit(t) visit, in preorder, the nodes of the tree t
[ Summary entry | Source code ]
link tuple
June 10, 1988; William H. Mitchell
This file is in the public domain.
This procedure implements a "tuple" feature that produces the effect of multiple keys. A tuple is created by an expression of the form tuple([exrp1, expr2, ..., exprn]) The result can be used in a case expression or as a table subscript. Lookup is successful provided the values of expr1, expr2, ..., exprn are the same (even if the lists containing them are not). For example, consider selecting an operation based on the types of two operands. The expression case [type(op1), type(op2)] of { ["integer", "integer"]: op1 + op2 ["string", "integer"] : op1 || "+" || op2 ["integer", "string"] : op1 || "+" || op2 ["string", "string"] : op1 || "+" || op2 } does not work, because the comparison in the case clauses compares lists values, which cannot be the same as control expression, because the lists are different, even though their contents are the same. With tuples, however, the comparison succeeds, as in case tuple([type(op1), type(op2)]) of { tuple(["integer", "integer"]): op1 + op2 tuple(["string", "integer"]) : op1 || "+" || op2 tuple(["integer", "string"]) : op1 || "+" || op2 tuple(["string", "string"]) : op1 || "+" || op2 }
[ Summary entry | Source code ]
link typecode
April 6, 1993; Ralph E. Griswold
This file is in the public domain.
typecode(x) produces a one-letter string identifying the type of its argument. In most cases, the code is the first (lowercase) letter of the type, as "i" for the integer type. Structure types are in uppercase, as "L" for the list type. All records have the code "R". The code "C" is used for the co-expression type to avoid conflict for the "c" for the cset type. In the case of graphics, "w" is produced for windows.
[ Summary entry | Source code ]
link unsigned
April 2, 1990; Robert J. Alexander
This file is in the public domain.
unsigned() -- Puts raw bits of characters of string s into an integer. The value is taken as unsigned. If large integers are supported, this routine will work for integers of arbitrary size. If large integers are not supported, the following are true: If the size of s is the same as or greater than the size of an integer in the Icon implementation, the result will be negative or positive depending on the value of the integer's sign bit. If the size of s is less than the size of an integer, the bytes are put into the low order part of the integer, with the remaining high order bytes filled with zero. If the string is too large, the most significant bytes will be lost. This procedure is normally used for processing of binary data read from a file.
[ Summary entry | Source code ]
link usage
July 19, 1991; Ralph E. Griswold
This file is in the public domain.
These procedures provide various common services: Usage(s) stops executions with a message concerning the expected form of usage of a program. Error(L[]) writes arguments to &errout and returns. ErrorCheck(l,f) reports an error that has been converted to failure. Feature(s) succeeds if feature s is available in the running implementation of Icon. Requires(s) terminates execution is feature s is not available. Signature() writes the version, host, and features support in the running implementation of Icon.
[ Summary entry | Source code ]
link varsub
November 2, 1995; Robert J. Alexander
This file is in the public domain.
Variable values are obtained from the supplied procedure, "varProc", which returns the value of its variable-name argument or fails if there is no such variable. "varProc" defaults to the procedure, "getenv". As with the UNIX Bourne shell and C shell, variable names are preceded by $. Optionally, the variable name can additionally be surrounded by curly braces {}, which is usually done when necessary to isolate the variable name from surrounding text. As with the C-shell, the special symbol ~<username> is handled. Username can be omitted, in which case the value of the variable "HOME" is substituted. If username is supplied, the /etc/passwd file is searched to supply the home directory of username (this action is obviously not portable to non-UNIX environments).
[ Summary entry | Source code ]
procedure verncnt: number of n-digit versum numbers
link verncnt
January 2, 1998; Ralph E. Griswold
This file is in the public domain.
This procedure produces an approximation to the number of n-digit versum numbers, using a recurrence described in "Versum Numbers" in Icon Analyst 35.
[ Summary entry | Source code ]
link version
September 2, 1991; Ralph E. Griswold
This file is in the public domain.
This procedure produces the version number of Icon on which a program is running. It only works if the &version is in the standard form.
[ Summary entry | Source code ]
procedure vhttp: validate HTTP: URL
link vhttp
May 15, 2002; Gregg M. Townsend
Requires: Unix, dynamic loading
This file is in the public domain.
vhttp(url) validates a URL (a World Wide Web link) of HTTP: form by sending a request to the specified Web server. It returns a string containing a status code and message. If the URL is not in the proper form, or if it does not specify the HTTP: protocol, vhttp fails. ____________________________________________________________ vhttp(url) makes a TCP connection to the Web server specified by the URL and sends a HEAD request for the specified file. A HEAD request asks the server to check the validity of a request without sending the file itself. The response code from the remote server is returned. This is a line containing a status code followed by a message. Here are some typical responses: 200 OK 200 Document follows 301 Moved Permanently 404 File Not Found See the HTTP protocol spec for more details. If a response cannot be obtained, vhttp() returns one of these invented codes: 551 Connection Failed 558 No Response 559 Empty Response ____________________________________________________________ The request sent to the Web server can be parameterized by setting two global variables. The global variable vhttp_agent is passed to the Web server as the "User-agent:" field of the HEAD request; the default value is "vhttp.icn". The global variable vhttp_from is passed as the "From:" field of the HEAD request, if set; there is no default value. ____________________________________________________________ vhttp() contains deliberate bottlenecks to prevent a naive program from causing annoyance or disruption to Web servers. No remote host is connected more than once a second, and no individual file is actually requested more than once a day. The request rate is limited to one per second by keeping a table of contacted hosts and delaying if necessary so that no host is contacted more than once in any particular wall-clock second. Duplicate requests are prevented by using a very simple cache. The file $HOME/.urlhist is used to record responses, and these responses are reused throughout a single calendar day. When the date changes, the cache is invalidated. These mechanisms are crude, but they are effective good enough to avoid overloading remote Web servers. In particular, a program that uses vhttp() can be run repeatedly with the same data without any effect after the first time on the Web servers referenced. The cache file, of course, can be defeated by deleting or editing. The most likely reason for this would be to retry connections that failed to complete on the first attempt.
[ Summary entry | Source code ]
procedure point_field: create VRML point field procedure u_crd_idx: create VRML coordinate index procedure vrml1: write VRML 1.0 file procedure vrml2: produce VRML 2.0 file
link vrml
May 2, 2001; Ralph E. Griswold
Requires: Version 9 graphics for color conversion
See also: vrml1lib.icn and vrml2.icn
This file is in the public domain.
This file contains procedures for producing VRML files. point_field(L) create VRML point field from point list L u_crd_idx(i) create VRML coordinate index for 0 through i - 1 render(x) render node x vrml1(x) produces VRML 1.0 file for node x vrml2(x) produces VRML 2.0 file for node x vrml_color(s) convert Icon color specification to vrml form Notes: Not all node types have been tested. Where field values are complex, as in vectors, these must be built separately as strings to go in the appropriate fields. There is no error checking. Fields must be given in the order they appear in the node record declarations and field values must be of the correct type and form. The introduction of record types other than for nodes will cause bogus output. A structural loop will produce output until the evaluation stack overflows.
[ Summary entry | Source code ]
link vrml1lib
November 19, 1997; Ralph E. Griswold
See also: vrml2lib.icn, vrml.icn
This file is in the public domain.
This file contains record declarations for VRML 1.0 nodes. Note: Although VRML 1.0 allows node fields to be given in any order, they must be specified in the order given in the record declarations that follow. Omitted (null-valued) fields are ignored on output. Group nodes require list arguments for lists of nodes.
[ Summary entry | Source code ]
link vrml2lib
November 19, 1997; Ralph E. Griswold
This file is in the public domain.
This file contains record declarations for VRML 2.0 nodes. Note: Although VRML 2.0 allows node fields to be given in any order, they must be specified in the order given in the record declarations that follow. Group nodes require list arguments for lists of nodes.
[ Summary entry | Source code ]
procedure wdiag: write labeled global values
link wdiag
March 25, 2002; Ralph E. Griswold
This file is in the public domain.
widag(s1, s2, ...) writes the values of the global variables named s1, s2, ... with s1, s2, ... as identifying labels. It writes a diagnostic message to standard error output if an argument is not the name of a global variable. Note that this procedure only works for global variables; there is no way it can access the local variables of the procedure from which it is called.
[ Summary entry | Source code ]
procedure shaftmap: produce shaft map for characters procedure genshafts: generate shafts for string mapping procedure genmapshafts: map string and generate shafts
link weavgenr
August 3, 2000; Ralph E. Griswold
This file is in the public domain.
AD HOC
[ Summary entry | Source code ]
procedure Block: weaving block procedure DownRun: weaving downrun procedure DownUp: weaving downup procedure Downto: weaving downto procedure Extend: weaving extension procedure Interleave: weaving interleave procedure Palindrome: weaving palindrome procedure Pbox: weaving pbox procedure Permute: weaving permutation procedure Template: weaving Template procedure UpDown: weaving updown procedure UpRun: weaving uprun procedure Upto: weaving upto
link weaving
October 22, 1999; Ralph E. Griswold
This file is in the public domain.
These procedures implement the weaving expressions supported by Painter and described in the PDF document "Advanced Weaving" that accompanies that application.
[ Summary entry | Source code ]
procedure writepfd: write PFD procedure expandpfd: expand PFD procedure write_spec: write weaving include file procedure write_spec1: weaving include file procedure write_spec2: weaving include file procedure check: check for pattern form procedure sympos: position of symbol in symbol list procedure possym: symbol in position i of symbol list
link weavutil
April 13, 2002; Ralph E. Griswold
This file is in the public domain.
Links: expander, tables
[ Summary entry | Source code ]
link weighted
May 23, 1994; Erik Eid
This file is in the public domain.
WeightedShuffle returns the list "sample" with only a portion of the elements switched. Examples: L := WeightedShuffle (X, 100) - returns a fully shuffled list L := WeightedShuffle (X, 50) - every other element is eligible to be switched L := WeightedShuffle (X, 25) - every fourth element is shuffled L := WeightedShuffle (X, 0) - nothing is changed The procedure will fail if the given percentage is not between 0 and 100, inclusive, or if it is not a numeric value.
[ Summary entry | Source code ]
link wildcard
September 26, 1990; Robert J. Alexander
This file is in the public domain.
This is a kit of procedures to deal with UNIX-like filename wild-card patterns containing *, ?, and [...]. The meanings are as of the pattern characters are the same as in the UNIX shells csh and sh. They are described briefly in the wild_pat() procedure. These procedures are interesting partly because of the "recursive suspension" technique used to simulate conjunction of an arbitrary number of computed expressions. The public procedures are: wild_match(pattern,s,i1,i2) : i3,i4,...,iN wild_find(pattern,s,i1,i2) : i3,i4,...,iN wild_match() produces the sequence of positions in "s" past a substring starting at "i1" that matches "pattern", but fails if there is no such position. Similar to match(), but is capable of generating multiple positions. wild_find() produces the sequence of positions in "s" where substrings begin that match "pattern", but fails if there is no such position. Similar to find(). "pattern" can be either a string or a pattern list -- see wild_pat(), below. Default values of s, i1, and i2 are the same as for Icon's built-in string scanning procedures such as match(). wild_pat(s) : L Creates a pattern element list from pattern string "s". A pattern element is needed by wild_match() and wild_find(). wild_match() and wild_find() will automatically convert a pattern string to a pattern list, but it is faster to do the conversion explicitly if multiple operations are done using the same pattern.
[ Summary entry | Source code ]
link word
August 14, 1996; Robert J. Alexander
This file is in the public domain.
word(s) -- Produces the position past a UNIX-style command line word. dequote(s) -- Produces the UNIX-style command line word s with any quoting characters removed.
[ Summary entry | Source code ]
link wrap
December 5, 1989; Robert J. Alexander
This file is in the public domain.
wrap(s,i) -- Facilitates accumulation of small strings into longer output strings, outputting when the accumulated string would exceed a specified length (e.g. outputting items in multiple columns). s -- string to accumulate i -- width of desired output string Wrap fails if the string s did not necessitate output of the buffered output string; otherwise the output string is returned (which never includes s). s defaults to the empty string (""), causing nothing to be accumulated; i defaults to 0, forcing output of any buffered string. Note that calling wrap() with no arguments produces the buffer (if it is not empty) and clears it. Wrap does no output to files. Here's how wrap is normally used: wrap() # Initialize (not really necessary unless # a previous use might have left stuff in # the buffer). every i := 1 to 100 do # Loop to process strings to output -- write(wrap(x[i],80)) # only writes when 80-char line filled. write(wrap()) # Output what's in buffer -- only outputs # if something to write. wraps(s,i) -- Facilitates managing output of numerous small strings so that they do not exceed a reasonable line length (e.g. outputting items in multiple columns). s -- string to accumulate i -- maximum width of desired output string If the string "s" did not necessitate a line-wrap, the string "s" is returned. If a line-wrap is needed, "s", preceded by a new-line character ("\n"), is returned. "s" defaults to the empty string (""), causing nothing to be accumulated; i defaults to 0, forcing a new line if anything had been output on the current line. Thus calling wraps() with no arguments reinitializes it. Wraps does no output to files. Here's how wraps is normally used: wraps() # Initialize (not really necessary unless # a previous use might have left it in an # unknown condition). every i := 1 to 100 do # Loop to process strings to output -- writes(wraps(x[i],80))# only wraps when 80-char line filled. writes(wraps()) # Only outputs "\n" if something written # on last line.
[ Summary entry | Source code ]
procedure write_cpt: convert matrix to numerical carpet
link writecpt
August 7, 1997; Ralph E. Griswold
This file is in the public domain.
write_cpt(output, carpet) writes the carpet with heading information to the specified file.
[ Summary entry | Source code ]
procedure xencode: write structure to file procedure xdecode: read structure from file
link xcode
November 19, 1997; Bob Alexander
Contributor: Ralph E. Griswold
See also: codeobj.icn
This file is in the public domain.
Description ----------- These procedures provide a way of storing Icon values in files and retrieving them. The procedure xencode(x,f) stores x in file f such that it can be converted back to x by xdecode(f). These procedures handle several kinds of values, including structures of arbitrary complexity and even loops. The following sequence will output x and recreate it as y: f := open("xstore","w") xencode(x,f) close(f) f := open("xstore") y := xdecode(f) close(f) For "scalar" types -- null, integer, real, cset, and string, the above sequence will result in the relationship x === y For structured types -- list, set, table, and record types -- y is, for course, not identical to x, but it has the same "shape" and its elements bear the same relation to the original as if they were encoded and decoded individually. Files, co-expressions, and windows cannot generally be restored in any way that makes much sense. These objects are restored as empty lists so that (1) they will be unique objects and (2) will likely generate run-time errors if they are (probably erroneously) used in computation. However, the special files &input, &output, and &errout are restored. Not much can be done with functions and procedures, except to preserve type and identification. The encoding of strings and csets handles all characters in a way that it is safe to write the encoding to a file and read it back. xdecode() fails if given a file that is not in xcode format or it the encoded file contains a record for which there is no declaration in the program in which the decoding is done. Of course, if a record is declared differently in the encoding and decoding programs, the decoding may be bogus. xencoden() and xdecoden() perform the same operations, except xencoden() and xdecoden() take the name of a file, not a file. xencodet() and xdecodet() are like xencode() and xdecode() except that the trailing argument is a type name. If the encoded decoded value is not of that type, they fail. xencodet() does not take an opt argument. ____________________________________________________________ Complete calling sequences -------------------------- xencode(x, f, p) # returns f where x is the object to encode f is the file to write (default &output) p is a procedure that writes a line on f using the same interface as write() (the first parameter is always a the value passed as "file") (default: write) xencode(f, p) # returns the restored object where f is the file to read (default &input) p is a procedure that reads a line from f using the same interface as read() (the parameter is always a the value passed as "file") (default: read) The "p" parameter is not normally used for storage in text files, but it provides the flexibility to store the data in other ways, such as a string in memory. If "p" is provided, then "f" can be any arbitrary data object -- it need not be a file. For example, to "write" x to an Icon string: record StringFile(s) procedure main() ... encodeString := xencode(x,StringFile(""),WriteString).s ... end procedure WriteString(f,s[]) every f.s ||:= !s f.s ||:= "\n" return end ____________________________________________________________ Notes on the encoding --------------------- Values are encoded as a sequence of one or more lines written to a plain text file. The first or only line of a value begins with a single character that unambiguously indicates its type. The remainder of the line, for some types, contains additional value information. Then, for some types, additional lines follow consisting of additional object encodings that further specify the object. The null value is a special case consisting of an empty line. Each object other than &null is assigned an integer tag as it is encoded. The tag is not, however, written to the output file. On input, tags are assigned in the same order as objects are decoded, so each restored object is associated with the same integer tag as it was when being written. In encoding, any recurrence of an object is represented by the original object's tag. Tag references are represented as integers, and are easily recognized since no object's representation begins with a digit. Where a structure contains elements, the encodings of the elements follow the structure's specification on following lines. Note that the form of the encoding contains the information needed to separate consecutive elements. Here are some examples of values and their encodings: x encode(x) ------------------------------------------------------- 1 N1 2.0 N2.0 &null "\377" "\377" '\376\377' '\376\377' procedure main p "main" co-expression #1 (0) C [] L N0 set() "S" N0 table("a") T N0 "a" ["hi","there"] L N2 "hi" "there" A loop is illustrated by L2 := [] put(L2,L2) for which x encode(x) ------------------------------------------------------- L2 L N1 2 The "2" on the third line is a tag referring to the list L2. The tag ordering specifies that an object is tagged *after* its describing objects, thus the list L2 has the tag 2 (the integer 1 has tag 1). Of course, you don't have to know all this to use xencode and xdecode.
[ Summary entry | Source code ]
procedure xencode: write structure to file procedure xdecode: read structure from file
link xcodes
November 19, 1997; Bob Alexander
Contributor: Ralph E. Griswold
See also: codeobj.icn
This file is in the public domain.
Note: This version handles the encoding of records using canonical names: record0, record1, ... . This allows programs to decode files by providing declarations for these names when the original declarations are not available. This version also provides for procedures and files present in the encoded file that are not in the decoding program. This version should be merged with the ordinary version. Description ----------- These procedures provide a way of storing Icon values in files and retrieving them. The procedure xencode(x,f) stores x in file f such that it can be converted back to x by xdecode(f). These procedures handle several kinds of values, including structures of arbitrary complexity and even loops. The following sequence will output x and recreate it as y: f := open("xstore","w") xencode(x,f) close(f) f := open("xstore") y := xdecode(f) close(f) For "scalar" types -- null, integer, real, cset, and string, the above sequence will result in the relationship x === y For structured types -- list, set, table, and record types -- y is, for course, not identical to x, but it has the same "shape" and its elements bear the same relation to the original as if they were encoded and decoded individually. Files, co-expressions, and windows cannot generally be restored in any way that makes much sense. These objects are restored as empty lists so that (1) they will be unique objects and (2) will likely generate run-time errors if they are (probably erroneously) used in computation. However, the special files &input, &output, and &errout are restored. Not much can be done with functions and procedures, except to preserve type and identification. The encoding of strings and csets handles all characters in a way that it is safe to write the encoding to a file and read it back. xdecode() fails if given a file that is not in xcode format or it the encoded file contains a record for which there is no declaration in the program in which the decoding is done. Of course, if a record is declared differently in the encoding and decoding programs, the decoding may be bogus. xencoden() and xdecoden() perform the same operations, except xencoden() and xdecoden() take the name of a file, not a file. xencodet() and xdecodet() are like xencode() and xdecode() except that the trailing argument is a type name. If the encoded decoded value is not of that type, they fail. xencodet() does not take an opt argument. ____________________________________________________________ Complete calling sequences -------------------------- xencode(x, f, p) # returns f where x is the object to encode f is the file to write (default &output) p is a procedure that writes a line on f using the same interface as write() (the first parameter is always a the value passed as "file") (default: write) xencode(f, p) # returns the restored object where f is the file to read (default &input) p is a procedure that reads a line from f using the same interface as read() (the parameter is always a the value passed as "file") (default: read) The "p" parameter is not normally used for storage in text files, but it provides the flexibility to store the data in other ways, such as a string in memory. If "p" is provided, then "f" can be any arbitrary data object -- it need not be a file. For example, to "write" x to an Icon string: record StringFile(s) procedure main() ... encodeString := xencode(x,StringFile(""),WriteString).s ... end procedure WriteString(f,s[]) every f.s ||:= !s f.s ||:= "\n" return end ____________________________________________________________ Notes on the encoding --------------------- Values are encoded as a sequence of one or more lines written to a plain text file. The first or only line of a value begins with a single character that unambiguously indicates its type. The remainder of the line, for some types, contains additional value information. Then, for some types, additional lines follow consisting of additional object encodings that further specify the object. The null value is a special case consisting of an empty line. Each object other than &null is assigned an integer tag as it is encoded. The tag is not, however, written to the output file. On input, tags are assigned in the same order as objects are decoded, so each restored object is associated with the same integer tag as it was when being written. In encoding, any recurrence of an object is represented by the original object's tag. Tag references are represented as integers, and are easily recognized since no object's representation begins with a digit. Where a structure contains elements, the encodings of the elements follow the structure's specification on following lines. Note that the form of the encoding contains the information needed to separate consecutive elements. Here are some examples of values and their encodings: x encode(x) ------------------------------------------------------- 1 N1 2.0 N2.0 &null "\377" "\377" '\376\377' '\376\377' procedure main p "main" co-expression #1 (0) C [] L N0 set() "S" N0 table("a") T N0 "a" ["hi","there"] L N2 "hi" "there" A loop is illustrated by L2 := [] put(L2,L2) for which x encode(x) ------------------------------------------------------- L2 L N1 2 The "2" on the third line is a tag referring to the list L2. The tag ordering specifies that an object is tagged *after* its describing objects, thus the list L2 has the tag 2 (the integer 1 has tag 1). Of course, you don't have to know all this to use xencode and xdecode.
[ Summary entry | Source code ]
procedure transform: transform point list by matrix procedure transform_points transform point list procedure set_scale: matrix for scaling procedure set_trans: matrix for translation procedure set_xshear: matrix for x shear procedure set_yshear: matrix for y shear procedure set_rotate: matrix for rotation
link xforms
March 25, 2002; Stephen W. Wampler and Ralph E. Griswold
This file is in the public domain.
These procedures produce matrices for affine transformation in two dimensions and transform point lists. A point list is a list of Point() records. See gobject.icn.
[ Summary entry | Source code ]
procedure ximage: string image of value procedure xdump: write images of values
link ximage
May 19, 1996; Robert J. Alexander
This file is in the public domain.
ximage(x) : s Produces a string image of x. ximage() differs from image() in that it outputs all elements of structured data types. The output resembles Icon code and is thus familiar to Icon programmers. Additionally, it indents successive structural levels in such a way that it is easy to visualize the data's structure. Note that the additional arguments in the ximage procedure declaration are used for passing data among recursive levels. xdump(x1,x2,...,xn) : xn Using ximage(), successively writes the images of x1, x2, ..., xn to &errout. Some Examples: The following code: ... t := table() ; t["one"] := 1 ; t["two"] := 2 xdump("A table",t) xdump("A list",[3,1,3,[2,4,6],3,4,3,5]) Writes the following output (note that ximage() infers the predominant list element value and avoids excessive output): "A table" T18 := table(&null) T18["one"] := 1 T18["two"] := 2 "A list" L25 := list(8,3) L25[2] := 1 L25[4] := L24 := list(3) L24[1] := 2 L24[2] := 4 L24[3] := 6 L25[6] := 4 L25[8] := 5
[ Summary entry | Source code ]
link xrotate
April 30, 1993; Ralph E. Griswold
This file is in the public domain.
xrotate(X, i) rotates the values in X right by one position. It works for lists and records. This procedure is mainly interesting as a recursive version of x1 :=: x2 :=: x3 :=: ... xn since a better method for lists is push(L, pull(L))
[ Summary entry | Source code ]
procedure iszip: check for ZIP archive procedure zipdir: open ZIP directory procedure zipfile: open member of ZIP archive
link zipread
March 5, 2000; Gregg M. Townsend
Requires: UNIX with "unzip" utility.
This file is in the public domain.
These Unix procedures read files from ZIP format archives by opening pipes to the "unzip" utility. It is assumed that "unzip" is in the shell search path. iszip(zname) succeeds if zname is a ZIP archive. zipdir(zname) opens a ZIP archive directory. zipfile(zname, fname) opens a member of a ZIP archive. ____________________________________________________________ iszip(zname) succeeds if the named file appears to be a ZIP format archive file. ____________________________________________________________ zipdir(zname) returns a pipe from which the members of the ZIP archive can be read, one per line, as if reading a directory. It is assumed that zname is a ZIP archive. ____________________________________________________________ zipfile(zname, fname) returns a pipe from which the file fname within the ZIP archive zname can be read. It is assumed that zname and fname are valid.
[ Summary entry | Source code ]