Skip to content

Instantly share code, notes, and snippets.

@jonhoo
Created January 22, 2011 07:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jonhoo/790945 to your computer and use it in GitHub Desktop.
Save jonhoo/790945 to your computer and use it in GitHub Desktop.
SRI SAL mode for Emacs
(require 'generic-x) ;; we need this
(define-generic-mode
'atg-mode ;; name of the mode to create
'("---") ;; comments start with '!!'
'("Path" "Step") ;; some keywords
'(("=" . 'font-lock-function-name-face)) ;; '=' is an operator
'("\\.atg$") ;; files for which to activate this mode
nil ;; other functions to call
"A mode for SRI SAL ATG generated files" ;; doc string for this mode
)
(provide 'atg-mode)
(add-to-list 'auto-mode-alist '("\\.sal\\'" . sal-mode))
;; Syntax highlighting
(defvar sal-keywords
'("BEGIN" "END" "MODULE" "INITIALIZATION" "TRANSITION" "TYPE" "LOCAL" "INPUT" "OUTPUT" "THEOREM" "CONTEXT" "IF" "THEN" "ELSE" "ENDIF" "DEFINITION") )
(defvar sal-operators
'("OR" "AND" "NOT" "X" "G" "F") )
(defvar sal-types
'("boolean" "int") )
(defvar sal-font-lock-defaults
`((
("^[ \t]*%.*$" . font-lock-comment-face)
( ,(regexp-opt sal-keywords 'words) . font-lock-builtin-face)
("\\(-->\\|\\[]\\||-\\)" . font-lock-builtin-face)
("\\(=>?\\|<=?\\|>=?\\|+\\|*\\|/\\|-\\)" . font-lock-function-name-face)
( ,(regexp-opt sal-operators 'words) . font-lock-function-name-face)
; ("=[ \t]*\\w+" . font-lock-string-face)
; (":[ \t]*\\w+" . font-lock-type-face)
("\\b[A-Z]\\w*\\b" . font-lock-type-face)
( ,(regexp-opt sal-types 'words) . font-lock-type-face)
("\\b[\\w\\[\\]]+'" . font-lock-variable-name-face)
("{[^}]+}" . font-lock-string-face)
("\\b[0-9]+\\b" . font-lock-string-face)
; ("\\b\\w+\\b" . font-lock-constant-face)
)))
;; Clear memory
(setq sal-keywords nil)
(setq sal-operators nil)
;; Indentation
(defun sal-indent-line ()
"Indent current line as SAL code."
(interactive)
(beginning-of-line)
(if (bobp)
(indent-line-to 0) ; First line is always non-indented
(let ((not-indented t) cur-indent (is-brackets (looking-at "^[ \t]*\\[\\]")))
(if (looking-at "^[ \t]*\\(END\\|\\]\\)") ; If the line we are looking at is the end of a block, then decrease the indentation
(progn
(save-excursion
(forward-line -1)
(setq cur-indent (- (current-indentation) default-tab-width)))
(if (< cur-indent 0) ; We can't indent past the left margin
(setq cur-indent 0)))
(save-excursion
(while not-indented ; Iterate backwards until we find an indentation hint
(forward-line -1)
(if (looking-at "^[ \t]*\\(END\\|\\]\\)") ; This hint indicates that we need to indent at the level of the end token
(progn
(setq cur-indent (current-indentation))
(setq not-indented nil))
(if (looking-at "^[ \t]*\\(BEGIN\\|TRANSITION\\)") ; This hint indicates that we need to indent an extra level
(progn
(setq cur-indent (+ (current-indentation)
(if is-brackets
(/ default-tab-width 2)
default-tab-width))) ; Do the actual indenting
(setq not-indented nil))
(if (bobp)
(setq not-indented nil)))))))
(if cur-indent
(indent-line-to cur-indent)
(indent-line-to 0))))) ; If we didn't see an indentation hint, then allow no indentation
;; Entry point
(define-derived-mode sal-mode fundamental-mode "SAL"
"Major mode for editing SRI SAL files."
(setq comment-start "%")
(setq comment-end "")
(setq font-lock-defaults sal-font-lock-defaults)
(setq indent-line-function 'sal-indent-line)
)
(provide 'sal-mode)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment