1 ;;;;------------------------------------------------------------------
3 ;;;; Copyright (C) 2001, 2004
4 ;;;; Department of Computer Science, University of Tromso, Norway.
6 ;;;; For distribution policy, see the accompanying file COPYING.
8 ;;;; Filename: movitz-mode.el
9 ;;;; Description: Modifies Franz' ELI slightly to integrate with Movitz.
10 ;;;; Author: Frode Vatvedt Fjeld <frodef@acm.org>
11 ;;;; Created at: Thu Sep 27 18:12:17 2001
13 ;;;; $Id: movitz-mode.el,v 1.10 2005/08/21 12:11:51 ffjeld Exp $
15 ;;;;------------------------------------------------------------------
17 (defvar movitz-common-lisp-mode-map nil
)
19 (defun make-movitz-common-lisp-mode-map (&optional new
)
21 (when (or new
(not movitz-common-lisp-mode-map
))
22 ;; (setq movitz-common-lisp-mode-map (make-keymap))
23 (fi::initialize-mode-map
'movitz-common-lisp-mode-map
))
24 (define-key movitz-common-lisp-mode-map
"\C-c\C-d" 'movitz-dump-image
)
25 (define-key movitz-common-lisp-mode-map
"\C-c\C-v" 'movitz-disassemble-defun
)
26 (define-key movitz-common-lisp-mode-map
"\C-c\C-b" 'movitz-compile-file
)
27 (define-key movitz-common-lisp-mode-map
"\C-\M-x" 'movitz-compile-defun
)
28 (define-key movitz-common-lisp-mode-map
"\C-cm" 'movitz-macroexpand
)
29 (define-key movitz-common-lisp-mode-map
"\C-ca" 'movitz-arglist
)
30 movitz-common-lisp-mode-map
)
32 (defun in-movitz-package-p ()
33 (or (and (< 6 (length fi
:package
))
34 (string= "MUERTE." (upcase (substring fi
:package
0 7))))
35 (member (upcase fi
:package
)
36 '("MUERTE" "X86" "X86-PC"))
39 "(cl:mapcar #'cl:package-name (cl:package-use-list \"%s\"))" (upcase fi
:package
)))))
41 (defun movitz-defun-name-and-type ()
44 (let ((definition-type
45 (let ((x (buffer-substring-no-properties (progn (fi:beginning-of-defun
)
48 (progn (forward-symbol 1)
51 ((string-equal "defun" x
)
53 ((string-match "^define-" x
)
55 ((string-match "^def" x
)
59 (buffer-substring-no-properties (progn (forward-char)
61 (progn (forward-sexp 1)
64 (buffer-substring-no-properties (progn (forward-char)
66 (progn (forward-sexp 1)
68 (if (and (equalp "method" definition-type
)
69 (char-equal 58 (string-to-char lambda-list
)))
70 (let ((qualifier lambda-list
)
71 ;; XXX we only deal with one (potential) qualifier..
72 (lambda-list (buffer-substring-no-properties (progn (forward-char)
74 (progn (forward-sexp 1)
76 (values definition-name
80 (values definition-name
85 (defun movitz-arglist (string)
86 (interactive (fi::get-default-symbol
"Movitz arglist for" t t
))
89 "(cl:let* ((cl:*print-case* :downcase)
91 (funobj (movitz::movitz-env-named-function name)))
93 (cl:format nil \"~A\" (movitz::movitz-print (movitz::movitz-funobj-lambda-list funobj)))))"
96 (message "Movitz args for %s: %s." string message
)
97 (fi:lisp-arglist string
))))
99 (defun movitz-dump-image (dont-run-bochs-p)
100 "Dump a Movitz image."
102 (message "Dumping Movitz image...")
103 (fi:eval-in-lisp
"(movitz::dump-image)")
104 ;;; (with-current-buffer "*common-lisp*"
105 ;;; (fi:inferior-lisp-newline))
108 (message "Dumping Movitz image...done. Bootblock ID: %d. Running qemu.."
109 (fi:eval-in-lisp
"movitz::*bootblock-build*"))
110 ;; (call-process "/bin/sh" nil 0 nil "-c"
111 ;; (format "DISPLAY=\"%s\" cd ~/clnet/movitz && qemu -fda los0-image -boot a"
112 ;; display-shortcut))
114 (t (message "Dumping Movitz image...done. Bootblock ID: %d. Running bochs on \"%s\"..."
115 (fi:eval-in-lisp
"movitz::*bootblock-build*")
117 (call-process "/bin/sh" nil
0 nil
"-c"
118 (format "DISPLAY=\"%s\" cd ~/clnet/movitz && ~/tmp/bochs-cvs/bochs -nocp > bochs-parameters"
119 display-shortcut
)))))
121 (defun movitz-compile-file ()
124 (message "Movitz compiling \"%s\"..." (buffer-file-name))
125 (fi:eval-in-lisp
"(movitz:movitz-compile-file \"%s\")" (buffer-file-name))
126 (message "Movitz compiling \"%s\"...done."
129 (defun movitz-eval-in-acl (string msg
)
130 (fi::note-background-request nil
)
132 (buffer (current-buffer)))
134 (lep::evaluation-request
135 :transaction-directory fi
:emacs-to-lisp-transaction-directory
136 ;; The addition of the format wrapper in the next line works
137 ;; around the incredible bogosity of fsf emacs 19.x that prints
138 ;; strings with non-null fontification using vector syntax.
139 ;; The format call reliably if inefficiently strips the font data.
140 ;; bug3330 smh 22jun94
141 :text
(fi::defontify-string string
)
142 :echo fi
:echo-evals-from-buffer-in-listener-p
144 :pathname
(buffer-file-name)
146 :return-string
(eq 'minibuffer
(car fi
:pop-up-temp-window-behavior
)))
147 ((buffer compilep msg
) (results stuff
)
151 ((eq 'minibuffer
(car fi
:pop-up-temp-window-behavior
))
152 (if (and (stringp stuff
) (= 0 (length stuff
)))
153 (fi::note-background-reply
(list compilep
))
154 (fi:show-some-text nil stuff
)))
156 (fi::note-background-reply
(list compilep
))))
157 ;; (fi::note-background-reply (list compilep))
158 (when (and results
(null fi
:echo-evals-from-buffer-in-listener-p
))
159 (fi:show-some-text nil results
)))
160 (when fi
:pop-to-sublisp-buffer-after-lisp-eval
; bug2683
161 (pop-to-buffer fi
:common-lisp-buffer-name
)
162 (goto-char (point-max)))
163 (message "%sdone." msg
))
164 ((buffer compilep
) (error)
167 (fi::note-background-reply
(list compilep
))
168 (message "Error during %s: %s"
169 (if compilep
"compile" "eval")
173 (defun movitz-compile-defun (&optional inverse-optimize-p
)
175 (multiple-value-bind (defun-name defun-type
)
176 (movitz-defun-name-and-type)
178 (let* ((end (save-excursion (end-of-defun) (point)))
179 (start (save-excursion
180 (fi:beginning-of-defun
)
182 (tmp-file (make-temp-name "/tmp/movitz-compile-defun-"))
183 (in-package (format "(in-package %s)\n" fi
:package
))
184 (msg (format "Movitz compiling %s %s..." defun-type defun-name
)))
185 (with-temp-file tmp-file
187 (write-region start end tmp-file t
)
188 ;; (fi:eval-in-lisp "(movitz:movitz-compile-file \"%s\")" tmp-file)
189 (if (not inverse-optimize-p
)
190 (movitz-eval-in-acl (format "(movitz:movitz-compile-file \"%s\" :delete-file-p t)" tmp-file
) msg
)
192 (format "(cl:let ((movitz::*compiler-do-optimize* (cl:not movitz::*compiler-do-optimize*)))
193 (movitz:movitz-compile-file \"%s\" :delete-file-p t))" tmp-file
) msg
))))))
194 ;;; (with-current-buffer (get-buffer-create "*MOVITZ-eval*")
196 ;;; (insert (format "(movitz:movitz-compile-file \"%s\")" tmp-file))
197 ;;; (movitz-eval-region-internal (point-min) (point-max) nil))))))
199 (defun movitz-disassemble-defun (not-recursive-p)
201 (multiple-value-bind (defun-name defun-type lambda-list options
)
202 (movitz-defun-name-and-type)
204 ((string= "function" defun-type
)
205 (message "Movitz disassembling %s %s..." defun-type defun-name
)
207 "(cl:let ((defun-name (cl:let ((cl:*package* (cl:find-package :%s))) (cl:read-from-string \"%s\")))
208 (cl:*print-base* 16))
209 (movitz::movitz-disassemble defun-name :recursive %s))"
210 fi
:package defun-name
(if not-recursive-p
"cl:nil" "cl:t"))
211 (switch-to-buffer "*common-lisp*")
212 (message "Movitz disassembling %s %s...done." defun-type defun-name
))
213 ((string= "method" defun-type
)
214 (message "Movitz disassembling %s %s %s..." defun-type defun-name lambda-list
)
216 "(cl:let* ((gf-name (cl:let ((cl:*package* (cl:find-package :%s)))
217 (cl:read-from-string \"%s\")))
218 (qualifiers (cl:read-from-string \"%s\"))
219 (lambda-list (cl:let ((cl:*package* (cl:find-package :%s)))
220 (cl:read-from-string \"%s\")))
221 (cl:*print-base* 16))
222 (movitz::movitz-disassemble-method gf-name lambda-list qualifiers))"
223 fi
:package defun-name options fi
:package lambda-list
)
224 (switch-to-buffer "*common-lisp*")
225 (message "Movitz disassembling %s %s...done." defun-type defun-name
))
226 ((string= "primitive-function" defun-type
)
227 (message "Movitz disassembling %s %s..." defun-type defun-name
)
229 "(cl:let ((defun-name (cl:let ((cl:*package* (cl:find-package :%s)))
230 (cl:read-from-string \"%s\")))
231 (cl:*print-base* 16))
232 (movitz::movitz-disassemble-primitive defun-name))"
233 fi
:package defun-name
)
234 (switch-to-buffer "*common-lisp*")
235 (message "Movitz disassembling %s %s...done." defun-type defun-name
))
236 (t (message "Don't know how to Movitz disassemble %s %s." defun-type defun-name
)))))
238 (defun movitz-macroexpand ()
240 (let* ((start (point))
241 (end (save-excursion (forward-sexp) (point)))
242 (tmp-file (make-temp-name "/tmp/movitz-macroexpand-"))
243 (expansion (unwind-protect
245 (write-region start end tmp-file t
)
247 (cl:with-output-to-string (cl:*standard-output*)
248 (cl:let ((cl:*print-pretty* t) (cl:*package* (cl:find-package :%s)))
250 (movitz::translate-program
251 (movitz::movitz-macroexpand-1
252 (cl:let ((cl:*package* (cl:find-package :%s)))
253 (cl:with-open-file (stream \"%s\" :direction :input)
255 :common-lisp :muerte.common-lisp))))"
259 (delete-file tmp-file
))))
260 (if (and (not (find 10 expansion
))
261 (< (length expansion
) 80))
262 (message "Movitz: \"%s\"" expansion
)
263 (let ((buffer (get-buffer-create "*Movitz Macroexpand*")))
264 (with-current-buffer buffer
265 (delete-region 1 (point-max))
269 (pop-to-buffer buffer
))))))
272 (add-hook 'fi
:inferior-common-lisp-mode-hook
274 (define-key fi
:inferior-common-lisp-mode-map
"\C-c\C-d" 'movitz-dump-image
)))
276 (add-hook 'fi
:common-lisp-mode-hook
278 (when (in-movitz-package-p)
279 (message "Switching to Movitz keymap.")
280 (use-local-map (make-movitz-common-lisp-mode-map)))))
282 (defun movitz-mode ()
283 "Switch on Movitz-mode."
285 (use-local-map (make-movitz-common-lisp-mode-map)))
287 (let ((tag 'fi
:common-lisp-indent-hook
))
288 (put 'compiler-values tag
'(like with-open-file
))
289 (put 'compiler-values-list tag
'(like with-open-file
))
290 (put 'compiler-values-bind tag
'(like multiple-value-bind
))
291 (put 'compiler-values-list-bind tag
'(like multiple-value-bind
))
292 (put 'compiler-call tag
'(like make-instance
))
293 (put 'compiler-values-setq tag
'(like multiple-value-setq
))
294 (put 'named-integer-case tag
'(like with-slots
))
295 (put 'with-ne2000-io tag
'(like with-slots
))
296 (put 'vector-double-dispatch tag
'(like case
))
297 (put 'sequence-dispatch tag
'(like case
))
298 (put 'sequence-double-dispatch tag
'(like case
))
299 (put 'number-double-dispatch tag
'(like case
))
300 (put 'simple-stream-dispatch tag
'(like case
))
301 (put 'with-inline-assembly tag
'(like prog
))
302 (put 'with-inline-assembly-case tag
'(like prog
))
303 (put 'do-case tag
'(like prog
))
304 (put 'select tag
'(like case
))
305 (put 'compiler-typecase tag
'(like case
)))