jashkenas / jashkenas/coffeescript

Discussion: Supporting plugins

Open
#5,320 4 comments 0 reactions 0 assignees View on GitHub
enhancement
Dominant language
CoffeeScript
Stars
16.6k
Forks
2k
PR merge metrics
No merged PRs in 30d

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](https://github.com/jashkenas/coffeescript/issues/5307)" discussion, for a health evolution of the language and the CoffeeScript ecosystem.

As I understand, the CoffeeScript source is a elaborated [Jison](http://zaa.ch/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](https://github.com/jashkenas/coffeescript/blob/75d376f2eff7108ea8bb91d4326aac62989c8556/src/lexer.coffee#L69-L80).
* `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. Some `nodes.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?

Contributor guide

Open the contributing guide

Research direction

Start by reading the Jison configuration, Cakefile, src/lexer.coffee, grammar, and nodes.coffee referenced in the discussion, along with the linked TypeScript Output issue. Determine whether the proposed runtime-built compiler and plugin hooks have an agreed design; the issue currently defines no concrete acceptance criteria for what done looks like.

Written by the indexing model from the issue text.

Assessment

Tech stack
coffeescript
Domain
compilers
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
20/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.