isVowel() - プログラミング言語 Ring 関連メモ

Ring 言語に関する資料の翻訳や執筆、拡張機能の開発など

Ring 1.8 日本取り扱い説明書の校閲作業

Ring API の解析に戻りたいところですが、色々と思うところがあるため、日本語版取り扱い説明書の推敲、校閲作業をしているところです。具体的な方法は、 SphinxePub を生成して BluetoothAndroid タブレットへ転送後、 Lithium で読んで気になるところはメモを残しています。

 

f:id:isVowel:20180706234428j:image

 

いつまで経っても、原著の品質が改善しないのは、レビューガイドラインの未定義によるものであるので、この機会に用意するのもありかなと思います。

 

たまに出られなくなります。

今週~来月上旬までは通信容量制限と Wikipedia の翻訳などで、なかなかこちらに出ることができないことがあります。これは毎月起きるのでご了承ください。

 

さて Wikipedia 記事の翻訳に関して

午前4時から作業して正午に完成しました。 LOVE2D Wiki の翻訳をしていた人 (GreenWing) なので MediaWiki の使用経験はありますが、方言があるので面倒ですね。面倒なのは infobox の編集くらいで、残りは和訳済みの資料を編集して対応しました。現在は完訳しています

 

ただし、あの Wikipedia 記事で興味を持っていただくのは無理です。「Ring 言語を使うとこういう楽しいことがある」という内容がない。セールスレターやカタログを書くときは、あんな書き方しませんよね。Wikibooks 読んでね。ソースコード読んでね。ロゼッタコード読んでね....じゃダメなんですよ。公式サイトのリンクを踏んでもらって Ring をダウンロードして、コードを書き続けることができる環境がないと思うんですよ。せめて Ruby くらいの水準でなければ...と思うのです。

 

今後の課題ですかね。まずは日本語版からなんとかする予定です。

RING API - ring_vm_funcregister2 の解析 (作業中)

まだまだ Ring ウェブサイトのほうは翻訳中です。

さて、該当個所のソースコードを引用しておきます。
ソースコードを読むに当たってすることは「辞書を作る」ことであると考えています。

/* Copyright (c) 2013-2018 Mahmoud Fayed <msfclipper@yahoo.com> */
#include "ring.h"
/* Support for C Functions */

RING_API void ring_vm_funcregister2 ( RingState *pRingState,const char *cStr, void (*pFunc)(void *) )
{
	List *pList  ;
	if ( pRingState->pRingCFunctions == NULL ) {
		pRingState->pRingCFunctions = ring_list_new_gc(pRingState,0);
	}
	pList = ring_list_newlist_gc(pRingState,pRingState->pRingCFunctions);
	ring_list_addstring_gc(pRingState,pList,cStr);
	ring_list_addfuncpointer_gc(pRingState,pList,pFunc);
}

ring/ring_api.c at ring-1.7-branch · ring-lang/ring · GitHubより引用 (使用条件は Ring のライセンスに従います)。


まず、気になるのがブロック内で使用されている関数ですね。これらは、 リスト・関数処理用ルーチンとして
ring/ring_list.c at ring-1.7-branch · ring-lang/ring · GitHub に収められています。

関数名 読み方 用途
ring_list_new_gc リング・リスト・ニュー・ジーシー
ring_list_newlist_gc リング・リスト・ニュー・リスト・ジーシー
ring_list_addstring_gc リング・リスト・アド・ストリング・ジーシー
ring_list_addfuncpointer_gc リング・リスト・アド・ファンク・ポインタ・ジーシー

現時点で用途は?にしておきますが、これではわからないので、

単語 意味
add 追加
gc ガベージコレクター(メモリ自動管理機構)の略記
list データ構造のリスト
new 新規作成
func 関数
pointer ポインタ

とすれば、少し当たりが付いて、用途が見えてくるかもしれません。
要するに、この ring_vm_funcregister2 は、

  • 関数ポインタ用のリスト配列に使用するメモリ配列オブジェクトの新規作成 (new_gc)
  • ...または作業領域の確保 (new_gc / new_list_gc)
  • Ring へ登録する拡張機能の命令追加? (ring_list_addstring_gc)
  • Ring へ登録する拡張機能の関数ポインタの追加? (ring_list_addfuncpointer_gc)

から構成されているものと思われます。
なのでキモとなるのは、

	ring_list_addstring_gc(pRingState,pList,cStr);
	ring_list_addfuncpointer_gc(pRingState,pList,pFunc);

の二行です。これが RingVM へ拡張機能を登録するための核の一つでしょう。

Ring の落とし穴(1) - 文字列宣言

ただいま、 Ring ウェブサイトを翻訳しているところです。こういうのが発生してしまうと、こちらの更新が遅れてしまうことが結構あります。日本国内で Ring を使用しているのは私以外いませんから仕方のないことです。


さて、
Ring には ShitJIS で問題となる 0x5C 問題はない(ファイル関数は未だ検証していません)ようで、

str = "表示シソ"
see str + nl

としても問題なく表示されます (文字列処理関数は別途製作のこと)。
ところが、 Ring のクォート処理には落とし穴があり、

str = "表示""シソ"
see str + nl

としてしまうとクォートの誤認識により「シソ」は切り捨てられていまいます (エラーにならないので見つけづらいものでもあります)。
なので

str = "表示" + "シソ"
see str + nl

とすれば表示されます。もしクォートも代入したい場合は、

str = "表示" + char(34) + "シソ"
see str + nl

とすれば良いです。また、 UTF-8 環境でしたら

str = :表示シソ
see str + nl

の記法を使用できます。この場合は文字列に空白文字を入れることはできませんので、状況に応じて使い分けるのが良いでしょう。



参考

RING API - ring_vm_funcregister について

簡易静的解析の結果です。正確さは保証しません。

用途
 RingVM へ拡張機能 (C関数) を登録します。

書式
 ring_vm_funcregister(x, y)

引数
 x : RingVM 側から呼び出される関数名 (const char *cStr)
 y : RING_API void hoge 形式の関数本体 (void *pfunc)

その他
 マクロ宣言は ./include/ring_api.h にあります。マクロに関連づけられている関数は ring_api.c の ring_vm_funcregister2() です。

対象バージョン
 Ring 1.7


読み方辞書 - ring_vm_funcregister
 こういう意味です。つまり「リング仮想計算機へC関数を登録するために使用されるマクロ定義関数」ですね。アスタリスクはみなさんのだいきらいなポインタです。ポインタについては Ring で拡張機能を作るには理解する以外無いので、そのうちイヤでも慣れるでしょう。

ring : リング
 プログラミング言語 Ring のことを指します。

vm : ブイエム (Virtual Machine の略称)
 仮想計算機、仮想機械

func : ファンク (Function の略称)
 関数

register : レジスタ
 登録する

str : エスティアール (Strings の略称)
 文字列。人によっては str の発音が異なるようです(スター、シュター、ストラなど)。詳しいことは str pronunciation あたりで検索してください。この連載では「エスティアール」とします。

parsec.ring の使用方法(1) - はじめに

はじめに

一通り Ring を学習し終えた後にデスクトップ、 RingQt など標準提供されている拡張機能をウェブ検索して資料・翻訳を集めながら使用するか、または拡張機能を自作するかのどちらかになりますが、これは英語読解の次に乗り越えるのが難しい壁でもあります。

しかし、他のマイナープログラミング言語とは違い、プログラミング言語 Ring には標準でC/C++コードラッパー生成器 (parsec.ring) が付属しています。ただ、 C/C++ のヘッダファイルを渡しただけでは自動生成できません (SWIGと同じ方法)。あらかじめ接続したい内容を記述した構成ファイルを用意する必要があります。この構成ファイルは、添付の説明書だけでは理解できない点が多くて parsec.ring と Ring に付属の *.cf ファイルを読まないと書くことも使うことすらできません。

これは多くのマイナー言語に当てはまることで、言語自体は習得しやすくても拡張機能を作るのは容易ではないのは Ring でもある意味で当てはまります。この記事では、 parsec.ring と *.cf の解析を行うことで RING_API と *.cf ファイルに関する理解を深めることを目的としています。

 

目次(予定)

事前準備

 ~未定~

 

ディレクティブ

  • <class> ~ </class>
  • <code> ~ </code>
  • <constant> ~ </constant>
  • <comment> ~ </comment>
  • <filter> ~ </filter>
  • <funcstart> ~ </funcstart>
  • <ignorecpointertype> ~ </ignorecpointertype>
  • <libinitfunc> ~ </libinitfunc>
  • <nodllstartup> ~ </nodllstartup>
  • <register> ~ </register>
  • <runcode> ~ </runcode>
  • <struct> ~ </struct>

 

ディレクティブ (変数)

  • aEnumTypes
  • aBeforeReturn
  • aFunctionCallback
  • aNewMethodName
  • aNumberTypes
  • aStringTypes

 

ディレクティブ (クラス属性)

  • abstract
  • codename
  • name
  • nonew
  • para
  • parent
  • passvmpointer
  • staticmethods (Ring 1.8 以降)

説明書に書いていないこと。

プログラミング言語 Ring の拡張機能を製作するにあたって取扱説明書 (extension.html, codegenerator.html) に記載されていないことを書いていきます (随時更新)。解析を始めたばかりだけでなく、Cはかなりの期間使用していなかったため、記述に間違いが多く含まれています。まだ未完成です。ご了承ください。


●対応 C/C++ コンパイラ
Visual C++ 2010 以降です。場合によっては C99 拡張でエラーになる箇所を C89 規格に対応したものに書き換える必要があります


●よく使われる型などの実体

 ・RingState 型は ring_state.h で構造体型として宣言されています。
 ・List 型は ring_list.h で構造体型として宣言されています。
 ・RING_API マクロは ring.h に定義されています。

宣言の内容がわからない場合は ./include フォルダにあるヘッダファイルに対して typedef, struct, define あたりで grep 検索すれば出てきます。また、構造体メンバの使用方法がわからないときも ./src フォルダのソースファイルに対して構造体メンバ名を検索することで使用して良いのか否かがわかります。


●void *pPointer の実体

ただの仮引数のようです。仮想機械の内部操作で使用されるため、ほとんどの関数では操作することはないようです。vm_stackvars.c の void vm_setreference関数では RING_VM_STACK_READP (ring_vm.h) が入ります。 VM構造体へキャストされて使われるのがセオリーのようです。これについては、もっとよくソースコードをよく調べてみないとわかりません。