トップページへ | [ 一覧 | 検索 | 最終更新 ] [ 差分 | 履歴 | 凍結 ] |
関数†基礎の基礎†YAYAにおける「関数」とは、
処理の集まりです。 引数の数は、変数 _argc、各引数は、変数 _argv[n] に格納されています。 出力候補とは、関数内に直接書かれた文字列や数値、変数名など、左辺値(「=」の左側)が無いものの集まりです。 また、同名の関数が複数存在するとエラーになります。(特に既存のゴーストをベースに改編する場合に注意) 次の「基礎」の章は、汎用言語DLLとしてのYAYAにとっての「関数」です。良く分からない場合は読み飛ばしてかまいません。 基礎†request実行時に"Hello World"という文字列を返すプログラムコードの全体を以下に示します。 request { "Hello World" } 文をロードしたモジュールがHGLOBAL request(HGLOBAL h, long *len)を実行すると、このスクリプトが実行され、"Hello World"が
返されます。
loadとunloadも同様です。 loadとrequestはひとつの引数を持っています。これは変数で取り出せます。 _argc†引数の数。loadとrequestでは引数はひとつの文字列ですから1となります。unloadは引数を持たないので、この値は0となります。 _argv†引数の実体が格納されています。これは_argc個の要素を持つ配列です。各要素へのアクセスは演算子[i]で行います。 基礎編のまとめとして、loadでは変数strに"Hello"を格納し、requestで引数として渡された文字列とstrを結合して返すプログラムコードを 示します。~これまでの説明を踏まえて読んでみてください。 load { str = "Hello" } request { str + " " + _argv[0] + "!" } 処理対象文字列を"World"としてrequestを実行すると、結果として"Hello World!"が得られます。 書式†以下の則があります。
つまり先に挙げたHello Worldコードは以下のように1行に詰めて書くことが出来ます。 request{"Hello World"} では以下のように書いてもいいのか? もちろん。問題なく動作します。(ただしこんな風に書くのは感心できない!) req/ uest { "/ Hello World" } /の次の行(新たに結合される行)先頭にある空白文字はインデント文字と見なされ、消されます。 "ABCD EFG" 第4項を説明します。 request { answer = 1 + 2 "答えは" + answer + "です。" } セミコロンを使用して以下のように書けます。 request { answer = 1 + 2; "答えは" + answer + "です。" } セミコロンは過剰に書いても問題ありません。それらは無視され、動作に影響は与えません。 ユーザー関数の定義と実行†load、unload、request以外に好きな名前の関数を作成できます。 request { hello } hello { "Hello World" } 上に示したのはもっとも単純な例です。requestは結果として"Hello World"を返します。 同じ結果が得られるもう少し複雑な例を、以下に示します。 request { combine("Hello", "World") } combine { _argv[0] + " " + _argv[1] } 関数名の後ろに( )をつけて、その中にカンマで値を並べて書くと、これらは該関数に渡される引数として扱われます。
すなわち変数_argvと_argcに値が格納されて、該関数内で参照できるようになります。
関数は再帰呼び出しが可能です。 request { factorial(5) } factorial { if !_argv[0] 1 else factorial(_argv[0] - 1)*_argv[0] } requestは120を返します。 択一†request { "Hello World" "こんにちは世界" "Hallo Welt" } このように列挙すると、これらは平等な「出力候補」として扱われ、出力はこれらのうちのいずれかひとつになります。 下記のいずれかを選ぶことができます。ただし、voidとarray / pool_arrayは特殊な用途のみで使用します。 指定なし / random†デフォルトでは無作為に選択します。 nonoverlap†できるだけ直前と同じ候補を選択しなくなります。 request : nonoverlap { "Hello World" "こんにちは世界" "Hallo Welt" } 上のように、関数名の後ろに ": nonoverlap" を付け加えます。 関数によっては実行毎に出力候補の数が変動します。~たとえば以下の関数は、変数iの値によって候補数は2個もしくは4個に変化します。 request : sequential { if i { "1" "2" } "3" "4" } 候補数が変化した場合、nonoverlapとsequential(後述)の巡回順序は初期化され、最初からやり直しになります。この時に限って、前回と同じ値が重複して 出力されることはあり得ます。 sequential†記述された順に出力します。最後まで出力したらまた先頭に戻ります。 request : sequential { "Hello World" "こんにちは世界" "Hallo Welt" } 上のように、関数名の後ろに ": sequential" を付け加えます。 array†出力候補をすべて結合した汎用配列を関数の返値とします。 request : array { "This is a pen." ("A","B","C") 3.14 } 出力は汎用配列 ("This is a pen.", "A", "B", "C", 3.14) となります。 void†何も出力しなくなります。 request : void { "Hello World" "こんにちは世界" "Hallo Welt" } 「何も実行しない」ではなく、「何も出力しない」であることに注意してください。 increment_i : void { i++ i } 上の関数increment_iはiに1を加算します。voidが無い場合、この関数は加算結果を返しますが、voidを指定すると値を返さず、 ただ加算を行うのみとなります。 all†Tc567-1で実装 選択候補すべてを1つの文字列に結合します。 last†Tc567-1で実装 選択候補の中から、一番最後の候補を出力として選択します。 _pool 修飾子†Tc563-1で実装 択一指定の後ろに_poolを加えると、下記のようなコードにおいて… request : random //または random_pool (poolと書くだけでも可) { "Hello World" if 1 { "こんにちは世界" "Hallo Welt" } } 中括弧に囲まれた部分は本来random指定として選択された後で候補に加えられますが、random_pool指定では囲まれない部分と同列に扱うことができます。
nonoverlap_pool、sequential_pool、array_poolなどのようにも書けます。 melt_ 修飾子†Tc567-1で実装 択一指定の前に melt_ を加えると、汎用配列のパラレル出力と同じ効果になります。 例:melt_array 主に下記の「入れ子」で使います。 入れ子†request { { "Hello World" "こんにちは世界" } "Hallo Welt" } { } は階層的にいくつでも重ねて書くことが出来ます。動きは最上層の{ }と同じです。すなわち、包含される候補からひとつを選択して出力します。 入れ子内の択一指定 (Tc564-1)†request { nonoverlap : { "Hello World" "こんにちは世界" } "Hallo Welt" } 以上のように、入れ子それぞれに前項の択一指定を追加できます。 if文などの直後に続く { } に指定するには、";"で区切って以下のようにするか、改行を追加します。 request { if 1 ; nonoverlap : { "Hello World" "こんにちは世界" } "Hallo Welt" } request { if 1 nonoverlap : { "Hello World" "こんにちは世界" } "Hallo Welt" } 出力確定子†request { "Hello" "Perfect" "Peaceful" -- " Wor" -- "ld" "th" } ‐‐は出力確定子というもので、選択候補はここを区切りとしてグループ分けされます。そして、グループごとに選ばれた結果がひとつの文字列に結合されます。 "Hello World" "Perfect World" "Peaceful World" "Hello Worth" "Perfect Worth" "Peaceful Worth" nonoverlap、sequential、arrayと組み合わせて使用した場合、(グループ単位ではなく)関数が取り得る全ての組み合わせに対して動作します。 たとえばsequentialは、 request : sequential { "1" "2" "3" -- "A" "B" } requestは以下の順序で出力を発生します。 "1A" "2A" "3A" "1B" "2B" "3B" "1A" "2A" … たとえばarrayは、 request : array { "1" "2" "3" -- "A" "B" } 上記関数は、 ("1A","1B","2A","2B","3A","3B") という汎用配列を出力します。 文は文字列のほかに数値なども扱えますが、出力確定子は結合する際にそれらをすべて文字列に変換し、文字列として結合します。 |
最終更新日: 2021-12-09 (木) 16:08:57
|