言語のしくみを読む

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)

pythonのソースコードを調べる

Objectsフォルダの中身を調べる
それっぽい名前としては

boolobject.c
bytearrayobject.c
bytesobject.c
cellobject.c
classobject.c
codeobject.c
complexobject.c
descrobject.c
dictobject.c
enumobject.c
fileobject.c
floatobject.c
frameobject.c
funcobject.c
genobject.c
iterobject.c
listobject.c
longobject.c
memoryobject.c
methodobject.c
moduleobject.c
namespaceobject.c
object.c
odictobject

object.cの主な関数(?)

void _Py_AddToAllObjects(PyObject op, int force) void Py_IncRef(PyObject o)
void Py_DecRef(PyObject *o)
PyObject * PyObject_Init(PyObject op, PyTypeObject tp)
PyVarObject * PyObject_InitVar(PyVarObject op, PyTypeObject tp, Py_ssize_t size)
PyObject * _PyObject_New(PyTypeObject *tp)
PyVarObject * _PyObject_NewVar(PyTypeObject *tp, Py_ssize_t nitems)
void PyObject_CallFinalizer(PyObject *self)
int PyObject_CallFinalizerFromDealloc(PyObject *self)
int PyObject_Print(PyObject op, FILE fp, int flags)
void _PyObject_Dump(PyObject* op)
PyObject * PyObject_Repr(PyObject *v)
PyObject * PyObject_Str(PyObject *v)
PyObject * PyObject_ASCII(PyObject *v)
PyObject * PyObject_Bytes(PyObject *v)
int _Py_SwappedOp = {Py_GT, Py_GE, Py_EQ, Py_NE, Py_LT, Py_LE};
static char *opstrings = {“<”, “<=”, “==”, “!=”, “>”, “>=”};
static PyObject * do_richcompare(PyObject v, PyObject w, int op)
PyObject * PyObject_RichCompare(PyObject v, PyObject w, int op)
int PyObject_RichCompareBool(PyObject v, PyObject w, int op)
Py_hash_t PyObject_HashNotImplemented(PyObject *v)
Py_hash_t PyObject_Hash(PyObject *v)
PyObject * PyObject_GetAttrString(PyObject v, const char name)
int PyObject_HasAttrString(PyObject v, const char name)
int PyObject_SetAttrString(PyObject v, const char name, PyObject *w)
int _PyObject_IsAbstract(PyObject *obj)
PyObject * PyObject_GetAttrId(PyObject *v, Py_Identifier *name)
int PyObject_HasAttrId(PyObject *v, Py_Identifier *name)
int PyObject_SetAttrId(PyObject *v, Py_Identifier name, PyObject w)
PyObject * PyObject_GetAttr(PyObject v, PyObject name)
int PyObject_HasAttr(PyObject v, PyObject name)
int PyObject_SetAttr(PyObject v, PyObject name, PyObject *value)
PyObject * _PyObject_GetDictPtr(PyObject obj)
PyObject * PyObject_SelfIter(PyObject *obj)
PyObject * _PyObject_GetBuiltin(const char *name)
PyObject * _PyObject_NextNotImplemented(PyObject *self)
PyObject * _PyObject_GenericGetAttrWithDict(PyObject obj, PyObject name, PyObject *dict)
PyObject * PyObject_GenericGetAttr(PyObject obj, PyObject name)
int _PyObject_GenericSetAttrWithDict(PyObject obj, PyObject name, PyObject value, PyObject dict)
int PyObject_GenericSetAttr(PyObject obj, PyObject name, PyObject *value)
int PyObject_GenericSetDict(PyObject obj, PyObject value, void *context)
int PyObject_IsTrue(PyObject *v)
int PyObject_Not(PyObject *v)
int PyCallable_Check(PyObject *x)
static PyObject * _dir_locals(void)
static PyObject * _dir_object(PyObject *obj)
PyObject * PyObject_Dir(PyObject *obj)
static PyObject * none_repr(PyObject *op)
static void none_dealloc(PyObject* ignore)
static PyObject * none_new(PyTypeObject type, PyObject args, PyObject *kwargs)
static int none_bool(PyObject *v)
static PyNumberMethods none_as_number = { 0, / nb_add / 0, / nb_subtract / 0, / nb_multiply / 0, / nb_remainder / 0, / nb_divmod / 0, / nb_power / 0, / nb_negative / 0, / nb_positive / 0, / nb_absolute / (inquiry)none_bool, / nb_bool / 0, / nb_invert / 0, / nb_lshift / 0, / nb_rshift / 0, / nb_and / 0, / nb_xor / 0, / nb_or / 0, / nb_int / 0, / nb_reserved / 0, / nb_float / 0, / nb_inplace_add / 0, / nb_inplace_subtract / 0, / nb_inplace_multiply / 0, / nb_inplace_remainder / 0, / nb_inplace_power / 0, / nb_inplace_lshift / 0, / nb_inplace_rshift / 0, / nb_inplace_and / 0, / nb_inplace_xor / 0, / nb_inplace_or / 0, / nb_floor_divide / 0, / nb_true_divide / 0, / nb_inplace_floor_divide / 0, / nb_inplace_true_divide / 0, / nb_index / };
PyTypeObject _PyNone_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) “NoneType”, 0, 0, none_dealloc, /tp_dealloc/ /never called/ 0, /tp_print/ 0, /tp_getattr/ 0, /tp_setattr/ 0, /tp_reserved/ none_repr, /tp_repr/ &none_as_number, /tp_as_number/ 0, /tp_as_sequence/ 0, /tp_as_mapping/ 0, /tp_hash / 0, /tp_call / 0, /tp_str / 0, /tp_getattro / 0, /tp_setattro / 0, /tp_as_buffer / Py_TPFLAGS_DEFAULT, /tp_flags / 0, /tp_doc / 0, /tp_traverse / 0, /tp_clear / 0, /tp_richcompare / 0, /tp_weaklistoffset / 0, /tp_iter / 0, /tp_iternext / 0, /tp_methods / 0, /tp_members / 0, /tp_getset / 0, /tp_base / 0, /tp_dict / 0, /tp_descr_get / 0, /tp_descr_set / 0, /tp_dictoffset / 0, /tp_init / 0, /tp_alloc / none_new, /tp_new / };
PyObject Py_NoneStruct = { PyObject_EXTRA_INIT 1, &_PyNone_Type };
static PyObject * NotImplemented_repr(PyObject *op)
static PyObject * NotImplemented_reduce(PyObject *op) static PyMethodDef notimplemented_methods[] = { {“reduce”, (PyCFunction)NotImplemented_reduce, METH_NOARGS, NULL}, {NULL, NULL} };
static PyObject * notimplemented_new(PyTypeObject type, PyObject args, PyObject *kwargs)
static void notimplemented_dealloc(PyObject* ignore)
PyTypeObject _PyNotImplemented_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) “NotImplementedType”, 0, 0, notimplemented_dealloc, /tp_dealloc/ /never called/ 0, /tp_print/ 0, /tp_getattr/ 0, /tp_setattr/ 0, /tp_reserved/ NotImplemented_repr, /tp_repr/ 0, /tp_as_number/ 0, /tp_as_sequence/ 0, /tp_as_mapping/ 0, /tp_hash / 0, /tp_call / 0, /tp_str / 0, /tp_getattro / 0, /tp_setattro / 0, /tp_as_buffer / Py_TPFLAGS_DEFAULT, /tp_flags / 0, /tp_doc / 0, /tp_traverse / 0, /tp_clear / 0, /tp_richcompare / 0, /tp_weaklistoffset / 0, /tp_iter / 0, /tp_iternext / notimplemented_methods, /tp_methods / 0, /tp_members / 0, /tp_getset / 0, /tp_base / 0, /tp_dict / 0, /tp_descr_get / 0, /tp_descr_set / 0, /tp_dictoffset / 0, /tp_init / 0, /tp_alloc / notimplemented_new, /tp_new / };
PyObject Py_NotImplementedStruct = { PyObject_EXTRA_INIT 1, &_PyNotImplemented_Type };
void _Py_ReadyTypes(void)
void _Py_NewReference(PyObject *op)
void _Py_ForgetReference(PyObject *op)
void _Py_Dealloc(PyObject *op)
void _Py_PrintReferences(FILE *fp)
void _Py_PrintReferenceAddresses(FILE *fp)
PyObject * _Py_GetObjects(PyObject self, PyObject args)
Py_ssize_t (_Py_abstract_hack)(PyObject ) = PyObject_Size;
void _PyObject_DebugTypeStats(FILE *out)
int Py_ReprEnter(PyObject *obj)
void Py_ReprLeave(PyObject *obj)
int _PyTrash_delete_nesting = 0;
PyObject *_PyTrash_delete_later = NULL;
void _PyTrash_deposit_object(PyObject *op)
void _PyTrash_thread_deposit_object(PyObject *op)
void _PyTrash_destroy_chain(void)
void _PyTrash_thread_destroy_chain(void)
PyAPI_FUNC(void) Py_Dealloc(PyObject *); void Py_Dealloc(PyObject *op)