For reasons I'll save for a later post, I've been meaning to implement a solid piece of software in LOLCODE. This is all good and well — a reasonable joke in and of itself — with exception to the fact that none of the existing parsers (that I found) were up to par for serious use. They made excellent, if buggy, imperative interpreters for simple scripts, but lacked the oomph to, say, calculate a recursive function.
Enter YALI. To stick with good computer concept nomenclature, you've got two options on this one: Yet Another LOLCODE Interpreter, or YALI: Another LOLCODE Interpreter, but I prefer the former (recursive acronyms are so 1990s).
YALI is implemented mostly up through LOLCODE spec 1.2, probably with a few caveats. It is a Perl-based interpreter, using the beautiful Parse::RecDescent module, and is based (loosely) off of original work by Joe Drago. Notably, since YALI is an interpreted language running on top of an interpreted language (at work, we refer to it simply as “Double-VMed”), it can get really bogged down with too much code or too many variables.
YALI is my first venture into language implementation — if using Perl even allows me to call it that — so be gentle.
Although YALI adheres closely to LOLCODE spec 1.2, it's probably best to call out all available keywords, since some changes have definitely been made.
Unless otherwise stated, all statements must be delimited by newlines.
HAI...KTHXBYE
IZ [comparator] O RLY? ... KTHX
[comparator]
; if true, jumps to YA RLY
statement, otherwise to NO WAI
statement (only one of which is necessary).IZ [comparator] ? [action]
YA RLY
is implicit and newlines are not permitted.IM IN YR [loop label] ... KTHX
GTFO
DIAF [function]
function
, print result to STDOUT
, and exit.OBTW ... TLDR
OBTW
and TLDR
need to be on their own lines.BTW ...
I HAS A [variable] [ITZ [function]]
variable
. With ITZ
declaration, assigns the result of function
to variable
.LOL [variable] R [function]
function
to variable
; barfs if variable
has not been declared.VISIBLE [pipe] [variable][!]
variable
to pipe
, defaulting to STDOUT
if pipe
is not declared. With !
, does not print newline.UP [variable]!![amount]
variable
. If amout
is present (and a series of digits), increments by amount
instead of 1.[formula] BIGR THAN [formula]
IZ
statements.[formula] SMALR THAN [formula]
IZ
statements.[formula] LIEK [formula]
IZ
statements. Returns value equivalence for values, strict equivalence for references.[variable] SORTA [string list]
variable
against string list
as a (Perl) regular expression. If capturing groups are used, the results are available through SORTA [digits]
.GIMMEH [LINEZ|LINE|WURD|LETTAR|NUMBR] [variable] [OUTTA [source]]
source
, defaulting to STDIN
. LINEZ
should be used only for file IO and sockets. source
is a file descriptor, either local or a URL, which will load all at once. In this case, if LINEZ
is the selected option, will return an array of results.DO NOT WANTZ [variable]
variable
; presently deprecated.HOW DUZ I [function name] [YR [variable name] [AN YR [variable name] [...]]] ... IF U SAY SO
FOUND YR [function]
function
and returns its result, breaking from all necessary loops in the process.MEBBE [function1] MEBBE [function2]
function1
and function2
, inclusive.ALL [variable]
variable
, taken as an array.TYEP [variable]
ARRAY
or VALUE
, as appropriate for variable
.General syntax out of the way, here are the definitions for a few key terms:
variable name
: a variable identifier; anything matching /[a-z][a-z0-9_]*/i
is valid.variable
: [[...] [formula] IN MAH] [variable name]
. Numbers prefixing the variable name are taken as array indices in reverse order; also, possibly a determined value: a string or number.digits
: a string of numbers, 0-9 (a natural number).number
: any possibly-floating point value; scientific notation is not allowed.string
: "..."
string list
: variable [N variable [...]]
concatenates values to form a single string.formula
: a straight variable name; possibly formula [UP|NERF|TIEMZ|OVARZ|BOOMZ] [(] formula [)]
(you can probably figure out what the operators are). If a number is used in a formula, it must be the last entry (see bug list).function
: [variable name] [YR [variable] [AN YR [variable] [...]]] MKAY
. Evaluates the function named [variable name]
on the supplied parameters (overloading is not permitted). To pass formula and function values to a function, first pass to a variable and then pass to the function.Last but not least, a note on value versus reference. In YALI, all variables may be either values or arrays; consider values as leaf nodes, and arrays as branches. When a leaf node is passed to a function, it is passed by value; when a branching node is passed to a function, it is passed by reference. To pass a value by reference, use LOL 0 IN MAH array R value
and pass the array instead. You cannot pass an array by value, but you can possibly rebuild a copy yourself.
Like the rest of you, I learn poorly from documentation and excellently from examples. So here we go.
HAI
BTW Hello, world!
VISIBLE "Hello, " N "world!"
KTHXBYE
Aww, memories.
HAI
BTW Cheater's quine
I HAS A quine
GIMMEH LINEZ quine OUTTA "quine.lol"
I HAS A loop_max ITZ ALL quine
I HAS A loop_index ITZ 0
IM IN YR loop
IZ loop_index LIEK loop_max O RLY?
YA RLY
GTFO
KTHX
VISIBLE loop_index IN MAH quine
UP loop_index!!
KTHX
KTHXBYE
It's a cheater's quine since it's just reading its own source code and printing it out. Nothing algorithmically intriguing here, but it's a good introduction to basic syntax usage.
HAI
OBTW
Naive Fibonacci, with no caching
TLDR
HOW DUZ I fibonacci YR index
IZ index SMALR THAN 2 ? FOUND YR 1
LOL index R index NERF 1
I HAS A fibs_left ITZ fibonacci YR index MKAY
LOL index R index NERF 1
I HAS A fibs_right ITZ fibonacci YR index MKAY
FOUND YR fibs_left UP fibs_right
IF U SAY SO
I HAS A index
VISIBLE "Watnz numbr: "!
GIMMEH NUMBR index
I HAS A fibs ITZ fibonacci YR index MKAY
VISIBLE index N " fibs r " N fibs
KTHXBYE
A simple Fibonacci sequence generator (when given an index).
HAI
OBTW
join
Basic array join.
TLDR
HOW DUZ I join YR a AN YR b
I HAS A count ITZ ALL a
LOL count R count NERF 1
IZ count SMALR THAN 0 ? FOUND YR ""
I HAS A output ITZ ""
IM IN YR LOOP
LOL output R count IN MAH a N output
IZ count BIGR THAN 0 ? LOL output R b N output
IZ count LIEK 0 ? GTFO
LOL count R count NERF 1
KTHX
FOUND YR output
IF U SAY SO
OBTW
mapMult
Toy function to demonstrate pass-by-reference.
TLDR
HOW DUZ I mapMult YR array AN YR factor
I HAS A index ITZ 0
I HAS A array_lemf ITZ ALL array
IM IN YR loop
IZ index LIEK array_lemf ? GTFO
LOL index IN MAH array R index IN MAH array TIEMZ factor
UP index!!
KTHX
IF U SAY SO
I HAS A array
I HAS A array_lemf ITZ 10
I HAS A current_lemf
IM IN YR loop
LOL current_lemf R ALL array
IZ current_lemf LIEK array_lemf ? GTFO
LOL current_lemf IN MAH array R MEBBE 1 MEBBE array_lemf
KTHX
I HAS A array_join ITZ join YR array AN YR "\n" MKAY
VISIBLE "Before:\n" N array_join
I HAS A NUFN ITZ mapMult YR array AN YR 3 MKAY
LOL array_join R join YR array AN YR "\n" MKAY
VISIBLE "\n\nAfter:\n" N array_join
KTHXBYE
Just a quick toy demonstration of reference versus value.
A much more detailed, specific, practical, and complete example will follow shortly — there had to be some reason for me to implement this.
Sadly, the YALI implementation is imperfect. A quick list of pertinent bugs follows:
TYEP
should be able to return N00B
, or undef
.NOT LIEK
is broken.Frankly, those are probably ordered in terms of difficulty to fix (the first item being the most difficult). If you want to attack them, head from the bottom up.
Update 2008-09-20:
Alex Klink has been kind enough to discover and patch a bug in variable filenames in GIMMEH
. The newest version of YALI is available here: download YALI1.1!
Thanks, Alex!
If you find errors in any of the above, please let me know. Feel free to update and distribute YALI at your leisure.
Update 2013-12-16:
Due to a server migration three years ago, YALI has been unavailable for download for awhile. Fortunately, it turns out that YALI is the standard LOLCODE implementation shipped with FreeBSD, so their archives came to the rescue and the interpreted is again available for download.
Included \(\LaTeX\) graphics are generated at LaTeX to png or by .
Sorry, further commenting on this post has been disabled. For more information, contact me.