sboisen@BBN.COM (Sean Boisen) (05/31/91)
Appended below (in shar format) is a simple GNU Emacs utility that lets you check the syntax of Icon expressions: for example, while editing a program, i may forget the arguments to "any". I can then call the Emacs function describe-icon-symbol, which displays any(cset,string,i,j) Much easier than reaching for the manual! Richard Goerwitz encouraged me to post it here: no guarantees, but enjoy. I'd be particularly interested if somebody has more complete descriptions (mine are only a single line, not always enough to keep me from reaching for the manual). ........................................ Sean Boisen -- sboisen@bbn.com BBN Systems and Technologies, Cambridge MA ------------------------------ snip snip ------------------------------ #! /bin/sh # To extract, remove mail header lines and type "sh filename" echo x - icon-describe.text sed -e 's/^X//' > icon-describe.text << '!FaR!OuT!' XThis is a quick syntax helper for Icon users that work with GNU Emacs. XThe idea is a simple one: while creating a program, say, you're unsure Xabout the arguments or their orders for push(). With icon-describe, you Xsimple execute the function "describe-icon-symbol" with point Xsomewhere around the word push, and the following information Xis displayed in the mini-buffer: X Xpush(list,x) X XThis works with procedures, infix/prefix operators, control Xstructures/reserved words, and keywords. Note that you get notified if Xsomething isn't in the documentation file, so you can also use it to Xcheck whether you've got the right symbol name or not (but you'd have Xto actually go look at the file to see what the _right_ one is). X X XCaveats: X XSee your Emacs manual for how to load this automatically when you Xvisit .icn files (look at auto-mode-alist and icon-mode-hook, assuming Xyou're using an icon-mode). X Xdescribe-icon-symbol is not initially bound to a key, but you'll Xprobably want to do so. X XThe format of the documentation file is one to a line: this is nice Xbecause it can be displayed in the minibuffer instead of a pop-up Xwhich then has to be gotten rid of. It's not so nice in that it limits Xthe amount of information pretty severely. If somebody wants to Xprovide a larger documentation file i might provide a pop-up version X(or some hybrid): i'm too lazy to do all the typing, for one thing! XThere's also an uneven mix of bare syntax description with some Xdiscussion of what (especially prefix) operators do. A few keywords Xhave no description because they're newer than the Icon book, and i Xdidn't have a description handy. Please contribute to this doc file if Xyou can! X XThe function which determines the symbol at point isn't perfect X(surprise surprise!). In particular it depends on the syntax tables to Xdetermine what punctuation is, so if your syntax tables aren't right, Xthis won't be either. I'm open to suggestions for better algorithms. XThe current version has a preference for looking backward if not Xactually on part of a symbol: this seemed more useful for those cases Xwhere you become hesitant about the arguments to a function just after Xtyping it. X XWhile the usual lack of warranty and support applies, i'd still like Xto hear if there are problems with this. X XSean Boisen XBBN Systems and Technologies Corporation X X XTwo files follow: i call the first icon-describe.el (don't forget to Xbyte-compile it!), and the second icondoc.txt. Whatever you decide to Xcall the latter, make sure you set the variable icon-doc-file accordingly! !FaR!OuT! echo x - icon-describe.el sed -e 's/^X//' > icon-describe.el << '!FaR!OuT!' X;;; Icon syntax describer: by Sean Boisen, BBN Systems and X;;; Technologies Corporation, sboisen@bbn.com. Standard lack of X;;; warranty applies: may be freely distributed subject to the X;;; restrictions of the GNU Emacs copyright. Please send me any bug X;;; fixes and/or improvements! X;;; X;;; This still has at least the following known deficiences: X;;; X;;; The descriptive text file lacks descriptions for the newer X;;; keywords. Please add them and send me a version if you can! X;;; X;;; It might be nice if icon-symbol-at-point did escape sequences as X;;; well: it doesn't. X;;; X;;; Someday it might be more useful to provide more than one line of X;;; information, especially for procedures: the main hurdle here is X;;; that i'm too lazy to type all the text in. X X;;; additions: X;;; X;;; sboisen 2/23/89: i noticed that &pos gets X;;; picked up as pos. Hacked describe-icon-symbol for this as a X;;; special case. Still imperfect if point in just past the colon in X;;; 0:&pos however... X;;; X;;; sboisen 2/23/89: symbols which contain characters with special X;;; meanings in regexps don't get handled properly! not yet fixed... X X(require 'icon-mode) X X(provide 'icon-describe) X X(defvar icon-doc-file "/d4m/sboisen/emacs/icondoc.txt" X "Where the documentation file can be found.") X X;; a helper function: get a string containing all the characters matching X;; some spec in a syntax table. Class is an atom. Useful in conjunction with X;; skip-chars-forward. Doesn't do the eighth bit. X X(defun get-chars-in-class (class syntax-table) X (let ((classcode X (cond X ((eq class 'whitespace) 0) X ((eq class 'punctuation) 1) X ((eq class 'word) 2) X ((eq class 'symbol) 3) X ((eq class 'open) 4) ;this doesn't work! X ((eq class 'close) 5) X ((eq class 'prefix) 6) X ((eq class 'stringquote) 7) X ((eq class 'charquote) 9) X ((eq class 'startcomment) 11) X ((eq class 'endcomment) 12) X )) X (index 0) X (str "")) X (while (< index 128) X (if (eql (aref syntax-table index) classcode) X (setq str (concat str (char-to-string index)))) X (setq index (1+ index))) X str)) X X(defvar wordchars "a-zA-Z0-9_") X(defvar junkchars (concat " \n\t\r" "({[)}]")) X(defvar punct (get-chars-in-class 'punctuation icon-mode-syntax-table)) X X(defun icon-symbol-at-point () X "Get the closest Icon symbol to point, but don't change your X position. Has a preference for looking backward when not X directly on a symbol." X (let (start end symbol) X (save-excursion X ;; first see if you're just past a symbol X (if (looking-at "\\s-\\|\\s(\\|\\s)\\|\\s>") X (skip-chars-backward junkchars) X ;; else move forward one character, presumably either a \w or X ;; a symbol: but not if at the end of the buffer X (or (= (point) (point-max)) X (forward-char 1))) X X (cond X ;; special case for (potential) keywords: just past a & X ((eql (preceding-char) 38) X (setq start (1- (point))) X (cond X ((looking-at "\\w") X (skip-chars-forward wordchars)) X ((looking-at "\\s.") X (skip-chars-forward punct)) X ;; else whitespace? X )) X ;; just past a \\w X ((eql (aref icon-mode-syntax-table (preceding-char)) 2) X (skip-chars-backward wordchars) X ;; worry about being in the middle of a keyword X (if (eql (preceding-char) 38) X (setq start (1- (point))) X (setq start (point))) X (skip-chars-forward wordchars)) X ;; else a symbol? X (t X (skip-chars-backward punct) X (setq start (point)) X (skip-chars-forward punct))) X ;; THE OLD WAY THAT LOOKED FORWARD INSTEAD OF BACKWARD X;; ;; skip past whitespace and parens X;; (while (looking-at "\\s-\\|\\s(\\|\\s)\\|\\s>") X;; (skip-chars-forward junkchars)) X;; (if (looking-at "\\w") X;; (progn X;; (skip-chars-forward wordchars) X;; (setq start (point)) X;; (skip-chars-backward wordchars)) X;; ;; else a symbol? X;; (progn X;; (skip-chars-forward punct) X;; (setq start (point)) X;; (skip-chars-backward punct))) X (buffer-substring start (point))))) X X(defun describe-icon-symbol (symbol) X "Display the documentation of SYMBOL, an Icon operator." X (interactive X (let ((fn (icon-symbol-at-point)) X (enable-recursive-minibuffers t) X (case-fold-search nil) ;require that case match for search X val args-file regexp) X (setq val (read-from-minibuffer X (if fn X (format "Symbol (default %s): " fn) X "Symbol: "))) X (if (string= val "") X (setq val fn)) X ;; this may not work for characters which are special to regexp X ;; (like ".") X (setq regexp (concat "^" val "[ \t(]")) X (if (not (get-file-buffer icon-doc-file)) X (progn X (setq args-file X (find-file-noselect icon-doc-file)) X (set-buffer args-file) X (rename-buffer "*ICON-DOC*"))) X (set-buffer (get-file-buffer icon-doc-file)) X (goto-char (point-min)) X (list (if (re-search-forward regexp (point-max) t) X (save-excursion X (beginning-of-line 1) X (let ((lnstart (point))) X (end-of-line) X (message (buffer-substring lnstart (point))))) X (error (format "No definition for %s" val))))))) !FaR!OuT! echo x - icondoc.txt sed -e 's/^X//' > icondoc.txt << '!FaR!OuT!' XFORMAT: a regexp like "^word(args)" of "^word[\t ]descriptive_text Xabs(numeric) Xany(cset,string,i,j) Xbal(cset1,cset2,cset3,string,i,j) Xcenter(string1,i,string2) Xchar(i) Xclose(file) Xcollect() Xcopy(x) Xcset(x) Xdelete(x1,x2) Xdetab(string,i1,i2,...,in) Xdisplay(i,file) Xentab(string,i1,i2,...,in) Xerrorclear() Xexit(i) Xfind(string1,string2,i,j) Xget(list) Xgetenv(string) Xiand(i,j) Xicom(i) Ximage(x) Xinsert(x1,x2,x3) Xinteger(x) Xior(i,j) Xixor(i,h) Xishift(i,j) Xleft(string1,i,string2) Xlist(i,x) Xmany(cset,string,i,j) Xmap(string1,string2,string3) Xmatch(string1,string2,i,j) Xmember(x1,x2) Xmove(i) Xnumeric(x) Xopen(string1,string2) Xord(string) Xpop(list) Xpos(i) Xproc(x) Xpull(list) Xpush(list,x) Xput(list,x) Xread(file) Xreads(file,i) Xreal(x) Xremove(string) Xrename(string1,string2) Xrepl(string,i) Xreverse(string) Xright(string1,i,string2) Xrunerr(i,x) Xsave(string) Xseek(file,i) Xseq(i,j) Xset(list) Xsort(list) Xsort(table,i) Xstop(x1,x2,...,xn) Xstring(x) Xsystem(string) Xtab(i) Xtable(x) Xtrim(string,cset) Xtype(x) Xupto(cset,string,i,j) Xwhere(file) Xwrite(x1,x2,...,xn) Xwrites(x1,x2,...,xn) XCONTROL STRUCTURES/RESERVED WORDS Xbreak expr Xby i to j by k Xcase expr of {...} Xcreate x Xdefault : expr Xdo every expr1 do expr2; until expr1 do expr2; while expr1 do expr2 Xdynamic identifiers Xelse if expr1 then expr2 else expr3 Xend Xevery expr1 do expr2 Xfail Xglobal identifiers Xif expr1 then expr2 else expr3 Xinitial expr Xlink file1,file2,...filen Xlocal identifiers Xnext Xnot expr Xof case expr of {...} Xprocedure identifier(identifiers) Xrecord identifiers(fields) Xrepeat expr Xreturn expr Xstatic identifiers Xsuspend expr Xthen if expr1 then expr2 else expr3 Xto i to j by k Xuntil expr1 do expr2 Xwhile expr1 do expr2 X| expr1 | expr2; |expr X\ expr \ i ; \x produces x if x is not null, otherwise fails X?:= s ?:= x X? s ? x; ?x produces a random element of x, failing if x is empty XINFIX OPERATIONS X+ n + m produces the sum of n and m; +n produces the numeric value of n X- n - m produces the difference of n and m; -n produces the negative of n X* n * m produces the product of n and m; *x produces the size of x X/ n / m produces n divided by m; /x produces x if x is null, or else fails X% n % m produces the remainder of n divided by m X^ n ^ m produces n to the power of m; ^e produces a refreshed copy of e X< n < m produces m if n is less than m, else fails X<= n <= m produces m if n is less than or equal to m, else fails X= n = m produces m if n equals m, else fails; =s equiv. to tab(match(s)) X>= n >= m produces m if n is greater than or equal to m, else fails X> n > m produces m if n is greater than m, else fails X~= n ~= m produces m if n is not equal to m, else fails X++ c1 ++ c2 produces the cset union of c1 and c2 X-- c1 -- c2 produces the cset difference of c1 and c2 X** c1 ** c2 produces the cset intersection of c1 and c2 X|| s1 || s2 produces a string consisting of s1 followed by s2 X<< s1 << s2 produces s2 if s1 is lexically less than s2, else fails X<<= s1 <<= s2 produces s2 if s1 is lexically <= s2, else fails X== s1 == s2 produces s2 if s1 is lexically equal to s2, else fails X>>= s1 >>= s2 produces s2 if s1 is lexically >= s2, else fails X>> s1 >> s2 produces s2 if s1 is lexically greater than s2, else fails X~== s1 ~== s2 produces s2 if s2 isn't lexically equal to s2, else fails X||| a1 ||| a2 produces a list of the values of a1 followed by those of a2 X@ x @ e activates e and transmits x to it; @e produces the outcome of activating e X:= x := y assigns the value of y to x, and produces the variable x X<- x <- y assigns y to x and produces x; reverses assignment if resumed X:=: x :=: y exchanges the values of x and y and produces the variable x X<-> x <-> y exchanges x and y and produces x; reverses exchange if resumed X=== x === y produces y if x and y have the same value, else fails X~=== x ~=== y produces y if x and y don't have the same value, else fails X& x & y produces y; produces a variable if y is a variable X. x . y produces a variable for the y field of record x X+:= n +:= m assigns the sum of n and m to n and produces n X-:= n -:= m assigns the difference of n and m to n and produces n X*:= n *:= m assigns the product of n and m to n and produces n X/:= n /:= m assigns the difference of n and m to n and produces n X%:= n %:= m assigns the remainder of n divided by m to n and produces n X^:= n ^:= m assigns n raised to the power m to n and produces n X<:= n <:= m assigns m to n if n < m, else fails; produces n X<=:= n <=:= m assigns m to n if n <= m, else fails; produces n X=:= n =:= m assigns m to n if n = m, else fails; produces n X>=:= n >=:= m assigns m to n if n >= m, else fails; produces n X>:= n >:= m assigns m to n if n > m, else fails; produces n X~=:= n ~=:= m assigns m to n if n ~= m, else fails; produces n X++:= c1 ++:= c2 assigns the cset union of c1 and c2 to c1 and produces c1 X--:= c1 --:= c2 assigns the cset difference of c1 and c2 to c1, producing c1 X**:= c1 **:= c2 assigns the intersection of c1 and c2 to c1, producing c1 X||:= s1 ||:= s2 assigns the string s1 || s2 to s1 and produces s1 X<<:= s1 <:= s2 assigns s2 to s1 if s1 << s2, else fails; produces s1 X<<=:= s1 <=:= s2 assigns s2 to s1 if s1 <<= s2, else fails; produces s1 X==:= s1 =:= s2 assigns s2 to s1 if s1 == s2, else fails; produces s1 X>>=:= s1 >=:= s2 assigns s2 to s1 if s1 >>= s2, else fails; produces s1 X>>:= s1 >:= s2 assigns s2 to s1 if s1 >> s2, else fails; produces s1 X~==:= s1 ~=:= s2 assigns s2 to s1 if s1 ~== s2, else fails; produces s1 X|||:= a1 |||:= a2 assigns to a1 the concatenation of a1 and a2; produces a1 X@:= x @:= e activates e with the value of x, and assigns the result to x X===:= x ===:= y assigns y to x if x === y, else fails; produces x X~===:= x ~===:= y assigns y to x if x ~=== y, else fails; produces x X&:= x &:= y assigns the value of y to x and produces x XPREFIX OPERATIONS (some under infix instead) X~ ~c produces the cset complement of c with respect to &cset X! !x generates the elements of x, failing if x is empty (x may be a file) X. .x produces the value of x XKEYWORDS X&ascii produces a cset of the 128 ASCII characters X&clock produces a string consisting of the current time of day X&collections X&cset produces a cset consisting of all 256 characters X¤t X&date produces a string consisting of the current date X&dateline produces a string of the current date and time of day X&digits X&error X&errornumber X&errortext X&errorvalue X&errout produces the standard error output file X&fail fails X&features X&file X&host produces a string that identifies the host computer X&input produces the standard input file X&lcase produces a cset consisting of the 26 lowercase letters X&level produces the integer level of the current procedure call X&line X&main produces a co-expression for the initial call of main X&null produces the null value X&output produces the standard output file X&pos produces the integer position of scanning in &subject X&random produces the value of the seed for the psuedo-random sequence X®ions X&source produces a co-expression for the activator of the current co-expression X&storage how much of each storage region is currently being used X&subject produces the variable whose value is the string being scanned X&time produces the integer number of msecs since beginning of execution X&trace produces a variable whose value controls procedure tracing X&ucase produces a cset consisting of the 26 uppercase characters X&version produces a string that identifies the version of Icon !FaR!OuT! exit