config

Personal configuration.
git clone git://code.dwrz.net/config
Log | Files | Refs

ob-forth.el (3203B)


      1 ;;; ob-forth.el --- Babel Functions for Forth        -*- lexical-binding: t; -*-
      2 
      3 ;; Copyright (C) 2014-2024 Free Software Foundation, Inc.
      4 
      5 ;; Author: Eric Schulte
      6 ;; Keywords: literate programming, reproducible research, forth
      7 ;; URL: https://orgmode.org
      8 
      9 ;; This file is part of GNU Emacs.
     10 
     11 ;; GNU Emacs is free software: you can redistribute it and/or modify
     12 ;; it under the terms of the GNU General Public License as published by
     13 ;; the Free Software Foundation, either version 3 of the License, or
     14 ;; (at your option) any later version.
     15 
     16 ;; GNU Emacs is distributed in the hope that it will be useful,
     17 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
     18 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     19 ;; GNU General Public License for more details.
     20 
     21 ;; You should have received a copy of the GNU General Public License
     22 ;; along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.
     23 
     24 ;;; Commentary:
     25 
     26 ;; Requires the gforth forth compiler and `forth-mode' (see below).
     27 ;; https://www.gnu.org/software/gforth/
     28 
     29 ;;; Requirements:
     30 
     31 ;; Session evaluation requires the gforth forth compiler as well as
     32 ;; `forth-mode' which is distributed with gforth (in gforth.el).
     33 
     34 ;;; Code:
     35 
     36 (require 'org-macs)
     37 (org-assert-version)
     38 
     39 (require 'ob)
     40 (require 'org-macs)
     41 
     42 (declare-function forth-proc "ext:gforth" ())
     43 
     44 (defvar org-babel-default-header-args:forth '((:session . "yes"))
     45   "Default header arguments for forth code blocks.")
     46 
     47 (defun org-babel-execute:forth (body params)
     48   "Execute Forth BODY according to PARAMS.
     49 This function is called by `org-babel-execute-src-block'."
     50   (if (string= "none" (cdr (assq :session params)))
     51       (error "Non-session evaluation not supported for Forth code blocks")
     52     (let ((all-results (org-babel-forth-session-execute body params)))
     53       (if (member "output" (cdr (assq :result-params params)))
     54 	  (mapconcat #'identity all-results "\n")
     55 	(car (last all-results))))))
     56 
     57 (defun org-babel-forth-session-execute (body params)
     58   "Execute Forth BODY in session defined via PARAMS."
     59   (org-require-package 'forth-mode)
     60   (let ((proc (forth-proc))
     61 	(rx " \\(\n:\\|compiled\n\\|ok\n\\)")
     62 	(result-start))
     63     (with-current-buffer (process-buffer (forth-proc))
     64       (mapcar (lambda (line)
     65 		(setq result-start (progn (goto-char (process-mark proc))
     66 					  (point)))
     67 		(comint-send-string proc (concat line "\n"))
     68 		;; wait for forth to say "ok"
     69 		(while (not (progn (goto-char result-start)
     70 				   (re-search-forward rx nil t)))
     71 		  (accept-process-output proc 0.01))
     72 		(let ((case (match-string 1)))
     73 		  (cond
     74 		   ((string= "ok\n" case)
     75 		    ;; Collect intermediate output.
     76 		    (buffer-substring (+ result-start 1 (length line))
     77 				      (match-beginning 0)))
     78 		   ((string= "compiled\n" case))
     79 		   ;; Ignore partial compilation.
     80 		   ((string= "\n:" case)
     81 		    ;; Report errors.
     82 		    (org-babel-eval-error-notify 1
     83 		                                 (buffer-substring
     84 		                                  (+ (match-beginning 0) 1) (point-max)))
     85 		    nil))))
     86 	      (split-string (org-trim
     87 			     (org-babel-expand-body:generic body params))
     88 			    "\n"
     89 			    'omit-nulls)))))
     90 
     91 (provide 'ob-forth)
     92 
     93 ;;; ob-forth.el ends here