読者です 読者をやめる 読者になる 読者になる

言語のしくみを読む

node_run関数
strm_seq_init(),strm_socket_init()が準備を完了させたら
次に呼ぶのがexec_expr関数で、渡されたnodeをswitch文で分岐させながら
taskを作ってキューに登録する。登録されたtaskはqueue.cのstrm_queue_exec関数が
実行を行っている。
キューに登録された関数はwrite_cb関数で渡されたデータは"Hello world"という文字列
であった。

exec_expr関数にnodeが渡されると最初に取り出されるのはNODE_STMTS  
そこから再帰的にexec_expr関数が呼ばれNODE_OPが取り出される。
strm_string opは文字列に"|“を持っている
node * lhs NODE_ARRAY
node * rhs NODE_IDENT

lhsからexec_expr関数を呼び出し、中身は"Hello world"を持っている
一度呼び出し側に戻り今度はrhsでexec_expr関数を呼び出す。
NODE_OPに帰ってきたらexec_call関数を呼び出す。
この時呼び出される関数はexec_bar関数で、今回はlhs:arrayのコメントが
あるパートからstrm_alloc_stream関数を呼びstrm_taskにタスクを登録している
start_funcにwrite_cb関数を登録している。

他のスレッドによりstrm_queue_exec関数内からwrite_cb関数を
呼び、画面に(STDOUT)に"Hello World"を表示させている

言語のしくみを読む

main関数からstrm_var_def関数を呼び出す
引数の"ARGV"はstrm_stringに保管されてる、av変数にはコマンドライン
引数が入っているので"ARGV"の名前で保管される。

次はnode_run関数を呼ぶ //exec.c

node_init関数内でstrm_var_def関数を使ってシンボルをハッシュに登録している
“STDIN”->strm_io_new(0, STRM_IO_READ)
“STDOUT”->strm_io_new(1, STRM_IO_WRITE)
“STDERR”->strm_io_new(2, STRM_IO_WRITE)
“puts”->strm_cfunc_value(exec_puts)
“+”->strm_cfunc_value(exec_plus)
“-”->strm_cfunc_value(exec_minus)
“*”->strm_cfunc_value(exec_mult)
“/”->strm_cfunc_value(exec_div)
“<”->strm_cfunc_value(exec_lt)
“<=”->strm_cfunc_value(exec_le)
“>”->strm_cfunc_value(exec_gt)
“>=”->strm_cfunc_value(exec_ge)
“==”->strm_cfunc_value(exec_eq)
“!=”->strm_cfunc_value(exec_neq)
“|”->strm_cfunc_value(exec_bar)
“%”->strm_cfunc_value(exec_mod)
“fread”->strm_cfunc_value(exec_fread)
“fwrite”->strm_cfunc_value(exec_fwrite)

strem_seq_init関数を呼ぶ strem_var_def関数を使ってseq->strem_cfunc_value(exec_seq)を登録している
strem_socket_init関数を呼ぶ
strem_var_def関数を使って
tcp_server->strem_cfunc_value(exec_tcp_server)
strem_var_def関数を使って
tcp_socket->strem_cfunc_value(exec_tcp_socket)
を登録している

言語のしくみを読む

main関数から読んでいく

$ ./streem ../examples/02hello.strm

main関数
オプション処理部はパスして
node_parse_init(&state) //node.c
state構造体の初期化
e_progはNULLなのでelse節以降を実行、引数を持っているので最後のelse節を実行
for(i = 1;i < argc;i++){
node_parse_file(&state,argv[i]) //node_parse_file node.c
}
node_parse_fileに渡されるのは引数の"../examples/02hekko.strm"になる。
渡されたファイル名を使ってreadモードで開かれる。
node_parse_input関数を呼び出す。
yyrestart関数にファイルポインタを渡して呼び出す //yyrestart:y.tab.c
yyparse関数のparser変数を渡して呼び出す
中身はまったくわからない。
parser_state pは
p.nerr = 0
p.lval = (void
) 0x61a510 ?
p.fname = 0x0
p.lineno = 2
p.tline = 3
node_parse_file関数に戻ってきてファイルを閉じる
main関数に戻る
strm_ary_new(NULL,argc=2)関数を呼ぶ。//array.c
struct strem_array + struct strem_value * lenだけメモリを確保
main関数に戻る
先ほど確保したstrm_arrayはav変数が指示、strm_value部分はbufが指示している
strm_str_value関数->strm_ptr_value->strm_str_new関数 //string.c
シングルスレッドモードのときとマルチスレッドモードで文字列確保関数を
呼び分けている。
シングルスレッドモードのときはstr_intern関数でsym_tableにkeyと一緒に文字列を保存
マルチスレッドモードの時はstr_new関数でメモリを確保してstrm_stringを返してmain関数の
buf[]配列に保存している。

言語のしくみを読む

Cの開発環境を整備

ソースの分量が増えてきたのでエディタだけで読むのが困難になってきたので
Cの統合環境を入れることにした。
最初はeclise C/C++ Linuxを入れたが使い方がわからず。
次にNetBeans IDE 8.2 C/C++ Linuxを入れたところ比較的わかりやすく
こちらにした。

<installの仕方>

netbeans.org

上記リンク先の画面の右上オレンジ色のボタンを押して「NetBeans IDE 8.2 ダウンロード」画面 に遷移する。 f:id:bitop:20170312112115p:plain 「ダウンロードx64」のボタンを押下。
f:id:bitop:20170312112422p:plain

手元のPCのダウンロードフォルダにnetbeans-8.2-cpp-linux-x64.sh(119.7MB)が
ダウンロードされている。ファイルを選択してマウスの右ボタンでコンテキストメニューを出し
一番下のプロパティを選択。アクセス権タグを選択し、下にある実行欄のプログラムとして
実行可能を チエックし、端末からsudo netbeans-8.2-cpp-linux-x64.shと入力した後は 画面の指示に従ってインストールが進む。
途中-jdkhomeがないといわれるが仔細がわからないため無視して続行した。  現在順調に作動中。  

言語のしくみを読む

2-7AST(抽象構文木)に変換

今回はsrcフォルダーに大幅に追加がなされた。
早速makeしてみるが、node.cコンパイル中にy.tab.hがないとエラーが出ている。
Gitで次のtag(201507)に行ってみるとy.tab.hがあったので201506は無視して201507tag
で実行。
binフォルダーにstreemができていたので

./streem ../examples/01cat.stem
<結果>
dw (stdin 入力)
dw (stdout 出力)
エコーです

./streem ../examples/02hello.stem
<結果>
Hello World

結構おもしろい。

src/main関数の最初でオプションをチエックしているようだが特になにもしていない?
読み込んだファイルをパースしているようだ(フロントエンド)。
そのあとstat変数をnode_run関数に渡してnode.cのexec_expr関数に
実行させている(バックエンド)ようだ。

言語のしくみを読む

2-6キャッシュとシンボル

stringを生成するためのstruct sym_keyが新たに定義されている。
渡された文字列の特徴からハッシュ値を取り出している。
これがシンボル検索の高速化に寄与しているのかな?
khash.hが新規に追加,string.cが大幅な書き換えとなっている。

言語のしくみを読む

2-5マルチスレッドとオブジェクト

core.cのstrm_loop関数を中心にマルチスレッド対応になっている。
queue.cにpush_high_task,push_low_task関数が追加などの変更がある。
ncpu.c,string.c,value.cが新規で入っている
srcフォルダにも新規ファイルが入っているがコンパイルの方法がわからないので
パス。
libフォルダでコンパイルすると-lgcが見つからないとのエラー
sudo apt-get install libgc-dev
コンパイル成功a.outができる

<メモ>
GitKrakenのFullScreenを戻す方法:shift+ctrl+F (ubuntu)