unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* hide/show mode definitions for g77
@ 2004-10-25 17:16 David McKee
  2004-11-02  9:48 ` Thien-Thi Nguyen
  0 siblings, 1 reply; 5+ messages in thread
From: David McKee @ 2004-10-25 17:16 UTC (permalink / raw)


Folks,
   Please find, below, a first stab at hide/show mode definitions for the
g77 dialect of Fortran. 

The code is derived from a f90 mode posted to the Usenet in 2002 by Glenn
Morris---who has given me his permission to submit this work---and
functions pretty well for programs written using structured block pairs. No
attempt is made to handle strict fortran 77 syntax in which blocks are
delimited with CONTINUEs and GO TOs.

This code has received little testing to date---I have show it to some
colleagues working on the same code I wanted it for, but have not heard
back from anyone. Also note that I am by no means a lisp programmer.

No guarantees or warranty, etc.

The code is also availible at:

	<http://www.jlab.org/~dmckee/G0/g77_hs_mode.el>

-- 
-- David McKee
-- dmckee@jlab.org
-- (757) 269-7492    (Office)


===========================

;; g77 fortran dialect hide-show mode definition.
;;
;; 19--22 October 2004  David W. McKee
;; Version 0.1  
;; Initial implementation.
;;
;; Hacked up from a f90 mode posted to the usenet:
;; From: Glenn Morris
;; Newsgroups: gnu.emacs.help </groups?hl=en&lr=&group=gnu.emacs.help>
;; Date: 2002-04-26 18:58:34 PST

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Features and what not:
;; ----------------------
;; ==> Tries to work with the g77 dialect
;;
;; ==> Assume that the code is as structured as possible.  Indeed, we
;; make no attempt to deal with unstructured code. If you don't use
;; endif, enddo, etc. this code won't help you.
;;
;; ==> Identifies "IF" statements as block starts by finding the
;; "THEN" part, so that the condition remains visible after hiding.
;; Similarly for "WHILE (..) DO"

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Known bugs in the f77 version:
;; ------------------------------
;; 22 October 2004 David McKee 
;;
;; ==> Comment hiding doesn't seem to work work. I don't understand
;; what it's supposed to do so I don't know where to go from here.
;;
;; ==> "CONTINUE" is a difficult case and is not treated at all.
;;
;; ==> Condition-at-the-end loops are often implemented as:
;;
;;    10   DO
;;         ...
;;         IF (...) GOTO 10
;;         ENDDO
;;
;; which will have the conditional hidden. Too bad.
;;
;; ==> I've cheeted in the ident-or-num regular expression, and it
;; will accept some constructions that the compiler will
;; reject. eg. "1abc" and the like...
;;
;; ==> So far it has recieved very little testing.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defvar fortran-line-start-regexp "^\\ *[0-9]*\\ *" 
  "Allow for arbitrary white space at the start of a line.")

(defvar fortran-ident-regexp "\\<[A-Za-z][A-Za-z0-9_]*\\>" 
  "Regular expresion for fortran identifiers.")

;; Not precisly correct, but probably do the trick anyway
(defvar fortran-ident-or-num-regexp "\\<[A-Za-z0-9][A-Za-z0-9_]*\\>" 
  "")

;; Block "IF (..) THEN" and "WHIE (...) DO" statements could easily span
;; lines, so we select the block start on the ending keyword...
(defvar fortran-block-start-regexp
  (concat fortran-line-start-regexp
          "\\("
	  "\\(" "\\<program\\>[ \t]+" fortran-ident-regexp "\\)" "\\|" 
 	  "\\(" "\\<subroutine\\>[ \t]+" fortran-ident-regexp 
	                                 "[ \t]*([^)]*)" "\\)" "\\|" 
 	  "\\(" fortran-ident-regexp "[ \t]+\\<function\\>[ \t]+" 
	                             fortran-ident-regexp "[ \t]*([^)]*)" 
				     "\\)" "\\|"
	  ;; 'if (...) then'
	  ;; Note that 'if' without 'then' does not mark a block
 	  "\\(" ".*\\<then\\>" "\\)" "\\|"
	  ;; basic iterative 'do's
 	  "\\(" "\\<do\\>[ \t]*[0-9]*[ \t]+" fortran-ident-regexp 
                                       "[ \t]*=[ \t]*"
				       fortran-ident-or-num-regexp 
				       "\\([ \t]*,[ \t]*" 
				           fortran-ident-or-num-regexp 
				       "\\)+" "\\)" "\\|"
	  ;; do forever syle unconditional loop,
	  ;; also picks up 'while (...) do' constructs...
	  ;;
	  ;; Should proceed the while (..) do branch
 	  "\\(" "\\<do\\>[ \t]$" "\\)" "\\|"
	  ;; 'do while (...)'
	  ;; fails when the condition spans lines...
	  ;; but this does not seem to be part of the g77 dialect in any case
 	  "\\(" ".*\\<while\\>[ \t]*([^)]*)" "\\([ \t]*\\<do\\>\\)?" 
	                                     "\\)" "\\|"
	  ;;
	  ;; ELSE only starts a block if it is not followed by an IF
	  ;; for ELSE IF constructs, we start on the THEN.
	  ;; Look at fortran-block-end-start-regexp and the handling
	  ;; in fortran-forward-block...
	  "\\(" "\\<else\\>\\s *\\(!.*\\)?$" "\\)"
	  "\\)"
	  )
  "Regexp matching the start of a \"block\" of FORTRAN code.")

(defvar fortran-block-end-regexp
  (concat fortran-line-start-regexp 
	  "\\("
	  ;; structured fortran uses 'end<stuff>'
 	  "\\(" "\\<enddo\\>" "\\)" "\\|" 
 	  "\\(" "\\<endif\\>" "\\)" "\\|" 
	  ;; some dialects
 	  "\\(" "\\<endwhile\\>" "\\)" "\\|" 
	  ;; end<space>[if|do|while]type stuff
	  "\\(" "\\<end\\>[ \t]+" fortran-ident-regexp "\\)" "\\|" 
	  ;; catchall
	  "\\(" "\\<end\\>" "\\)" "\\|"
	  ;; CONTINUE causes trouble, it marks the end of old-fashioned
	  ;; do i=start,stop,inc type loops, but also serves as a 
	  ;; general labeling construct.
	  ;;
	  ;; leave it out by default
 	     ;; "\\(" "\\<continue\\>" "\\)" 
	  ;;
	  ;; Start and end bock markers...
	  ;;
	  "\\(" "\\<elseif\\>" "\\)" "\\|"
	  "\\(" "\\<else\\>\\s +\\<if\\>" "\\)" "\\|"
	  "\\(" "\\<else\\>" "\\)"
	  "\\)"
	  )
  "Regexp matching the end of a \"block\" of FORTRAN code.")

(defvar fortran-block-end-start-regexp
  (concat fortran-line-start-regexp
	  "\\("
	  "\\(" "\\<elseif\\>" "\\)" "\\|"
	  "\\(" "\\<else\\>\\s +\\<if\\>" "\\)" "\\|"
	  "\\(" "\\<else\\>\\s +\\<if\\>" "\\)"
	  "\\)"
	  )
  "Regexp matching a construct that marks the end of one \"block\" of
FORTRAN code, and the start of another. At this time this is only
ELSEIF constructs and ELSE statements.")

(defvar fortran-comment-regexp
  (concat ;;"\\("
	  "\\(" "^[CcDd\\*]" "\\)" ;;"\\|" 
          ;;"\\(" "^\\s *!.*$" "\\)"
	  ;;"\\)"
	  )
  "Regular expression for identifiying block comments in fortran")

;; Utility functions for checking my regexps
(defun fortran-find-next-block-start ()
  "Search forward to the next line matching fortran-block-end-regexp."
  (interactive)
  (search-forward-regexp fortran-block-start-regexp))

(defun fortran-find-next-block-end ()
  "Search forward to the next line matching fortran-block-end-regexp."
  (interactive)
  (search-forward-regexp fortran-block-end-regexp))

(defun fortran-next-block-start (arg)
  "Move forward a line at a time until we reach one matching fortran-block-start-regexp." 
  (interactive "p")
  (while (and (zerop (forward-line 1))
	      (not (looking-at fortran-block-start-regexp))) 
    (forward-line 1)))

(defun fortran-find-end-start-start ()
  "Move the point to the beginning of the next line--including the current
line--which matches fortran-block-start-regexp"
  (interactive)
  ((beginning-of-line)
   (while (null (looking-at fortran-block-start-regexg))
     (forward-line 1))
   (begining-of-line)))

(defun fortran-find-end-start-end ()
  "Move the point to the beginning of the most recent line--including
the current line--which matches fortran-block-end-regexp"
  (interactive)
  (beginning-of-line)
  (while (null (looking-at fortran-block-end-regexg))
    (forward-line -1))
  (beginning-of-line))

(defun fortran-forward-block (arg)
  "Move point to the forward until reaching exiting ARG levels of blocks"
  (interactive "p")
  (let ((count (or arg 1)))
    (while (and (> count 0) (zerop (forward-line 1)))
      (if (looking-at fortran-block-end-regexp) (setq count (1- count)))
      (and (> count 0) ()
	(if (looking-at fortran-block-end-start-regexp) 
	    (fortran-find-end-start-end))
	(if (looking-at fortran-block-start-regexp) 
	    (setq count (1+ count)))))))

(defun fortran-forward-block-adjust (arg)
  "Execute fortran-forward-block, then adjust the point to the end of the preceding line. Serves to leaves block ending constructs visible in hs-node."
  (interactive "p")
  (let ((count (or 1 arg)))
   (fortran-forward-block count)
   (forward-line -1)
   (end-of-line)))

;; Should have a fortran-backward-block for completeness
;; ...

(add-to-list 'hs-special-modes-alist
	     `(fortran-mode 
               ,fortran-block-start-regexp
               ,fortran-block-end-regexp
	       ,fortran-comment-regexp
	       fortran-forward-block-adjust ; forward-sexp-like behavior
	       nil
	       ))

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: hide/show mode definitions for g77
  2004-10-25 17:16 hide/show mode definitions for g77 David McKee
@ 2004-11-02  9:48 ` Thien-Thi Nguyen
  2004-11-02 11:05   ` Glenn Morris
  0 siblings, 1 reply; 5+ messages in thread
From: Thien-Thi Nguyen @ 2004-11-02  9:48 UTC (permalink / raw)
  Cc: emacs-devel

  [g77_hs_mode.el]

thanks for posting this code.  feel free to use gnu-emacs-sources for
the next time around (don't forget to include a license notice in the
header comments, to avoid ambiguity).

thi

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: hide/show mode definitions for g77
  2004-11-02  9:48 ` Thien-Thi Nguyen
@ 2004-11-02 11:05   ` Glenn Morris
  2004-11-02 17:26     ` Thien-Thi Nguyen
  2004-11-11 18:38     ` David McKee
  0 siblings, 2 replies; 5+ messages in thread
From: Glenn Morris @ 2004-11-02 11:05 UTC (permalink / raw)
  Cc: emacs-devel, David McKee

Thien-Thi Nguyen wrote:

>   [g77_hs_mode.el]
>
> thanks for posting this code.  feel free to use gnu-emacs-sources for
> the next time around (don't forget to include a license notice in the
> header comments, to avoid ambiguity).

My bad. I suggested to David that he post it here. I'll add this (or
something based on it) to fortran.el, since I think it belongs more
naturally there than in hideshow.el. OK with you?

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: hide/show mode definitions for g77
  2004-11-02 11:05   ` Glenn Morris
@ 2004-11-02 17:26     ` Thien-Thi Nguyen
  2004-11-11 18:38     ` David McKee
  1 sibling, 0 replies; 5+ messages in thread
From: Thien-Thi Nguyen @ 2004-11-02 17:26 UTC (permalink / raw)
  Cc: emacs-devel, dmckee

   From: Glenn Morris <gmorris+emacs@ast.cam.ac.uk>
   Date: Tue, 02 Nov 2004 11:05:59 +0000

   My bad. I suggested to David that he post it here. 

no worries.

   I'll add this (or something based on it) to fortran.el, since I think
   it belongs more naturally there than in hideshow.el. OK with you?

i was thinking the same thing.  if you haven't already, have a look at
how vhdl-mode.el integrates hideshow functionality (VHDL shares the same
sorts of --er-- "challenging syntax issues" w/ FORTRAN ;-).

thi

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: hide/show mode definitions for g77
  2004-11-02 11:05   ` Glenn Morris
  2004-11-02 17:26     ` Thien-Thi Nguyen
@ 2004-11-11 18:38     ` David McKee
  1 sibling, 0 replies; 5+ messages in thread
From: David McKee @ 2004-11-11 18:38 UTC (permalink / raw)
  Cc: emacs-devel

Folks,
   Last weekend I was able to give a little time to this code again. The
version originally posted had some problems which I have partially
remedied...

I've updated the version in my web-space
<http://www.jlab.org/~dmckee/G0/g77_hs_mode.el>

First and foremost, the forward block implementation was simply broken.
Blame it on my (nearly complete lack of) lisp skills.

Secondly, is the issue of column 1 comments. Evidently these are
quite a headache in the fortran mode as they cannot be handled using the
usual syntax table methods. The new code completely ignores column 1
comments. Comments indicated with a '!' are now treated. I think this even
works. As a hack, one can indicate column one comments with a '!' and then
they will work too. G77 seems to accept this.

Thirdly, the regexps that identify block start/stop conditions are
extended objects, and if the point is somewhere inside or immediately before
them when hs-hide-block is called, it hides the block _containing_ the
indicated block deliminator. Which is not what I expected. Not sure if I
can beat this, or if the user will simply have to beware. I looked for a
Pascal hide/show implementation to see if this is normal with extended
delimnators (begin/end), but didn't find one. Is there an extant hide/show
implementation for a language with extended deliminators? Does it do this?

I've not heard back from any of my colleagues on this and don't know if
anyone is using it. Still very little testing.

cc: Glenn Morris

Cheers,

-- 
-- David McKee
-- dmckee@jlab.org
-- (757) 269-7492    (Office)

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2004-11-11 18:38 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-10-25 17:16 hide/show mode definitions for g77 David McKee
2004-11-02  9:48 ` Thien-Thi Nguyen
2004-11-02 11:05   ` Glenn Morris
2004-11-02 17:26     ` Thien-Thi Nguyen
2004-11-11 18:38     ` David McKee

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).