6.5 Bridging with Python - naver/lispe GitHub Wiki

Python

Version française

LispE provides a bridge with Python3 through a specific dynamic library: pylispe.

This library acts as a double direction library. In other words:

  • You can execute LispE code in a Python program
  • You can execute Python code in a LispE program

Compiling

To compile the right version of pylispe.so on your machine, you need first to run: python checklib.py.

This command will explore your library directory to find out about the current Python 3 installation on your machine.

If none is found, you can still have a look in Makefile.in, which might contains the following lines:

INCLUDEPYTHON = -I/usr/include
PYTHONLIB = /usr/lib64/python3

The /usr/include and /usr/lib64/python3 are given as examples. If these paths do not match your actual installation, you can modify them to connect with your own version of Python3.

To compile this version, go to the following directory: pythonlispe and run make all

Executing some LispE code in Python

The pylispe library exposes the following Python methods:


import pylispe

lisp = pylispe.lisp() # this method creates a LispE interpreter

# this method loads a LispE program
lisp.load(filename) 

# this method evaluates a LispE program given as a string
lisp.eval('...') 

# this method executes a LispE function with p1...p2 as parameters.
r = lisp.execute("function", p1, p2...) 

Important: since LispE distingues between atoms and strings, strings should be provided with double-quote inside: '"string"'. However, if this string contains non alphabetical characters, it is automatically considered as a string and not an atom:

Example


r = lisp.execute("function", "a", '"a"', 'this is a test')

"function"       is an atom
"a"              is an atom
'"a"'            is a string
'this is a test' cannot be an atom and hence is a string

Example

First the LispE code:

; First this is the code that will be loaded in Python: called_in_python.lisp 

(defun mult(x y) (* x y))

(defun add(x y) (+ x y))

Then the Python code:

# This code executes some LispE code within Python

import pylispe

# we create a lisp interpreter
a=pylispe.lisp()

# We load the current file

print(a.load("called_in_python.lisp"))

# an evaluation
print(a.eval("(setq d 10)"))


# We can actually call an instruction or an operator directly
# Note the '".."' structure to pass strings to LispE, while
# atoms are passed as simple strings: the 'd' is the atom
# that was created above in the 'setq' instruction
print(a.execute("+", '"test"', 'd'))

# We can also use the add function that has been implemented in called.lisp
# The 'd' is again the one that was declared above with the value 10


print(a.execute("add", "d", 31.654))

Execute some Python code in LispE

The pylispe library exposes the following LispE instructions:


; How to load the library 
; (do not forget to set: LISPEPATH to the actual path where the library is)
(use "pylispe")

; creates a Python interpreter through which all interactions
; with Python will be processed.
; NOTE THAT WE STORE THIS INTERPRETER IN A VARIABLE: py, 
; which we use in the rest of the instructions. 
; Of course 'py' is given here as an example...
(setq py (python)) 

; executes some Python code
(python_run py code) 

; adds a path to the list of valid paths to Python libraries
(python_setpath py path) 

; loads a Python library
(python_import py filename) 

; executes a function with a list of arguments.
(python_execute py funcname arguments) 

Loading and Executing Python code

This is an example of how Python can be executed from within LispE

First our Python code:


# A simple function

def testing(i):
   return i+10

Then our LispE code:

(use 'pylispe)

; we create a python intepreter
(setq py (python))

; We set a path to the current directory
; where our Python program is...
; _current is the directory where this LispE program is stored
(python_setpath py _current)

;We load a python program
(python_import py "called_in_lispe")

; We execute the function loaded with the program
(println (python_execute py "testing" '(20)))

Example 2

This other example shows how python_run is used:

(use 'pylispe)

; we create a python intepreter
(setq py (python))

; We execute some code
(python_run py "i = 100 + 20")
(python_run py "print('Within:',i)")

; We define a Python function
; as a LispE string
(setq myFunc
`def toto(i):
   return i+10;
`
)

; we store our function definition
(python_run py myFunc)

; which we can execute and retrieve a result from it
(println (python_execute py "toto" '(21)))

; Another way to do it is to use a macro:
(defmacro toto(v) (python_execute py "toto" (list v)))

(println (toto 21))