Lunatic Python

41 views
Skip to first unread message

sagasw

unread,
Aug 9, 2009, 8:59:45 PM8/9/09
to lu...@googlegroups.com

Lunatic Python is a two-way bridge between Python and Lua, allowing these languages to intercommunicate. Being two-way means that it allows Lua inside Python, Python inside Lua, Lua inside Python inside Lua, Python inside Lua inside Python, and so on.

Why?

Even though the project was born as an experiment, it's already being used in real world projects to integrate features from both languages.

Please, let me know if you use it in real world projects.

Examples

Lua inside Python

A basic example.

>>> import lua
>>> lg = lua.globals()
>>> lg.string
<Lua table at 0x81c6a10>
>>> lg.string.lower
<Lua function at 0x81c6b30>
>>> lg.string.lower("Hello world!")
'hello world!'

Now, let's put a local object into Lua space.

>>> d = {}
>>> lg.d = d
>>> lua.execute("d['key'] = 'value'")
>>> d
{'key': 'value'}

Can we get the reference back from Lua space?

>>> d2 = lua.eval("d")
>>> d is d2
True

Good! Is the python interface available inside the Lua interpreter?

>>> lua.eval("python")
<Lua table at 0x81c7540>

Yes, it looks so. Let's nest some evaluations and see a local reference passing through.

>>> class MyClass: pass
...
>>> obj = MyClass()
>>> obj
<__main__.MyClass instance at 0x403ccb4c>
>>> lua.eval(r"python.eval('lua.eval(\"python.eval(\'obj\')\")')")
<__main__.MyClass instance at 0x403ccb4c>

Are you still following me? :) Good. Then you've probably noticed that the Python interpreter state inside the Lua interpreter state is the same as the outside Python we're running. Let's see that in a more comfortable way.

>>> lua.execute("pg = python.globals()")
>>> lua.eval("pg.obj")
<__main__.MyClass instance at 0x403ccb4c>

Things get more interesting when we start to really mix Lua and Python code.

>>> table = lua.eval("table")
>>> def show(key, value):
... print "key is %s and value is %s" % (`key`, `value`)
...
>>> t = lua.eval("{a=1, b=2, c=3}")
>>> table.foreach(t, show)
key is 'a' and value is 1
key is 'c' and value is 3
key is 'b' and value is 2
>>>

Of course, in this case the same could be achieved easily with Python.

>>> def show(key, value):
... print "key is %s and value is %s" % (`key`, `value`)
...
>>> t = lua.eval("{a=1, b=2, c=3}")
>>> for k in t:
... show(k, t[k])
...
key is 'a' and value is 1
key is 'c' and value is 3
key is 'b' and value is 2

Python inside Lua

Now, let's have a look from another perspective. The basic idea is exactly the same.

> require("python")
> python.execute("import string")
> pg = python.globals()
> =pg.string
<module 'string' from '/usr/lib/python2.3/string.pyc'>
> =pg.string.lower("Hello world!")
hello world!

As Lua is mainly an embedding language, getting access to the batteries included in Python may be interesting.

> re = python.import("re")
> pattern = re.compile("^Hel(lo) world!")
> match = pattern.match("Hello world!")
> =match.group(1)
lo

Just like in the Python example, let's put a local object in Python space.

> d = {}
> pg.d = d
> python.execute("d['key'] = 'value'")
> table.foreach(d, print)
key value

Again, let's grab back the reference from Python space.

> d2 = python.eval("d")
> print(d == d2)
true

Is the Lua interface available to Python?

> =python.eval("lua")
<module 'lua' (built-in)>

Good. So let's do the nested trick in Lua as well.

> t = {}
> =t
table: 0x80fbdb8
> =python.eval("lua.eval('python.eval(\"lua.eval(\\'t\\')\")')")
table: 0x80fbdb8
>

It means that the Lua interpreter state inside the Python interpreter is the same as the outside Lua interpreter state. Let's show that in a more obvious way.

> python.execute("lg = lua.globals()")
> =python.eval("lg.t")
table: 0x80fbdb8

Now for the mixing example.

> function notthree(num)
>> return (num ~= 3)
>> end
> l = python.eval("[1, 2, 3, 4, 5]")
> filter = python.eval("filter")
> =filter(notthree, l)
[1, 2, 4, 5]
Reply all
Reply to author
Forward
0 new messages