There are those who will tell you that LISP is an acronnym for LISt Processor and others who insist that it stands for Lots of Infuriantingly Silly Parenthesis.
--- R. Jones, C. Maynard, I. Stewart, "The Art of Lisp Programming"
Because Python's list comprehensions are Turing complete (Japanese article, the proof as implementation of brainfxxk), we can implement everything on list comprehensions, off course LISP, as you wish.
This is an implementation of LISP, and this is wrote as a Python's list comprehension.
- python 3.x
$ python3 <(curl -sL https://raw.githubusercontent.com/t-sin/lisc/master/lisc.py)
> (cons (quote a) nil)
(a)
> (eq (quote a) nil)
nil
> (eq () nil)
t
> (define val (quote foo))
foo
> (if (eq val bar) (quote true) (quote false))
false
> ((lambda (a) (quote lisp)) t)
lisp
We can treat strings, especially input/output.
> "some string"
'some string'
> (reads "input> ")
input> test string
'test string'
> (prints "output!")
output!
nil
> (heads "test")
't'
> (tails "test")
'est'
Reversing a list with recursion and list operation.
> (define -reverse-rec (lambda (lis rev) (if (eq lis nil) rev (-reverse-rec (cdr lis) (cons (car lis) rev)))))
[lambda ['lis', 'rev'] <function <listcomp>.<lambda>.<locals>.<lambda> at 0x7f8052332ea0>]
> (define reverse (lambda (lis) (-reverse-rec lis nil)))
[lambda ['lis'] <function <listcomp>.<lambda>.<locals>.<lambda> at 0x7f8052356048>]
> (reverse (quote (1 2 3 4 5)))
(5 4 3 2 1)
LISC can run programs in file.
$ cat examples/reverse.l
(define _reverse
(lambda (lis rev)
(if (eq lis nil)
rev
(_reverse (cdr lis) (cons (car lis) rev)))))
(define reverse
(lambda (lis) (_reverse lis nil)))
$ python3 lisc.py
> (load "examples/reverse.l")
...
> (reverse (quote (1 2 3 4 5)))
(5 4 3 2 1)
Of cource, now we can implement the meta-circular evaluator.
> (load "examples/lisc.l")
[lambda ['form'] <fn 139990349635096>]
> (eval (quote (define fn (lambda (a b) (cons a (cons b nil))))))
...
> (eval (quote (fn (quote foo) (quote bar))))
(foo bar)
For details, see lisc.l.
- load programs from stdin/files
- string type
- input/output string
- Foreign Function Interfaces against Python
For restriction of list comprehension, some LISC's behaviours are felt little strange.
- Conses are represented as a Python's lists
- therefore, behaviours of
cons
,car
andcdr
are different from Pure LISP little a bit cons
behaves like Clojure's one
- therefore, behaviours of
- Errors are returned as a normal value like
__*__
- because raising and excepting exception are statements, not expression
- lisc.py -- interpreter as a single list comprehension
- lisc_parts.py -- interpreter as several parts, such as parser, evaluator, printer etc...
- lisc_ref.py -- base and reference implementation of pure LISP
LISC is licensed under the GNU General Public License version 3. But example codes (examples/*.l
) are public domain.