|
SCPP
A simple scripting language in C++
|
Webドキュメント「SCPPの使い方」で、名前空間や関数の解説ページへのリンクが貼られたドキュメントを閲覧できます。
SCPPは、C++17で動作します。 SCPPを使用するためには、scpp_ast.hppとscpp_evaluater.hppの2ファイルをincludeしなければいけません。
SCPPは、整数型を用い、スクリプトは式(の組み合わせ)によって記述されます。 式は、SCPP::Expr 構造体のインスタンスとして表現されます。
SCPPの記述に用いる関数は、名前空間SCPPに定義されています。
整数型は、C++のint型と同様に、16ビット以上の符号付き整数です。 整数型は、 tInt()関数を用いて記述します。 整数型は、式の一種です。
四則演算(加算+、減算-、乗算*、除算/)は、 tAdd(), tSub(), tMul(), tDiv()関数を用いて記述します。 これらの関数は、2つの式SCPP::Exprを引数にとります。
mod式は、 tMod()関数を用いて記述します。 これは、2つの式SCPP::Exprを引数にとります。
比較演算(==、!=、<、<=、>、>=)は、 tEq(), tNe(), tLt(), tLe(), tGt(), tGe()関数を用いて記述します。 これらの関数は、2つの式SCPP::Exprを引数にとります。
真の場合は1、偽の場合は0として評価されます。
否定!は、SCPPに存在する唯一の単項論理演算です。 tNot()関数を用いて記述します。 これは、1つの式SCPP::Exprを引数にとります。
評価する式が真(非ゼロ)の場合は0、偽(ゼロ)の場合は1として評価されます。
二項論理演算(論理積AND、論理和OR、排他的論理和XOR、論理否定NAND、論理否定NOR)は、 tAnd(), tOr(), tXor(), tNand(), tNor()関数を用いて記述します。 これらの関数は、2つの式SCPP::Exprを引数にとります。
評価する式は、非ゼロの場合真、ゼロの場合偽として評価します。 演算結果が真の場合は1、偽の場合は0として評価されます。
条件分岐は、 tIf()関数を用いて記述します。 これは、3つの式 SCPP::Expr condition, thenClause, elseClauseを引数にとります。
conditionが真の場合は、thenClauseが評価され、偽の場合はelseClauseが評価されます。
変数は、代入及び参照することができます。
変数の代入は、 tAssign()関数を用いて記述します。 この関数は、第1引数として、変数名を表す文字列 string nameを、第2引数として、代入する式 SCPP::Expr valueを、それぞれとります。
第1引数として与えられた名前の変数が存在しない場合、新たに変数が宣言され、第2引数の式が代入されます。
変数の代入は、式の一種であり、評価される際は、代入された値、すなわち、第2引数の式の評価結果が返されます。
変数の参照は、 tIdent()関数を用いて記述します。 この関数は、変数名を表す文字列を引数にとります。
与えられた名前の変数が存在しない場合、新たに変数が宣言され、0が代入されます。
複数の式を連続して実行する、連接式は、 tSeq()関数を用いて記述します。 この関数は、任意の個数の式SCPP::Exprを引数にとり、それらを左から順に評価します。 一番最後の式の評価結果が、連接式の評価結果となります。
なお、引数が0個の場合は、0として評価されます。
繰り返しは、while式及びfor式の2種類があります。
繰り返しの本体や初期化式ではじめて代入された変数も、グローバル変数として扱われ、繰り返しの外側からも参照可能になります。
while式は、 tWhile()関数を用いて記述します。 この関数は、第1引数として、繰り返し条件を表す式SCPP::Expr conditionを、第2引数として、繰り返し本体を表す式SCPP::Expr bodyを、それぞれとります。
conditionが真の間、bodyを繰り返し実行します。 conditionが偽になった時点で、while式の評価結果となります。
初期状態でconditionが偽の場合、while式の評価結果は0となります。
この例において、tIdent()が初めて呼ばれた際、変数xが宣言され、0が代入されていることに注意してください。
for式は、 tFor()関数を用いて記述します。 この関数は、第1引数として、初期化式SCPP::Expr initを、第2引数として、繰り返し条件を表す式SCPP::Expr conditionを、第3引数として、繰り返し後の処理を表す式SCPP::Expr stepを、第4引数として、繰り返し本体を表す式SCPP::Expr bodyを、それぞれとります。
initを実行し、conditionが真の間、bodyとstepを続けて実行します。 conditionが偽になった時点で、for式の評価結果となります。
初期状態でconditionが偽の場合、for式の評価結果は0となります。
関数呼び出し式は、 tCall()関数を用いて記述します。 この関数は、第1引数として、関数名を表す文字列string nameを、第2引数として、任意の個数の引数を表す式SCPP::Exprを、それぞれとります。
宣言されていない関数を呼び出した場合、エラーとなり、その旨が標準エラー出力に出力されます。式は、0として評価されます。
関数の定義については、後述します。
式は、evaluate()関数を用いて評価することができます。
evaluate()関数に、評価したい式を引数として渡すと、その式の評価結果がC++のint型として返されます。
この例では、1+5の評価結果である6が返され、標準出力に出力されます。
プログラム機能を用いると、独自の関数を定義し、それを用いたプログラムを記述することができます。
プログラム内で宣言された変数・関数のスコープは、そのプログラム内です。
プログラムは、構造体 SCPP::SFunctionのインスタンスとして表現されます。 実用上、tProgram()関数を用いて記述することができます。
この関数は、第1引数として、関数の構造体のリスト list<struct SCPP::SFunction> functionsをとり、第2引数以降は、0個以上の任意の個数の式SCPP::Exprをとります。 functionsで定義された関数は、プログラムの中で呼び出すことができます。
関数の構造体のリストlist<struct SCPP::SFunction>は、FunctionList()関数を用いて作成することができます。(後述) リストは、空であってもよく、複数の同名関数が定義された場合は、最後に定義された関数が優先されます。
評価時には、第2引数から前から順に評価され、最後の式の評価結果が、プログラムの評価結果となります。
関数は、構造体 SCPP::SFunctionのインスタンスとして表現されます。 実用上、tFunction()関数を用いて記述することができます。
この関数は、第1引数として、関数名を表す文字列 string nameを、第2引数として、引数のリスト list<string> argsを、第3引数以降は、0個以上の任意の個数関数の本体を表す式 SCPP::Exprを、それぞれとります。
引数のリスト list<string> argsは、ParamList()関数を用いて作成することができます。 ParamListは、0個以上の任意個数のstring引数名を引数としてとり、それらをリストにして返します。 ParamListの引数として、定義する関数の仮引数の名前を全て指定します。
リストは、空であってもよいですが、同名の仮引数がある場合の動作は未定義です。
プログラム構造体の作成の際は、FunctionList()関数を用いて、関数の構造体のリストを作成しなくてはなりません。 この関数は、0個以上の任意個数のSCPP::SFunctionを引数としてとり、それらをリストにして返します。
プログラムは、evaluateProgram()関数を用いて実行・評価することができます。
evaluateProgram()関数に、実行したいプログラムを引数として渡すと、そのプログラムの評価結果がC++のint型として返されます。