sysrpl-mode.el 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. ;;; -*- mode: emacs-lisp; lexical-binding: t -*-
  2. ;;; sysrpl-mode.el -- Major mode for the SysRPL programming language
  3. ;; Copyright (C) 2014 Paul Onions
  4. ;; Author: Paul Onions <paul.onions@acm.org>
  5. ;; Keywords: RPL, SysRPL, HP48, HP49, HP50, calculator
  6. ;; This file is free software, see the LICENCE file in this directory
  7. ;; for copying terms.
  8. ;;; Commentary:
  9. ;; A major mode for the SysRPL language, the system programming
  10. ;; language of HP48/49/50-series calculators.
  11. ;;; Code:
  12. (require 'cl-lib)
  13. (require 'rpl-base)
  14. (require 'rpl-edb)
  15. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  16. ;; Customizations
  17. ;;
  18. (defcustom rpl-sysrpl-default-calculator :48G
  19. "Default calculator type for SysRPL mode."
  20. :type '(radio :38G :39G :48G :49G)
  21. :group 'rpl)
  22. (defface sysrpl-name '((t :foreground "darkblue"))
  23. "Face used for displaying SysRPL names (e.g DROP)."
  24. :group 'rpl)
  25. (defface sysrpl-keyword '((t :foreground "purple"))
  26. "Face used for displaying SysRPL keywords (e.g. :: ;)."
  27. :group 'rpl)
  28. (defface sysrpl-comment '((t :foreground "darkgreen"))
  29. "Face used for displaying SysRPL comments."
  30. :group 'rpl)
  31. (defcustom sysrpl-font-lock-name-face 'sysrpl-name
  32. "Name of face to use for displaying SysRPL names."
  33. :type 'symbol
  34. :group 'rpl)
  35. (defcustom sysrpl-font-lock-keyword-face 'sysrpl-keyword
  36. "Name of face to use for displaying SysRPL keywords."
  37. :type 'symbol
  38. :group 'rpl)
  39. (defcustom sysrpl-font-lock-comment-face 'sysrpl-comment
  40. "Name of face to use for displaying SysRPL comments."
  41. :type 'symbol
  42. :group 'rpl)
  43. (defvar sysrpl-mode-syntax-table
  44. (let ((table (make-syntax-table prog-mode-syntax-table)))
  45. (modify-syntax-entry ?: "w" table)
  46. (modify-syntax-entry ?\; "w" table)
  47. (modify-syntax-entry ?! "w" table)
  48. (modify-syntax-entry ?@ "w" table)
  49. (modify-syntax-entry ?# "w" table)
  50. (modify-syntax-entry ?$ "w" table)
  51. (modify-syntax-entry ?% "w" table)
  52. (modify-syntax-entry ?^ "w" table)
  53. (modify-syntax-entry ?& "w" table)
  54. (modify-syntax-entry ?\? "w" table)
  55. (modify-syntax-entry ?- "w" table)
  56. (modify-syntax-entry ?_ "w" table)
  57. (modify-syntax-entry ?= "w" table)
  58. (modify-syntax-entry ?+ "w" table)
  59. (modify-syntax-entry ?* "w" table)
  60. (modify-syntax-entry ?/ "w" table)
  61. (modify-syntax-entry ?< "w" table)
  62. (modify-syntax-entry ?> "w" table)
  63. (modify-syntax-entry ?| "w" table)
  64. table)
  65. "The SysRPL syntax table.")
  66. (defun sysrpl-font-lock-compile-keywords (names)
  67. "Construct a list of keyword matcher clauses suitable for `font-lock-keywords'."
  68. (append (list (list "^\\*.*$" (list 0 'sysrpl-font-lock-comment-face))
  69. (list "(.*)" (list 0 'sysrpl-font-lock-comment-face))
  70. (list (concat "\\<" (regexp-opt '("::" ";")) "\\>") (list 0 'sysrpl-font-lock-keyword-face)))
  71. (mapcar (lambda (str) (list (concat "\\<" (regexp-quote str) "\\>")
  72. (list 0 'sysrpl-font-lock-name-face)))
  73. names)))
  74. (defvar sysrpl-font-lock-keywords
  75. (sysrpl-font-lock-compile-keywords (rpl-edb-all-names rpl-sysrpl-default-calculator)))
  76. (defvar sysrpl-selected-calculator rpl-sysrpl-default-calculator
  77. "Currently selected calculator model.")
  78. (defun sysrpl-select-38g ()
  79. "Set the currently selected calculator model to be the 38G."
  80. (interactive)
  81. (setq sysrpl-selected-calculator :38G)
  82. (setq sysrpl-font-lock-keywords (sysrpl-font-lock-compile-keywords (rpl-edb-all-names :38G)))
  83. (sysrpl-mode))
  84. (defun sysrpl-select-39g ()
  85. "Set the currently selected calculator model to be the 39G."
  86. (interactive)
  87. (setq sysrpl-selected-calculator :39G)
  88. (setq sysrpl-font-lock-keywords (sysrpl-font-lock-compile-keywords (rpl-edb-all-names :39G)))
  89. (sysrpl-mode))
  90. (defun sysrpl-select-48g ()
  91. "Set the currently selected calculator model to be the 48G."
  92. (interactive)
  93. (setq sysrpl-selected-calculator :48G)
  94. (setq sysrpl-font-lock-keywords (sysrpl-font-lock-compile-keywords (rpl-edb-all-names :48G)))
  95. (sysrpl-mode))
  96. (defun sysrpl-select-49g ()
  97. "Set the currently selected calculator model to be the 49G."
  98. (interactive)
  99. (setq sysrpl-selected-calculator :49G)
  100. (setq sysrpl-font-lock-keywords (sysrpl-font-lock-compile-keywords (rpl-edb-all-names :49G)))
  101. (sysrpl-mode))
  102. (defun sysrpl-show-stack-effect (name)
  103. (message (rpl-edb-get-stack-effect sysrpl-selected-calculator name)))
  104. (defun sysrpl-apropos-thing-at-point (name)
  105. "Show information about NAME in a popup buffer.
  106. When called interactively NAME defaults to the word around
  107. point."
  108. (interactive (list (completing-read "Apropos: " (rpl-edb-all-names sysrpl-selected-calculator)
  109. nil nil (thing-at-point 'word))))
  110. (let ((bufname (format "*SysRPL: %s*" name)))
  111. (with-current-buffer (get-buffer-create bufname)
  112. (setq buffer-read-only nil)
  113. (erase-buffer)
  114. (insert (rpl-edb-get-stack-effect sysrpl-selected-calculator name))
  115. (newline)
  116. (insert (rpl-edb-get-description sysrpl-selected-calculator name))
  117. (newline)
  118. (insert (format "Address: %s" (rpl-edb-get-address sysrpl-selected-calculator name)))
  119. (newline)
  120. (insert (format "Flags: %s" (rpl-edb-get-flags sysrpl-selected-calculator name)))
  121. (newline)
  122. (end-of-buffer)
  123. (help-mode)
  124. (set-buffer-modified-p nil)
  125. (setq buffer-read-only t))
  126. (fit-window-to-buffer (display-buffer bufname))))
  127. (defvar sysrpl-mode-map
  128. (let ((map (make-sparse-keymap))
  129. (menu-map (make-sparse-keymap)))
  130. (set-keymap-parent map rpl-common-keymap)
  131. ;; Menu items
  132. (define-key map [menu-bar rpl-menu] (cons "RPL" menu-map))
  133. (define-key menu-map [sysrpl-menu-separator-1]
  134. '(menu-item "--"))
  135. (define-key menu-map [sysrpl-menu-select-49g]
  136. '(menu-item "HP49G" sysrpl-select-49g
  137. :button (:radio . (eql :49G sysrpl-selected-calculator))))
  138. (define-key menu-map [sysrpl-menu-select-48g]
  139. '(menu-item "HP48G" sysrpl-select-48g
  140. :button (:radio . (eql :48G sysrpl-selected-calculator))))
  141. (define-key menu-map [sysrpl-menu-select-39g]
  142. '(menu-item "HP39G" sysrpl-select-39g
  143. :button (:radio . (eql :39G sysrpl-selected-calculator))))
  144. (define-key menu-map [sysrpl-menu-select-38g]
  145. '(menu-item "HP38G" sysrpl-select-38g
  146. :button (:radio . (eql :38G sysrpl-selected-calculator))))
  147. map)
  148. "The SysRPL mode local keymap.")
  149. (defvar sysrpl-mode-hook nil
  150. "Hook for customizing SysRPL mode.")
  151. (define-derived-mode sysrpl-mode prog-mode "SysRPL"
  152. "Major mode for the SysRPL language."
  153. :group 'rpl
  154. (setq font-lock-defaults (list 'sysrpl-font-lock-keywords))
  155. (setq rpl-menu-compile-file-enable nil))
  156. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  157. ;; End of file
  158. ;;
  159. (provide 'sysrpl-mode)