一般情報¶
プログラミング言語 Ring の一般情報を記載しています。
- Ring アーキテクチャ
- メモリ管理
- データ表現
Ring アーキテクチャ¶
アーキテクチャの構成は、
- Ring アプリケーション (自作コード) - Ring で記述 - ring/applications フォルダを参照してください。
- Ring ライブラリ (StdLib, WebLib, GameEngine, など) - Ring で記述 - ring/ringlibs フォルダを参照してください。
- Ring 拡張機能 (RingAllegro, RingQt, など) - C/C++ で記述 (Ring コードもあります) - ring/extensions フォルダを参照してください。
- Ring 仮想機械 (Ring VM) - C 言語で記述
- オペレーティングシステム (現在のプラットフォーム) - (Windows, Linux, macOS, Android, など)
拡張機能の実態は動的ライブラリです (DLL, So, Dylib)。 拡張機能の更新時、自作コードの更新は不要です。
フォルダ (ringlibdepwin) ====> Windows プラットホーム用の Ring 拡張機能 (C 言語で記述) をビルドするために使用される C ライブラリ
フォルダ (ringringlibs) ====> Ring で記述した Ring ライブラリ (StdLib, WebLib, GameEngine, など)
フォルダ (ringrnoteexe) ====> rnote.ring の起動用実行可能ファイルを作成用の C ソースファイル
フォルダ (ringvisualsrc) ====> Ring コンパイラと Ring VM のビジュアル版ソースコードは Programming Without Coding Technology (PWCT) で開発
用語「Ring ライブラリ」の語釈は ─→ Ring で記述したライブラリのコード
用語「Ring 拡張機能」の語釈は ─→ C または C++ で記述したライブラリのコード
メモリ管理¶
- 関数を呼び出し時、この関数で新しいスコープの取得を行い、このスコープ内へ変数を格納します。
この関数で一時作業用メモリを取得します。 この一時作業用メモリ内へ一時作業用リストを格納します。
これは関数呼び出し終了直後に全て削除されます (スコープの終了)。
- Ring でメモリを削除するには、
2.1 関数スコープの終了まで待機
2.2 代入演算子の使用
2.3 callgc() 関数の使用 (一時作業用メモリの削除、リストのみ)
- Ring のガベージコレクターではエスケープ解析と参照カウントを使用
90% の場合では、ガベージコレクターの実行を不要にするために エスケープ解析 が使用されます。 メモリから削除、および残存対象を即時認識します。
10% 以下の場合では Ring は参照カウントを使用します。
例えば、関数へリストと部分リストを渡すとき、 Ring はリストを参照渡しで渡しますが、親リストを削除してしまうとどうなりますか?
この場合、部分リストは参照カウントを使用します。そして親リストの削除時は関数の終了までメモリに残存します。
Ring では、参照、および代入演算子で値によるリストのコピーの回避を奨励していることを覚えておいてください。 そして、 Ring で参照カウントを使うときは非常に限定された特別な場合です。ほとんどの場合はエスケープ解析で十分であり、非常に高速であることです。
Ring 1.9 から参照カウントへの対応を Ring 拡張機能と低水準 C ポインタまで拡大しました。 例えば、 fopen() の使用時に fclose() の使用に関して注意深くなる必要はありません。また RingODBC, RingSQLite, RingMySQL, RingQt などの拡張機能でも同じことが言えます。
使用完了後、割り当てられた全資源はガーベジコレクターにより整理されます (最後の参照を失ったとき)。
データ表現¶
- Ring において、文字列は「バイトから構成される配列」です。
Ring は 8 ビットクリーン実装であり、文字列内の各文字列は 8 ビット(1 バイト) です。
「Int2Bytes(), Float2Bytes() および Double2Bytes()」関数は文字列を返します。
文字列にはバイナリデータも格納できます。
mystring = read("myfile.exe")
- 変数について考えるときは、このことを覚えておいてください
- 値 —> 内容物 (データとしてメモリに格納するもの) - 低水準概念
- 型 —> どう内容物を扱うことができるか、あるいは取り扱い方法 (単なる論理的概念)
電子計算機のメモリ —-> [Bytes] (バイト) で格納 - 各バイトは 8 ビット - (ここでは単語「メモリ」の概念については扱いません)
メモリとプロセッサのレジスタ間で移動処理が行われるとき、これらのバイトは一緒にされてからまとめられます。 ここでは、例えば 32 ビットと 64 ビットの「レジスタの大きさ」は同じです。 また、バイトオーダーもあります。
プログラミング言語 —-> これらのバイトに型を追加 (単なる概念) することで取り扱いかたと処理方法について決定します。
さらに、プログラミング言語では「型変換」ができます —> ほとんどの場合、型は論理的概念であるため、実際は単なるデータです (バイト、バイトカウント、バイトオーダーなど)。
Ring 文字列 —-> これらのバイト (各バイトは 8 ビット) があるので、 Ring は文字列の大きさを認識します (数値として String構造体へ格納)。
よって NULL 文字の確認をしたり、あるい文字列の終端へ NULL 文字を追加しません (不要です)。
Ring VM 内部の処理全般では Ring データの大きさの確認を行い文字列をバイナリデータとして扱います (各文字は 8 ビット)。
C 言語では —> 通常は各文字列の終端へ NULL 文字 (\0) を追加します。
また、文字列関数は NULL 文字を確認するため、バイナリデータを処理するには不適切です。
符号付き (Signed) vs 符号なし (Unsigned) —> データの算術演算をするときに重要な論理的概念でありますが、データを格納するとき、格納されるデータが全て8 ビットの場合は一切考慮されません。 —> よって注意する必要はありません。
Ring では、これらの詳細について考えないでください。この件に関しては利用者側から見えないようになっています。このおかげでアプリケーションとしたいことのために開発に集中できます。
C 言語で低水準コードの記述を行い、万物を支配したいならば (必要に応じて) C 言語を検討してください。 —-> 優れた処理能力とメモリ管理
うんざりするような細かいことを考えず開発に専念して Ring コードを記述したいならぱ Ring を検討してください。 —–> 優れた生産性と迅速なソフトウェアの開発完了
吉報「プロジェクトで Ring と C を併用できます」
- Int2Bytes(), Float2Bytes() および Double2Bytes() 関数
これらの関数の入力値は数値を扱います。—> 数値型 (int|float|double) に基づきバイト集合を変換します。 —> 結果として、これらのバイトがある Ring 文字列を返します。
Int2Bytes() —> Ring 文字列 (バイト集合) と文字列の大きさ = sizeof(int)
Float2Bytes() —> Ring 文字列 (バイト集合) と文字列の大きさ = sizeof(float)
Double2Bytes() —> Ring 文字列 (バイト集合) と文字列の大きさ = sizeof(double)
用例:
? len( int2bytes(1) )
? len( float2bytes(1) )
? len( double2bytes(1) )
実行結果:
4
4
8
- 数値の格納
数値使用時、 Ring はメモリの数値表現で Double データ型を常時使用します。 数値への算術演算時、これを理解していることは重要です。
“” + 数値で数値を文字列へ変換するとき、あるいは文字列 (数値) で文字列を取得すると数値ごとの 1 バイト表現となります (記憶領域では好ましくはない考えかたですが、文字列処理で便利です)。
記憶領域の特定容量 (int|float|double) で数値表現をする必要があるならば、データをバイナリファイルとして書き出すときに bytes2int(), bytes2float() および bytes2double() を使用してください。
Ring 数値 (double) —-> int2bytes() - 数値を double から int へキャストしてバイトを返します —-> 4 バイト (Ring 文字列)
Ring 数値 (double) —-> float2bytes() - 数値を double から float へキャストしてバイトを返します —-> 4 バイト (Ring 文字列)
Ring 数値 (double) —-> double2bytes() - 数値 (double) でバイトを返します —-> 8 バイト (Ring 文字列)
Ring の内部処理に限り int 型が使用されますが、 Ring アプリケーション、またはコードでは数値型 (double) のみ使用します。
- Unsigned() 関数
unsigned() 関数の第一と第二仮引数は数値を要求します。
unsigned(nNumber1,nNumber2,cOperator)
bytes2int() 関数はバイトを数値へ変換できます。
用例:
B = list(4)
for k=1 to 4
{
B[k]= Space(4)
for kk=1 to 4 { B[k][kk]= char(60+4*k +kk) }
? " B" +k +": " +B[k]
}
A12= Space(4) A12= bytes2int(B[1]) ^ bytes2int(B[2])
? "A12: " +string(A12)
A34= Space(4) A34= bytes2int(B[3]) ^ bytes2int(B[4])
? "A34: " +string(A34)
A12= space(4) A12= Unsigned(bytes2int(B[1]),bytes2int(B[2]),"^")
? "unsigned A12: " +A12
A34= space(4) A34= Unsigned(bytes2int(B[3]),bytes2int(B[4]),"^")
? "unsigned A34: " +A34
実行結果:
B1: ABCD
B2: EFGH
B3: IJKL
B4: MNOP
A12: 201589764
A34: 470025220
unsigned A12: 201589764
unsigned A34: 470025220