一般情報

プログラミング言語 Ring の一般情報を記載しています。

  1. Ring アーキテクチャ
  2. メモリ管理
  3. データ表現

Ring アーキテクチャ

このようなアーキテクチャから構成されています。

  1. Ring アプリケーション (自作コード) - Ring で記述 - ring/applications フォルダを参照してください。
  2. Ring ライブラリ (StdLib, WebLib, GameEngine, など) - Ring で記述 - ring/ringlibs フォルダを参照してください。
  3. Ring 拡張機能 (RingAllegro, RingQt, など) - C/C++ で記述 (Ring コードもあります) - ring/extensions フォルダを参照してください。
  4. Ring 仮想機械 (Ring VM) - C 言語で記述
  5. オペレーティングシステム (現在のプラットフォーム) - (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++ で記述したライブラリのコード

メモリ管理

  1. 関数を呼び出し時、この関数で新しいスコープの取得を行い、このスコープ内へ変数を格納します。

この関数で一時作業用メモリを取得します。 この一時作業用メモリ内へ一時作業用リストを格納します。

これは関数呼び出し終了直後に全て削除されます (スコープの終了)。

  1. Ring のメモリの削除では、このような選択肢があります

2.1 関数スコープの終了まで待機

2.2 代入演算子の使用

2.3 callgc() 関数の使用 (一時作業用メモリの削除、リストのみ)

  1. Ring のガベージコレクターではエスケープ解析と参照カウントを使用

90% の場合では、ガベージコレクターの実行を不要にするために エスケープ解析 が使用されます。 メモリから削除、および残存対象を即時認識します。

10% 以下の場合では Ring は参照カウントを使用します。

例えば、関数へリストと部分リストを渡すとき、 Ring はリストを参照渡しで渡しますが、親リストを削除してしまうとどうなりますか?

この場合、部分リストは参照カウントを使用します。そして親リストの削除時は関数の終了までメモリに残存します。

Ring では、参照、および代入演算子で値によるリストのコピーの回避を奨励していることを覚えておいてください。 そして、 Ring で参照カウントを使用するときは非常に限定された特別な場合です。ほとんどの場合はエスケープ解析で十分であり、非常に高速であることです。

Ring 1.9 から参照カウントへの対応を Ring 拡張機能と低水準 C ポインタまで拡大しました。 例えば、 fopen() の使用時に fclose() の使用に関して注意深くなる必要はありません。また RingODBC, RingSQLite, RingMySQL, RingQt などの拡張機能でも同じことが言えます。

使用完了後、割り当てられた全資源はガーベジコレクターにより整理されます (最後の参照を失ったとき)。

データ表現

  1. Ring において、文字列は「バイトから構成される配列」です。

Ring は 8 ビットクリーン実装であり、文字列内の各文字列は 8 ビット(1 バイト) です。

「Int2Bytes(), Float2Bytes() および Double2Bytes()」関数は文字列を返します。

文字列にはバイナリデータも格納できます。

mystring = read("myfile.exe")
  1. 変数について考えるときは、このことを覚えておいてください
  • 値 —> 内容物 (データとしてメモリに格納するもの) - 低水準概念
  • 型 —> どう内容物を扱うことができるか、あるいは取り扱い方法 (単なる論理的概念)

電子計算機のメモリ —-> [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 を併用できます」

  1. 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
  1. 数値の格納

数値使用時、 Ring はメモリの数値表現で Double データ型を常時使用します。 数値への算術演算時、これを理解していることは重要です。

“” + 数値で数値を文字列へ変換するとき、あるいは文字列 (数値) を使用して文字列を取得すると各数値は 1 バイト表現となります (記憶領域では好ましくはない考えかたですが、文字列処理で便利です)。

記憶領域に対して指定の大きさで数値表現をする必要があるならば、データをバイナリファイルとして書き出すときに 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) のみ使用します。

  1. 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