Hi, I have yet to write anything in TH, although I've been toying with it a little bit and asking some questions on IRC. I have come across a problem that doesn't seem to have a good solution without using some sort of preprocessor. I want to take a simple spec and generate some marshalling code using a straighforward transformation. The spec should look something like:
$(declPkt "ip" [ ("Word8", "v_hl", "0x45"), ("Word8", "tos", "0"), ("Word16", "len", "0"), ("Word16", "id", "0"), ("Word16", "off", "0"), ("Word8", "ttl", "64"), ("Word8", "p", "6"), ("Word16", "sum", "0"), ("Word32", "src", "0"), ("Word32", "dst", "0")])
and should generate something like:
data IP = IP { ip_v_hl :: Word8, ip_tos :: Word8, ip_len :: Word16, ip_id :: Word16, ip_off :: Word16, ip_ttl :: Word8, ip_p :: Word8, ip_sum :: Word16, ip_src :: Word32, ip_dst :: Word32 } deriving Show newIP = IP 0x45 0 20 0 0 64 6 0 0 0
instance ByteContainer IP where getByteAt b 0 = getByteAt (ip_v_hl b) 0 getByteAt b 1 = getByteAt (ip_tos b) 0 getByteAt b 2 = getByteAt (ip_len b) 0 getByteAt b 3 = getByteAt (ip_len b) 1 getByteAt b 4 = getByteAt (ip_id b) 0 getByteAt b 5 = getByteAt (ip_id b) 1 getByteAt b 6 = getByteAt (ip_off b) 0 getByteAt b 7 = getByteAt (ip_off b) 1 getByteAt b 8 = getByteAt (ip_ttl b) 0 getByteAt b 9 = getByteAt (ip_p b) 0 getByteAt b 10 = getByteAt (ip_sum b) 0 getByteAt b 11 = getByteAt (ip_sum b) 1 getByteAt b 12 = getByteAt (ip_src b) 0 getByteAt b 13 = getByteAt (ip_src b) 1 getByteAt b 14 = getByteAt (ip_src b) 2 getByteAt b 15 = getByteAt (ip_src b) 3 getByteAt b 16 = getByteAt (ip_dst b) 0 getByteAt b 17 = getByteAt (ip_dst b) 1 getByteAt b 18 = getByteAt (ip_dst b) 2 getByteAt b 19 = getByteAt (ip_dst b) 3
containerLength b = 20
makeContainer b = IP { ip_v_hl = makeContainer (Slice b 0), ip_tos = makeContainer (Slice b 1), ip_len = makeContainer (Slice b 2), ip_id = makeContainer (Slice b 4), ip_off = makeContainer (Slice b 6), ip_ttl = makeContainer (Slice b 8), ip_p = makeContainer (Slice b 9), ip_sum = makeContainer (Slice b 10), ip_src = makeContainer (Slice b 12), ip_dst = makeContainer (Slice b 16) }
This definitely looks feasible using TH. However, it looks like I might have to mess with ASTs manually. My questions is -- is there an easy way to perform this transformation making use of quasi-quotes for much of the code, or will it be necessary to construct all of the ASTs manually? This seems like something that should have a fairly simple solution but so far I haven't been able to come up with one :(. Tim Newsham http://www.lava.net/~newsham/