[comp.lang.pascal] Looking for Pascal mode

mike@mecazh.UUCP (Michele Ravani) (07/04/89)

Does anyone have a Pascal mode for gnumacs?
Better still would be one for Hewlett_Packard Pascal.

Thanks in advance


Michele Ravani
Mecasoft Sa
Zurich
Switzerland     ..mcvax!cernvax!mecazh!mike

bob@allosaur.cis.ohio-state.edu (Bob Sutterfield) (07/05/89)

This was posted many moons ago, and we've been using it ever since.
From the comments, it's got quite a long and varied pedigree, but
since it originally appeared on the net it can at least be distributed
via the same mechanisms and with similar (non?)restrictions.

Article 638 of comp.emacs:
Relay-Version: version B 2.10.3 alpha 5/22/85; site osu-eddie.UUCP
Path: osu-eddie!cbatt!ihnp4!ptsfa!lll-lcc!seismo!mnetor!utzoo!utgpu!water!watnot!watcgl!pjmbaker
From: pjmbaker@watcgl.UUCP
Newsgroups: comp.emacs
Subject: Re: Pascal mode for GNU emacs (here is one)
Message-ID: <807@watcgl.UUCP>
Date: 30 Mar 87 15:01:01 GMT
Date-Received: 4 Apr 87 07:35:30 GMT
References: <27@gt-eedsp.UUCP>
Reply-To: pjmbaker@watcgl.UUCP (Peter J M Baker)
Distribution: world
Organization: U. of Waterloo, Ontario
Lines: 389


Here is a pascal mode that was sent to me awhile back after I made the
same request.  I have subsequently had a number of requests for it so
I decided to post it.  I did NOT write it.  I do not even *like*
Pascal but was required to use it for a graphics project at U. of
Waterloo.  I believe the GNU people are including something derived
from this in their current (or next?) release of GNU emacs.

				Happy Editting
Peter Baker, Computer Science Dept., University of Waterloo
USENET:  {ihnp4|allegra|utzoo|utcsri}!watmath!watcgl!pjmbaker
CSNET :  pjmbaker%watcgl@waterloo.csnet
BITNET :  pjmbaker@water.bitnet
arpa  :  pjmbaker%watcgl%waterloo.csnet@csnet-relay.arpa


---------------- cut here ----------------
; Pascal editing support package
; Author Mick Jordan for Modula-2
; amended Peter Robinson
; ported to GNU Michael Schmidt <michael@pbinfo.uucp>
; Modified by Tom Perrine <Perrin@LOGICON.ARPA> (TEP)
; analogue for pascal by Vincent Broman <broman@bugs.nosc.mil>

(setq auto-mode-alist (cons (cons "\\.p$" 'pascal-mode) auto-mode-alist))
(setq auto-mode-alist (cons (cons "\\.h$" 'pascal-mode) auto-mode-alist))

;;; Added by TEP
(defvar pascal-mode-syntax-table nil
  "Syntax table in use in Pascal-mode buffers.")

(if pascal-mode-syntax-table
    ()
  (let ((table (make-syntax-table)))
    (modify-syntax-entry ?\\ "." table)
    (modify-syntax-entry ?\{ "<" table)
    (modify-syntax-entry ?\} ">" table)
    (modify-syntax-entry ?\( "()1" table)
    (modify-syntax-entry ?\) ")(4" table)
    (modify-syntax-entry ?\[ "(]" table)
    (modify-syntax-entry ?\] ")[" table)
    (modify-syntax-entry ?* ". 23" table)
    (modify-syntax-entry ?/ "." table)
    (modify-syntax-entry ?+ "." table)
    (modify-syntax-entry ?- "." table)
    (modify-syntax-entry ?= "." table)
    (modify-syntax-entry ?% "." table)
    (modify-syntax-entry ?\& "." table)
    (modify-syntax-entry ?\| "." table)
    (modify-syntax-entry ?\$ "_" table)
    (modify-syntax-entry ?< "." table)
    (modify-syntax-entry ?> "." table)
    (modify-syntax-entry ?\' "\"" table)
    (modify-syntax-entry ?\" "\"" table)
    (setq pascal-mode-syntax-table table)))

;;; Added by TEP
(defvar pascal-mode-map nil
  "Keymap used in Pascal mode.")

(if pascal-mode-map ()
  (let ((map (make-sparse-keymap)))
    (define-key map "\C-i" 'pascal-tab)
    (define-key map "\C-m" 'pascal-newline)
    (define-key map "\C-cb" 'pascal-begin)
    (define-key map "\C-cc" 'pascal-case)
    (define-key map "\C-c\C-c" 'pascal-const)
    (define-key map "\C-ce" 'pascal-else)
    (define-key map "\C-cf" 'pascal-for)
    (define-key map "\C-c\C-f" 'pascal-function)
    (define-key map "\C-ch" 'pascal-header)
    (define-key map "\C-ci" 'pascal-if)
    (define-key map "\C-c\C-i" 'pascal-include)
    (define-key map "\C-c\C-p" 'pascal-procedure)
    (define-key map "\C-cp" 'pascal-program)
    (define-key map "\C-cr" 'pascal-repeat)
    (define-key map "\C-c\C-r" 'pascal-record)
    (define-key map "\C-c\C-t" 'pascal-type)
    (define-key map "\C-c\C-v" 'pascal-var)
    (define-key map "\C-cw" 'pascal-while)
    (define-key map "\C-c\C-w" 'pascal-with)
    (define-key map "\C-c*" 'pascal-star-display-comment)
    (define-key map "\C-c{" 'pascal-display-comment)
    (define-key map "\C-c}" 'pascal-inline-comment)
    (define-key map "\C-c(" 'pascal-paired-parens)
    (define-key map "\C-c[" 'pascal-paired-brackets)
    (define-key map "\C-ct" 'pascal-toggle)
    (define-key map "\C-cL" 'pascal-link)
    (define-key map "\C-cC" 'pascal-compile)
    (setq pascal-mode-map map)))

(defvar pascal-indent 4 "*This variable gives the indentation in Pascal-Mode")
  
(defun pascal-mode ()
"This is a mode intended to support program development in Pascal.
Most control constructs of Pascal can be created by typing
Control-C followed by the first character of the construct.

C-c p    program        C-c b    begin-end
C-c C-c  const          C-c c    case-do
C-c C-t  type           C-c t    toggle between .p-.h
C-c C-v  var            C-c {    enter matched braces
C-c C-r  record         C-c r    repeat-until
C-c C-w  with-do        C-c w    while-do
C-c C-i  #include       C-c i    if-then
C-c C-p  procedure      C-c e    else
C-c C-f  function       C-c f    for-do

\\{pascal-mode-map}

Variable pascal-indent controls the number of spaces for each indentation."
  (interactive)
  (kill-all-local-variables)
  (use-local-map pascal-mode-map)
  (setq major-mode 'pascal-mode)
  (setq mode-name "Pascal")
  (make-local-variable 'comment-column)
  (setq comment-column 41)
  (make-local-variable 'end-comment-column)
  (setq end-comment-column 72)
  (set-syntax-table pascal-mode-syntax-table)
  (make-local-variable 'paragraph-start)
  (setq paragraph-start (concat "^$\\|" page-delimiter))
  (make-local-variable 'paragraph-separate)
  (setq paragraph-separate paragraph-start)
;  (make-local-variable 'indent-line-function)
;  (setq indent-line-function 'c-indent-line)
  (make-local-variable 'require-final-newline)
  (setq require-final-newline t)
  (make-local-variable 'comment-start)
  (setq comment-start "{\n")
  (make-local-variable 'comment-end)
  (setq comment-end "\n}")
  (make-local-variable 'comment-column)
  (setq comment-column 41)
  (make-local-variable 'comment-start-skip)
  (setq comment-start-skip "/\\*+ *")
  (make-local-variable 'comment-indent-hook)
  (setq comment-indent-hook 'c-comment-indent)
  (make-local-variable 'parse-sexp-ignore-comments)
  (setq parse-sexp-ignore-comments t)
  (run-hooks 'pascal-mode-hook))

(defun pascal-newline ()
  "Start new line and indent to current tab stop."
  (interactive)
  (setq cc (current-indentation))
  (newline)
  (indent-to cc)
  )

(defun pascal-tab ()
  "Indent to next tab stop."
  (interactive)
  (indent-to (* (1+ (/ (current-indentation) pascal-indent)) pascal-indent)))

(defun pascal-begin ()
  "Insert a BEGIN-END pair and indent for the line between."
  (interactive)
  (insert "BEGIN")
  (pascal-newline)
  (pascal-newline)
  (insert "END;")
  (let ((comment (read-string "comment about block: ")))
    (cond ((not (string-equal comment "")) (insert " {" comment "}"))))
  (end-of-line 0))

(defun pascal-case ()
  "Build skeleton CASE statment, prompting for the <expression>."
  (interactive)
  (insert "CASE ")
  (let ((selector (read-string "selector-expr: ")))
    (progn
      (insert selector " OF")
      (pascal-newline)
      (pascal-newline)
      (insert "END; {case " selector "}")))
  (end-of-line 0)
  (pascal-tab))

(defun pascal-else ()
  "Insert ELSE keyword and indent for next line."
  (interactive)
  (insert "ELSE")
  (pascal-newline)
  (pascal-tab))

(defun pascal-for ()
  "Build skeleton FOR loop statment, prompting for the loop parameters."
  (interactive)
  (insert "FOR ")
  (insert (read-string "init: ") " TO ")
  (insert (read-string "limit: ") " DO")
  (pascal-newline)
  (pascal-tab))

(defun pascal-header ()
  "Insert a comment block containing the module title, author, etc."
  (interactive)
  (insert "(*\n    Title: \t")
  (insert (read-string "Title: "))
  (insert "\n    Created:\t")
  (insert (current-time-string))
  (insert "\n    Author: \t")
  (insert (user-full-name))
  (insert (concat "\n\t\t<" (user-login-name) "@" (system-name) ">\n"))
  (insert "*)\n\n"))

(defun pascal-if ()
  "Insert skeleton IF statment, prompting for a boolean-expression."
  (interactive)
  (insert "IF ")
  (insert (read-string "condition: ") " THEN")
  (pascal-newline)
  (pascal-tab))

(defun pascal-program ()
  (interactive)
  (insert "PROGRAM ")
  (let ((name (read-string "program name: " )))
    (insert name " (input, output")
    (let ((arglist (read-string "other file vars: ")))
      (cond ((not (string-equal "" arglist)) (insert ", " arglist)))
      (insert ");"))
    (pascal-newline)
    (pascal-newline)
    (insert "BEGIN")
    (pascal-newline)
    (pascal-newline)
    (insert "END. {")
    (insert name)
    (insert "}")
    (end-of-line 0)
    (pascal-tab)))

(defun pascal-procedure ()
  (interactive)
  (insert "PROCEDURE ")
  (let ((name (read-string "name: " )))
    (insert name "(")
    (insert (read-string "argument list: ") ");")
    (pascal-newline)
    (pascal-newline)
    (pascal-tab)
    (insert "BEGIN")
    (pascal-newline)
    (pascal-newline)
    (insert "END; {")
    (insert name)
    (insert "}")
    (end-of-line 0)
    (pascal-tab)))

(defun pascal-function ()
  (interactive)
  (insert "FUNCTION ")
  (let ((name (read-string "name: " )))
    (insert name "(")
    (insert (read-string "argument list: ") "): ")
    (insert (read-string "result type: ") ";")
    (pascal-newline)
    (pascal-newline)
    (pascal-tab)
    (insert "BEGIN")
    (pascal-newline)
    (pascal-newline)
    (insert "END; {")
    (insert name)
    (insert "}")
    (end-of-line 0)
    (pascal-tab)))

(defun pascal-with ()
  (interactive)
  (insert "WITH ")
  (insert (read-string "idents: "))
  (insert " DO")
  (pascal-newline)
  (pascal-tab))

(defun pascal-record ()
  (interactive)
  (insert "RECORD")
  (pascal-newline)
  (pascal-newline)
  (insert "END;")
  (let ((comment (read-string "comment about record: ")))
    (cond ((not (string-equal comment "")) (insert " {" comment "}"))))
  (end-of-line 0)
  (pascal-tab))

(defun pascal-type ()
  (interactive)
  (insert "TYPE")
  (pascal-newline)
  (pascal-tab))

(defun pascal-const ()
  (interactive)
  (insert "CONST")
  (pascal-newline)
  (pascal-tab))

(defun pascal-repeat ()
  (interactive)
  (insert "REPEAT")
  (pascal-newline)
  (pascal-newline)
  (insert "UNTIL ")
  (insert (read-string "exit cond: ") ";")
  (end-of-line 0)
  (pascal-tab))

(defun pascal-var ()
  (interactive)
  (insert "VAR")
  (pascal-newline)
  (pascal-tab))

(defun pascal-while ()
  (interactive)
  (insert "WHILE ")
  (insert (read-string "entry cond: "))
  (insert " DO")
  (pascal-newline)
  (pascal-tab))

(defun pascal-include ()
  (interactive)
  (insert "\n#include \"")
  (insert (read-string "header file: "))
  (insert "\"")
  (pascal-newline)
  (pascal-newline))


(defun pascal-paired-parens ()
  (interactive)
  (insert "()")
  (backward-char))


(defun pascal-paired-brackets ()
  (interactive)
  (insert "[]")
  (backward-char))

(defun pascal-inline-comment ()
  (interactive)
  (insert "{}")
  (backward-char))

(defun pascal-display-comment ()
"puts comment delimiters around a blank line, making a display comment."
  (interactive)
  (insert "{\n\n}")
  (end-of-line 0))

(defun pascal-star-display-comment ()
"starts a UNIX-style display comment."
  (interactive)
  (insert "(*\n *\n *)")
  (end-of-line 0)
  (pascal-tab))

(defun pascal-compile ()
  (interactive)
  (setq modulename (buffer-name))
  (compile (concat "pc -c " modulename)))

(defun pascal-link ()
  (interactive)
  (compile "make"))

;UNUSED?
;(defun execute-monitor-command (command)
;  (let* ((shell shell-file-name)
;	 (csh (equal (file-name-nondirectory shell) "csh")))
;    (call-process shell nil t t "-cf" (concat "exec " command))))

(defun pascal-toggle ()
  "Toggle between .p and .h files for the module."
  (interactive)
  (cond ((string-equal (substring (buffer-name) -2) ".h")
	 (find-file-other-window
	   (concat (substring (buffer-name) 0 -2) ".p")))
	((string-equal (substring (buffer-name) -2) ".p")
	 (find-file-other-window
	   (concat (substring (buffer-name) 0 -2)  ".h")))))