* jck0ライブラリについて -(by [[K]], 2018.06.07) ** (0) これはなに? -jck0ライブラリは、JITコンパイラなプログラミング言語を自作したいときに支援する目的で作られたライブラリです。言語のバックエンドで動作することを想定しているため、人間にとっての可読性は最低限度しか追求していません。 -jck0ライブラリを使えば、JITコンパイラをCPUに依存せずに書くことができます。また最低限度の最適化機能も(将来的には)提供されます。 -呼び出し元は最適化をがんばらないという想定で考えています。だからベタに生成したソースコードが回されてくると思っています。 -jはJITのj、cはコンパイラのc、kはKHシリーズのk、0は言語における最下層レイヤという意味でゼロをつけました。 ** (1) 関数 -int jck0(const unsigned char *src, unsigned char *dst, int siz1, int *pc0, int *pc1, int *pc2) --このライブラリにおける中心的な関数。srcにjck0のソーステキスト、dstは出力先、siz1は出力可能な最大バイト数。pc0~pc2はエラー時の情報提供用。関数の返値は、0以上のときは成功で出力バイト数。負の場合はエラーでエラーコード。エラーコードはヘッダファイルに書いてある。 --pc0はエラーを起こした命令の文頭を示す(該当箇所はsrc[*pc0]である)。 --pc1はエラーとなったトークンを指している(該当箇所はsrc[*pc1]である)。当然 *pc0 <= *pc1 となる。 --pc2はエラーを起こすまでに到達した、最後のチェックポイント命令の位置を示している(該当箇所はsrc[*pc2]である)。当然*pc2<=*pc0となる。 --ソースの先頭に半角スペースを置いておくと、jck0ライブラリのpc1~pc2へのサポート度合いが判定しやすくなる。pc1やpc2のサポートがない場合は*pc1や*pc2は0にされ、有効であればそれ以外の値が設定されるので、区別できる。*pc1や*pc2が0になるということは、半角スペースを指しているということでもあり、つまりトークン長0のトークンを指しているということでもある。 --以上は2018.07.02以降にリリースされた版で有効となる。 -void *mallocRWX(int siz) --jck0ライブラリではOSに対して実行権限のついたメモリを要求するケースがよくあるだろうと想定されたので、機種依存を容易に解消するために、この関数がバンドルされた。 ** (2) 基本構文 ** (1) 基本構文 -パーサーをがんばりたくないので、トークンはすべて1つのスペースによって区切られなければいけません。それどころか、文末のトークンにもスペースを忘れずにつけなければいけません。 (例) "i = i + 1 ; " -文頭のみ、スペース、改行、タブを好きなだけおくことができます。あっても無視するだけなので、置かなくてもいいです。 -//は行コメント命令なので、これを置けば'\n'まではすべて無視します。 -演算子以外の予約語はすべて「$」で始まります。なぜ$にしたのかですが、SystemのSに形が似ていたからです。ということで$で始まる名前は他の用途では使わないでください。 -変数名やラベルの文字数は自由です。数字で始まるものはダメですが、それ以外の制約はほとんどありません。なんなら記号を含んでいてもかまいません。ただし演算子とは違う文字列にはしてください。 -jck0ライブラリでは1つのソースコードに含まれる関数は1つだという前提になっています。ですから複数の関数をコンパイルしたい場合は関数の数だけコンパイラを呼び出すことになります。 -雰囲気を分かってもらうために例をだします。 $startup ; // スタックフレームを作らせる $local $int32 i ; // ローカル変数の宣言 i = 0 ; $label l ; // ラベル宣言 i = i + 1 ; $if i < 100000000 $goto l ; $#0 = i ; // 第一引数を i にする $call 0x???? ; // 関数呼び出し. $return ; // スタックフレームを解放して関数を終了する ** (2) 関数 -int jck0(const unsigned char *src, unsigned char *dst, int siz1, int *pc0, int *pc1, int *pc2) --このライブラリにおける中心的な関数。srcにjck0のソーステキスト、dstは出力先、siz1は出力可能な最大バイト数。pc0~pc2はエラー時の情報提供用。関数の返値は、0以上のときは成功で出力バイト数。負の場合はエラーでエラーコード。エラーコードはヘッダファイルに書いてある。 --pc0はエラーを起こした命令の文頭を示す(該当箇所はsrc[*pc0]である)。 --pc1はエラーとなったトークンを指している(該当箇所はsrc[*pc1]である)。当然 *pc0 <= *pc1 となる。 --pc2はエラーを起こすまでに到達した、最後のチェックポイント命令の位置を示している(該当箇所はsrc[*pc2]である)。当然*pc2<=*pc0となる。 --ソースの先頭に半角スペースを置いておくと、jck0ライブラリのpc1~pc2へのサポート度合いが判定しやすくなる。pc1やpc2のサポートがない場合は*pc1や*pc2は0にされ、有効であればそれ以外の値が設定されるので、区別できる。*pc1や*pc2が0になるということは、半角スペースを指しているということでもあり、つまりトークン長0のトークンを指しているということでもある。 --以上は2018.07.02以降にリリースされた版で有効となる。 -void *mallocRWX(int siz) --jck0ライブラリではOSに対して実行権限のついたメモリを要求するケースがよくあるだろうと想定されたので、機種依存を容易に解消するために、この関数がバンドルされた。 ** (3) 位置独立なコードを生成するには? -デフォルトでは位置独立なコードを生成するための努力はしないが、$option命令などでサポートする可能性はある。 -位置独立なコードが生成できるようになると、静的なコンパイルにもjck0ライブラリが使えることになる。 ** (4) 関連リンク -[[page0015]] : ローカルラベル(jck0_v02以降で使える機能) -[[page0016]] : jck0ライブラリのバージョン * こめんと欄 #comment