emacs prolog mode: mlisp source
Saumya Debray
debray at sbcs.UUCP
Sat Mar 3 02:12:44 AEST 1984
The Prolog mode for emacs:
=========================
I. Description:
--------------
This is a set of mlisp functions that facilitates the writing and execution
of Prolog programs within emacs. Text files with a '.P' suffix are
automatically put into electric-prolog mode upon entry.
II. Features:
------------
1) When a right-paren ")" or right-bracket "]" is entered, the cursor
flashes back to the corresponding left-paren or left-bracket. If there is
a parenthesis mismatch, an error is signalled.
2) When a period "." is typed in at the end of a clause, the clause is
checked for unbalanced "("s or "["s: if any are found, an error is
signalled.
3) Prolog may be called directly from within emacs by typing "ESC-x prolog".
This results in the spawning of a Prolog process which may be manipulated
as follows:
Stop Prolog ------------------------------------ ^z
Continue (after stopping prolog with a ^z): ---- ^q
Terminate Prolog ------------------------------- ^d
Interrupt Prolog ------------------------------- ^c
4) During debugging, it often becomes necessary to reconsult files
repeatedly. This is simply achieved in electric-prolog by putting the
cursor in the buffer corresponding to the file to be reconsulted and
typing "^Xr" (control-x followed by r); electric-prolog will then write
the file out, construct the reconsult command for Prolog and position the
user in the buffer corresponding to the Prolog process, whereupon, by
simply hitting <return>, the file will be reconsulted.
III. Bugs:
----------
1) The "%" comment-starter is not recognized by electric-prolog (mainly
because I never used it and never got around to putting it in).
2) When a character that is not a period, followed by a period ".", followed
by a space, tab or newline is encountered, the end of a clause is assumed
to have been reached. (The period at the end of a clause is required to
be preceded by a character other than a period so that constructs like
"p =.. [X|Y]" are not interpreted to be at the end of the clause.) This
may lead to spurious error messages at times, if an operator is defined in
a manner that confuses electric-prolog.
IV. Installation:
----------------
(i) The following lines are to be added to ..../maclib/profile.ml (for the
system) or the user's ".emacs_pro" file:
==================================================
(autoload "electric-prolog-mode" "prolog.ml")
(auto-execute "electric-prolog-mode" "*.P")
(autoload "prolog" "prolog.ml")
==================================================
(ii) The following is the source code for the electric-prolog functions:
They should be placed in a file "prolog.ml" (or any other name that is
consistent with the 3 lines above ((autoload ...), (auto-execute ...))
in .../maclib (for the system) or the user's home directory.
(Note: in order that users can execute prolog in any directory, the complete
path to the "prolog.ml" file should really be included in the autoload/auto-
execute commands in the user's ".emacs_pro" file, above, e.g.:
(autoload "electric-prolog-mode" "/ue/db2/debray/prolog.ml")
(auto-execute "electric-prolog-mode" "*.P")
(autoload "prolog" "/ue/db2/debray/prolog.ml")
).
Please send mail regarding experienes/questions/bugs to:
Saumya Debray, Dept. of Computer Science, SUNY at Stony Brook: (516)-246-7146
philabs!sbcs!debray debray at suny-sbcs@CSNet-Relay
==================================================
; "Electric-prolog mode"
; Author: Saumya K. Debray, Dept. of Computer Science, SUNY at Stony Brook.
; Date: Sept. 1983.
;
; "prolog-paren" flashes the cursor back to a balancing parenthesis within
; the same clause.
;
(defun
(prolog-paren currbuf
(insert-character (last-key-struck))
(save-excursion
(setq currbuf (current-buffer-name))
(clause-to-buffer "$0001$")
(backward-paren)
(if (bobp)
(progn
(erase-buffer)
(switch-to-buffer currbuf)
(error-message (concat "Too many "
(concat (char-to-string
(last-key-struck))
"s"))))
(progn
(erase-buffer)
(switch-to-buffer currbuf)
(backward-paren)
(if (dot-is-visible)
(sit-for 5)
(progn
(beginning-of-line)
(set-mark)
(end-of-line)
(message (region-to-string)))))
)
)
)
(erase-comment
(set-mark)
(forward-word)
(if (in-comment)
(progn
(search-forward "*/")
(delete-region-to-buffer "$0003$")
(delete-white-space)
1)
0)
)
(clause-to-buffer buffname
(setq buffname (arg 1 "c-t-b buffname: "))
(set-mark)(back-to-end-of-clause)
(exchange-dot-and-mark)
(copy-region-to-buffer buffname)
(temp-use-buffer buffname)
(electric-prolog-mode)
)
(prolog-reverse-paren currbuf
; (insert-character '.')
(if (! (in-comment))
(progn
(delete-white-space)
(save-excursion
(setq currbuf (current-buffer-name))
(backward-character)(clause-to-buffer "$0002$")
(beginning-of-file)
(if (looking-at '.')
(delete-next-character))
(delete-white-space)
(while (erase-comment)(novalue))
(end-of-file)
(insert-character ')')
(if (! (error-occured (backward-paren)))
(if (! (bobp))
(error-message "There are unbalanced ('s in this clause")))
(end-of-file)(delete-previous-character)(insert-character ']')
(backward-paren)
(if (! (bobp))
(error-message "There are unbalanced ['s in this clause"))
(erase-buffer)
(switch-to-buffer currbuf)
)
)
)
)
(check-clause char
(insert-character (last-key-struck))
(setq char (get-tty-character))
(push-back-character char)
(if (+ (+ (= char 9) ; tab = ^I
(= char 10) ; newline = ^J
)
(+ (= char 13) ; newline = ^M
(= char 32) ; space
))
(prolog-reverse-paren)
)
)
; "in-comment" returns true if dot is within a comment, false otherwise.
(in-comment begin-com end-com curr-pos
(save-excursion
(setq curr-pos (dot))
(if (! (error-occured (search-reverse "/*")))
(progn
(setq begin-com (dot))
(goto-character curr-pos)
(if (error-occured (search-reverse "*/"))
(setq end-com 0)
(setq end-com (dot)))
(> begin-com end-com)))
)
)
; "back-to-end-of-clause" moves the dot to the end of the previous clause.
(back-to-end-of-clause
(re-search-reverse "[^.]\\.$\\|[^.]\\.[ ]\\|\\`.")
(while (in-comment)
(re-search-reverse "[^.]\\.$\\|[^.]\\.[ ]\\|\\`."))
(novalue)
)
(reconsult-file fname
(if
(= (active-process) "Prolog")
(progn
(write-current-file)
(setq fname (concat "[-'"
(concat (current-file-name) "'].")))
(pop-to-buffer "Prolog")
(insert-string fname)
)
(error-message "Prolog process does not exist!")
)
)
(prolog
(message "prolog ...")
(start-prolog)
(local-bind-to-key "input-to-prolog" "\^M")
(local-bind-to-key "stop-prolog" "\^Z")
(local-bind-to-key "continue-prolog" "\^Q")
(local-bind-to-key "eot-prolog" "\^D")
(local-bind-to-key "interrupt-prolog" "\^C")
(local-bind-to-key "reconsult-file" "\^Xr")
(novalue)
)
(start-prolog
(if (= (active-process) "Prolog")
(pop-to-buffer "Prolog")
(start-process "prolog" "Prolog")
)
)
(input-to-prolog
(newline)
(region-to-process "Prolog")
)
(stop-prolog
(stop-process "Prolog")
(message "Prolog stopped")
)
(continue-prolog
(continue-process "Prolog")
(message "continuing Prolog")
(pop-to-buffer "Prolog")
)
(eot-prolog
(eot-process "Prolog")
)
(interrupt-prolog
(int-process "Prolog")
)
)
(defun
(electric-prolog-mode
(remove-all-local-bindings)
(local-bind-to-key "prolog-paren" ")")
(local-bind-to-key "prolog-paren" "]")
(local-bind-to-key "check-clause" ".")
(local-bind-to-key "reconsult-file" "\^Xr")
(setq mode-string "prolog")
(use-syntax-table "prolog")
(novalue)
)
)
(use-syntax-table "prolog")
(modify-syntax-entry "() (")
(modify-syntax-entry ")( )")
(modify-syntax-entry "(] [")
(modify-syntax-entry ")[ ]")
(modify-syntax-entry """ '")
(modify-syntax-entry """ """)
(modify-syntax-entry """ { /*")
(modify-syntax-entry """ }*/")
(modify-syntax-entry "w _a-zA-Z0-9")
; ============================= EOF =========================================
--
Saumya Debray, SUNY at Stony Brook
uucp:
{floyd, cbosgd, ihnp4, mcvax, cmcl2}!philabs \
{amd70, akgua, decwrl, utzoo}!allegra > !sbcs!debray
{teklabs, hp-pcd, metheus}!ogcvax /
CSNet: debray at suny-sbcs@CSNet-Relay
More information about the Comp.sources.unix
mailing list