Sunday, December 11, 2005

Yhc Core

Some people might have seen or heard of GHC's Core language, there is a detailed account of it here. As part of my PhD I need to convert from full Haskell to a reduced Haskell-like language. How should I go about doing this? Well the obvious thing is to use a Haskell compiler to translate to a reduced language, then tweak this reduced language to my personal taste. A few months ago when I started this process, the options available to me were:
  • GHC - a massive monster, but with an emerging API, and somewhat complex Core
  • Hugs - C, yuk!
  • nhc98 - doesn't work on Windows
With a choice like that, I went for GHC and started doing some work. It turns out the GHC Core that I was getting had let's, so learning let floating seemed necessary. Also all the symbols are nastily mangled - GHCziBase.ZMZN is the Core way of saying []. Also there is no natural correspondance between the original and the new names, and multi-module stuff looked like it was going to be a problem as well - HsAllInOne seemed to do the business, but thats yet another layer of mangling on top of that, which makes it look revolting.

Well that was 3 months ago I think, and since then an extra compiler has emerged, Yhc! So I thought I'd fire off Yhc and see what i got. Amazingly, I just compiled with -lift and suddenly everything looked beautifully close to what i wanted. The syntax was horrible, but it looked very nice! From this initial observation, I've hacked around a bit to try and define an easily parseable Core language for Yhc, which external tools (i.e. mine) can work with. It's a bit different from GHC's, compare and contast:
{from1 :: GHCziBase.Int -> GHCziBase.ZMZN GHCziBase.Int =
\ (n::GHCziBase.Int) ->
GHCziBase.ZC @ GHCziBase.Int n
(from1
(%case (GHCziBase.Int) zddNum
%of (tpl::GHCziNum.ZCTNum GHCziBase.Int)
{GHCziNum.ZCDNum
(tpl1::GHCziBase.ZCTEq GHCziBase.Int)
(tpl2::GHCziShow.ZCTShow GHCziBase.Int)
(tpl3::GHCziBase.Int -> GHCziBase.Int -> GHCziBase.Int)
(tpl4::GHCziBase.Int -> GHCziBase.Int -> GHCziBase.Int)
(tpl5::GHCziBase.Int -> GHCziBase.Int -> GHCziBase.Int)
(tpl6::GHCziBase.Int -> GHCziBase.Int)
(tpl7::GHCziBase.Int -> GHCziBase.Int)
(tpl8::GHCziBase.Int -> GHCziBase.Int)
(tpl9::GHCziNum.Integer -> GHCziBase.Int) ->
tpl3 n lit}))};
vs:
Main.from v379 =
(Prelude.: v379 (Main.from (Prelude.Prelude.Num.Prelude.Int.+ v379 1)))
A couple of differences to note. Yhc has no types, GHC has lots. Yhc resembles Haskell, GHC doesn't. The names are much clearer in Yhc. Yhc has a nice property that if you just cat all the modules together, it works perfectly. Another difference not shown here is that Yhc knows exactly where Main.from is defined, and can even track down exactly where that constant 1 comes from. It doesn't display this information, but it could do.

It finally looks like I've got a way to make Yhc part of my Phd!

[Note: all this code isn't in the build, its only in my copy, but it didn't take more than about 2 hours. Hopefully it can get into the main Yhc sometime soon]

0 Comments:

Post a Comment

<< Home