Hi Henry I'm taking a similar approach to Galler for a proof-of-concept, but without the macrology. This should make the ideas more widely accessible (and my skill with macros is limited).
First, thank-you again for supplying the example. By comparing input and output readers can infer the kinds of things your DSL does, even with only a smattering of Forth. The first thing to do is to devise a more Lispy representation of the DSL. Let's take the original: : NAME S"John Doe" CU4 HCTZ25 30P 1CPM OMZ20 30P 1CPM INSTOMZ SIMVA20 30P 1CPN L/D; and re-cast it using parentheses and prefix notation. I've chosen to notate as follows, adapting from Galler: '(script (name "John Doe") (directions (CU 4)) (medication (HCTZ 25) (P 30) (CPM 1)) (medication (OMZ 20) (P 30) (CPM 1) (INSTOMZ)) (medication (SIMVA 20) (P 30) (CPN 1))) [I've left off the L/D because I didn't follow the mapping, but you get the idea.] Now -- in practice -- a physician doesn't want to fiddle with parentheses, so a simple parser (16 lines in the proof-of-concept) is needed to go from something close to the original DSL to the new, parenthesized DSL. >From this new DSL there are many ways to get to the expanded script. Because it keeps coming up (and it's a quick hack ;-) I've used eval. A simple desugaring approach (as described in Shriram's PLAI book and course) would also work well, IMO. Here's my proof-of-concept in action... Input: (shorthand->script "John Doe CU4 HCTZ25 30P 1CPM OMZ20 30P 1CPM INSTOMZ SIMVA20 30P 1CPN") Output: John Doe Continuous use - 4 months Hydrochlorothiazide 25mg ---------------- 30 pills Take 1 pill in the morning. Omeprazol 20mg ---------------- 30 pills Take 1 pill in the morning, 1/2 hour before breakfast. Simvastatin 20mg ---------------- 30 pills Take 1 pill at night. Code pasted here: http://pasterack.org/pastes/67082 To summarize: 1. Design the Lispy version of the DSL 2. Parse from the input DSL to the Lispy DSL 3. Expand from the Lispy DSL to the full script 4. Bells and whistles: graphics, file-handling, proper user-interface, error-handling, etc. I hope that helps. I think this would be a good open-source project, and well-suited to Racket. BTW: If you want to produce nicely type-set output, consider looking into the Scribble language / tool. Dan
____________________ Racket Users list: http://lists.racket-lang.org/users