From mboxrd@z Thu Jan 1 00:00:00 1970 From: Eric Schulte Subject: Re: Babel support for the D language Date: Sun, 01 Dec 2013 07:13:49 -0700 Message-ID: <87bo10u09u.fsf@gmail.com> References: <52977819.6000901@free.fr> Mime-Version: 1.0 Content-Type: text/plain Return-path: Received: from eggs.gnu.org ([2001:4830:134:3::10]:46941) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Vn7nP-0001rw-6Z for emacs-orgmode@gnu.org; Sun, 01 Dec 2013 09:14:55 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Vn7nK-0007Hu-T7 for emacs-orgmode@gnu.org; Sun, 01 Dec 2013 09:14:51 -0500 Received: from mail-pd0-x22d.google.com ([2607:f8b0:400e:c02::22d]:65430) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Vn7nK-0007Ho-HO for emacs-orgmode@gnu.org; Sun, 01 Dec 2013 09:14:46 -0500 Received: by mail-pd0-f173.google.com with SMTP id p10so16437074pdj.32 for ; Sun, 01 Dec 2013 06:14:45 -0800 (PST) List-Id: "General discussions about Org-mode." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-orgmode-bounces+geo-emacs-orgmode=m.gmane.org@gnu.org Sender: emacs-orgmode-bounces+geo-emacs-orgmode=m.gmane.org@gnu.org To: Thierry Banel Cc: emacs-orgmode@gnu.org Hi Thierry, I've added ob-D.el to the contrib/lisp directory of Org-mode. Would it make sense to add D as a c-variant in ob-C.el? Thanks for the contribution, and for the documentation! Thierry Banel writes: > emacs-orgmode@gnu.org > > * Hi all Org fans. > > I added support in Org-Babel for executing Digital Mars D code. > This is derived from the code in ob-C.el, by Eric Schulte > (thanks Eric). > I release it under the same GPL license as Emacs and Org-mode. > > Comments and enhancements are welcome ! > > * Example. The following source block: > #+begin_src D > import std.stdio; > void main() > { > foreach (i; 0..9) > writefln ("i= %4d", i); > } > #+end_src > > will result in: > #+results: > : i= 0 > : i= 1 > : i= 2 > : i= 3 > : i= 4 > : i= 5 > : i= 6 > : i= 7 > : i= 8 > > * About Digital Mars D Language (http://dlang.org/) > D is (imo) quite an interesting language: > - C++ syntax > - Built-in garbage collector > - Strong type system > - Meta-programming > - Seamless assembler support > - Usable as a scripting language > - C binary compatibility > - and much more. > > * Installation: > - Install D > be sure to have the rdmd compiler in the path > - add ob-D.el in the lisp/org/ source tree > - in the org.el file, find a line which says: > (const :tag "C" C) > add a similar line for D: > (const :tag "D" D) > - byte-compile the 2 modified *.el > - customize the variable org-babel-load-languages enabling D > - either through M-x customize-variable > (you may need a restart of Emacs prior to customization) > - or in your .emacs > > -----8<----------(ob-D.el file to put in lisp/org/)----------->8-------- > ;;; ob-D.el --- org-babel functions for the D language > > ;; Copyright (C) 2013 Thierry Banel > > ;; Author: Thierry Banel, derived from the Eric Schulte work > ;; Keywords: literate programming, reproducible research > > ;; This file is NOT (yet) part of GNU Emacs. > > ;; ob-D.el is free software: you can redistribute it and/or modify > ;; it under the terms of the GNU General Public License as published by > ;; the Free Software Foundation, either version 3 of the License, or > ;; (at your option) any later version. > > ;; ob-D.el is distributed in the hope that it will be useful, > ;; but WITHOUT ANY WARRANTY; without even the implied warranty of > ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > ;; GNU General Public License for more details. > > ;; the GNU General Public License can be obtained here: > ;; . > > ;;; Commentary: > ;; Org-Babel support for evaluating Digital Mars D Language code. > ;; The D language home page is here: > ;; http://dlang.org/ > > ;;; Code: > (require 'ob) > (require 'ob-eval) > ;;(require 'd-mode) > > (declare-function org-entry-get "org" > (pom property &optional inherit literal-nil)) > > (defvar org-babel-tangle-lang-exts) > (add-to-list 'org-babel-tangle-lang-exts '("D" . "D")) > > (defvar org-babel-default-header-args:D '()) > > (defvar org-babel-D-compiler "rdmd" > "Command used to compile and run a D source code file into an > executable.") > > (defun org-babel-execute:D (body params) > "Execute a block of D code with org-babel. This function is > called by `org-babel-execute-src-block'." > (org-babel-D-execute body params)) > > (defun org-babel-D-execute (body params) > "This function should only be called by `org-babel-execute:D'" > (let* ((tmp-src-file (org-babel-temp-file "Dsrc" ".d")) > (cmdline (cdr (assoc :cmdline params))) > (flags (cdr (assoc :flags params))) > (rdmd (format "%s %s %s" > org-babel-D-compiler > (mapconcat 'identity > (if (listp flags) flags (list flags)) " ") > > ;; On Unix, keep directory separator > (org-babel-process-file-name tmp-src-file))) > > ;; On Windows, directory separator must be fixed > ;;(replace-regexp-in-string > ;; "/" "\\\\" > ;; (org-babel-process-file-name tmp-src-file)))) > > (full-body (org-babel-D-expand body params))) > (with-temp-file tmp-src-file (insert full-body)) > > ;; add path to D binaries if not already there > ;;(let ((bin "c:/DLang/dmd2/windows/bin;") > ;; (path (getenv "PATH"))) > ;; (unless (string-match bin path) > ;; (setenv "PATH" (concat bin path)))) > > (org-babel-eval rdmd ""))) > > (defun org-babel-D-expand (body params) > "Expand a block of D code with org-babel according to > its header arguments." > (let ((vars (mapcar #'cdr (org-babel-get-header params :var))) > (colname-names (cdr (car (org-babel-get-header params :colname-names)))) > (main-p (not (string= (cdr (assoc :main params)) "no"))) > (imports (mapcar #'cdr (org-babel-get-header params :import)))) > (mapconcat 'identity > (list > "module aaa;\n" > ;; imports > (mapconcat > (lambda (inc) (format "import %s;" inc)) > imports "\n") > ;; variables > (mapconcat 'org-babel-D-var-to-D vars "\n") > (mapconcat 'org-babel-D-colnames-to-D colname-names "\n") > ;; body > (if main-p > (org-babel-D-ensure-main-wrap body) > body) "\n") "\n"))) > > (defun org-babel-D-ensure-main-wrap (body) > "Wrap body in a \"main\" function call if none exists." > (if (string-match "^[ \t]*[intvod]+[ \t\n\r]*main[ \t]*(.*)" body) > body > (format "int main() {\n%s\nreturn(0);\n}\n" body))) > > (defun org-babel-prep-session:D (session params) > "This function does nothing as D is a compiled language with no > support for sessions" > (error "D is a compiled languages -- no support for sessions")) > > (defun org-babel-load-session:D (session body params) > "This function does nothing as D is a compiled language with no > support for sessions" > (error "D is a compiled languages -- no support for sessions")) > > ;; helper functions > > (defun org-babel-D-var-to-D (pair) > "Convert an elisp value into a string of D code specifying a variable > of the same value." > (let ((var (car pair)) > (val (cdr pair))) > (when (symbolp val) > (setq val (symbol-name val)) > (when (= (length val) 1) > (setq val (string-to-char val)))) > (cond > ((integerp val) > (format "int %S = %S;" var val)) > ((floatp val) > (format "double %S = %S;" var val)) > ((stringp val) > (format "string %S = \"%s\";" var val)) > ((listp val) > (if (assoc var colname-names) () > (setq colname-names > (cons (cons > var > (let ((i 0)) (mapcar (lambda (x) (setq i (1+ i)) (format > "$%s" i)) > (car val)))) > colname-names))) > (format "string[][] %S = [\n[%s]];" var > (mapconcat (lambda (row) > (if (listp row) > (mapconcat (lambda (v) (format "\"%s\"" v)) > row > ","))) > val > "],\n["))) > (t > (format "u32 %S = %S;" var val))))) > > (defun org-babel-D-colnames-to-D (pair) > "Convert an elisp list of header table into a D vector > specifying a variable with the name of the table" > (let ((table (car pair)) > (headers (cdr pair))) > (format "string[] %S_headers = [%s];" > table > (mapconcat (lambda (h) (format "%S" h)) headers ",")))) > > (provide 'ob-D) > > ;;; ob-D.el ends here > > -----8<----------(end of ob-D.el)----------->8-------- > > > -- Eric Schulte https://cs.unm.edu/~eschulte PGP: 0x614CA05D