# 11章
### インスタンスメソッドの流儀
Pythonは明示的にselfを記載する(他にもgoやrustもそうらしい)
関数的なものをメソッドとして使う場合は、こういう風にあらわにやる必要がある(もしくはそうした方がわかりやすい)
https://python.ms/self/#%E7%96%91%E5%95%8F-%E3%81%AA%E3%82%93%E3%81%A7%E6%98%8E%E7%A4%BA%E7%9A%84%E3%81%AB-self-%E3%82%92%E6%9B%B8%E3%81%8F%E3%81%AE%EF%BC%9F
### 変数のスコープ
```
# 適当な例(雑にローカル変数だけのテーブルとして)
method void hogeMethod() {
var int foo, bar
let foo = 100;
while(true) {
var int foo, bar
let foo = 10;
if(hoge) {
var int foo, bar
let foo = 1; # ブロック内のfooを指す(外に影響しない)
}
}
}
[{hogeMethod: [:foo, :bar, {whileBlock1: [:foo, :bar, {ifBlock1: [:foo, :bar]}]}]}, {fugaFunction: [:i, :j, :k]} ]
```
# 10章
(Rubyの例)ASTとVMコードのみかたこんな感じです
```
$ ruby --dump parsetree -e 'puts :hoge'
###########################################################
## Do NOT use this node dump for any purpose other than ##
## debug and research. Compatibility is not guaranteed. ##
###########################################################
# @ NODE_SCOPE (line: 1, location: (1,0)-(1,10))
# +- nd_tbl: (empty)
# +- nd_args:
# | (null node)
# +- nd_body:
# @ NODE_FCALL (line: 1, location: (1,0)-(1,10))*
# +- nd_mid: :puts
# +- nd_args:
# @ NODE_ARRAY (line: 1, location: (1,5)-(1,10))
# +- nd_alen: 1
# +- nd_head:
# | @ NODE_LIT (line: 1, location: (1,5)-(1,10))
# | +- nd_lit: :hoge
# +- nd_next:
# (null node)
$ ruby --dump insns -e 'puts :hoge'
== disasm: #<ISeq:<main>@-e:1 (1,0)-(1,10)> (catch: FALSE)
0000 putself ( 1)[Li]
0001 putobject :hoge
0003 opt_send_without_block <callinfo!mid:puts, argc:1, FCALL|ARGS_SIMPLE>, <callcache>
0006 leave
```
トークナイザの結果
```
> require 'ripper'
=> true
> code = <<~RUBY
a = (1 + 2) * 3
puts a - 1
RUBY
=> "a = (1 + 2) * 3\nputs a - 1\n"
> Ripper.tokenize(code)
=> ["a", " ", "=", " ", "(", "1", " ", "+", " ", "2", ")", " ", "*", " ", "3", "\n", "puts", " ", "a", " ", "-", " ", "1", "\n"]
> Ripper.sexp(code)
=> [:program,
[[:assign, [:var_field, [:@ident, "a", [1, 0]]], [:binary, [:paren, [[:binary, [:@int, "1", [1, 5]], :+, [:@int, "2", [1, 9]]]]], :*, [:@int, "3", [1, 14]]]],
[:command, [:@ident, "puts", [2, 0]], [:args_add_block, [[:binary, [:var_ref, [:@ident, "a", [2, 5]]], :-, [:@int, "1", [2, 9]]]], false]]]]
```
Tokenizer(単にバラバラにする) -> Lexer(tokenの種類を判別) -> Parser(ASTを組み立てる)っていう段取りになってるんですね。
```
> Ripper.lex(code)
=> [[[1, 0], :on_ident, "a", EXPR_CMDARG],
[[1, 1], :on_sp, " ", EXPR_CMDARG],
[[1, 2], :on_op, "=", EXPR_BEG],
[[1, 3], :on_sp, " ", EXPR_BEG],
[[1, 4], :on_lparen, "(", EXPR_BEG|EXPR_LABEL],
[[1, 5], :on_int, "1", EXPR_END],
[[1, 6], :on_sp, " ", EXPR_END],
[[1, 7], :on_op, "+", EXPR_BEG],
[[1, 8], :on_sp, " ", EXPR_BEG],
[[1, 9], :on_int, "2", EXPR_END],
[[1, 10], :on_rparen, ")", EXPR_ENDFN],
[[1, 11], :on_sp, " ", EXPR_ENDFN],
[[1, 12], :on_op, "*", EXPR_BEG],
[[1, 13], :on_sp, " ", EXPR_BEG],
[[1, 14], :on_int, "3", EXPR_END],
[[1, 15], :on_nl, "\n", EXPR_BEG],
[[2, 0], :on_ident, "puts", EXPR_CMDARG],
[[2, 4], :on_sp, " ", EXPR_CMDARG],
[[2, 5], :on_ident, "a", EXPR_END|EXPR_LABEL],
[[2, 6], :on_sp, " ", EXPR_END|EXPR_LABEL],
[[2, 7], :on_op, "-", EXPR_BEG],
[[2, 8], :on_sp, " ", EXPR_BEG],
[[2, 9], :on_int, "1", EXPR_END],
[[2, 10], :on_nl, "\n", EXPR_BEG]]
```
# 10章実装
大嶋(WIP)
https://github.com/h-shima/jack_compiler/pull/1
大西さん
https://github.com/fursich/hack_jack_compiler
# 参考Wikipedia
https://ja.wikipedia.org/wiki/%E5%86%8D%E5%B8%B0%E4%B8%8B%E9%99%8D%E6%A7%8B%E6%96%87%E8%A7%A3%E6%9E%90#%E3%83%91%E3%83%BC%E3%82%B5%E3%81%AE%E4%BE%8B
## トークナイザー
おおしまさん
https://github.com/h-shima/jack_compiler/pull/1/files#diff-02351efa8099765f7a345465cd05909f
おおにし
* トークンを表すクラス
https://github.com/fursich/hack_jack_compiler/blob/master/lib/tokenizer/token.rb
* トークン全体のコレクションを入れておくやつ
https://github.com/fursich/hack_jack_compiler/blob/master/lib/parser/token_container.rb
* トークンの分類器(分類ルール)
https://github.com/fursich/hack_jack_compiler/blob/master/lib/tokenizer/token_classifier.rb
* トークナイザー本体
https://github.com/fursich/hack_jack_compiler/blob/master/lib/tokenizer/processor.rb
* ソースコードを格納するやつ
https://github.com/fursich/hack_jack_compiler/blob/master/lib/utils/source.rb
## パーサー
おおにし
https://github.com/fursich/hack_jack_compiler/blob/master/lib/parser/processor.rb