A toy S-EXP (a particular flavor) to python transpiler in the spirit of sxc. The plan is to exploit the macro system of common lisp to emit plain python source (not vm bytecode). Most of the useful stuff will go as regular lisp macros.
For a practical python-lisp, see hy.
lake build
./bin/pigeon <input-file> <output-path>
(pgfmt
(import (numpy :as np))
(defun random (size)
(np.random.rand size size))
(defun some-key (a :key-arg 10)
(+ 1 1))
(setf a "hello")
(print a))
import numpy as np def random(size): return np.random.rand(size, size) def some_key(a, key_arg=10): return (1 + 1) a = "hello" print(a)
(pgfmt
t ;; True
f ;; False
none ;; None
(setf some-array #(1 2 3 5)) ;; lisp type vectors go as numpy array
(setf some-list [12 2 3]) ;; hy style lists go as python lists
(setf some-dict (dict "a" "world" "b" "hello"))
(setf some-tuple (tuple 1 2)))
True False None some_array = np.array([1, 2, 3, 5]) some_list = [12, 2, 3] some_dict = {"a": "world", "b": "hello"} some_tuple = (1, 2)
(pgfmt
(fn "lol kek")
(fn-xy (+ x y))
(fn-abc (+ a b (/ 2 c))))
(lambda : "lol kek") (lambda x, y: (x + y)) (lambda a, b, c: (a + b + (2 / c)))
(pgfmt
(cond ((this-thing) (then-that))
((another-thing) (another-that))
(t fallback)))
if this_thing(): then_that() elif another_thing(): another_that() else: fallback
(pgfmt @[(+ x x) :for x :in (range 10) :if (evenp x)])
[(x + x) for x in range(10) if evenp(x)]
(pgfmt
(with (open "this-thing")
(do-something))
(with (some-fn) :as k
(something-else k)))
with open("this-thing"): do_something() with some_fn() as k: something_else(k)
Pigeon uses usual lisp macros loaded from a .pgl
files using require
. Macro
expansion works on the pigeon code before converting to python.
(pgfmt
(require ./samples/macros))
# loaded extension from ./SAMPLES/MACROS
(pgfmt
(import numpy)
(import (kek :as lol) :from lel)
(import (this :as that) (who :as whom)))
import numpy from lel import kek as lol import this as that import who as whom
To use case sensitive python ids, use #i
reader macro:
(pgfmt
(setf #iTHisIsSick 343)
(import #iLastFm))
THisIsSick = 343 import LastFm
(pgfmt
(setf some-list @<[a for a in range(10)]>)
(defun a-fun (arg)
(compute arg)
@<
def something_in_python(a, b):
return a + b
>
(something-in-python 1 arg)))
some_list = [a for a in range(10)] def a_fun(arg): compute(arg) def something_in_python(a, b): return a + b return something_in_python(1, arg)