[BACK]Return to gmpasm-mode.el CVS log [TXT][DIR] Up to [local] / OpenXM_contrib / gmp / mpn / lisp

Annotation of OpenXM_contrib/gmp/mpn/lisp/gmpasm-mode.el, Revision 1.1.1.1

1.1       maekawa     1: ;;; gmpasm-mode.el -- GNU MP asm and m4 editing mode.
                      2:
                      3:
                      4: ;; Copyright (C) 1999, 2000 Free Software Foundation, Inc.
                      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: ;;
                     26: ;; gmpasm-mode is an editing mode for m4 processed assembler code and m4
                     27: ;; macro files in GMP.  It's similar to m4-mode, but has a number of
                     28: ;; settings better suited to GMP.
                     29: ;;
                     30: ;;
                     31: ;; Install
                     32: ;; -------
                     33: ;;
                     34: ;; To make M-x gmpasm-mode available, put gmpasm-mode.el somewhere in the
                     35: ;; load-path and the following in .emacs
                     36: ;;
                     37: ;;     (autoload 'gmpasm-mode "gmpasm-mode" nil t)
                     38: ;;
                     39: ;; To use gmpasm-mode automatically on all .asm and .m4 files, put the
                     40: ;; following in .emacs
                     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: ;;
                     60: ;; FSF Emacs 20.x - gmpasm-mode is designed for this.
                     61: ;; XEmacs 20.x - seems to work.
                     62: ;;
                     63: ;; FSF Emacs 19.x - should work if replacements for some 20.x-isms are
                     64: ;;    available.  comment-region with "C" won't really do the right thing
                     65: ;;    though.
                     66:
                     67:
                     68: ;;; Code:
                     69:
                     70: (defgroup gmpasm nil
                     71:   "GNU MP m4 and asm editing."
                     72:   :prefix "gmpasm-"
                     73:   :group 'languages)
                     74:
                     75: (defcustom gmpasm-mode-hook nil
                     76:   "*Hook called by `gmpasm-mode'."
                     77:   :type 'hook
                     78:   :group 'gmpasm)
                     79:
                     80: (defcustom gmpasm-comment-start-regexp "[#;!@C]"
                     81:   "*Regexp matching possible comment styles.
                     82: See `gmpasm-mode' docstring for how this is used."
                     83:   :type 'regexp
                     84:   :group 'gmpasm)
                     85:
                     86:
                     87: (defun gmpasm-add-to-list-second (list-var element)
                     88:   "(gmpasm-add-to-list-second LIST-VAR ELEMENT)
                     89:
                     90: Add ELEMENT to LIST-VAR as the second element in the list, if it isn't
                     91: already in the list.  If LIST-VAR is nil, then ELEMENT is just added as the
                     92: sole element in the list.
                     93:
                     94: This is like `add-to-list', but it puts the new value second in the list.
                     95:
                     96: The first cons cell is copied rather than changed in-place, so references to
                     97: the list elsewhere won't be affected."
                     98:
                     99:   (if (member element (symbol-value list-var))
                    100:       (symbol-value list-var)
                    101:     (set list-var
                    102:         (if (symbol-value list-var)
                    103:             (cons (car (symbol-value list-var))
                    104:                   (cons element
                    105:                         (cdr (symbol-value list-var))))
                    106:           (list element)))))
                    107:
                    108:
                    109: (defun gmpasm-delete-from-list (list-var element)
                    110:   "(gmpasm-delete-from-list LIST-VAR ELEMENT)
                    111:
                    112: Delete ELEMENT from LIST-VAR, using `delete'.
                    113: This is like `add-to-list', but the element is deleted from the list.
                    114: The list is copied rather than changed in-place, so references to it elsewhere
                    115: won't be affected."
                    116:
                    117:   (set list-var (delete element (copy-sequence (symbol-value list-var)))))
                    118:
                    119:
                    120: (defvar gmpasm-mode-map
                    121:   (let ((map (make-sparse-keymap)))
                    122:
                    123:     ;; assembler and dnl commenting
                    124:     (define-key map "\C-c\C-c" 'comment-region)
                    125:     (define-key map "\C-c\C-d" 'gmpasm-comment-region-dnl)
                    126:
                    127:     ;; kill an M-x compile, since it's not hard to put m4 into an infinite
                    128:     ;; loop
                    129:     (define-key map "\C-c\C-k" 'kill-compilation)
                    130:
                    131:     map)
                    132:   "Keymap for `gmpasm-mode'.")
                    133:
                    134:
                    135: (defvar gmpasm-mode-syntax-table
                    136:   (let ((table (make-syntax-table)))
                    137:     ;; underscore left as a symbol char, like C mode
                    138:
                    139:     ;; m4 quotes
                    140:     (modify-syntax-entry ?`  "('"  table)
                    141:     (modify-syntax-entry ?'  ")`"  table)
                    142:
                    143:     table)
                    144:   "Syntax table used in `gmpasm-mode'.
                    145:
                    146: m4 ignores quote marks in # comments at the top level, but inside quotes #
                    147: isn't special and all quotes are active.  There seems no easy way to express
                    148: this in the syntax table, so nothing is done for comments.  Usually this is
                    149: best, since it picks up invalid apostrophes in comments inside quotes.")
                    150:
                    151:
                    152: (defvar gmpasm-font-lock-keywords
                    153:   (eval-when-compile
                    154:     (list
                    155:      (cons
                    156:       (concat
                    157:        "\\b"
                    158:        (regexp-opt
                    159:        '("deflit" "defreg" "defframe" "defframe_pushl"
                    160:          "define_not_for_expansion"
                    161:          "ASM_START" "ASM_END" "PROLOGUE" "EPILOGUE"
                    162:          "forloop"
                    163:          "TEXT" "DATA" "ALIGN" "W32"
                    164:          "builtin" "changecom" "changequote" "changeword" "debugfile"
                    165:          "debugmode" "decr" "define" "defn" "divert" "divnum" "dumpdef"
                    166:          "errprint" "esyscmd" "eval" "__file__" "format" "gnu" "ifdef"
                    167:          "ifelse" "include" "incr" "index" "indir" "len" "__line__"
                    168:          "m4exit" "m4wrap" "maketemp" "patsubst" "popdef" "pushdef"
                    169:          "regexp" "shift" "sinclude" "substr" "syscmd" "sysval"
                    170:          "traceoff" "traceon" "translit" "undefine" "undivert" "unix")
                    171:        t)
                    172:        "\\b") 'font-lock-keyword-face)))
                    173:
                    174:   "`font-lock-keywords' for `gmpasm-mode'.
                    175:
                    176: The keywords are m4 builtins and some of the GMP macros used in asm files.
                    177: L and LF don't look good fontified, so they're omitted.
                    178:
                    179: The right assembler comment regexp is added dynamically buffer-local (with
                    180: dnl too).")
                    181:
                    182:
                    183: ;; Initialized if gmpasm-mode finds filladapt loaded.
                    184: (defvar gmpasm-filladapt-token-table nil
                    185:   "Filladapt token table used in `gmpasm-mode'.")
                    186: (defvar gmpasm-filladapt-token-match-table nil
                    187:   "Filladapt token match table used in `gmpasm-mode'.")
                    188: (defvar gmpasm-filladapt-token-conversion-table nil
                    189:   "Filladapt token conversion table used in `gmpasm-mode'.")
                    190:
                    191:
                    192: ;;;###autoload
                    193: (defun gmpasm-mode ()
                    194:   "A major mode for editing GNU MP asm and m4 files.
                    195:
                    196: \\{gmpasm-mode-map}
                    197: `comment-start' and `comment-end' are set buffer-local to assembler
                    198: commenting appropriate for the CPU by looking for something matching
                    199: `gmpasm-comment-start-regexp' at the start of a line, or \"#\" is used if
                    200: there's no match (if \"#\" isn't what you want, type in a desired comment
                    201: and do \\[gmpasm-mode] to reinitialize).
                    202:
                    203: `adaptive-fill-regexp' is set buffer-local to the standard regexp with
                    204: `comment-start' and dnl added.  If filladapt.el has been loaded it similarly
                    205: gets `comment-start' and dnl added as buffer-local fill prefixes.
                    206:
                    207: Font locking has the m4 builtins, some of the GMP macros, m4 dnl commenting,
                    208: and assembler commenting (based on the `comment-start' determined).
                    209:
                    210: Note that `gmpasm-comment-start-regexp' is only matched as a whole word, so
                    211: the `C' in it is only matched as a whole word, not on something that happens
                    212: to start with `C'.  Also it's only the particular `comment-start' determined
                    213: that's added for filling etc, not the whole `gmpasm-comment-start-regexp'.
                    214:
                    215: `gmpasm-mode-hook' is run after initializations are complete.
                    216: "
                    217:
                    218:   (interactive)
                    219:   (kill-all-local-variables)
                    220:   (setq major-mode 'gmpasm-mode
                    221:         mode-name  "gmpasm")
                    222:   (use-local-map gmpasm-mode-map)
                    223:   (set-syntax-table gmpasm-mode-syntax-table)
                    224:   (setq fill-column 76)
                    225:
                    226:   ;; Short instructions might fit with 32, but anything with labels or
                    227:   ;; expressions soon needs the comments pushed out to column 40.
                    228:   (setq comment-column 40)
                    229:
                    230:   ;; Don't want to find out the hard way which dumb assemblers don't like a
                    231:   ;; missing final newline.
                    232:   (set (make-local-variable 'require-final-newline) t)
                    233:
                    234:   ;; The first match of gmpasm-comment-start-regexp at the start of a line
                    235:   ;; determines comment-start, or "#" if no match.
                    236:   (set (make-local-variable 'comment-start)
                    237:        (save-excursion
                    238:         (goto-char (point-min))
                    239:         (if (re-search-forward
                    240:              (concat "^\\(" gmpasm-comment-start-regexp "\\)\\(\\s-\\|$\\)")
                    241:              nil t)
                    242:             (match-string 1)
                    243:           "#")))
                    244:   (set (make-local-variable 'comment-end) "")
                    245:
                    246:   ;; If comment-start ends in an alphanumeric then \b is used to match it
                    247:   ;; only as a separate word.  The test is for an alphanumeric rather than
                    248:   ;; \w since we might try # or ! as \w characters but without wanting \b.
                    249:   (let ((comment-regexp
                    250:         (concat (regexp-quote comment-start)
                    251:                 (if (string-match "[a-zA-Z0-9]\\'" comment-start) "\\b"))))
                    252:
                    253:     ;; Whitespace is required before a comment-start so m4 $# doesn't match
                    254:     ;; when comment-start is "#".
                    255:     ;; Only spaces or tabs match after, so newline isn't included in the
                    256:     ;; font lock below.
                    257:     (set (make-local-variable 'comment-start-skip)
                    258:         (concat "\\(^\\|\\s-\\)" comment-regexp "[ \t]*"))
                    259:
                    260:     ;; Comment fontification based on comment-start, matching through to the
                    261:     ;; end of the line.
                    262:     (add-to-list (make-local-variable 'gmpasm-font-lock-keywords)
                    263:                 (cons (concat
                    264:                        "\\(\\bdnl\\b\\|" comment-start-skip "\\).*$")
                    265:                       'font-lock-comment-face))
                    266:
                    267:     (set (make-local-variable 'font-lock-defaults)
                    268:         '(gmpasm-font-lock-keywords
                    269:           t             ; no syntactic fontification (of strings etc)
                    270:           nil           ; no case-fold
                    271:           ((?_ . "w"))  ; _ part of a word while fontifying
                    272:           ))
                    273:
                    274:     ;; Paragraphs are separated by blank lines, or lines with only dnl or
                    275:     ;; comment-start.
                    276:     (set (make-local-variable 'paragraph-separate)
                    277:         (concat "[ \t\f]*\\(\\(" comment-regexp "\\|dnl\\)[ \t]*\\)*$"))
                    278:     (set (make-local-variable 'paragraph-start)
                    279:         (concat "\f\\|" paragraph-separate))
                    280:
                    281:     ;; Adaptive fill gets dnl and comment-start as comment style prefixes on
                    282:     ;; top of the standard regexp (which has # and ; already actually).
                    283:     (set (make-local-variable 'adaptive-fill-regexp)
                    284:         (concat "[ \t]*\\(\\("
                    285:                 comment-regexp
                    286:                 "\\|dnl\\|[-|#;>*]+\\|(?[0-9]+[.)]\\)[ \t]*\\)*"))
                    287:     (set (make-local-variable 'adaptive-fill-first-line-regexp)
                    288:         "\\`\\([ \t]*dnl\\)?[ \t]*\\'")
                    289:
                    290:     (when (fboundp 'filladapt-mode)
                    291:       (when (not gmpasm-filladapt-token-table)
                    292:        (setq gmpasm-filladapt-token-table
                    293:              filladapt-token-table)
                    294:        (setq gmpasm-filladapt-token-match-table
                    295:              filladapt-token-match-table)
                    296:        (setq gmpasm-filladapt-token-conversion-table
                    297:              filladapt-token-conversion-table)
                    298:
                    299:        ;; Numbered bullet points like "2.1" get matched at the start of a
                    300:        ;; line when it's really something like "2.1 cycles/limb", so delete
                    301:        ;; this from the list.  The regexp for "1.", "2." etc is left
                    302:        ;; though.
                    303:        (gmpasm-delete-from-list 'gmpasm-filladapt-token-table
                    304:                                 '("[0-9]+\\(\\.[0-9]+\\)+[ \t]"
                    305:                                   bullet))
                    306:
                    307:        ;; "%" as a comment prefix interferes with x86 register names
                    308:        ;; like %eax, so delete this.
                    309:        (gmpasm-delete-from-list 'gmpasm-filladapt-token-table
                    310:                                 '("%+" postscript-comment))
                    311:
                    312:        (add-to-list 'gmpasm-filladapt-token-match-table
                    313:                     '(gmpasm-comment gmpasm-comment))
                    314:        (add-to-list 'gmpasm-filladapt-token-conversion-table
                    315:                     '(gmpasm-comment . exact))
                    316:        )
                    317:
                    318:       (set (make-local-variable 'filladapt-token-table)
                    319:           gmpasm-filladapt-token-table)
                    320:       (set (make-local-variable 'filladapt-token-match-table)
                    321:           gmpasm-filladapt-token-match-table)
                    322:       (set (make-local-variable 'filladapt-token-conversion-table)
                    323:           gmpasm-filladapt-token-conversion-table)
                    324:
                    325:       ;; Add dnl and comment-start as fill prefixes.
                    326:       ;; Comments in filladapt.el say filladapt-token-table must begin
                    327:       ;; with ("^" beginning-of-line), so put our addition second.
                    328:       (gmpasm-add-to-list-second 'filladapt-token-table
                    329:                                 (list (concat "dnl[ \t]\\|" comment-regexp)
                    330:                                       'gmpasm-comment))
                    331:       ))
                    332:
                    333:   (run-hooks 'gmpasm-mode-hook))
                    334:
                    335:
                    336: (defun gmpasm-comment-region-dnl (beg end &optional arg)
                    337:   "(gmpasm-comment-region BEG END &option ARG)
                    338:
                    339: Comment or uncomment each line in the region using `dnl'.
                    340: With \\[universal-argument] prefix arg, uncomment each line in region.
                    341: This is `comment-region', but using \"dnl\"."
                    342:
                    343:   (interactive "r\nP")
                    344:   (let ((comment-start "dnl")
                    345:        (comment-end ""))
                    346:     (comment-region beg end arg)))
                    347:
                    348:
                    349: (provide 'gmpasm-mode)
                    350:
                    351: ;;; gmpasm-mode.el ends here

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>