From mboxrd@z Thu Jan 1 00:00:00 1970 From: Eric Schulte Subject: Re: [PATCH] ob-C: Add list support. Date: Thu, 06 Jun 2013 10:21:26 -0600 Message-ID: <87y5an5hx5.fsf@gmail.com> References: <3345834.7iimcA7jmY@descartes> Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Return-path: Received: from eggs.gnu.org ([2001:4830:134:3::10]:59857) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UkcxB-0004Mg-Tv for emacs-orgmode@gnu.org; Thu, 06 Jun 2013 12:22:28 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Ukcx6-00051e-MJ for emacs-orgmode@gnu.org; Thu, 06 Jun 2013 12:22:21 -0400 Received: from mail-pb0-x230.google.com ([2607:f8b0:400e:c01::230]:39075) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Ukcx6-000508-CX for emacs-orgmode@gnu.org; Thu, 06 Jun 2013 12:22:16 -0400 Received: by mail-pb0-f48.google.com with SMTP id md4so3454246pbc.21 for ; Thu, 06 Jun 2013 09:22:15 -0700 (PDT) In-Reply-To: <3345834.7iimcA7jmY@descartes> (=?utf-8?Q?=22R=C3=BCdiger?= Sonderfeld"'s message of "Wed, 05 Jun 2013 23:20:19 +0200") 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: =?utf-8?Q?R=C3=BCdiger?= Sonderfeld Cc: emacs-orgmode@gnu.org Hi R=C3=BCdiger, Thanks for sharing this patch. I looks great, however as it is >10 lines long to apply it we'll need you to sign the FSF papers. Please see the following page for more information. http://orgmode.org/worg/org-contribute.html Thanks, R=C3=BCdiger Sonderfeld writes: > * lisp/ob-C.el (org-babel-C-var-to-C): Add list support > (org-babel-C-val-to-C-list-type, org-babel-C-val-to-C-type, > org-babel-C-format-val): New functions. > (org-babel-C-ensure-main-wrap, org-babel-execute:C, > org-babel-execute:C++, rg-babel-execute:cpp, org-babel-C++-compiler, > org-babel-C-compiler): Improve docstring. > * testing/examples/ob-C-test.org (string_var): Add required std:: > (Array): Add missing ID. > (Matrix): Add tests for list support. > * testing/lisp/test-ob-C.el (ob-C/table): Test succeeds. > (ob-C/list-var, ob-C/vector-var, ob-C/list-list-var): Add tests for > list support. > > Signed-off-by: R=C3=BCdiger Sonderfeld > --- > lisp/ob-C.el | 98=20 > +++++++++++++++++++++++++++++++----------- > testing/examples/ob-C-test.org | 28 +++++++++++- > testing/lisp/test-ob-C.el | 20 ++++++++- > 3 files changed, 118 insertions(+), 28 deletions(-) > > diff --git a/lisp/ob-C.el b/lisp/ob-C.el > index b1e8a06..e9eec93 100644 > --- a/lisp/ob-C.el > +++ b/lisp/ob-C.el > @@ -44,24 +44,24 @@ (defvar org-babel-default-header-args:C '()) >=20=20 > (defvar org-babel-C-compiler "gcc" > "Command used to compile a C source code file into an > - executable.") > +executable.") >=20=20 > (defvar org-babel-C++-compiler "g++" > "Command used to compile a C++ source code file into an > - executable.") > +executable.") >=20=20 > (defvar org-babel-c-variant nil > "Internal variable used to hold which type of C (e.g. C or C++) > is currently being evaluated.") >=20=20 > (defun org-babel-execute:cpp (body params) > - "Execute BODY according to PARAMS. This function calls > -`org-babel-execute:C++'." > + "Execute BODY according to PARAMS. > +This function calls `org-babel-execute:C++'." > (org-babel-execute:C++ body params)) >=20=20 > (defun org-babel-execute:C++ (body params) > - "Execute a block of C++ code with org-babel. This function is > -called by `org-babel-execute-src-block'." > + "Execute a block of C++ code with org-babel. > +This function is called by `org-babel-execute-src-block'." > (let ((org-babel-c-variant 'cpp)) (org-babel-C-execute body params))) >=20=20 > (defun org-babel-expand-body:C++ (body params) > @@ -70,8 +70,8 @@ (defun org-babel-expand-body:C++ (body params) > (let ((org-babel-c-variant 'cpp)) (org-babel-C-expand body params))) >=20=20 > (defun org-babel-execute:C (body params) > - "Execute a block of C code with org-babel. This function is > -called by `org-babel-execute-src-block'." > + "Execute a block of C code with org-babel. > +This function is called by `org-babel-execute-src-block'." > (let ((org-babel-c-variant 'c)) (org-babel-C-execute body params))) >=20=20 > (defun org-babel-expand-body:c (body params) > @@ -146,10 +146,10 @@ (defun org-babel-C-expand (body params) > body) "\n") "\n"))) >=20=20 > (defun org-babel-C-ensure-main-wrap (body) > - "Wrap body in a \"main\" function call if none exists." > + "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))) > + (format "int main() {\n%s\nreturn 0;\n}\n" body))) >=20=20 > (defun org-babel-prep-session:C (session params) > "This function does nothing as C is a compiled language with no > @@ -163,6 +163,59 @@ (defun org-babel-load-session:C (session body params) >=20=20 > ;; helper functions >=20=20 > +(defun org-babel-C-format-val (type val) > + "Handle the FORMAT part of TYPE with the data from VAL." > + (let ((format-data (cadr type))) > + (if (stringp format-data) > + (cons "" (format format-data val)) > + (funcall format-data val)))) > + > +(defun org-babel-C-val-to-C-type (val) > + "Determine the type of VAL. > +Return a list (TYPE-NAME FORMAT). TYPE-NAME should be the name of the t= ype. > +FORMAT can be either a format string or a function which is called with = VAL." > + (cond > + ((integerp val) '("int" "%d")) > + ((floatp val) '("double" "%f")) > + ((or (listp val) (vectorp val)) > + (lexical-let ((type (org-babel-C-val-to-C-list-type val))) > + (list (car type) > + (lambda (val) > + (cons > + (format "[%d]%s" > + (length val) > + (car (org-babel-C-format-val type (elt val 0)))) > + (concat "{ " > + (mapconcat (lambda (v) > + (cdr (org-babel-C-format-val type v))) > + val > + ", ") > + " }")))))) > + (t ;; treat unknown types as string > + '("char" (lambda (val) > + (let ((s (format "%s" val))) ;; convert to string for unknown ty= pes > + (cons (format "[%d]" (1+ (length s))) > + (concat "\"" s "\"")))))))) > + > +(defun org-babel-C-val-to-C-list-type (val) > + "Determine the C array type of a VAL." > + (let (type) > + (mapc > + #'(lambda (i) > + (let* ((tmp-type (org-babel-C-val-to-C-type i)) > + (type-name (car type)) > + (tmp-type-name (car tmp-type))) > + (when (and type (not (string=3D type-name tmp-type-name))) > + (if (and (member type-name '("int" "double" "int32_t")) > + (member tmp-type-name '("int" "double" "int32_t"))) > + (setq tmp-type '("double" "" "%f")) > + (error "Only homogeneous lists are supported by C. You can not = mix=20 > %s and %s" > + type-name > + tmp-type-name))) > + (setq type tmp-type))) > + val) > + type)) > + > (defun org-babel-C-var-to-C (pair) > "Convert an elisp val into a string of C code specifying a var > of the same value." > @@ -173,22 +226,17 @@ (defun org-babel-C-var-to-C (pair) > (setq val (symbol-name val)) > (when (=3D (length val) 1) > (setq val (string-to-char val)))) > - (cond > - ((integerp val) > - (format "int %S =3D %S;" var val)) > - ((floatp val) > - (format "double %S =3D %S;" var val)) > - ((or (integerp val)) > - (format "char %S =3D '%S';" var val)) > - ((stringp val) > - (format "char %S[%d] =3D \"%s\";" > - var (+ 1 (length val)) val)) > - (t > - (format "u32 %S =3D %S;" var val))))) > - > + (let* ((type-data (org-babel-C-val-to-C-type val)) > + (type (car type-data)) > + (formated (org-babel-C-format-val type-data val)) > + (suffix (car formated)) > + (data (cdr formated))) > + (format "%s %s%s =3D %s;" > + type > + var > + suffix > + data)))) >=20=20 > (provide 'ob-C) >=20=20 > - > - > ;;; ob-C.el ends here > diff --git a/testing/examples/ob-C-test.org b/testing/examples/ob-C-test.= org > index 32ab88b..1d0a83f 100644 > --- a/testing/examples/ob-C-test.org > +++ b/testing/examples/ob-C-test.org > @@ -24,7 +24,7 @@ * Simple tests >=20=20 > #+source: string_var > #+begin_src cpp :var q=3D"word" :includes '( ) :resul= ts=20 > silent > - std::cout << q << ' ' << strlen(q); > + std::cout << q << ' ' << std::strlen(q); > return 0; > #+end_src >=20=20 > @@ -35,6 +35,9 @@ * Simple tests > #+end_src >=20=20 > * Array > + :PROPERTIES: > + :ID: 2df1ab83-3fa3-462a-a1f3-3aef6044a874 > + :END: > #+source: array > #+begin_src cpp :includes "" :results vector :results silent > for (int i=3D1; i<3; i++) { > @@ -42,3 +45,26 @@ * Array > } > return 0; > #+end_src > +* Matrix > + :PROPERTIES: > + :ID: cc65d6b3-8e8e-4f9c-94cd-f5a00cdeceb5 > + :END: > +#+name: C-matrix > +| 1 | 2 | > +| 3 | 4 | > + > +#+source: list_var > +#+begin_src cpp :var a=3D'("abc" "def") :includes "" :results = silent > + std::cout << a[0] << a[1] << sizeof(a)/sizeof(*a) << '\n'; > +#+end_src > + > +#+source: vector_var > +#+begin_src cpp :var a=3D'[1 2] :includes "" :results silent > + std::cout << a[0] << a[1] << sizeof(a)/sizeof(*a) << '\n'; > +#+end_src > + > +#+source: list_list_var > +#+begin_src cpp :var q=3DC-matrix :includes "" :results silent > + std::cout << q[0][0] << ' ' << q[1][0] << '\n' > + << q[0][1] << ' ' << q[1][1] << '\n'; // transpose > +#+end_src > diff --git a/testing/lisp/test-ob-C.el b/testing/lisp/test-ob-C.el > index 4243bb6..4430ceb 100644 > --- a/testing/lisp/test-ob-C.el > +++ b/testing/lisp/test-ob-C.el > @@ -57,10 +57,26 @@ (ert-deftest ob-C/preprocessor () >=20=20 > (ert-deftest ob-C/table () > "Test of a table output" > - :expected-result :failed > (org-test-at-id "2df1ab83-3fa3-462a-a1f3-3aef6044a874" > (org-babel-next-src-block) > (should (equal '((1) (2)) (org-babel-execute-src-block))))) >=20=20 > +(ert-deftest ob-C/list-var () > +"Test of a list input variable" > + (org-test-at-id "cc65d6b3-8e8e-4f9c-94cd-f5a00cdeceb5" > + (org-babel-next-src-block 1) > + (should (string=3D "abcdef2" (org-babel-execute-src-block))))) > + > +(ert-deftest ob-C/vector-var () > +"Test of a vector input variable" > + (org-test-at-id "cc65d6b3-8e8e-4f9c-94cd-f5a00cdeceb5" > + (org-babel-next-src-block 2) > + (should (equal 122 (org-babel-execute-src-block))))) > + > +(ert-deftest ob-C/list-list-var () > + "Test of a list list input variable" > + (org-test-at-id "cc65d6b3-8e8e-4f9c-94cd-f5a00cdeceb5" > + (org-babel-next-src-block 3) > + (should (equal '((1 3) (2 4)) (org-babel-execute-src-block))))) > + > ;;; test-ob-C.el ends here > -=20 --=20 Eric Schulte http://cs.unm.edu/~eschulte