Documentation: Alien access to a tcl interpreter

This page provides an example of using the CMUCL foreign function interface to call a Tcl interpreter.

This is a naive way of calling out to Tcl; it wouldn't be much more complicated to bind to a persistent interpreter to avoid instance creation overhead on each call to EVAL-IN-TCL.

;;; Evaluate (alien:load-foreign "/usr/lib/libtcl8.0.so") before
;;; compiling or loading this file.

(in-package :CL-USER)

(alien:def-alien-type tcl-interp (* t))

(declaim (inline tcl-createinterp))
(alien:def-alien-routine "Tcl_CreateInterp" tcl-interp)

(declaim (inline tcl-eval))
(alien:def-alien-routine "Tcl_Eval" c-call:int
  (interp tcl-interp :in)
  (string c-call:c-string :in))

(declaim (inline tcl-getstringresult))
(alien:def-alien-routine "Tcl_GetStringResult" c-call:c-string
  (interp tcl-interp :in))

(declaim (inline tcl-deleteinterp))
(alien:def-alien-routine "Tcl_DeleteInterp" c-call:void
  (interp tcl-interp :in))

(defun eval-in-tcl (string)
  (let ((inter (tcl-createinterp)))
    (unwind-protect
         (let* ((result-code (tcl-eval inter string))
                (result-string (tcl-getstringresult inter)))
           (values result-code (copy-seq result-string)))
      (tcl-deleteinterp inter))))

Once you have loaded the code, you can evaluate expressions in Tcl from CMUCL as follows:

USER> (eval-in-tcl "puts [expr 2 + 3]")
5

0
""

This description is adapted from an article <87ya8j77df.fsf@orion.dent.isdn.cs.tu-berlin.de> posted to the USENET group comp.lang.lisp on 2000-02-18 by Pierre Mai.