LoginSignup
27
25

More than 5 years have passed since last update.

Re: TypedCoffeeScript

Posted at

というのを昔作ってたんだけど、最近また作り始めた。

mizchi/tcs

npmにはまだ登録してない。npm install -g mizchi/tcs で入る。typescriptのtscと紛らわしいので、たぶんそのうち名前変える。

今動いてるコード。

# this is comment

# expr

1
a.b
(a()).b
1 > 2
{}
{a: 1, b: 2}
{
  c: 1
  d: 2
}

# assignment with type annotation
var x1 = 3
var x2: number = 3

# Can declare let and const but flowtype can't parse them yet
let y = 2

# function
myFunc(a: number, b: number): number
  # return last expression
  a + b

() => 1

setTimeout(() =>
  myFunc(1, 2)
, 1000)

# class
class X<T>
  n: number
  _x: T
  static staticFunc() {}

  foo<U>()
    a

  get prop() {this._x}

  set prop(_x:number)
    @._x = x

class Y extends X<number>
  constructor()
    super()

var y = new Y()

# interface
interface Point
  x: number
  y: number

interface Point3d extends Point
  z: number

# if
if true
  a
else if false
  b
else if false
  c
else
  d

# switch
switch e
  when 1
    a
  when 2
    a
  else
    a

# for
for var i in items
  print(i)
# for of is same with es6, not coffee
for i of items
  print(i)

# module
import x from './x'
export default {}

ES2015時代のcoffeescript、というコンセプトで設計した。

使い方

$ tcs -s src -o _tcs -t flow
$ flow init
$ flow
$ tcs -s src -o lib  -t es5

flowのコード、もしくはes5へコンパイルできる。

TypedCoffeeScript v1の反省

昔作った版でやっていたこと

  • 既存のCoffeeScriptコンパイラへの大規模な介入
  • 型システムの自作

要約: 頑張りすぎた。勉強にはなったが、設計ミスに気づき作業量を見積もった段階で、個人で手を付けられるものではなくなり、放置してしまった。

その反省を活かして、今回は次のようになっている

  • flowtypeのコードを生成する(型システムを実装しない)
  • パーサのみの実装(直接flowtypeのASTを構築し、複雑な後処理をしない)

設計

  • pegjs/pegcoffee
  • recast
  • babel

recastはreact-toolsの中で使われているパーサで、flowtypeの型アノテーション付きコードを生成できる唯一の実装。ParserAPI + 型アノテーションの独自ASTで、これをターゲットにしてpegjsでパースしながらASTを直接組み立てる。

ここは仕様化されてないので、今後パーサを書き直すことも想定している。

で、この言語使えるの?

es5がターゲットのcoffeescript風言語として扱うだけならとくに問題ない。とはいえエラーメッセージが不親切だったり、分割代入や、自分があんまり使わないwhileの実装が実は抜けてたりする。これは単純に完成度の問題なので、時間をかければどうとでもなる。

というのと別に、flowtypeの型チェック機能、ファイル単体なら使えるんだけど、複数ファイルに分割した時のimport/export の挙動がかなり怪しい。これはfacebook/flowに実装依存になるので、なんとも言いがたい。とりあえずコード生成まではできる。

この言語が使えない、というよりは、flowtypeの挙動がよくわからんってのがある。nuclidの公開のタイミングでアップデートしてくると思うので、そのタイミングでまた考える。

CoffeeScriptからの変更点

  • そもそもスーパーセットを目指さない(頑張り過ぎない)
  • CoffeeScript主要な機能はES2015に取り込まれたので、できるだけES2015に近づける
  • 議論が多い変数の自動宣言は削除。letやconstを使いたいのもある。

reiny への適用

reinyっていうテンプレートエンジンを作っていたのだけど、テンプレートエンジン上で、テンプレートエンジン内のロジックとして if 2 > 1 みたいなコードを書けるようにしようとしたとき、ここで 2 > 1 をパース出来るexpressionノードのパーサが必要になる。これを実装するとなるとほぼプログラミング言語に近くなる。

だたら先に前々から作りたかったtyped coffee script v2 実装して、その後バックポートすりゃいいじゃん、と作り始めた。実はそんなに時間はかけてなくて、およそ3日分ぐらいの作業量。

今後

隙をみてちゃんと作っていく。頑張り過ぎず長期的に開発するのが目標。実装は単なるpegjs(pegcoffee) のパーサジェネレータがあるだけなので、興味ある人は読んでみるといいと思います。

ちょっとコード汚いけど… https://github.com/mizchi/tcs/tree/master/grammars

flowtypeのコード生成についてはflowの成り行きを見届ける感じで。

27
25
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
27
25