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