Saturday, September 10, 2005

Domain Specific Languages

I still see old world flat file specifications like the following:







TypeNameDescription
9(8)Some DateDDMMYYYY
9(6)Some TimeHHMMSS
x(20)Lovely NameA Good Name
x(36)fillerIgnore

I thought I would do something different implement the parser as if I was a Lisper. So, here's what I came up with:

recordLayout
^#(
(9(8) someDate asDDMMYYYY)
(9(6) someTime asHHMMSS)
(x(20) lovelyName)
(x36) filler)
)

And what does the code look like to parse it? It's even simpler than I thought:

parse: aStream
self recordLayout do: [:eachLayout | | typeInfo typeLength fieldName converterSelector rawData data |
typeInfo := eachLayout first.
typeLength := eachLayout second first.
fieldName := eachLayout third.
converterSelector := eachLayout at: 4 ifAbsent: [#yourself].
rawData := aStream next: typeLength.
(typeInfo == 9) ifTrue: [self verifyIsNumeric: rawData].
data := rawData perform: converterSelector.
self perform: (self setterFor: fieldName) with: data]

WOW! I now have a method that shows the record layout that could be parsed for creating test records as well. I could even show it to a non-Smalltalker and they would know what's going on. I love the flexibility of Smalltalk! I love adding new tricks to my bag.

No comments: