This post originated from an RSS feed registered with Python Buzz
by Andrew Dalke.
Original Post: LOLPython
Feed Title: Andrew Dalke's writings
Feed URL: http://www.dalkescientific.com/writings/diary/diary-rss.xml
Feed Description: Writings from the software side of bioinformatics and chemical informatics, with a heaping of Python thrown in for good measure.
Example code to generate all Fibonacci numbers less than a given value
of N. Max value is 100 if N is not given on the command line. Idea
derives from original lolcode implementation by Kieran O'Niell.
IN MAI datetime GIMME date LIKE DATE
SO IM LIKE FIBBING WIT N OK?
LOL ITERATE FIBONACCI TERMS LESS THAN N /LOL
SO GOOD N BIG LIKE EASTERBUNNY
BTW, FIBONACCI LIKE BUNNIES! LOL
U BORROW CHEEZBURGER
U BORROW CHEEZBURGER
I CAN HAZ CHEEZBURGER
HE CAN HAZ CHEEZBURGER
WHILE I CUTE?
I AND HE CAN HAZ HE AND I ALONG WITH HE
IZ HE BIG LIKE N?
KTHXBYE
U BORROW HE
IZ __name__ KINDA LIKE "__main__"?
COMPLAIN "NOW IZ" AND DATE OWN today THING
IZ BIGNESS ARGZ OK KINDA LIKE 1?
N CAN HAS 100
NOPE?
N CAN HAS NUMBR ARGZ LOOK AT 1!!
GIMME EACH I IN UR FIBBING WIT N OK?
VISIBLE I
and in action (you must first install the most excellent PLY package):
It works by coverting the LOLPython code into Python. The converted
Fibonacci in Python is:
# LOLPython to Python converter version 1.0
# Written by Andrew Dalke, who should have been working on better things.
# sys is used for COMPLAIN and ARGZ
import sys as _lol_sys
from datetime import date as DATE
def FIBBING ( N ) :
'ITERATE FIBONACCI TERMS LESS THAN N'
assert N >= 0
# BTW, FIBONACCI LIKE BUNNIES! LOL
yield 1
yield 1
I = 1
HE = 1
while 1:
I , HE = HE , I + HE
if HE >= N :
break
yield HE
if __name__ == '__main__' :
print >>_lol_sys.stderr, 'NOW IZ' , DATE . today ()
if len(_lol_sys.argv) == 1 :
N = 100
else :
N = int(_lol_sys.argv[ 1 ])
for I in FIBBING ( N ) :
print I
# The end.
Like all modern software should, LOLPython has unit
tests.
% python lolpython.pyloltests.lol
UNIT TESTS R LEET!
READYSETGO!!!
...........
----------------------------------------------------------------------
Ran 11 tests in 0.001s
OK
Import, classes, iterators, generators, exceptions, comparison,
operators .. most of Python is supported by LOLPython. Not
everything, so free free to add the rest. It's in the public
domain so you can do whatever you want. Just don't complain
if/when it doesn't work. I am a consultant so if you want to
pay me to maintain it, let me know :) .
Translate a program from stdin into Python on stdout
% echo "COMPLAIN 'HAI WORLD!'" | python lolpython.py --convert
# LOLPython to Python converter version 1.0
# Written by Andrew Dalke, who should have been working on better things.
# sys is used for COMPLAIN and ARGZ
import sys as _lol_sys
print >>_lol_sys.stderr, 'HAI WORLD!'
# The end.
Specify the LOLPython program filename on the command line
% cat count_letters.lol
LETTERZ CAN HAS INVISIBLE BUCKET
F CAN HAS open WIT "count_letters.lol"!
S CAN HAS F OWN read THING
GIMME EACH C IN THE S?
N CAN HAS LETTERZ OWN get WIT C AND 0! ALONG WITH CHEEZBURGER
LETTERZ LET THE C OK CAN HAS N
GIMME EACH C IN THE sorted WIT LETTERZ OK?
VISIBLE repr WIT C! AND LETTERZ LOOK AT C!
% python lolpython.pycount_letters.lol | head
'\n' 8
' ' 67
'!' 4
'"' 2
'.' 1
'0' 1
'?' 2
'A' 16
'B' 4
'C' 15
Translate one or more LOLPython program files into Python files
% python lolpython.py --convert count_letters.lol
% cat count_letters.py
# LOLPython to Python converter version 1.0
# Written by Andrew Dalke, who should have been working on better things.
# sys is used for COMPLAIN and ARGZ
import sys as _lol_sys
LETTERZ = {}
F = open ( 'count_letters.lol' )
S = F . read ()
for C in S :
N = LETTERZ . get ( C , 0 ) + 1
LETTERZ [ C ] = N
for C in sorted ( LETTERZ ) :
print repr ( C ) , LETTERZ [ C ]
# The end.
Implementation
I started with the GardenSnake
parser I wrote last year, because it could handle Python's indentation
grammar. Pulled out the parser component so there's only a lexer.
The converter is quite simple. It reads the LOLPython tokens and
converts each one to Python code. The only hard part is that "!" or
"OK" act as close ")", "}" or "]" to match whichever was the most
recent opening form.
Indeed, you could say that LOLPython is a Python macro. But then
the Lisp people might get mad at me.
I take it back. The hard part was figuring out the LOLPython
grammar so it would be reasonably cute and cover most of Python.
Future
Ha! Ha-ha-ha-ha! I've had enough with this project. But if you want
to make changes, go ahead. Some thoughts: improved error reporting,
preserve original indentation, finish support for all of Python, add
an import hook for ".lol" files, add missing unit tests, improve the
grammar, fix predecence bugs (like "AINT GOOD" -> "assert not" where
the "not" doesn't have the right strength), and write a converter from
Python to LOLPython.