ひとり勉強会

ひとり楽しく勉強会

シンタックスハイライト

スーパーpre記法で言語ごとの色分けができるようになったそうです。ソースコードを色付けして記述する(シンタックス・ハイライト) - はてなダイアリーのヘルプ早速今まで書いた記事全部に導入してみました!綺麗ですねー。対応ファイルタイプ一覧を見てい…

まとめ

以上、そろそろ構文木から命令列リストへの変換を読むのに飽きてきたので、一気に駆け抜けて終わらせようとした軌跡でした。あと残っているのはクラス/メソッド定義のような、定義関係のノードです。次回はそこを読んで、一旦ここまで9回分をスライドか何か…

動的文字列&正規表現

文字列リテラルにも色々ありまして NODE 例 NODE_DSTR "a = #{a}" NODE_EVSTR "#{a}" 文字列がputstring命令になるのは、式展開が含まれていない、単純な文字列リテラルのときだけです。 "値は #{a} と #{b} です" のように式展開が含まれる場合は NODE_DSTR…

リテラル系

リテラル式は、そのリテラルをスタックに積む命令1個にコンパイルされます。対応表はこうです。 NODE 命令 NODE_LIT putobject NODE_SELF putself NODE_NIL putnil NODE_TRUE putobject true NODE_FALE putobject false NODE_STR putstring

NODE_OPTBLOCK

YARVの最適化の一つとして、「ブロックのインライン化」があります。例えば 3.times { ブロックの中身 } をブロックを作ったりyieldで呼んだりすると、スタック操作が無駄に発生してしまって効率がよくありません。あと、ブロックを使うとredoやnextが例外に…

BEGIN と END

大文字の BEGIN BEGIN { ... } は、そのファイルの他の部分より先に必ず評価されるブロックで、構文解析の段階で、NODE_PRELUDE というノードになります。構文解析器がソースコードの中のBEGINブロックを全部取り出して node nd_head : ソース中のBEGINブロ…

NODE_MATCH 系

ノードは3種類ありますが、要するにどれも =~ です。基本は、単純に =~ メソッドを呼ぶだけです。 case NODE_MATCH: case NODE_MATCH2: case NODE_MATCH3:{ ... 思いっきり略 ... COMPILE(recv, "reciever", node->nd_recv); COMPILE(val, "value", node->n…

NODE_FLIP系

NODE_DOTの範囲式が条件式として使われると、特別な意味になります。そういう位置にある範囲式はNODE_DOTではなくNODE_FLIPとしてコンパイルされます。 式1 .. 式2 は「式1が真になるまでは偽を返し、その後は式2が真を返すまでは真を返します。式2が真にな…

NODE_DOT系

"a".."z" 0...10 のようなRangeオブジェクトを表す式です。ドット2個の NODE_DOT2 とドット3個の NODE_DOT3 があって、どちらもnewrange命令にコンパイルされて引数のフラグで区別されます。 case NODE_DOT2: case NODE_DOT3:{ int flag = type == NODE_DO…

NODE_HASH

ハッシュリテラルです。 {"aaa",3,"bbb",4} {"ccc"=>5,"ddd"=>6} newarrayのハッシュ版命令「newhash」があるので、実はこれも、左から順に要素をスタックに積んで、newhashするだけなのです。重要なとこだけコンパイラのコードを抜粋すると、こうです。 cas…

NODE_VALUES

return 1,2,3 の 1,2,3 などなどの時に出現するノードなようです。要するに配列なので、そのまま順番に評価してnewarray、というコードにコンパイルされます。全部リテラルな時の最適化はこっちにはありませんでした。

NODE_ARRAY

配列式のコンパイルです。たとえば [a,b,c] という式は eval a eval b eval c newarray 3こういう命令列になります。newarray がスタックから値を拾ってきて配列オブジェクトを作る命令です。コンパイル処理は compile_array という補助関数に丸投げです。 c…

変数/定数読み取り

Rubyには変数にも色々種類があります...というのは、代入文のところでやりました。 種類 NODE 命令 メソッドローカル変数 NODE_LVAR getlocal ブロックローカル変数 NODE_DVAR getdynamic グローバル変数 NODE_GVAR getglobal インスタンス変数 NODE_IVAR ge…

NODE_RETURN

return は メソッド定義の直下からreturnする場合 メソッドの中のブロックの中からreturnする場合 でコンパイル結果の命令列が変わってきます。それ以外の場所(クラス定義の直下や、トップレベル)でreturnしようとするとエラーです。 どちらも、breakのコ…

NODE_YIELD

yield は、呼び出すものがブロックに変わるだけで、本質的にはメソッド呼び出しです。ただし、ブロックにブロックを渡したりはしません。あとレシーバを考える必要もないです。その分 call や super より簡単です。 引数をスタックに積んで 呼び出し(invoke…

NODE_SUPER

最初は super のコンパイルです。親クラスの同じメソッドに処理を回すやつです。super には二種類あって、 super(100) # 引数つきsuper super # 引数なしsuper 引数つきの方は NODE_SUPER、引数なしの方は NODE_ZSUPER と構文解析の段階で分かれています。ZS…

YARVソースコード勉強会 (8)

わわわ!オレンジニュースに載ってる!!! まとめエントリは本当に目次だけで不親切だったので(すみません。。。)、さっき少しだけ説明も追記しときました。さて、では第8回を開始します。今回から読むバージョンをr584にあげました。といっても、compil…

はてブ

はてなブックマーク - 2006-12-08 - ひとり勉強会 2006年12月10日 b:id:talo ruby, trivia superはvcallなのだろうか superはメソッド呼び出しとはさらに別になっていて、NODE_SUPER (引数つきsuper) と NODE_ZSUPER (引数なし、いまの引数を横流しするsuper)…

まとめ

ぁ〜。時間不足でいろいろ調べきれずに残ってしまいました。ざんねん。 ||= と defined の関係はRuby的にどうなる方向? current_block の最下位ビット それではまた来週。

NODE_CALL 等

続いて、メソッド呼び出しです。3種類のノードがありますが、それぞれの内訳はこの通り。 case NODE_CALL: case NODE_FCALL: case NODE_VCALL:{ /* VCALL: variable or call */ /* call: obj.method(...) fcall: func(...) vcall: func */ vcallは、機能と…

NODE_OP_ASGN_OR 等

続いて、属性や添字式以外への、要するに普通の変数への &&= か ||= のノードです。繰り返しになりますが、普通の変数への += 等は = と + の組み合わせに展開して問題ないので、特別には扱われていません。というわけで、これが自己代入系最後のノードです…

NODE_OP_ASGN2

r.a op= vNODE_OP_ASGN2 は、属性への自己代入のノードです。 eval r # r dup # r r eval r.a # r o eval v # r o v send op # r w send a= # wr.a = r.a op v を、rを2度評価しないようにdupで複製しながら実行するコードですね。こちらも、op が && と ||…

NODE_OP_ASGN1

a[x] op= y のパターンは、NODE_OP_ASGN1 という名前になっています。どういうバイトコードにコンパイルされるのか、コメントがついていました。 /* * eval a # a * eval x # a x * dupn 2 # a x a x * send :[] # a x a[x] * eval y # a x a[x] y * send op…

[YARV] 自己代入の注意点

a += 100 自己代入とは、上のように、自分と他の値の演算結果を、また自分に代入し直すような式のことをいいます。これは基本的には、 a = a + 100 と書き直したのと同じ意味です。実際、ほんとうに同じ意味になる場合はRubyの構文解析器が、YARVに渡すより…

YARVソースコード勉強会 (7)

こんにちは。iseq_compile_each 勉強会です。今日は、自己代入式のコンパイルのあたりから再開です。

サティ

日曜は雑談を書くぞっ!って言っても、特に書くことないですね。街を歩いてると、サティのジムノペティの1番をモチーフにした洋楽が聴こえてきました。こういう、クラシックのメロディを生かした歌って好きなんです。家に帰ってから調べたら YouTube でした。

まとめ

今回こそは10KBにはおさめようと思ったんですけど...ぅー。今日の内容は 代入いろいろ 多重代入いろいろ でした。次回は後ろに自己代入がひかえています。なんかコードが長そげです。 そこが終われば山は抜けられるかな、って雰囲気なので、あと2回でiseq_c…

NODE_MASGN / 多重代入

ここまでのいろいろな代入より、順番的にはこっちのcaseが先に出てきてました。説明の都合で逆順に読んでいます。 a, b, c = 1, 2, 3 みたいな形の代入です。コンパイル処理はほぼ全て、補助関数に丸投げされています。 case NODE_MASGN:{ compile_massign(i…

代入いろいろ

さて代入の話に入りますね。Rubyには、代入(あるいは代入っぽく見えるもの)がたくさんあります。 コード 説明 NODE a = 100 メソッドローカル変数への代入 NODE_LASGN a = 100 ブロックローカル変数への代入 NODE_DASGN,NODE_DASGN_CURR $a = 100 グローバ…

NODE_AND ほか

その前に、3つほど別の構文が間にはさまってました。and (&&), or (||), not (!) です。条件分岐のなかに出てくる場合は前にやりましたが、ここでは普通に式の途中に出てくるケースです。簡単なのでサックリと終わらせちゃいます。コードは省略です。 式1 a…