Description
Barista, who can build new flavors of coffee for you.
It looks like we agree that is interesting to have a pluggable coffee compiler in the "TypeScript Output" discussion, for a health evolution of the language and the CoffeeScript ecosystem.
As I understand, the CoffeeScript source is a elaborated Jison configuration, and the compiler itself is a parser code generated by Jison. Make this generated code pluggable can be hard to do and harder to maintain.
I believe, the right path to make a pluggable coffee compiler is to have jison
as a execution dependency and the compiler itself must to be build at runtime.
Well it obviously will make the coffee compiler heavier and slower.
So I propose a new build task on the Cakefile to create the "barista compiler". It will be the same CoffeeScript compiler source, but not generated by Jison, its API will have plugin related configs, as its bin's CLI will have some plugins args. And, sure, it must be shipped with a different package.json
with "jison"
in the "dependencies"
list.
How a plugin may work
A plugin must implement methods to parameterize, extend or replace the transpiler units:
Lexer.tokenize()
: Looks like it will be the harder process to become pluggable. The method itself may stay untouchable by plugins, but they must to be able to change or parameterize its specialized tokenizers (identifierToken()
,stringToken()
, ...) or add new ones on any position of the tokenizers call line.grammar
must be exported as it is and freely modifiable by the plugin code.nodes
module looks like the most important is already exported and can be changed by the plugin. But it need to be clear where a new collection of node classes must to be attached to be used by the extended transpiler. Somenodes.coffee
helpers must to be exported to become usable by new node classes, and it must export a method to enable the plugins to replace this helpers if needed.
┌────────────────────────────────────────────────────────┐
│ barista + plugin1 + plugin2 + user-src.flavored-coffee │
└────────────────────────────────────────────────────────┘
⇩
╔════════════════════════╗
║ Barista Compiler ║
╟────────────────────────╢
║ ┌──────────────────┐ ║
║ │ CoffeeScript Src ├┐ ║
║ └┬─────────────────┘│ ║
║ └──────────────────┘ ║
║ ⇩ ║
║ ┏━━━━━━━━━━━━━━━━━━┓ ║
║ ┃ Plugin 1 ┃ ║
║ ┗━━━━━━━━━━━━━━━━━━┛ ║
║ ⇩ ║
║ ┏━━━━━━━━━━━━━━━━━━┓ ║
║ ┃ Plugin 2 ┃ ║
║ ┗━━━━━━━━━━━━━━━━━━┛ ║
║ ⇩ ║
║ ╔══════════════════╗ ║
║ ║ Cache Flavored ║ ║
║ ║ CoffeeScript ║ ║
║ ║ Transpiler ║ ║
║ ╚══════════════════╝ ║
╚════════════════════════╝
⇩
┌───────────────────────┐
│ user-src.transpiled │
└───────────────────────┘
What you think? What is missed? Is there a better path? Do you know specific details that need to be described?