-
Notifications
You must be signed in to change notification settings - Fork 7
PSLVM
#PSLVM C++クラスPSLVM
PSLスクリプトを実行する為のバーチャルマシンクラス
クラス名が全て大文字なのは許せ
##メソッド
- loadString(const string &str) // 文字列をソースとしてコンパイルする
- loadScript(const string &filename) // ソースを読み込んでコンパイル、またはバイトコードを読み込む
- loadCompiledCode(std::FILE *fp, unsigned long size) // コンパイル済みバイトコードを読み込む
- loadCompiledCode(const string &filename)
- writeCompiledCode(std::FILE *fp) // コンパイル済みのバイトコードを出力する
- writeCompiledCode(const string &filename)
ここまでは全てenum PSLVM::error列挙体の値を返す
NONE = 0,
FOPEN_ERROR,
PARSE_ERROR,
NOT_COMPILED_CODE,
- get(const string &name) // スクリプトグローバル変数を取得する
- add(const string &name, const variable &v) // スクリプトグローバル変数を設定する
- run(const variable &arg = 0) // スクリプト実行する
getの戻り値は特殊な内部の型で、一度variableで受けなければ数値や文字列に変換は出来ない
getはグローバル変数の持つ値を取得するのではなく
スクリプトグローバル変数そのものを取得する
変数の値はされ、受け取った変数を操作すればスクリプトグローバル変数も書き換わる
addは変数の値ではなく、variableそのものを登録する
つまりこちらも登録された変数は内外で共有される
一時的なvariable以外のもの(メンバ変数として所持しているものや、グローバルなvariable等)を登録する場合は注意すること
runの際に引数を渡せる、スクリプトは一番外側のローカル変数argとして受け取る
一番外側でリターンした値を返す
それもvariableでしか受けられない
###その他バインダ関係 binderとEmbeddableを適当に参照して下さい
###各種読み込みとrunについて
loadString,loadScript,loadCompiledCode,loadCompiledCodeは
スクリプトまたはバイトコードを読み込み、その実行準備を整える
実行準備が整った状態でrunを呼び出すことでスクリプトが実行される
runが終了したらVMは終了状態となり、再びrunしてももう一度スクリプトが実行される様なことはない
但し、run中にyieldしてrunの呼び出し元まで直接戻ってきた場合は
再びrunを呼び出すことで続きから再開出来る
終了したVMで、もう一度スクリプトを読み込むことは可能である
読み込み後には当然、run出来る様になる
スクリプトで定義した関数とクラスは読み込みが完了した時点で生成されている
よってrunしなくてもgetで取り出すことが可能である
その他のあらゆる文と式は実行時に解釈される
global変数の宣言も解釈され作成されるのは実行時である
runしないまま複数のスクリプトを読み込んだ場合は
次にrunした際にイメージとしてはscript2(script1());
こうなる
1度のrun呼び出しで一気に実行される
バインダを経由すると、run中にC++関数を呼び出しその中で更に(同じVMでの)loadやrunが可能であるが
普通に死ぬのでやらないで下さい
シナリオ制御スクリプトの様な特化言語では「次のスクリプトへのジャンプ」という動作が普通に行われますが
汎用言語であるPSLでは無理です
現在のコールツリーを無かったことにして別の関数にジャンプする
と考えれば無茶っぷりは分かるかと思います
適当な方法で代用して下さい
##クラスの性質
PSLVMのインスタンスは幾つ作っても問題ありませんが
作成時にPSL標準関数の登録をするので少しコストがあります
標準のコンパイルオプションでは
全てのVM間でグローバル変数を共有します
詳しい話はglobalの項を参照のこと
ネイティブスレッドの各スレッドにそれぞれVMを作りたい場合は
それ以外にも問題があるのでPSL_THREAD_SAFEをONにして下さい
また、stringとvariableをそのままスレッド間で受け渡しするのは避けた方が無難です