The best kittens, technology, and video games blog in the world.

Thursday, August 10, 2006

Amethyst

Amethyst cut by Wela49 from Wikimedia Commons (GFDL)This is some old stuff, but I haven't blogged about it before so here it goes. Amethyst is basically Perl with Ruby syntax and you can get it here. What it does is parsing Amethyst source (with Ruby-like syntax) using Parse::RecDescent, generating Perl code for the whole program at once (this is a very fragile part), and eval'ing it. Now Ruby and Perl have totally different sematics, so Amethyst hacks around both a lot - for example it can tell whether a Perl object "is" a string, or a number, so + operator acts the expected way on both, even though Perl pretends not to know that. Some examples. Iterators work:

arr = [1,2,3]
arr.each{|element| print(element,"\n")}
The code gets compiled to:
($arr = [1,2,3]);
call(
 method($arr,'each'),
 sub{
   my ($element)=@_;
   {call(function('print'), undef, $element, "\n")}
 },
 $arr
);
And of course prints 1 2 3. The following code prints "22" and "157" as expected:
xs = "15"
xi = xs.to_i

yi = 7
ys = yi.to_s

zi = xi + yi
zs = xs + ys

print(zi, "\n")
print(zs, "\n")
$xs, $xi, $yi, $ys are all native Perl objects, the same you'd get if you said $xs="15"; $yi=7 ; etc. Can you guess how to make a function that can tell them apart without looking inside Amethyst source code ? ;-) Don't expect too much. Unlike RLisp which is basically an usable (even if alpha-quality) programming language, Amethyst was just a single-evening "be evil" session, and half of it was spent learning Parse::RecDescent. Still, it was a lot of fun :-)

5 comments:

Christoffer S. said...

An one night stand or not, cool it is, Yoda says.

Anonymous said...

I know it's not intended to be a usable program and it's more a bit of fun, but that's some awfully hacky code you're outputting there. That in my perl would be
map($arr, sub{print shift,"\n"})

taw said...

James Laver: If we knew type of $arr. But $arr could be an object with redefined "each" method, in which case this awfully hacky code is needed.

Anonymous said...

Taw: That's a good point, and I suppose it's easier to do that than just perform a check. It's not like optimisation is the most important thing there. Perhaps it would be worth considering recreating the ruby class hierarchy in perl, though I can understand that's a great deal of work.

If you ever want a hand though, the project interests me, drop me an email

taw said...

James Laver: I don't plan any further work on Amethyst, but if you want go ahead. It's Open Source, the full source is there, svn repository is unfortunately on my box which isn't 24/7 on, but we can set it up somewhere else.