gmpasm-mode.el
上传用户:qaz666999
上传日期:2022-08-06
资源大小:2570k
文件大小:13k
源码类别:

数学计算

开发平台:

Unix_Linux

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