cosmopolitan/tool/emacs/cosmo-asm-mode.el

361 lines
9.5 KiB
EmacsLisp
Raw Blame History

This file contains invisible Unicode characters!

This file contains invisible Unicode characters that may be processed differently from what appears below. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to reveal hidden characters.

;; ╔──────────────────────────────────────────────────────────────────╗
;; │ To the extent possible under law, Justine Tunney has waived │
;; │ all copyright and related or neighboring rights to this file, │
;; │ as it is written in the following disclaimers: │
;; │ • http://unlicense.org/ │
;; │ • http://creativecommons.org/publicdomain/zero/1.0/ │
;; ╚──────────────────────────────────────────────────────────────────╝
;; Reconfigures GNU Emacs syntax highlighting for GNU Assembler syntax.
(require 'asm-mode)
(require 'cosmo-cpp-constants)
(defun cosmo-regexpify (x)
(let ((join (lambda (sep lis)
(mapconcat 'identity lis sep))))
(cond ((vectorp x)
(funcall join "" (mapcar 'cosmo-regexpify x)))
((listp x)
(concat "\\(?:"
(funcall join "\\|" (mapcar 'cosmo-regexpify x))
"\\)"))
('t x))))
(defun cosmo-fontify (faces regexp limit predicate)
"Set FACES on REGEXP matches until LIMIT that satisfy PREDICATE."
(while (re-search-forward regexp limit t)
(let (i (face (save-excursion
(backward-char)
(face-at-point)))
(syntax (syntax-ppss)))
(when (funcall predicate face syntax)
(dolist (i faces)
(put-text-property (match-beginning (car i))
(match-end (car i))
'face
(cdr i)))))))
(defconst asm-mode-gas-qualifiers-regexp
(cosmo-regexpify
[("comdat"
":req"
":vararg"
["@" (;; calculates offset relative to tls block end
;; load: mov %fs:boop@tpoff,%eax
;; addr: mov %fs:0,%rax
;; lea x1@tpoff(%rax),%rax
;; addr: mov %fs:0,%rax
;; add $x1@tpoff,%rax
"tpoff"
;; allocates TLS_index structure
;; lea x@tlsgd(,%rbx,1),%rdi
;; call __tls_get_addr@plt
"tlsgd"
"tlsld"
"dtpmod"
"dtpoff"
"gottpoff"
"function"
"object"
"got"
"size"
"gotoff"
"plt"
"pltoff"
"gotpcrel"
"progbits"
"nobits"
"init_array"
"fini_array")])
"\\>"])
"GNU Assembler section, relocation, macro param qualifiers.")
(defconst asm-mode-doctag-regexp
(cosmo-regexpify
'(["<"
("p" "br"
"b" "/b"
"i" "/i"
"pre" "/pre"
"h3" "h4" "/h3" "/h4"
"ul" "ol" "li" "/ol" "/ul"
"dl" "dt" "dd" "/dl"
"table" "tr" "td" "th" "td" "/table")
">"]
["@"
("param"
"return"
"define"
"see"
"throws"
"returnstwice"
"fileoverview"
"nullable"
"noreturn"
"domain"
"clob"
"since"
"forcealignargpointer"
"mode"
"speed"
"cost"
"todo"
"assume"
"define"
"domain"
"code"
"note"
"protip"
"nxbitsafe"
"preinitsafe"
"asyncsignalsafe"
"notasyncsignalsafe"
"isa"
"sideffect")
"\\>"]))
"Assembly docstring highlighting in Google Java Style.")
(defconst asm-mode-x86-prefix-ops-regexp
(cosmo-regexpify
[(["[lL][oO][cC][kK]\\>[ \t]*"
("[mM][oO][vV][sS]"
"[aA][dD][dDcC]"
"[sS][uUbB][bB]"
"[oO][rR]"
"[aA][nN][dD]"
"[xX][oO][rR]"
"[nN][oO][tT]"
"[nN][eE][gG]"
"[iI][nN][cC]"
"[dD][eE][cC]"
"[bB][tT][sSrRcC]?"
"[xX][aA][dD][dD]"
"[xX][cC][hH][gG]"
["[cC][mM][pP][xX][cC][hH][gG]" ("8[bB]" "16[bB]") "?"])]
["[rR][eE][pP]" ("[eEzZ]" "[nN][eEzZ]") "?\\>[ \t]*"
("[mM][oO][vV][sS]"
"[sS][tT][oO][sS]"
"[sS][cC][aA][sS]"
"[cC][mM][pP][sS]"
"[nN][oO][pP]"
"[rR][eE][tT]"
"[iI][nN][sS]"
"[oO][uU][tT][sS]")])
"[bBwWlLqQ]?\\>"])
"Legal high-level 80x86 prefix instruction combinations.")
(defconst cosmo-asm-font-lock-keywords
(append
`(;; AT&T Fortran-Style Assembler Comment
;;
;; - Valid
;;
;; * /heyho
;; * //heyho
;;
;; - Ignored
;;
;; *  /heyho
;; * code code //heyho
;;
("^/.*$" . font-lock-comment-face)
;; Immediate Argument
;;
;; - Valid
;;
;; * mov $2,%eax
;; * mov $~2+0x2ul,%eax
;; * mov $'c,%eax
;; * mov $'\n,%eax
;;
("[ \t,]\\$\\(\\(?:'\\(?:'\\|\\s\"\\|\\s\\.\\|.\\)\\|\\(?:0x[[:xdigit:]]+\\|0b[01]+\\|[1-9][0-9]*\\|0[0-7]*\\)\\(?:[fb]\\|u?l?l?\\)\\|[-*/&^|()%<>~+]\\|[_.$[:alpha:]][-_.[:alnum:]]*\\)+\\)"
1 font-lock-constant-face)
(cosmo-asm-doctag-keywords)
;; Static Branch Prediction
;;
;; - Valid
;;
;; * jnz,pt 1f
;; * jnz,pn 1b
;;
;; - Traditionally Implied
;;
;; * jnz,pn 1f
;; * jnz,pt 1b
;;
(",p[tn]" . font-lock-keyword-face)
("\\\\\\(?:@\\|()\\)" . font-lock-function-name-face)
("\\\\\\(\\sw\\|_\\|\\.\\)+\\>" . font-lock-variable-name-face)
(,asm-mode-x86-prefix-ops-regexp . font-lock-keyword-face)
(,(concat "^\\(\\(?:\\sw\\|\\s_\\|\\.\\)+\\):[ \t]*"
"\\(\\(?:\\sw\\|\\.\\)+\\)?")
(1 font-lock-function-name-face)
(2 font-lock-keyword-face nil t))
("^\\((\\sw+)\\)?\\s +\\(\\(\\.?\\sw\\|\\s_\\)+\\(\\.\\sw+\\)*\\)"
2 font-lock-keyword-face)
("^\\(\\.\\(\\sw\\|\\s_\\|\\.\\)+\\)\\>[^:]?"
1 font-lock-keyword-face)
("^.*?\\*/\\(\\.\\(\\sw\\|\\s_\\|\\.\\)+\\)\\>[^:]?"
1 font-lock-keyword-face)
;; it's complicated
(,asm-mode-gas-qualifiers-regexp . font-lock-type-face))
cpp-font-lock-keywords
`(;; GNU-Style Assembler Comment (Ltd. 80x86 &c.)
;;
;; - Valid
;;
;; * #heyho
;; * # heyho
;; * .org . #heyho
;; * .org . ####euhhcue
;; * .org .# ###euhhcue
;;
;; - Ignored
;;
;; * #if 0
;; * #endif
;; * .ascii "#heyho"
;;
("\\(#.*\\)$" 1 font-lock-comment-face)
("'\\(\\\\?.\\)\\>" 1 font-lock-constant-face)
;; Register Value
;;
;; - Valid
;;
;; * %al
;; * %eax
;;
;; - Ignored
;;
;; * %%al
;;
("%\\sw+" . font-lock-variable-name-face)
;; Hexadecimal Literal
;;
;; - Valid
;;
;; * 0x0123456789abcdef
;; * 0XDEADBEEFu
;; * -0xdeadbeefULL
;;
;; - Ignored
;;
;; * 0x0123456789abcdefg
;;
("\\b\\(0[xX]\\)[[:xdigit:]]+\\([ulUL]*\\)\\b"
(1 font-lock-constant-face)
(2 font-lock-constant-face))
;; Binary Literal
;;
;; - Valid
;;
;; * 0b0101101101
;; * 0B0101101101u
;; * -0b0101101101ULL
;;
;; - Ignored
;;
;; * 0b012
;;
("\\b\\(0[bB]\\)[01]+\\([ulUL]*\\)\\b"
(1 font-lock-constant-face)
(2 font-lock-constant-face))
;; Octal Literal
;;
;; - Valid
;;
;; * 01234567
;; * 01234567l
;; * -01234567ULL
;;
;; - Ignored
;;
;; * 012345678
;;
("\\b\\(0\\)[0-7]+\\([ulUL]*\\)\\b"
(1 font-lock-constant-face)
(2 font-lock-constant-face))
;; Bultin Constants
;;
;; - Valid
;;
;; * 123456789
;; * 123456789l
;; * -01234567ULL
;;
;; - Ignored
;;
;; * 123456789a
;; * 123456789aul
;;
("\\b[1-9][0-9]+\\([ulUL]*\\)\\b"
1 font-lock-constant-face)
;; AT&T Fortran-Style Assembler Comment
;;
;; - Valid
;;
;; * /heyho
;; * //heyho
;;
;; - Ignored
;;
;; *  /heyho
;; * code code //heyho
;;
("^/.*$" . font-lock-comment-face)
;; AT&T-Style Directional Label
;;
;; - Valid
;;
;; * 1f
;; * 99b
;;
("\\b\\([0-9]+\\)[fb]\\b" 1 font-lock-function-name-face)))
"Additional expressions to highlight in Assembler mode.")
(defun cosmo-asm-doctag-keywords (limit)
(cosmo-fontify '((0 . font-lock-constant-face))
asm-mode-doctag-regexp
limit
(lambda (face syntax)
(or (memq face '(font-lock-comment-face))
(and syntax
(nth 4 syntax))))))
(defun cosmo-asm-supplemental-hook ()
"GNU Assembly in Bell Laboratories Style."
(setq asm-comment-char ) ;; Was ESR using TASM?
(font-lock-add-keywords 'asm-mode
'((cosmo-asm-doctag-keywords))
'append)
(set (make-local-variable 'require-final-newline) nil)
(set (make-local-variable 'indent-tabs-mode) t)
(set (make-local-variable 'tab-width) 8))
(progn
(add-hook 'asm-mode-hook 'cosmo-asm-supplemental-hook)
(setq asm-font-lock-keywords cosmo-asm-font-lock-keywords))
;; Make -*-unix-assembly-*- mode line work correctly.
;; TODO(jart): Would be nice to use GitHub's name instead of changing asm-mode.
(defun unix-assembly-mode ()
(interactive)
(asm-mode))
(provide 'cosmo-asm-mode)