rpl-base.el 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. ;;; -*- mode: emacs-lisp; lexical-binding: t -*-
  2. ;;; rpl-base.el -- basic setup for the RPL tools
  3. ;; Copyright (C) 2014 Paul Onions
  4. ;; Author: Paul Onions <paul.onions@acm.org>
  5. ;; Keywords: RPL, SysRPL, HP48, HP49, HP50
  6. ;; This file is free software, see the LICENCE file in this directory
  7. ;; for copying terms.
  8. ;;; Commentary:
  9. ;; Basic setup for the RPL tools.
  10. ;;; Code:
  11. (require 'cl-lib)
  12. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  13. ;; Customizations
  14. ;;
  15. (defgroup rpl nil
  16. "Tools for working with the RPL calculator programming language.")
  17. (defcustom rpl-sysrpl-data-file-prefix "sysrpl-data"
  18. "Filename prefix for files from which to `read' SysRPL data."
  19. :type 'string
  20. :group 'rpl)
  21. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  22. ;; Utility functions for generating/loading pre-computed data
  23. ;;
  24. (defun rpl-make-sysrpl-data-filename (calculator)
  25. "Make the SysRPL data filename used for CALCULATOR.
  26. Where CALCULATOR should be a keyword symbol identifying the
  27. calculator model, e.g. :48G, :49G etc."
  28. (cl-assert (keywordp calculator))
  29. (concat rpl-sysrpl-data-file-prefix "." (substring (symbol-name calculator) 1) ".el"))
  30. (defvar rpl-tools-data-dir
  31. (and load-file-name (concat (file-name-directory load-file-name) "data/"))
  32. "RPL tools data directory.")
  33. (defun rpl-write-data-file (obj filename)
  34. "Write OBJ to FILENAME using function `print'.
  35. The directory in which to write the file defaults to the value of
  36. the variable `rpl-tools-data-dir'. This can be overridden by
  37. specifying a different path in the FILENAME string (either
  38. relative or absolute)."
  39. (let ((default-directory rpl-tools-data-dir))
  40. (with-temp-buffer
  41. (print obj (current-buffer))
  42. (write-region (point-min) (point-max) filename))))
  43. (defun rpl-read-data-file (filename)
  44. "Read a Lisp object from FILENAME using function `read'.
  45. The directory in which FILENAME resides is assumed to be the
  46. value of the variable `rpl-tools-data-dir'. This can be
  47. overridden by specifying a different path in the FILENAME
  48. string (either relative or absolute)."
  49. (let ((default-directory rpl-tools-data-dir))
  50. (with-temp-buffer
  51. (insert-file-contents filename)
  52. (goto-char (point-min))
  53. (read (current-buffer)))))
  54. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  55. ;; Load SysRPL names files
  56. ;;
  57. (message "Loading SysRPL information")
  58. (defvar rpl-sysrpl-data-38g
  59. (rpl-read-data-file (rpl-make-sysrpl-data-filename :38G))
  60. "SysRPL data for the 38G calculator.")
  61. (defvar rpl-sysrpl-data-39g
  62. (rpl-read-data-file (rpl-make-sysrpl-data-filename :39G))
  63. "SysRPL data for the 39G calculator.")
  64. (defvar rpl-sysrpl-data-48g
  65. (rpl-read-data-file (rpl-make-sysrpl-data-filename :48G))
  66. "SysRPL data for the 48G calculator.")
  67. (defvar rpl-sysrpl-data-49g
  68. (rpl-read-data-file (rpl-make-sysrpl-data-filename :49G))
  69. "SysRPL data for the 49G calculator.")
  70. (defun rpl-sysrpl-data-get-names (data)
  71. (let ((names nil))
  72. (maphash (lambda (key val)
  73. (setq names (cons key names)))
  74. data)
  75. names))
  76. (defun rpl-sysrpl-names (calculator)
  77. (cl-assert (keywordp calculator))
  78. (cond ((eql calculator :38G)
  79. (rpl-sysrpl-data-get-names rpl-sysrpl-data-38g))
  80. ((eql calculator :39G)
  81. (rpl-sysrpl-data-get-names rpl-sysrpl-data-39g))
  82. ((eql calculator :48G)
  83. (rpl-sysrpl-data-get-names rpl-sysrpl-data-48g))
  84. ((eql calculator :49G)
  85. (rpl-sysrpl-data-get-names rpl-sysrpl-data-49g))))
  86. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  87. ;; Common keymap (including the ``RPL'' menu)
  88. ;;
  89. (defvar rpl-menu-compile-file-enable nil)
  90. (make-variable-buffer-local 'rpl-menu-compile-file-enable)
  91. (defvar rpl-common-keymap
  92. (let ((map (make-sparse-keymap "RPL"))
  93. (menu-map (make-sparse-keymap "RPL")))
  94. (set-keymap-parent map prog-mode-map)
  95. ;; Key assignments
  96. (define-key map (kbd "C-c C-k") 'rpl-compile-file)
  97. ;; Menu items
  98. (define-key map [menu-bar rpl-menu] (cons "RPL" menu-map))
  99. (define-key menu-map [rpl-menu-compile-file]
  100. '(menu-item "Compile File..." rpl-compile-file
  101. :enable rpl-menu-compile-file-enable))
  102. (define-key menu-map [rpl-menu-separator-1]
  103. '(menu-item "--"))
  104. (define-key menu-map [rpl-menu-apropos]
  105. '(menu-item "Apropos (at point)..." rpl-apropos-thing-at-point))
  106. map)
  107. "The RPL tools common keymap.")
  108. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  109. ;; Developer utils
  110. ;;
  111. (defvar rpl-debug nil)
  112. (defmacro rpl-debug-message (msg)
  113. (if rpl-debug
  114. `(message ,msg)
  115. nil))
  116. (defun rpl-force-reload ()
  117. (interactive)
  118. (load "rpl-base")
  119. (load "rpl-sysrpl-mode"))
  120. (provide 'rpl-base)