Skip to content

未整理 coffeescript codereading

keqh edited this page Aug 17, 2011 · 2 revisions

未整理 coffeescript codereading

parser grammer.coffee lexer lexer.coffee 意味解析 nodes.coffee

n or= 1 定義されてなければ定義もされる

m ||= 1 事前に定義されている必要がある

nodes.coffee

access

'.'や'::'といったobjectへのaccess keyが文字列でも'.'でアクセスできるよう変換してくれる

Index

'[hoge]'

range

[1..10] [1...10]

  • conpileNode -- ?
  • compileSimple -- fromとtoが両方ともNumber literal
  • compileArray -- 変数が含まれてるとき

TODO: compileNode TODO: stepが指定できるみたいだけど、どうやって?

slice

array[1..10] array[1..] array[..9]

from, toは片方だけ省略できる from < = toでないとき、愚直に[]を返す マイナスは指定でき、rubyの様にendから数える

obj

TODO: obj

Arr

配列リテラル?

class

class解釈 class Hoge extends fuga constructor: (@a) -> f() method: -> g()

コンストラクタ名は'constructor' constructorはbound function'=>'にはできない

class A f: => A::f = -> 上記いずれかでA.prototypeのものに fのなかでインスタンス変数呼べないとおもったら、変な処理してる

class A @g: -> とかすると、A.gが定義される。A.prototype.gではない

TODO: classもういちど

assign

代入文

compilePatternMatch 左辺にarrayやobjectが指定されてたら、よきにはからってくれる [a, b] = [1, 2] { a:b, c:d } = obj

compileConditional ||=, &&=, ?=

compileSplice [a, b...]みたいな

code

たしか無名関数

Param

TODO: paramをgrammerで確認

splat

rubyの*aみたいな

while

while

Op

演算子

doの仕様をかくにんするならここ?

do, newも単項演算子

== : === != : !== of : in にそれぞれ変換される

1 < a < 2みたいなのをchainといっている 以下の演算子が可能 代入は特別処理なのでここにはない <, >, >=, <=, ===, !==

TODO: invertを調べて、!, !!, !!!の意味を理解

compileExistence var? みたいな定義済み確認

In

array if var in [1..9] then ...

線形探索で含まれているか 含まれていないことをやるなら var in ![1..9]

try

try

throw

throw

existence

undefined ではなく && nullでもない

parens

ただのかっこ

for

なぞのdoはpluckDirectCallで処理してる? stepは'by'で指定

switch

if

toplevelのifはstatement また親がstatementならstatement それいがいはexpression

grammer

root

toplevel

body -> 行の列 block -> indentでかこまれたもの

body

Lineのリスト。

Line

expression statement

Statement

値を返さないもの ここに挙がっているものはpure statement ifなど、 状況によってどちらにもなるものはexpression。

return throw comment STATEMENT

Expression

値を返すもの。 coffeeでは極力expressionとして表現するようになっている

value invocation code operation assign if try while for switch class

Block

indent付加されたBody

Identifier

変数名やプロパティ名

AlphaNumeric

数値と文字列のリテラル オブジェクトのkeyとなれるため、他のliteralと分けてる

Literal

リテラル

AlphaNumeric JS -> `` REGEX -> //, /// BOOL

Assign

代入文のroot '='で表現 左辺はassignale

AssignObj

Objectでの代入文 こちらは':'で表現 左辺は以下のObjAssignable

ObjAssignable

Identifier AlphaNumeric ThisProperty

Return

そのまま もちろん引数はexpressionのみ

comment

heredocument用の定義

Code

codeとあるが実際は無名関数だと思う 引数が無いときは()を省略できる

FunGlyph

->と=> =>のときはboundfunctionになる

OptComma

末尾の', 'は省略可能

ParamList

funcの引数リスト

Param

関数定義の引数 以下の3パターン

var ふつうの var... splat var = expr default引数

ParamVar

引数として指定可能なもの

Identifier ThisProperty Array Object

arrayとobjectはpatternmatch然として処理ができる g = ([a, b], c) ->

Splat

なんでここにsplatあるの? そしてなぜidentifierではなくexpressionなのか どうやら関数の引数以外の場所ででてくるsplatを表現してる そしてこのsplatは関数呼び出しのときしか使えない 後半のArg参照

SimpleAssignable

複雑な処理がなさげな左辺

Assignable

simpleに加えてarrayとobject patternmatch処理が行われる

Value

代入できたり関数として呼べたり、indexだったりclassだったり

Accessor

objectにアクセスするためのもの .Ident ?.Ident hogeが存在すること確認して、あれば呼び出し ::Ident hoge.prototype.Ident :: hoge.prototype Index 後述

Index

arrayやobjectのaccessor arr[1]みたいな SOAKは'?'の存在確認の表現らしい

START i END -> [i] SOAK i -> ?i PROTO i -> ::i

soakとprotoはobjのみ? 意味解析を確認すること

IndexValue

[hoge]みたいな値で指定できるもの expressionかslice sliceはおそらくarrayのみ

Object

object literal ex: { a:1, b:2 }

AssignList

assignとあるが、使用できるのはobject literalでのみ AssignObjのリスト

Class

魔境。 class単独でも合法だったり、クラス名省略できたり extendsは一つのみ。chainしたいときは単独で書く 下の例はclass定義とは別なら書ける ex: A extends B extends C

Blockを書かなければ宣言だけで定義は省略できる。 多分あとで追加できる

Invocation

関数呼び出し 定義に Invocation OptFuncExist Arguments とあるので、以下のような呼び出しができる (console.logとaddが関数) ex: console.log 1, add 2, 3 -> console.log(1, add(2, 3))

読みづらいのでやめたほうがいい また、引数の数を調べてるわけではなくて、右から単純に解釈してる fが二項だとして f f 1, 2, f 3, 4 期待:f(f(1, 2), f(3, 4)) 実際:f(f(1, 2, f(3, 4)))

OptFuncExist

関数があるか確認して、OKなときだけ呼び出し

Arguments

関数呼び出しの引数

This

this, @

ThisProperty

@Identifier

Array

array literal arrayの値は関数呼び出しのlistと同じように解釈される

RangeDots

.. inclusive [1..9] -> [1..9] ... exclusive [1...9] -> [1..9)

Range

arrayのrangeによるliteral ex: [1..9]

Slice

array slice literals from, toの片方が省略できる ex: arr[1..]

ArgList

関数の引数、または配列のリテラルのリスト

Arg

Expression Splat

SimpleArgs

switchで使用される argからsplat除いたもの

Try

だいたい期待どおり catchとfainarryは省略できる

catch

そのまま

throw

そのまま

Parenthetical

括弧 ( Body ) parentheticalはValueとして解釈される。expressionではない。 つまり、SimpleAssignableなどで使える 下記はifはexpressionだけど、()によってvalueになるのでaccessorを使用できる ex: (if a then b else c).hoge()

WhileSource

whileとuntilの中心部分の表現 一応whenも付けられるけど、条件にand入れるのと同じ forとの一貫性のためかと

While

前置と後置、あとloop

Loop

while(true)的な? 書けるのは BlockかExpression

For

forの前置後置

ForBody

forの本体部分 rangeと普通のforとの二つ ex: for i in [1..9] ex: for o in objs

ForStart

ownは、hasOwnPropertyによるチェックを加える これはobjectのときのみ有効?

ForValue

forで変数にbindできるもの。 ここでもarrayやobject指定でpatternmatchできる Identifier Array Object

ForVariables

変数のリスト

ForSource

forinとforof inはarray, ofはobjectで使用 forinで引数二つはvalueとindex forofで引数二つはkeyとvalue

forof 素とwhenのみ

forin 素 when by when by by when

byはstepを表現 whenはguard

Switch

switchの引数省略できる その場合falseと'!expr'が比較される elseは省略できる

常にbreakが挿入される

Whens, When

switchのwhenで指定できるのはSimpleArgs, つまりexpressionのみ

IfBlock

前置

If

後置

Operation

演算子

operators

演算子の結合則

end

terminator

semicolon, \n

STATEMENT

break, continue, debugger

リファレンス

公式のドキュメントは見た

lexer 字句解析 rewrite 字句の書き換え braceの補間など grammer 構文解析 nodes 意味解析

基本

コードは1対1でjavascriptに対応する 行末にセミコロンは必要無い。明示的に入れることはできる blockはインデントで表現される lineの区切りは改行もしくはセミコロン 殆どの要素は値を返す 返さないのは

  • throw
  • STATEMENT (lexerより) -- break -- continue -- debugger

literal

number

javascriptと同じ

string

文字列の途中で改行を入れても問題無い。

|| "hoge fuga" ||<

rubyのように、文字列の中に'#{}'使うことで、式を評価した値を書き込むことができる。シングルクォートでは展開されない。

|| "#{f}" '#{f}' ||<

|| ''' heredocument ''' ||<

  • heredocument
  • 文字列途中で改行ok

array

  • range -- expressionだけど使える型は? -- .. -- ...
  • slice -- 代入にも
  • in 線形探索 ?[ ::[]
  • index -- expression -- slice

object

  • yaml -- grammerみただけじゃわからない -- coffee -tで調べると、どこかで'{}'が補間されてる
  • 予約語のproperty自動変換
  • of key調査
  • ObjAssignable -- Identifier -- AlphaNumeric -- ThisProperty

js

regex

  • 複数行regex

bool

control expression

if, unless

後置 ()はいらない 値を返す 一行if

switch

条件省略 break補完

while, until, loop

後置 例によって式 until == while not loop == while true 一応whenが使える

for-in

for val, i in arr

by when returnはcomprehensions do for i in [1..9] do (i) -> console.log i

for-of

for key, val of obj own

try

try catchですら式 try catch finaaally

関数

定義

引数

  • splat (hoge...)
  • default
  • 無しなら()を省略できる
  • pattern match使える
  • ParamVar -- Identifier -- ThisProperty -- Array -- Object

-> =>

invoke

splat 括弧省略

class

block無し、つまり宣言だけもできる クラス名省略 extendsは一つのみ constructor super

  • 単独、引数あり @hoge extends メソッドで@ constructorでの引数でインスタンス変数に代入

Class::method methodsでのfuncdep

  • ->
  • =>

classの説明にあるmeta programmingを考えること

pattern match (desctururing assignment)

array, object splatsはsplit("")すれば文字列もいけるよ 再帰てきなものもおk

演算子

chain

  • <
  • <=
  • =>
  • ==
  • !=
  • =

or= ||=とは意味が違う and= &&= soak

  • ?
  • ?=
  • ?.
  • ?::
  • ?() == != is isnt not and or ~ typeof delete instanceof this = @ in(array) then one liner extends chain 優先順位

その他

()でvalue 変数のスコープ do f OptComma terminator herecomment

  • ###で囲う

undefinedはvoid 0 !!! {hoge} = hoge {hoge, fuga} = requiree 'foo' @[key] class Hoge @LEVELS: [..] Hoge::[level] =

代入文左辺に関数呼び出しある場合キャッシュされる 行末に''で行の継続を表現 herecommentはサニタイズされる(lexer)

  • 変換後に */が含まれるため

予約語 case, default, function, var, void, with const, let, enum, export, import, native __hasProp, __extends, __slice, __bind, __indexOf