Annotation of OpenXM_contrib/gmp/mpn/lisp/gmpasm-mode.el, Revision 1.1.1.2
1.1 maekawa 1: ;;; gmpasm-mode.el -- GNU MP asm and m4 editing mode.
2:
3:
1.1.1.2 ! ohara 4: ;; Copyright 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
1.1 maekawa 5: ;;
6: ;; This file is part of the GNU MP Library.
7: ;;
8: ;; The GNU MP Library is free software; you can redistribute it and/or modify
9: ;; it under the terms of the GNU Lesser General Public License as published by
10: ;; the Free Software Foundation; either version 2.1 of the License, or (at your
11: ;; option) any later version.
12: ;;
13: ;; The GNU MP Library is distributed in the hope that it will be useful, but
14: ;; WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15: ;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
16: ;; License for more details.
17: ;;
18: ;; You should have received a copy of the GNU Lesser General Public License
19: ;; along with the GNU MP Library; see the file COPYING.LIB. If not, write to
20: ;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
21: ;; MA 02111-1307, USA.
22:
23:
24: ;;; Commentary:
25: ;;
1.1.1.2 ! ohara 26: ;; gmpasm-mode is a major mode for editing m4 processed assembler code and
! 27: ;; m4 macro files in GMP. It's similar to m4-mode, but has a number of
1.1 maekawa 28: ;; settings better suited to GMP.
29: ;;
30: ;;
31: ;; Install
32: ;; -------
33: ;;
1.1.1.2 ! ohara 34: ;; To make M-x gmpasm-mode available, put gmpasm-mode.el somewhere in your
! 35: ;; load-path and the following in your .emacs
1.1 maekawa 36: ;;
37: ;; (autoload 'gmpasm-mode "gmpasm-mode" nil t)
38: ;;
39: ;; To use gmpasm-mode automatically on all .asm and .m4 files, put the
1.1.1.2 ! ohara 40: ;; following in your .emacs
1.1 maekawa 41: ;;
42: ;; (add-to-list 'auto-mode-alist '("\\.asm\\'" . gmpasm-mode))
43: ;; (add-to-list 'auto-mode-alist '("\\.m4\\'" . gmpasm-mode))
44: ;;
45: ;; To have gmpasm-mode only on gmp files, try instead something like the
46: ;; following, which uses it only in a directory starting with "gmp", or a
47: ;; sub-directory of such.
48: ;;
49: ;; (add-to-list 'auto-mode-alist
50: ;; '("/gmp.*/.*\\.\\(asm\\|m4\\)\\'" . gmpasm-mode))
51: ;;
52: ;; Byte compiling will slightly speed up loading. If you want a docstring
53: ;; in the autoload you can use M-x update-file-autoloads if you set it up
54: ;; right.
55: ;;
56: ;;
57: ;; Emacsen
58: ;; -------
59: ;;
1.1.1.2 ! ohara 60: ;; GNU Emacs 20.x, 21.x and XEmacs 20.x all work well. GNU Emacs 19.x
! 61: ;; should work if replacements for the various 20.x-isms are available,
! 62: ;; though comment-region with "C" doesn't do the right thing.
1.1 maekawa 63:
64:
65: ;;; Code:
66:
67: (defgroup gmpasm nil
68: "GNU MP m4 and asm editing."
69: :prefix "gmpasm-"
70: :group 'languages)
71:
72: (defcustom gmpasm-mode-hook nil
73: "*Hook called by `gmpasm-mode'."
74: :type 'hook
75: :group 'gmpasm)
76:
1.1.1.2 ! ohara 77: (defcustom gmpasm-comment-start-regexp "[#;!@*|C]"
1.1 maekawa 78: "*Regexp matching possible comment styles.
79: See `gmpasm-mode' docstring for how this is used."
80: :type 'regexp
81: :group 'gmpasm)
82:
83:
84: (defun gmpasm-add-to-list-second (list-var element)
85: "(gmpasm-add-to-list-second LIST-VAR ELEMENT)
86:
87: Add ELEMENT to LIST-VAR as the second element in the list, if it isn't
88: already in the list. If LIST-VAR is nil, then ELEMENT is just added as the
89: sole element in the list.
90:
91: This is like `add-to-list', but it puts the new value second in the list.
92:
93: The first cons cell is copied rather than changed in-place, so references to
94: the list elsewhere won't be affected."
95:
96: (if (member element (symbol-value list-var))
97: (symbol-value list-var)
98: (set list-var
99: (if (symbol-value list-var)
100: (cons (car (symbol-value list-var))
101: (cons element
102: (cdr (symbol-value list-var))))
103: (list element)))))
104:
105:
1.1.1.2 ! ohara 106: (defun gmpasm-remove-from-list (list-var element)
! 107: "(gmpasm-remove-from-list LIST-VAR ELEMENT)
1.1 maekawa 108:
1.1.1.2 ! ohara 109: Remove ELEMENT from LIST-VAR, using `copy-sequence' and `delete'.
! 110: This is vaguely like `add-to-list', but the element is removed from the list.
1.1 maekawa 111: The list is copied rather than changed in-place, so references to it elsewhere
1.1.1.2 ! ohara 112: aren't affected."
! 113:
! 114: ;; Only the portion of the list up to the removed element needs to be
! 115: ;; copied, but there's no need to bother arranging that, since this function
! 116: ;; is only used for a couple of initializations.
1.1 maekawa 117:
118: (set list-var (delete element (copy-sequence (symbol-value list-var)))))
119:
120:
121: (defvar gmpasm-mode-map
122: (let ((map (make-sparse-keymap)))
1.1.1.2 ! ohara 123:
1.1 maekawa 124: ;; assembler and dnl commenting
125: (define-key map "\C-c\C-c" 'comment-region)
126: (define-key map "\C-c\C-d" 'gmpasm-comment-region-dnl)
1.1.1.2 ! ohara 127:
1.1 maekawa 128: ;; kill an M-x compile, since it's not hard to put m4 into an infinite
129: ;; loop
130: (define-key map "\C-c\C-k" 'kill-compilation)
1.1.1.2 ! ohara 131:
1.1 maekawa 132: map)
133: "Keymap for `gmpasm-mode'.")
134:
135:
136: (defvar gmpasm-mode-syntax-table
137: (let ((table (make-syntax-table)))
138: ;; underscore left as a symbol char, like C mode
1.1.1.2 ! ohara 139:
1.1 maekawa 140: ;; m4 quotes
141: (modify-syntax-entry ?` "('" table)
142: (modify-syntax-entry ?' ")`" table)
143:
144: table)
145: "Syntax table used in `gmpasm-mode'.
146:
1.1.1.2 ! ohara 147: '#' and '\n' aren't set as comment syntax. In m4 these are a comment
! 148: outside quotes, but not inside. Omitting a syntax entry ensures that when
! 149: inside quotes emacs treats parentheses and apostrophes the same way that m4
! 150: does. When outside quotes this is not quite right, but having it right when
! 151: nesting expressions is more important.
! 152:
! 153: '*', '!' or '|' aren't setup as comment syntax either, on CPUs which use
! 154: these for comments. The GMP macro setups don't set them in m4 changecom(),
! 155: since that prevents them being used in eval() expressions, and on that basis
! 156: they don't change the way quotes and parentheses are treated by m4 and
! 157: should be treated by emacs.")
1.1 maekawa 158:
159:
160: (defvar gmpasm-font-lock-keywords
161: (eval-when-compile
162: (list
163: (cons
164: (concat
165: "\\b"
166: (regexp-opt
167: '("deflit" "defreg" "defframe" "defframe_pushl"
168: "define_not_for_expansion"
1.1.1.2 ! ohara 169: "m4_error" "m4_warning"
! 170: "ASM_START" "ASM_END"
! 171: "PROLOGUE" "PROLOGUE_GP" "MULFUNC_PROLOGUE" "EPILOGUE"
! 172: "DATASTART" "DATAEND"
1.1 maekawa 173: "forloop"
1.1.1.2 ! ohara 174: "TEXT" "DATA" "ALIGN" "W32" "FLOAT64"
1.1 maekawa 175: "builtin" "changecom" "changequote" "changeword" "debugfile"
176: "debugmode" "decr" "define" "defn" "divert" "divnum" "dumpdef"
177: "errprint" "esyscmd" "eval" "__file__" "format" "gnu" "ifdef"
178: "ifelse" "include" "incr" "index" "indir" "len" "__line__"
179: "m4exit" "m4wrap" "maketemp" "patsubst" "popdef" "pushdef"
180: "regexp" "shift" "sinclude" "substr" "syscmd" "sysval"
181: "traceoff" "traceon" "translit" "undefine" "undivert" "unix")
182: t)
183: "\\b") 'font-lock-keyword-face)))
184:
185: "`font-lock-keywords' for `gmpasm-mode'.
186:
187: The keywords are m4 builtins and some of the GMP macros used in asm files.
1.1.1.2 ! ohara 188: L doesn't look good fontified, so it's omitted.
1.1 maekawa 189:
190: The right assembler comment regexp is added dynamically buffer-local (with
191: dnl too).")
192:
193:
194: ;; Initialized if gmpasm-mode finds filladapt loaded.
195: (defvar gmpasm-filladapt-token-table nil
196: "Filladapt token table used in `gmpasm-mode'.")
197: (defvar gmpasm-filladapt-token-match-table nil
198: "Filladapt token match table used in `gmpasm-mode'.")
199: (defvar gmpasm-filladapt-token-conversion-table nil
200: "Filladapt token conversion table used in `gmpasm-mode'.")
201:
202:
203: ;;;###autoload
204: (defun gmpasm-mode ()
205: "A major mode for editing GNU MP asm and m4 files.
206:
207: \\{gmpasm-mode-map}
208: `comment-start' and `comment-end' are set buffer-local to assembler
209: commenting appropriate for the CPU by looking for something matching
210: `gmpasm-comment-start-regexp' at the start of a line, or \"#\" is used if
211: there's no match (if \"#\" isn't what you want, type in a desired comment
212: and do \\[gmpasm-mode] to reinitialize).
213:
214: `adaptive-fill-regexp' is set buffer-local to the standard regexp with
215: `comment-start' and dnl added. If filladapt.el has been loaded it similarly
216: gets `comment-start' and dnl added as buffer-local fill prefixes.
217:
218: Font locking has the m4 builtins, some of the GMP macros, m4 dnl commenting,
219: and assembler commenting (based on the `comment-start' determined).
220:
221: Note that `gmpasm-comment-start-regexp' is only matched as a whole word, so
222: the `C' in it is only matched as a whole word, not on something that happens
223: to start with `C'. Also it's only the particular `comment-start' determined
224: that's added for filling etc, not the whole `gmpasm-comment-start-regexp'.
225:
1.1.1.2 ! ohara 226: `gmpasm-mode-hook' is run after initializations are complete."
1.1 maekawa 227:
228: (interactive)
229: (kill-all-local-variables)
230: (setq major-mode 'gmpasm-mode
231: mode-name "gmpasm")
232: (use-local-map gmpasm-mode-map)
233: (set-syntax-table gmpasm-mode-syntax-table)
234: (setq fill-column 76)
235:
236: ;; Short instructions might fit with 32, but anything with labels or
237: ;; expressions soon needs the comments pushed out to column 40.
238: (setq comment-column 40)
239:
240: ;; Don't want to find out the hard way which dumb assemblers don't like a
241: ;; missing final newline.
242: (set (make-local-variable 'require-final-newline) t)
243:
244: ;; The first match of gmpasm-comment-start-regexp at the start of a line
245: ;; determines comment-start, or "#" if no match.
246: (set (make-local-variable 'comment-start)
247: (save-excursion
248: (goto-char (point-min))
249: (if (re-search-forward
250: (concat "^\\(" gmpasm-comment-start-regexp "\\)\\(\\s-\\|$\\)")
251: nil t)
252: (match-string 1)
253: "#")))
254: (set (make-local-variable 'comment-end) "")
255:
256: ;; If comment-start ends in an alphanumeric then \b is used to match it
257: ;; only as a separate word. The test is for an alphanumeric rather than
1.1.1.2 ! ohara 258: ;; \w since we might try # or ! as \w characters but without wanting \b on
! 259: ;; them.
1.1 maekawa 260: (let ((comment-regexp
261: (concat (regexp-quote comment-start)
262: (if (string-match "[a-zA-Z0-9]\\'" comment-start) "\\b"))))
1.1.1.2 ! ohara 263:
1.1 maekawa 264: ;; Whitespace is required before a comment-start so m4 $# doesn't match
265: ;; when comment-start is "#".
266: (set (make-local-variable 'comment-start-skip)
1.1.1.2 ! ohara 267: (concat "\\(^\\|\\s-\\)\\(\\<dnl\\>\\|" comment-regexp "\\)[ \t]*"))
1.1 maekawa 268:
1.1.1.2 ! ohara 269: ;; Comment fontification based on comment-start, and always with dnl.
! 270: ;; Same treatment of a space before "#" as in comment-start-skip, but
! 271: ;; don't fontify that space.
1.1 maekawa 272: (add-to-list (make-local-variable 'gmpasm-font-lock-keywords)
1.1.1.2 ! ohara 273: (list (concat "\\(^\\|\\s-\\)\\(\\(\\<dnl\\>\\|"
! 274: comment-regexp
! 275: "\\).*$\\)")
! 276: 2 'font-lock-comment-face))
1.1 maekawa 277:
278: (set (make-local-variable 'font-lock-defaults)
279: '(gmpasm-font-lock-keywords
280: t ; no syntactic fontification (of strings etc)
281: nil ; no case-fold
282: ((?_ . "w")) ; _ part of a word while fontifying
283: ))
284:
285: ;; Paragraphs are separated by blank lines, or lines with only dnl or
286: ;; comment-start.
287: (set (make-local-variable 'paragraph-separate)
288: (concat "[ \t\f]*\\(\\(" comment-regexp "\\|dnl\\)[ \t]*\\)*$"))
289: (set (make-local-variable 'paragraph-start)
290: (concat "\f\\|" paragraph-separate))
1.1.1.2 ! ohara 291:
1.1 maekawa 292: ;; Adaptive fill gets dnl and comment-start as comment style prefixes on
293: ;; top of the standard regexp (which has # and ; already actually).
294: (set (make-local-variable 'adaptive-fill-regexp)
295: (concat "[ \t]*\\(\\("
296: comment-regexp
297: "\\|dnl\\|[-|#;>*]+\\|(?[0-9]+[.)]\\)[ \t]*\\)*"))
298: (set (make-local-variable 'adaptive-fill-first-line-regexp)
299: "\\`\\([ \t]*dnl\\)?[ \t]*\\'")
300:
301: (when (fboundp 'filladapt-mode)
1.1.1.2 ! ohara 302: (unless gmpasm-filladapt-token-table
1.1 maekawa 303: (setq gmpasm-filladapt-token-table
304: filladapt-token-table)
305: (setq gmpasm-filladapt-token-match-table
306: filladapt-token-match-table)
307: (setq gmpasm-filladapt-token-conversion-table
308: filladapt-token-conversion-table)
1.1.1.2 ! ohara 309:
1.1 maekawa 310: ;; Numbered bullet points like "2.1" get matched at the start of a
1.1.1.2 ! ohara 311: ;; line when it's really something like "2.1 cycles/limb", so remove
1.1 maekawa 312: ;; this from the list. The regexp for "1.", "2." etc is left
313: ;; though.
1.1.1.2 ! ohara 314: (gmpasm-remove-from-list 'gmpasm-filladapt-token-table
1.1 maekawa 315: '("[0-9]+\\(\\.[0-9]+\\)+[ \t]"
316: bullet))
1.1.1.2 ! ohara 317:
! 318: ;; "%" as a comment prefix interferes with register names on some
! 319: ;; CPUs, like %eax on x86, so remove this.
! 320: (gmpasm-remove-from-list 'gmpasm-filladapt-token-table
1.1 maekawa 321: '("%+" postscript-comment))
1.1.1.2 ! ohara 322:
1.1 maekawa 323: (add-to-list 'gmpasm-filladapt-token-match-table
324: '(gmpasm-comment gmpasm-comment))
325: (add-to-list 'gmpasm-filladapt-token-conversion-table
1.1.1.2 ! ohara 326: '(gmpasm-comment . exact)))
! 327:
1.1 maekawa 328: (set (make-local-variable 'filladapt-token-table)
329: gmpasm-filladapt-token-table)
330: (set (make-local-variable 'filladapt-token-match-table)
331: gmpasm-filladapt-token-match-table)
332: (set (make-local-variable 'filladapt-token-conversion-table)
333: gmpasm-filladapt-token-conversion-table)
1.1.1.2 ! ohara 334:
1.1 maekawa 335: ;; Add dnl and comment-start as fill prefixes.
336: ;; Comments in filladapt.el say filladapt-token-table must begin
337: ;; with ("^" beginning-of-line), so put our addition second.
338: (gmpasm-add-to-list-second 'filladapt-token-table
339: (list (concat "dnl[ \t]\\|" comment-regexp)
1.1.1.2 ! ohara 340: 'gmpasm-comment))))
! 341:
1.1 maekawa 342: (run-hooks 'gmpasm-mode-hook))
343:
344:
345: (defun gmpasm-comment-region-dnl (beg end &optional arg)
1.1.1.2 ! ohara 346: "(gmpasm-comment-region-dnl BEG END &optional ARG)
1.1 maekawa 347:
348: Comment or uncomment each line in the region using `dnl'.
349: With \\[universal-argument] prefix arg, uncomment each line in region.
350: This is `comment-region', but using \"dnl\"."
351:
352: (interactive "r\nP")
353: (let ((comment-start "dnl")
354: (comment-end ""))
355: (comment-region beg end arg)))
356:
357:
358: (provide 'gmpasm-mode)
359:
360: ;;; gmpasm-mode.el ends here
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>