これは、Ubuntu Online、Fedora Online、Windows オンライン エミュレーター、または MAC OS オンライン エミュレーターなどの複数の無料オンライン ワークステーションの XNUMX つを使用して、OnWorks 無料ホスティング プロバイダーで実行できるコマンド prima-gencls です。
プログラム:
NAME
gencls - Prima コアモジュール用のクラスインターフェイスコンパイラ
SYNOPSIS
gencls --h --inc --tml -O -I --depend --sayparent ファイル名.cls
DESCRIPTION
Prima コア モジュール オブジェクト定義の C マクロと構造体を含むヘッダーを作成します。
議論
gencls は次の引数を受け入れます。
--h .h ファイルを生成します (XNUMX つ以上のファイルに含まれる宣言を含む)
--株式会社
.inc ファイルを生成します (宣言は file のみに含まれます)
-O .inc ファイルの最適化アルゴリズムをオンにします。 アルゴリズムは仮定に基づいています。
一部の関数は同じように宣言されているため、処理するコード部分は
パラメータと結果の変換を共有できます。 「-O」フラグをオンにすると、サンクボディは
関数の呼び出しに置き換えられ、その名前はすべてのメソッドのパラメータから構成されます。
プラスの結果。 実際の関数は .inc ファイルではなく .tml ファイルに記述されます。 全て
.tml ファイルのセットから重複した宣言を削除でき、リマインダーが表示されます。
tmlink ユーティリティによって XNUMX つのファイルに書き込まれます。
--tml
.tml ファイルを生成します。 「-O」を自動的にオンにします。
-IDirname
ユーティリティが .cls ファイルを検索する検索パスにディレクトリを追加します。 できる
何度か指定されました。
- それによる
指定されたファイルの依存関係を出力します。
--親と言う
指定されたファイル内のクラスの直接の親を出力します。
構文
つまり、.cls ファイルの構文は次のスキームで記述することができます。
[ XNUMX 個以上の型宣言 ]
[ XNUMX 個または XNUMX 個のクラス宣言 ]
Gencls は、オブジェクトがない場合、または .cls ファイルのベース名を持つ .h、.inc、または .tml ファイルを生成します。
指定されたパッケージ名、またはオブジェクトまたはパッケージの名前を使用します。
Basic スカラー データ
Gencls には、処理方法を知っているいくつかの組み込みスカラー データ型があります。 「取引」するには
これは、C と perl の間でこれらのタイプのデータを転送するコードを生成できることを意味します。
XS ( perlguts を参照) ライブラリ インターフェイスを使用します。
タイプは次のとおりです。
int型
ブール
Handle
SV*
HV*
文字 *
文字列 (C 宣言は char[256] )
いくつかの派生組み込み型もあります。
長い
短い
チャリオット
色圏
U8
int にマッピングされます。 転送処理ではデータは int に変換されませんが、
代わりに、次を使用して Perl スカラーに保存されます newSViv() 関数によりビットが失われる可能性があります
またはサイン。
派生 データ
新しいデータ型定義の構文は次のとおりです。
スコープは、「グローバル」または「ローカル」の XNUMX つのプラグマのいずれかになります。 新しいデータの使用法をほのめかす
type、そのタイプが XNUMX つ以上のオブジェクトに対してのみ使用されるかどうか。 「ローカル」の使い方は、
C プラグマ static にいくらか似ています。 現時点での唯一の違いは、関数であることです。
パラメーター リストで複雑なローカル型を使用しているか、結果が対象ではないため
「-O」の最適化。
スカラー
新しいスカラー型は、主に C コーディングの場合にのみ、既存のスカラー型のエイリアスとして使用できます。
快適。 スカラー型は次の XNUMX つの方法で定義できます。
ダイレクトエイリアシング
構文:
$id => ;
例:
グローバル $Handle => int;
新しい型 ID は C ファイルでは表示されませんが、型は上書きされます。
この定義を含むすべての .cls ファイル。
Cマクロ
構文:
id1 id2
例:
グローバル API_HANDLE UV
このようなコードは、.h ヘッダー ファイルに C マクロ定義を形式で作成します。
#id1 id2 を定義します
パラメーターを含む C マクロは許可されません。 id1 と id2 は存在する必要はありません
.cls 名前空間内にあり、.cls ファイルの処理中に置換は行われません。 これ
プラグマの使用は非常に制限されています。
複雑な
複雑なデータ型には、配列、構造体、ハッシュなどがあります。 組み合わせたり、
スカラー (ただし複雑ではない) データ型のベクトル。
Gencls では、C 言語ではできない複雑なデータ型のいくつかの組み合わせが可能です
認識。 これらについては以下で説明します。
複雑なデータ型は Perl コードにインポートされません。 Perl プログラマは以下に準拠する必要があります。
パラメータを関数に渡すときに使用されるデータ型。
配列
構文:
@id [寸法];
例:
グローバル @FillPattern U8[8];
配列を使用した関数の例:
Array * func( 配列 a1, 配列 * a2);
Perlコード:
@ret = func(@array1, @array2);
配列参照は使用されず、すべての配列内の項目の数に注意してください。
パラメータは配列の次元と正確に一致する必要があります。
注: C は返すことができないため、次の宣言は C コンパイラではコンパイルされません。
配列。 ただし、gencls ではエラーとして扱われません。
配列関数();
構造体
構文:
@id {
;
...
;
};
例:
グローバル @Struc {
整数;
文字列ID;
}
構造体を使用した関数の例:
Struc * func1( Struc a1, Struc * a2);
Struc func2( Struc a1, Struc * a2);
Perlコード:
@ret = func1( @struc1, @struc2);
@ret = func2( @struc1, @struc2);
配列参照は使用されず、すべての項目の数と順序の両方が使用されることに注意してください。
配列パラメータは、構造体の次元と順序と正確に設定する必要があります。 構造体
フィールド名は Perl コードでも使用されません。
ハッシュ
構文:
%id {
;
...
;
};
例:
グローバル %ハッシュ {
整数;
文字列ID;
}
ハッシュを使用する関数の例:
ハッシュ * func1( ハッシュ a1, ハッシュ * a2);
ハッシュ func2( ハッシュ a1, ハッシュ * a2);
Perlコード:
%ret = %{func1( \%hash1, \%hash2)};
%ret = %{func2( \%hash1, \%hash2)};
ハッシュ参照のみが使用され返されることに注意してください。 Perlからハッシュが渡される場合
コードでは、一部またはすべてのフィールドが設定されていない可能性があります。 C 構造体が埋められて、
C 関数に割り当てられ、設定解除されたフィールドは対応する関数に割り当てられます。
C_TYPE_UNDEF 値。TYPE は、NUMERIC、STRING、および POINTER リテラルのいずれかです。
逆変換ではこれらの値は考慮されず、常にすべてのハッシュ キーが返されます。
対応するペア。
名前空間
構文:
{
...
}
.cls ファイルには、関数の説明を含む名前空間セクションを XNUMX つまたは XNUMX つ含めることができます。
ここで説明する関数は、コードの初期化中に指定された ID にエクスポートされます。 あ
名前空間は「オブジェクト」または「パッケージ」のいずれかになります。
パッケージ名前空間構文では、「パッケージ」内の関数の宣言のみが許可されます。
ブロック。
パッケージ{
...
}
オブジェクトの名前空間構文には、関数だけでなく変数とプロパティも含まれます (
オブジェクト構文で呼び出されるメソッド)。 一般的なオブジェクト名前空間の構文は次のとおりです。
物体[(親クラスID)] {
}
オブジェクト名前空間内では、継承構文を使用できます。
物体( ) { ... }
または、裸のルート オブジェクトの説明 (祖先なし)
物体{ ... }
オブジェクトクラス宣言の場合。
機能
構文:
[ 】 ( ) [ => ];
例:
int package_func1( int a, int b = 1) => c_func_2;
ポイント package_func2( Struc * x, ...);
メソッド void object_func3( HV * プロファイル);
プレフィックスは、オブジェクト関数 (メソッド) でのみ使用されます。 接頭辞の詳細については「メソッド」を参照してください。
のセクションから無料でダウンロードできます。
関数は何も返さない ( void )、スカラー ( int、string など)、または複合値 (
配列、ハッシュ)タイプ。 型を指定したスカラーおよび複合パラメータも受け入れることができます。
前述の「基本的なスカラー データ型」で説明したルールに対応する変換
のセクションから無料でダウンロードできます。
関数に変換できない型のパラメータや結果がある場合
C と perl の間で自動的に宣言されますが、perl 名前空間には公開されません。 の
対応する警告が発行されます。 gencls 構文を使用して宣言することはできません。
カスタムパラメータまたは結果データを使用した関数。 このような目的のために、明示的な C
「newXS」呼び出しとともにコードの宣言を行う必要があります。
例: 省略記号 (...) は gencls では変換できませんが、正当な C 言語です。
建設。
ポイント package_func2( Struc * x, ...);
関数の構文には、いくつかの便利な追加機能があります。
デフォルトのパラメータ値
例:
void func( int a = 15);
このように宣言された関数は、パラメータ 0 または 1 の両方を指定して呼び出すことができます。 もしそれが
0 パラメータで呼び出された場合は、整数値 15 が自動的に使用されます。 の
構文では、int、ポインター、string 型のデフォルト パラメーターとそのスカラーが許可されます。
エイリアス。
デフォルトのパラメータはできるだけ多く指定できますが、パラメータはファイルの最後にある必要があります。
関数パラメータのリスト。 「func( int a = 1, int b)」という宣言が正しくありません。
エイリアシング
生成された C コードでは、パラメータが設定された後に C 関数を呼び出す必要があります。
解析された。 Gencls は、準拠した関数が固定名で C コードに存在することを期待します。
そしてパラメータリスト。 ただし、そのような関数のタスクが同一の関数のラッパーである場合は、
関数が別の名前で公開されている場合、エイリアシングを実行してコードとコードの両方を保存できます。
速度。
例:
パッケージ パッケージ {
void func( int x) => 内部;
}
そのように宣言された関数は呼び出されません パッケージ機能() C関数ですが、
内部() 代わりに関数を使用します。 唯一のお願いは、 内部() 関数には必ず必要があります
同一のパラメータと結果宣言 func().
インラインハッシュ
Perl からパラメータとしてハッシュを使用して関数を呼び出す便利な方法が考案されました。 もし
関数は最後のパラメータまたは型 "HV*" を使用して宣言され、パラメータ変換が行われます。
perl から C への変換は、渡されたすべてのパラメータがハッシュであるかのように実行されます。 このハッシュは
C 関数に渡され、その内容が返され、再びハッシュとして Perl に戻されます。
ハッシュの内容は C 関数内で変更できます。
この宣言はコンストラクターで頻繁に使用され、これが典型的な Perl コードです。
サブ初期化
{
私の %ret = シフト-> SUPER::init( @_);
...
%ret を返します。
}
そしてCコードは通常、
void Obj_init ( HV * プロファイル) {
継承された init(profile);
... [プロファイルの内容を変更する] ...
}
メソッド
メソッドは、オブジェクトのコンテキストで呼び出される関数です。 事実上すべてのメソッドで必要となるのは、
扱っているオブジェクトにアクセスできます。 Prima オブジェクトは C では次のように表示されます。
ハンドルのデータ型。 このようなハンドルは実際にはオブジェクト インスタンスへのポインタであり、オブジェクト インスタンスは
オブジェクト仮想メソッド テーブル ( VMT ) へのポインターが含まれます。 OO のようなものを促進するには
構文では、この Handle パラメーターがオブジェクトのすべてのメソッドで言及されることはほとんどありません。
cls ファイル内の記述は暗黙的にカウントされるため、すべての cls メソッド
宣言
メソッド void a( int x)
オブジェクトクラスの場合、Object は C に次のように反映されます。
void Object_a( 自分自身をハンドルします, int x)
関数宣言。 パッケージ関数とは異なり、gencls は次の場合には公開できません。
変換できないパラメータでサポートされていないパラメータを処理することはできません。
このような宣言をメソッドで発行します。 その主な用途は、メソッド名が取得されることです。
オブジェクトの VMT で予約されています。
C コードでは、「Handle self」を直接名前で逆参照することでメソッドにアクセスできます。
対応する構造:
((( PSampleObject) self)-> self)->sample_method( self, ...);
メソッドには、C コード生成を制御する XNUMX つのプレフィックスのいずれかを付けることができます。
方法
これは最初で最も基本的なメソッド タイプです。 プレフィックス名「メソッド」は
したがって、最もわかりやすい名前として が選ばれました。 メソッドは次のようにコーディングされることが期待されます
C では、オブジェクト ハンドルは暗黙的であり、.cls の記述には含まれません。
メソッド void a()
結果は
void Object_a( 自分自身をハンドル)
C宣言。 公開されたメソッドは、パラメータと結果を自動的に変換します。
C と Perl の間。
公共
自動的に実行できないパラメータや結果を持つメソッドの場合
C と Perl の間で変換された関数を宣言する必要があるか、関数宣言が必要ありません。
C 構文に適合させるには、「public」プレフィックスが使用されます。 「public」で宣言されたメソッドは次のとおりです。
XS ( perlxs を参照) インターフェイスを使用して perl と通信することが期待されます。 それも
「パブリック」メソッドは、REDEFINED 関数と FROMPERL 関数の両方を作成することが期待されます (「パブリック」メソッドを参照)
詳細については Prima::internal を参照してください)。 Prima ソース全体に例が多数あります。
ここでは表示されません。 「パブリック」メソッドは通常、結果が無効でパラメータがありませんが、
gencls はそのようなメソッドに対して変換を生成しないため、これはあまり問題ではありません。
import
C でコーディングするのが不合理なメソッドの場合は、代わりに perl を使用して gencls を使用できます。
「import」プレフィックスを使用して対応するラッパーを生成するように指示されます。 この種の
Method は裏返しに「メソッド」と見なすことができます。 「インポート」関数には C は必要ありません
自動生成コードを除く、対応するもの。
静的な
メソッドがオブジェクト インスタンスの有無にかかわらず動作できる必要がある場合、次のことが必要です。
「静的」プレフィックスを先頭に付加します。 「静的」メソッドはすべて「メソッド」メソッドと同様です。
ただし、「Handle self」の最初のパラメータが暗黙的に宣言されていない点が異なります。 「静的」の場合
メソッドはオブジェクトなしで (ただしクラスを使用して) 呼び出されます。次のようになります。
クラス::オブジェクト-> static_method();
最初のパラメータはオブジェクトではなく、「Class::Object」文字列です。 メソッドが決してない場合
オブジェクトを扱う場合は、その宣言を次のように使用するだけで十分です。
static a( char * className = "");
しかし、そうであれば、
static a( SV * class_or_object = nil);
申告が必要です。 後者の場合、C コード自体が正確に何を持っているかを判断する必要があります。
仮に合格したとしても。 ここでのデフォルトのパラメータに注意してください。「静的」メソッドは通常、
として呼び出すことができる
クラス::オブジェクト::静的メソッド();
ここではパラメータは渡されません。 デフォルトパラメータを使用しない場合、このような呼び出しは
「渡されたパラメーターが不十分です」ランタイム エラーが生成されます。
奇妙な
これ以上良い名前が見つかりませんでした。 「奇妙な」という接頭辞は、次のことを組み合わせた方法を示します。
「静的」と「パブリック」の両方のプロパティ。 言い換えれば、gencls は何も生成しません。
変換コードであり、そのようなメソッドの最初のパラメータとして「Handle self」を期待していません。
例として、Prima::Image::load を表すことができます。これは、ワイド メソッドを使用して呼び出すことができます。
呼び出しセマンティクスの範囲 (詳細については、Prima::image-load を参照)。
c_only
その名前が示すように、「c_only」は VMT 上に存在するメソッドですが、VMT には存在しません。
perlからアクセス可能。 C からのみオーバーロードできます。 また、許可されているのは、
「c_only」メソッドの名前で Perl 関数を登録し、それでもこれらのエンティティを登録します
相互に完全に独立しているため、過負荷は発生しません。
注意: 変換できない結果および/またはパラメータのデータ型を持つメソッド
自動的にプレフィックスを「c_only」に変更します。 おそらくこれは間違った行為であると思われますが、
このような状態はエラーを通知する必要があります。
プロパティ
Prima ツールキットは、メソッドを置き換えることが期待されるプロパティという名前のエンティティを導入します。
たとえば、内部オブジェクト変数を取得して割り当てる機能を持つペア。
オブジェクト名、色など。Object::set_color や
Object::color プロパティである Object::get_color が考案されました。 プロパティとは、
特別な考慮事項、特にパラメータなしで呼び出される場合、「get」モード
が暗示されています。 逆に、XNUMX つのパラメータを指定して呼び出された場合は、「set」モードがトリガーされます。
「set」呼び出しと「get」呼び出しの両方で、「Handle self」の最初の暗黙パラメータは次のとおりであることに注意してください。
常に存在します。
プロパティは、異なる、ただし固定量のパラメータを使用して動作し、「設定」を実行できます。
および 'get' 関数は XNUMX つだけです。 デフォルトでは、唯一のパラメータは暗黙的な「ハンドル」です。
自己":
プロパティ char * 名前
C に対応するものがある
char * Object_name( ハンドル自身、Bool セット、char * 名前)
モードに応じて、「Bool set」は「true」または「false」のいずれかになります。 「set」モードでは C コード
結果は破棄され、「get」モードではパラメータ値は未定義です。
複数パラメータプロパティの構文は次のとおりです。
プロパティ long ピクセル( int x, int y);
とCコード
long Object_pixel(ハンドル self、Bool セット、int x、int y、long ピクセル)
複数パラメータの場合、プロパティ名の後に宣言されたパラメータは次のとおりであることに注意してください。
「set」モードと「get」モードの両方で常に初期化されます。
インスタンス variables
すべてのオブジェクトは、その固有の内部状態によって特徴付けられます。 Gencls 構文では、
変数宣言。オブジェクト インスタンスごとに割り当てられる変数の場合。 それでも
変数のデータ型検証は実行されず、変数の宣言のみが取得されます。
配列、構造体、関数ポインタを含む複雑な C 宣言は「そのまま」コピーされます。
認識されません。 回避策として、typedef されたエンティティへのポインタが使用されます。 例:
オブジェクト SampleObject {
int x;
リストリスト;
struct { int x } s; # 違法な申告
}
C コードでは、「Handle self」を直接名前で逆参照することで変数にアクセスできます。
対応する構造:
(( PSampleObject) self)-> x;
作者
ドミトリー・カラシク[メール保護]>。 アントン・ベレジン[メール保護]>.
onworks.net サービスを使用してオンラインで prima-gencls を使用する