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