ひとり勉強会

ひとり楽しく勉強会

2006-12-01から1ヶ月間の記事一覧

ごあいさつ

Merry Christmas and a Happy New Year!!と、いうわけで。これが今年最後の更新です。来年の1月からは、ひとりYARV勉強会に加えて、ひとり http://mitpress.mit.edu/SICM/ (SICM) 読書会を始めようと考えてます。力学・物理ってもうどうしようもないくらい…

まとめ

というわけで、定義関係のコンパイル部分を読み終わりました!これにて [compile step 1] が無事?終了です。年末はお休みです。来年からは、コード生成部分の続き compile step 3 〜 5 に移ろうと思います。3,4,5 と3回で行ければいいな。では、よいお年を…

NODE_DEFINED

これが最後! defined? e変数などなどが定義されているかどうかを返す式です。定義されていれば式の種別を表す文字列、いなければ偽を返します。コンパイルはdefined_expr補助関数が全面的に担当しています。 case NODE_DEFINED:{ if (!poped) { LABEL *lfin…

NODE_UNDEF

undef メソッド名 一度定義したメソッドを取り消す処理です。わたし、aliasとundefの存在は今日始めて知りました。(^_^; こんなのあったんですね。 case NODE_UNDEF:{ if (nd_type(node->u2.node) != NODE_LIT) { rb_bug("undef args must be NODE_LIT"); } …

alias

Ruby の alias には2種類あります。メソッドに別名をつけるalias(NODE_ALIAS)と、グローバル変数に別名をつけるalias(NODE_VALIAS)です。 ノード コード NODE_ALIAS alias newmethod oldname NODE_ALIAS alias :newmethod :oldname NODE_VALIAS alias $…

NODE_DEFN 等

まず、クラスやメソッドを定義する文のコンパイルです。 ノード コード NODE_DEFN def mname(...) NODE_DEFS def obj.mname(...) NODE_MODULE module MName NODE_CLASS class CName NODE_SCLASS class ≪obj 例えばJavaやC++のような静的な言語では、この手の…

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

さてさて、今日は構文木からバイトコード命令列への変換、最終回です。今回はクラスやメソッドのなどの「定義」を扱うRuby構文のコンパイルを見ていきます。ほとんどがYARVの対応する数命令に変換される形なので、コンパイルはわりと簡単そうです。ではどう…

YARVソースコード勉強会(1-9)

まず最初にお知らせです。初回から今回までの内容を、スライドにまとめました。 第1回〜第9回まとめ (PowerPoint) 第1回〜第9回まとめ (PDF) なんだか長くて自分でも読み返すのがしんどかったので。。。 手っ取り早くて10分で読めるYARVソース読みの手がかり…

シンタックスハイライト

スーパー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 が && と ||…