.. index:: 
	single: 一般情報; はじめに

========
一般情報
========

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

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

.. index:: 
	pair: 一般情報; Ring アーキテクチャ

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)。
拡張機能の更新時、自作コードの更新は不要です。


フォルダ (ring\libdepwin) ====> Windows プラットホーム用の Ring 拡張機能 (C 言語で記述) をビルドするために使用される C ライブラリ

フォルダ (ring\ringlibs)  ====> Ring で記述した Ring ライブラリ (StdLib, WebLib, GameEngine, など)

フォルダ (ring\rnoteexe)  ====> rnote.ring の起動用実行可能ファイルを作成用の C  ソースファイル

フォルダ (ring\visualsrc) ====> Ring コンパイラと Ring VM のビジュアル版ソースコードは Programming Without Coding Technology (PWCT) で開発

用語「Ring ライブラリ」の語釈は ─→ Ring で記述したライブラリのコード

用語「Ring 拡張機能」の語釈は ─→ C または C++ で記述したライブラリのコード

.. index:: 
	pair: 一般情報; メモリ管理

メモリ管理
==========

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

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

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

(2) Ring でメモリを削除するには、

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

2.2 代入演算子の使用

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

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

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

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

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

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

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

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

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


.. index:: 
	pair: 一般情報; データ表現

データ表現
==========

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

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

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

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

.. code-block:: ring

	mystring = read("myfile.exe")

(2) 変数について考えるときは、このことを覚えておいてください

* 値 ---> 内容物 (データとしてメモリに格納するもの) - 低水準概念
* 型 ---> どう内容物を扱うことができるか、あるいは取り扱い方法 (単なる論理的概念)

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


(3) Int2Bytes(), Float2Bytes() および Double2Bytes() 関数

これらの関数の入力値は数値を扱います。---> 数値型 (int|float|double) に基づきバイト集合を変換します。 ---> 結果として、これらのバイトがある Ring 文字列を返します。

Int2Bytes() ---> Ring 文字列 (バイト集合) と文字列の大きさ = sizeof(int)

Float2Bytes() ---> Ring 文字列 (バイト集合) と文字列の大きさ = sizeof(float)

Double2Bytes() ---> Ring 文字列 (バイト集合) と文字列の大きさ = sizeof(double)

用例:

.. code-block:: ring

	? len( int2bytes(1) )
	? len( float2bytes(1) )
	? len( double2bytes(1) )

実行結果:

.. code-block:: none

	4
	4
	8

(4) 数値の格納

数値使用時、 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) のみ使用します。

(5) Unsigned() 関数

unsigned() 関数の第一と第二仮引数は数値を要求します。

.. code-block:: ring

	unsigned(nNumber1,nNumber2,cOperator)

bytes2int() 関数はバイトを数値へ変換できます。

用例:

.. code-block:: ring 

	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

実行結果:

.. code-block:: none

	B1: ABCD
	B2: EFGH
	B3: IJKL
	B4: MNOP
	A12: 201589764
	A34: 470025220
	unsigned A12: 201589764
	unsigned A34: 470025220
