[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.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>