Commit | Line | Data |
---|---|---|
afe98dfa CD |
1 | ;;; ob-scheme.el --- org-babel functions for Scheme |
2 | ||
3ab2c837 | 3 | ;; Copyright (C) 2010 Free Software Foundation |
afe98dfa CD |
4 | |
5 | ;; Author: Eric Schulte | |
6 | ;; Keywords: literate programming, reproducible research, scheme | |
7 | ;; Homepage: http://orgmode.org | |
3ab2c837 | 8 | ;; Version: 7.7 |
afe98dfa | 9 | |
acedf35c | 10 | ;;; License: |
afe98dfa | 11 | |
acedf35c | 12 | ;; This program is free software; you can redistribute it and/or modify |
afe98dfa | 13 | ;; it under the terms of the GNU General Public License as published by |
acedf35c CD |
14 | ;; the Free Software Foundation; either version 3, or (at your option) |
15 | ;; any later version. | |
16 | ;; | |
17 | ;; This program is distributed in the hope that it will be useful, | |
afe98dfa CD |
18 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of |
19 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
20 | ;; GNU General Public License for more details. | |
acedf35c | 21 | ;; |
afe98dfa | 22 | ;; You should have received a copy of the GNU General Public License |
acedf35c CD |
23 | ;; along with GNU Emacs; see the file COPYING. If not, write to the |
24 | ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | |
25 | ;; Boston, MA 02110-1301, USA. | |
afe98dfa CD |
26 | |
27 | ;;; Commentary: | |
28 | ||
29 | ;; Now working with SBCL for both session and external evaluation. | |
30 | ;; | |
31 | ;; This certainly isn't optimally robust, but it seems to be working | |
32 | ;; for the basic use cases. | |
33 | ||
34 | ;;; Requirements: | |
35 | ||
36 | ;; - a working scheme implementation | |
37 | ;; (e.g. guile http://www.gnu.org/software/guile/guile.html) | |
acedf35c | 38 | ;; |
afe98dfa CD |
39 | ;; - for session based evaluation cmuscheme.el is required which is |
40 | ;; included in Emacs | |
41 | ||
42 | ;;; Code: | |
43 | (require 'ob) | |
44 | (require 'ob-ref) | |
45 | (require 'ob-comint) | |
46 | (require 'ob-eval) | |
47 | (eval-when-compile (require 'cl)) | |
48 | ||
49 | (declare-function run-scheme "ext:cmuscheme" (cmd)) | |
50 | ||
51 | (defvar org-babel-default-header-args:scheme '() | |
52 | "Default header arguments for scheme code blocks.") | |
53 | ||
54 | (defvar org-babel-scheme-eoe "org-babel-scheme-eoe" | |
55 | "String to indicate that evaluation has completed.") | |
56 | ||
57 | (defcustom org-babel-scheme-cmd "guile" | |
58 | "Name of command used to evaluate scheme blocks." | |
59 | :group 'org-babel | |
60 | :type 'string) | |
61 | ||
62 | (defun org-babel-expand-body:scheme (body params) | |
63 | "Expand BODY according to PARAMS, return the expanded body." | |
64 | (let ((vars (mapcar #'cdr (org-babel-get-header params :var)))) | |
65 | (if (> (length vars) 0) | |
66 | (concat "(let (" | |
67 | (mapconcat | |
68 | (lambda (var) (format "%S" (print `(,(car var) ',(cdr var))))) | |
69 | vars "\n ") | |
70 | ")\n" body ")") | |
71 | body))) | |
72 | ||
73 | (defvar scheme-program-name) | |
74 | (defun org-babel-execute:scheme (body params) | |
75 | "Execute a block of Scheme code with org-babel. | |
76 | This function is called by `org-babel-execute-src-block'" | |
77 | (let* ((result-type (cdr (assoc :result-type params))) | |
78 | (org-babel-scheme-cmd (or (cdr (assoc :scheme params)) | |
79 | org-babel-scheme-cmd)) | |
80 | (full-body (org-babel-expand-body:scheme body params))) | |
81 | (read | |
82 | (if (not (string= (cdr (assoc :session params)) "none")) | |
83 | ;; session evaluation | |
84 | (let ((session (org-babel-prep-session:scheme | |
85 | (cdr (assoc :session params)) params))) | |
86 | (org-babel-comint-with-output | |
87 | (session (format "%S" org-babel-scheme-eoe) t body) | |
88 | (mapc | |
89 | (lambda (line) | |
90 | (insert (org-babel-chomp line)) (comint-send-input nil t)) | |
91 | (list body (format "%S" org-babel-scheme-eoe))))) | |
92 | ;; external evaluation | |
93 | (let ((script-file (org-babel-temp-file "scheme-script-"))) | |
94 | (with-temp-file script-file | |
95 | (insert | |
96 | ;; return the value or the output | |
97 | (if (string= result-type "value") | |
98 | (format "(display %s)" full-body) | |
99 | full-body))) | |
100 | (org-babel-eval | |
101 | (format "%s %s" org-babel-scheme-cmd | |
102 | (org-babel-process-file-name script-file)) "")))))) | |
103 | ||
104 | (defun org-babel-prep-session:scheme (session params) | |
105 | "Prepare SESSION according to the header arguments specified in PARAMS." | |
106 | (let* ((session (org-babel-scheme-initiate-session session)) | |
107 | (vars (mapcar #'cdr (org-babel-get-header params :var))) | |
108 | (var-lines | |
109 | (mapcar | |
110 | (lambda (var) (format "%S" (print `(define ,(car var) ',(cdr var))))) | |
111 | vars))) | |
112 | (when session | |
113 | (org-babel-comint-in-buffer session | |
114 | (sit-for .5) (goto-char (point-max)) | |
115 | (mapc (lambda (var) | |
116 | (insert var) (comint-send-input nil t) | |
117 | (org-babel-comint-wait-for-output session) | |
118 | (sit-for .1) (goto-char (point-max))) var-lines))) | |
119 | session)) | |
120 | ||
121 | (defun org-babel-scheme-initiate-session (&optional session) | |
122 | "If there is not a current inferior-process-buffer in SESSION | |
123 | then create. Return the initialized session." | |
124 | (require 'cmuscheme) | |
125 | (unless (string= session "none") | |
126 | (let ((session-buffer (save-window-excursion | |
127 | (run-scheme org-babel-scheme-cmd) | |
128 | (rename-buffer session) | |
129 | (current-buffer)))) | |
130 | (if (org-babel-comint-buffer-livep session-buffer) | |
131 | (progn (sit-for .25) session-buffer) | |
132 | (sit-for .5) | |
133 | (org-babel-scheme-initiate-session session))))) | |
134 | ||
135 | (provide 'ob-scheme) | |
136 | ||
5b409b39 | 137 | |
afe98dfa CD |
138 | |
139 | ;;; ob-scheme.el ends here |