Description
I've been thinking about this for a while. A lot of people (incl. me) expect a lot of Coffee. Some of us are happy with what the core has to offer, others want more. Instead of adding new features to the core, why not make it extensible? Unfortunately re-generating the parser is expensive and as attractive as it may seem, I don't think it's possible. Many languages, both static and dynamic, have found a way around this by introducing annotations/attributes. A classical example would be enforcing type checking on function parameters (let's just go with it):
sayHello: (person) ->
throw new Error 'ArgumentError: person not a Person' if not (person instanceof Person)
puts "Hello ${name.getName()}!"
[Type name: 'person', enforce: Person]
sayHello: (person) ->
puts "Hello ${name.getName()}!"
Coffee will completely ignore these in the generated code, unless there is a registered hook that can handle the generated AST. In the above example, Coffee would attempt to load a file 'type.coffee' and attach a processor from it to the sayHello
node. At compile time, the processor can decide what to do.
I realise this may be accomplished using comments, so if we can think about a way of letting outside extensions play nice with Coffee that would be great. Perhaps another command line option to register a bunch of files which will respond at compile time:
# MyType name: 'person', enforce: Person
sayHello: (person) ->
puts "Hello ${name.getName()}!"
> bin/coffee -c --register-addon addons/my_type.coffee input.coffee
I recall Jeremy already added a method to traverse the tree, so why not make it pluggable as above?
/rant almost over
EDIT: rant on: Having thought more about this, the easiest way to allow extensions would just be to include them and pass in the AST generated at compile time and let them do whatever they want with it. I would think some people may want certain extensions enabled permanently so perhaps Coffee can look in the users' home directory for installed and enabled exts?
rant over