Top(FrontPage)
トップページへ
[
一覧
|
検索
|
最終更新
] [
差分
|
履歴
]
ツール
ヘルプ
新規
開始行:
*AYA Version5 マニュアル [#z8a62102]
このマニュアルは、HTML形式で配布されているものを、すぐに...
[[AYA Version5 システム関数>../システム関数]]も参照してく...
#contents
*概要 [#ja5d0838]
「あや」と読みます。文字列処理を行なうためのDLLです。
C言語に似た文法を使用して、
-与えられた文字列を加工する
-プログラムした規則に拠って文字列を生成する
といった処理を行なうことが出来ます。
文はWindows DLLですので、直接利用するためには、プログラミ...
*環境 [#ca7d9a37]
Windows用です。
開発のごく初期に98SE、2000、xpで動作確認しましたが、最終...
報告をいただけると助かります。
*利用規定 [#d695caea]
-使途を限定せず自由に利用することが出来ます。~
-配布パッケージに含まれているすべてのファイルを自由に取り...
-このプログラムを使用した結果、あなたに何らかの損害が発生...
-ソースコードを改変して自由に異版を作成し、配布することが...
その際、配布者はその意志に基づいたライセンスを独自に策定...
*主な変更点 [#i6200e2f]
version 4系列の文をお使いの方は、この項を読むことでversio...
**新機能/改善された機能 [#r7165c5b]
-UTF-8に対応~
version 4で扱える文字コードはShift_JISのみでしたが、versi...
-数式書式の制限撤廃~
関数の引数に数式を記述できない、代入演算子や比較演算子を...
-if等の真偽判定が0/非0判定へ~
version 4ではif等の判定式のために特別の書式が必要でした。...
-汎用配列機能を追加~
型を混在して格納可能な配列構造が追加になりました。~文字列...
-範囲付き埋め込み展開~
"hello, %username" を "hello, %(username)" のように書けま...
-各種システム関数追加~
正規表現、ランダム選択、書式化出力など、従来不可能だった...
-foreach~
簡易配列、汎用配列に対してforeachが使えます。
-動作速度の向上~
実行するスクリプトに強く依存しますが、ループや変数展開な...
-version 4が抱える問題の解決~
version 4はパーサがぬるく、これに起因する種々の不安定動作...
version 5ではそのような不安定要因は極力排除されています。
-エラーログ改善~
ログに記録されえるエラーの内容が詳細化されました。エラー...
**変更された機能 [#dcaed67a]
version 5の開発においては、version 4が抱える不具合や仕様...
互換性の確保にも配慮が無かったわけではありませんが、それ...
以下の点で互換性が崩れています。移植の際には注意が必要で...
-上位/下位インタフェース変更~
重要で本質的な変更です。version 4ではHTTP風リクエストヘッ...
-システム関数全面見直し~
version 4が持つシステム関数のうち、完全に同一機能のまま引...
最も注意を要するのは文字列処理系の関数です。~
version 4 STR*系(バイト数単位)、MSTR*系(文字数単位)...
version 5 STR*系(文字数単位)~
STR*系関数が残されましたが、動作はMSTR*系のものになってい...
-システム変数全廃~
_argv、_argc以外のシステム変数は廃止されました。ただし同...
-空の文字列~
version 4では空の文字列と値無しの区別が不明確でした。vers...
-関数/変数名の先頭に数値を使えない~
version 4では使用可能でした(そもそも12hourというシステム...
他にも変数名/関数名として使用不可能になった文字が存在しま...
-機能制限設定機能は未搭載~
考えた結果、とりあえず未実装としました。
-そのほか...~
version 4のパーサが弱かったおかげで見逃されていたエラーが...
*エクスポートしている関数 [#ye0e5ed7]
文は以下の公開された関数を持っています。
文を利用するプログラムは、文をLoadLibraryした後にこれらの...
#code(c,nooutline,nolink,nonumber){{
extern "C" __declspec(dllexport) BOOL __cdecl load(HGLOBA...
}}
文に初期化を指示します。~
文をLoadLibraryして使用を開始する直前に、この関数を一度だ...
hには「文がカレントとして認識するディレクトリ絶対パス」を...
hの領域開放は文側で行ないますので、呼び出し側では使い放し...
#code(c,nooutline,nolink,nonumber){{
extern "C" __declspec(dllexport) BOOL __cdecl unload()
}}
文に終了を指示します。~
文をFreeLibraryする直前に一度だけ実行してください。
#code(c,nooutline,nolink,nonumber){{
extern "C" __declspec(dllexport) HGLOBAL __cdecl request(...
}}
文に処理を指示し、結果を得ます。~
hには処理対象の文字列を、*lenにhの長さを渡してください。
渡したhの領域開放は文側で行ないますので、呼び出し側では使...
処理結果は戻り値で得られます。処理結果の長さは*lenに格納...
戻り値を取得した後、領域を*lenで示されるサイズで開放(Glob...
なお、これはデスクトップマスコットソフトウェア「伺か」で...
のインタフェース規格と完全に同一のものです。
*基礎設定 [#nc75848b]
文 ver.5のデフォルトのDLLファイル名は「aya5.dll」です。~
主ファイル名「aya5」は他の名前に自由に変更することができ...
文を動作させるためには「基礎設定ファイル」と呼ばれるファ...
基礎設定ファイルのファイル名は「主ファイル名.txt」です。...
「hoge.dll」に変更したなら、基礎設定ファイルは「hoge.txt...
基礎設定ファイルはテキストファイルで、実行されるOSのデフ...
もし国際化に関して考慮しなければならないなら、マルチバイ...
以下に例を示します。
#code(aya,nooutline,nolink,nonumber){{
// dics
dic, basis.dic
dic, control./*doc*/ayc
// option parameters
charset, UTF-8
msglang, english
log, executelog.txt
iolog, off
fncdepth, 16
}}
設定はコマンドとパラメータをカンマで区切って指定します。~
空行(改行のみの行)、"//"以降、および"/*"と"*/"で囲まれ...
コマンドとその意味は以下の通りです。
***charset, name [#lfff9e83]
標準の文字コードを設定します。~
以下の予約値からいずれかを指定します。指定が無い場合はShi...
-Shift_JIS / ShiftJIS / SJIS~
シフトJISコード。
-UTF-8~
UTF-8。
-default~
実行OSのデフォルト文字コード。
***dic, filename [#rbfd65d8]
辞書ファイルfilenameをロードします。~
辞書ファイルは文スクリプトが記述されたプログラムソースフ...
辞書ファイルはいくつでも指定し、読み込むことができます。
filenameはloadで指定されたパス位置からの相対パスで指定し...
標準の辞書ファイルはcharsetで指定した文字コードで記述され...
暗号化ファイルを読み込むことができます。
***msglang, language [#ba19005d]
ログに記録されるエラーメッセージ類の言語を選択します。~
以下の予約値からいずれかを指定します。指定が無い場合はjap...
-japanese~
日本語。
-english~
英語。
***log, logfilename [#m583923d]
実行ログをファイルlogfilenameに記録します。~
charsetで指定した文字コードで書き込まれます。
logfilenameはloadで指定されたパス位置からの相対パスで指定...
***iolog, [on|off] [#pb05622c]
load、unload、request実行時の入出力文字列と処理時間をログ...
onで記録します。デフォルトではonになっていますので、不要...
***fncdepth, depth [#p6bb4967]
関数呼び出しの深さ上限を数値で指定します。~
デフォルト値は32です。最低値は2で、これより小さな値や不正...
*文スクリプトリファレンス [#p83ee35b]
文スクリプトの書式はC言語のそれを踏襲しています。~
したがってあらかじめC言語、およびC言語に類似する言語を習...
*関数 [#r29732f5]
**基礎 [#r94d7456]
request実行時に"Hello World"という文字列を返すプログラム...
#code(aya,nooutline,nolink,nonumber){{
request
{
"Hello World"
}
}}
文をロードしたモジュールがHGLOBAL request(HGLOBAL h, long...
返されます。
loadとunloadも同様です。~
ただしloadとunloadは値を返さないので、出力文字列を書いて...
unloadには逆にその後始末をするコードを書きます。
必要な関数だけ書けばよいです。不要なものは省けます。~
たとえば上の例ではloadとunloadは書いていませんが、これは...
極端な例を挙げるなら、辞書ファイルがまったく無くてもエラ...
requestは空の文字列を返します。
loadとrequestはひとつの引数を持っています。これは変数で取...
変数の名前は_argcと_argvで、これはC言語のmain関数のインタ...
***_argc [#f09b1d74]
引数の数。loadとrequestでは引数はひとつの文字列ですから1...
***_argv [#v1dd42c9]
引数の実体が格納されています。これは_argc個の要素を持つ配...
序数iは0オリジン指定です。たとえば_argcが1の場合は_argv[0...
基礎編のまとめとして、loadでは変数strに"Hello"を格納し、r...
示します。~これまでの説明を踏まえて読んでみてください。
#code(aya,nooutline,nolink,nonumber){{
load
{
str = "Hello"
}
request
{
str + " " + _argv[0] + "!"
}
}}
処理対象文字列を"World"としてrequestを実行すると、結果と...
**書式 [#s79234f5]
以下の則があります。
-空行(改行のみの行)、"//"以降、および"/*"と"*/"で囲まれ...
-1行の終わりがスラッシュ("/")の場合は、次の行がこの行の...
-行頭、および単語間には自由に空白文字を入れることが出来ま...
-複数のステートメントを1行に詰めて書きたい場合は、セミコ...
つまり先に挙げたHello Worldコードは以下のように1行に詰め...
#code(aya,nooutline,nolink,nonumber){{
request{"Hello World"}
}}
では以下のように書いてもいいのか? もちろん。問題なく動...
#code(aya,nooutline,nolink,nonumber){{
req/
uest {
"/
Hello World" }
}}
/の次の行(新たに結合される行)先頭にある空白文字はインデ...
したがって以下の文字列の結合結果は "ABCDEFG" であり、決し...
#code(aya,nooutline,nolink,nonumber){{
"ABCD
EFG"
}}
第4項を説明します。~
以下のrequestは1+2の答えを求め、日本語の文章にして返して...
#code(aya,nooutline,nolink,nonumber){{
request
{
answer = 1 + 2
"答えは" + answer + "です。"
}
}}
セミコロンを使用して以下のように書けます。
#code(aya,nooutline,nolink,nonumber){{
request
{
answer = 1 + 2; "答えは" + answer + "です。"
}
}}
セミコロンは過剰に書いても問題ありません。それらは無視さ...
したがって、あなたがC言語の書式に慣れているなら、各行の終...
**ユーザー関数の定義と実行 [#f5f27796]
load、unload、request以外に好きな名前の関数を作成できます...
作成した関数は、その名前を書くだけで実行できます。
#code(aya,nooutline,nolink,nonumber){{
request
{
hello
}
hello
{
"Hello World"
}
}}
上に示したのはもっとも単純な例です。requestは結果として"H...
同じ結果が得られるもう少し複雑な例を、以下に示します。
#code(aya,nooutline,nolink,nonumber){{
request
{
combine("Hello", "World")
}
combine
{
_argv[0] + " " + _argv[1]
}
}}
関数名の後ろに( )をつけて、その中にカンマで値を並べて書く...
すなわち変数_argvと_argcに値が格納されて、該関数内で参照...
ここで挙げた例では、combine関数内において_argcは2、_argv[...
関数名は自由につけられますが、以下に抵触する名前はエラー...
-数字0~9で始まる。
--定数の数字として解釈される可能性があります。
-アンダースコア("_")で始まる。
--アンダースコアで始まる名前はローカル変数で使われていま...
-以下の文字を含む。~
空白 ! " # $ % & ( ) * + , - / : ; <...
--アンダースコア以外の記号は使わないほうが良いでしょう。
-予約語と完全に一致する。
--アルファベット大文字+アンダースコアはシステム関数で使...
--forやwhile、ifなど、制御構造に使われるものも避けなけれ...
関数は再帰呼び出しが可能です。~
もっともありふれた例として階乗計算を行った例を挙げます。
#code(aya,nooutline,nolink,nonumber){{
request
{
factorial(5)
}
factorial
{
if !_argv[0]
1
else
factorial(_argv[0] - 1)*_argv[0]
}
}}
requestは120を返します。
**択一 [#vce5bec3]
#code(aya,nooutline,nolink,nonumber){{
request
{
"Hello World"
"こんにちは世界"
"Hallo Welt"
}
}}
このように列挙すると、これらは平等な「出力候補」として扱...
5種類の選択方法が用意されており、いずれかを選ぶことができ...
***なにもなし [#c8db39e4]
デフォルトでは無作為に選択します。
***nonoverlap [#y4e0c799]
すべての候補が出力されるまでは、同じ候補を選択しなくなり...
#code(aya,nooutline,nolink,nonumber){{
request : nonoverlap
{
"Hello World"
"こんにちは世界"
"Hallo Welt"
}
}}
上のように、関数名の後ろに": nonoverlap"を付け加えます。
***sequential [#m0d8b091]
記述された順に出力します。最後まで出力したらまた先頭に戻...
#code(aya,nooutline,nolink,nonumber){{
request : sequential
{
"Hello World"
"こんにちは世界"
"Hallo Welt"
}
}}
上のように、関数名の後ろに": sequential"を付け加えます。
***void [#sd2e95a2]
何も出力しなくなります。~
以下の例の場合、requestは3つの候補のどれも出力しません。
#code(aya,nooutline,nolink,nonumber){{
request : void
{
"Hello World"
"こんにちは世界"
"Hallo Welt"
}
}}
「何も実行しない」ではなく、「何も出力しない」であること...
内部に書かれた関数や数式は処理されます。
#code(aya,nooutline,nolink,nonumber){{
increment_i : void
{
i++
i
}
}}
上の関数increment_iはiに1を加算します。voidが無い場合、こ...
ただ加算を行うのみとなります。
***array [#b6965d54]
出力候補をすべて結合した汎用配列を関数の返値とします。~
#code(aya,nooutline,nolink,nonumber){{
request : array
{
"This is a pen."
("A","B","C")
3.14
}
}}
出力は汎用配列 ("This is a pen.", "A", "B", "C", 3.14) と...
nonoverlapとsequentialは、出力確定子が存在する場合でも取...
たとえばsequentialを例に挙げると、
#code(aya,nooutline,nolink,nonumber){{
request : sequential
{
"1"
"2"
"3"
--
"A"
"B"
}
}}
requestは以下の順序で出力を発生します。
#code(aya,nooutline,nolink,nonumber){{
"1A" "2A" "3A" "1B" "2B" "3B" "1A" "2A" …
}}
関数によっては実行毎に出力候補の数が変動します。~たとえば...
#code(aya,nooutline,nolink,nonumber){{
request : sequential
{
if i {
"1"
"2"
}
"3"
"4"
}
}}
候補数が変化した場合、nonoverlapとsequentialの巡回順序は...
出力されることはあり得ます。
**入れ子 [#icb3830b]
#code(aya,nooutline,nolink,nonumber){{
request
{
{
"Hello World"
"こんにちは世界"
}
"Hallo Welt"
}
}}
{ } は階層的にいくつでも重ねて書くことが出来ます。動きは...
ただし選択方法は無作為抽出のみで、最上層のようにnonoverla...
上の例では、{ }の有無にかかわらず結果は同じであるように思...
{ }が無い場合、それぞれが出力される確率は平等に1/3です。...
**出力確定子 [#bc934c88]
#code(aya,nooutline,nolink,nonumber){{
request
{
"Hello"
"Perfect"
"Peaceful"
--
" Wor"
--
"ld"
"th"
}
}}
--は出力確定子というもので、選択候補はここを区切りとして...
したがって上のrequestを実行すると、以下のいずれかが出力さ...
#code(aya,nooutline,nolink,nonumber){{
"Hello World"
"Perfect World"
"Peaceful World"
"Hello Worth"
"Perfect Worth"
"Peaceful Worth"
}}
nonoverlap、sequentialと組み合わせて使用した場合、(グル...
出力確定子はどこでも問題なく使用できます。{ }入れ子の深い...
文は文字列のほかに数値なども扱えますが、出力確定子は結合...
*値と変数 [#n1ee12d5]
**即値 [#g354a67e]
文が扱える値は整数、実数、文字列の3種類です。
***整数 [#l7eb7352]
符号付き32bit整数です。
10進数値はそのまま記述します。~
先頭に"0b"を付加することにより、2進数値を記述できます。~
先頭に"0x"を付加することにより、16進数値を記述できます。
以下の関数int10は整数10を返します。3つの記述はいずれも10...
#code(aya,nooutline,nolink,nonumber){{
int10
{
10
0b1010
0xa
}
}}
***実数 [#e2e3fb8f]
符号付き64bit浮動小数点数です。小数点以下の桁がある場合や...
整数との区別は小数点の有無です。文は数値に小数点を見つけ...
***文字列 [#db427a23]
ダブルクォート(")で囲まれた値は文字列です。
文字列の中にダブルクォートが含まれてはいけません。
***文字列(展開なし) [#ea52b392]
シングルクォート(')で囲まれた値は、展開されない単純な文...
文では文字列中に変数や関数を埋め込むことが出来ますが、こ...
文字列の中にシングルクォートが含まれてはいけません。
**変数 [#xb7e9ffb]
変数は値を格納するための領域です。~
ひとつの変数には、
-整数、実数、文字列
-要素ごとに上記のいずれかを格納可能な汎用配列
を格納することができます。
名前は以下の禁止条項に抵触しない限りは自由につけることが...
-数字0~9で始まる。
-以下の文字を含む。~
空白 ! " # $ % & ( ) * + , - / : ; <...
-予約語と完全に一致する。
-関数名と完全に一致する。
値の格納(代入)は代入演算子 = で行ないます。内容を出力す...
#code(aya,nooutline,nolink,nonumber){{
request
{
str = "こんにちは"
str
}
}}
上は単純な例で、変数strに文字列を格納し、そのまま出力して...
まだ値が代入されていない変数は、空の文字列を出力します。~...
#code(aya,nooutline,nolink,nonumber){{
request
{
"Hello World"
i
}
}}
i は存在しません。これは空の文字列になりますから、結局上...
#code(aya,nooutline,nolink,nonumber){{
request
{
"Hello World"
""
}
}}
**変数のスコープと寿命 [#b50694fc]
変数はスコープ(有効範囲)の違いによって2種類存在します。
-グローバル変数~
すべての関数で共通に使用できる変数。寿命は永遠。
-ローカル変数~
現在の{ }内、およびそれより深い入れ子階層のみで使用できる...
両者を区別するのは変数の名前です。変数名の先頭がアンダー...
「必要な範囲だけで有効な変数」であるローカル変数をうまく...
#code(aya,nooutline,nolink,nonumber){{
request
{
_i = "3*2は"
_j = multi(3)
_i +_j + "です"
}
multi
{
_i = _argv[0]
_i * 2
}
}}
requestとmultiが同じ名前の変数 _i を使っていますが、それ...
関数の引数を扱う変数_argcと_argvも実はローカル変数である...
ローカル変数になっているわけです。
ローカル変数が「現在の関数内で使用可能な変数」ではなく、...
#code(aya,nooutline,nolink,nonumber){{
request
{
{
_str = "Hello World"
}
_str
}
}}
このプログラムは期待通りには動作しません。~
_strは{ }内のみで有効ですから、出力を取り出そうとしている...
したがって、この関数requestは空の文字列を出力します。
グローバル変数とローカル変数の違いはもうひとつあります。...
ローカル変数は上で見たとおり、変数を使用している{ }から外...
対してグローバル変数はどこでも使用可能、さらにunloadでそ...
*演算 [#q3ea1bb9]
**基本 [#v84b1e7f]
C言語と同様の書式で四則演算、比較演算、代入、その他が可能...
演算の順序は演算子毎に重み付けされた演算優先度に基づいて...
演算子の種類と演算優先度は以下の通りです。
演算子 意味 ...
( ) [ ] ブラケ...
! 否定
++ -- ポスト...
* / % 乗除算...
+ - 加減算
& フィー...
== != >= <= > < _in_ !_in_ 比較
&& 論理積
|| 論理和
= := 代入
+= -= *= /= %= +:= -:= *:= /:= %:= ,= 演算し...
, 汎用配...
コロン(":")付きの代入演算子は過去互換性を保持するために...
~*は単項演算子です。
ブラケット( )については次項で詳説します。~
カンマ演算子(",")、およびスクウェアブラケット[ ]につい...
フィードバック演算子&については別項で詳説しています。
_in_と!_in_は文字列の包含チェックに使用する演算子です。
#code(aya,nooutline,nolink,nonumber){{
foo
{
"or" _in_ "World"
}
}}
_in_は左辺の文字列が右辺の文字列に含まれていれば1、含まれ...
上の関数fooは1を返します。
比較演算子は結果が真であれば整数1を、偽であれば0を返しま...
これらの演算子は文字列に対しても正しく機能します。値の大...
論理の真偽は以下で判断されます。~
偽 整数0、実数0.0、空の文字列、空の汎用配列~
真 上記以外のすべて
代入でない演算は結果がそのまま出力となります。
#code(aya,nooutline,nolink,nonumber){{
foo
{
(3+2)*4
}
}}
この関数fooは20を出力します。
同じ優先度の演算子が連続している場合は、常に左から結合さ...
#code(aya,nooutline,nolink,nonumber){{
1+2-3
}}
たとえば上の式は
+ 1+2
+ 3-3
の順に計算されます。
#code(aya,nooutline,nolink,nonumber){{
i = j = 10
}}
これはどうなるでしょう。C言語では代入演算子は右から結合さ...
しかし文では結合は常に左からです。すなわち
+ i = j
+ j = 10
の順に計算されます。したがって、iには10は入らないのです。
#code(aya,nooutline,nolink,nonumber){{
i = (j = 10)
}}
これで i にも10が入るようになります。
演算対象の項の型が一致していない場合、結果の型は以下のよ...
-整数と実数の演算~
結果は実数となります。
-整数/実数と文字列の加算~
数値は文字列に変換された後、もう一方の文字列に結合されま...
-整数/実数と文字列の演算(加算以外)~
演算不能ですがエラーとはなりません。結果は空の文字列とな...
ひとつの演算式内で型が混在していても構いません。~
必要に応じて、上記の法則により型変換が起こります。
#code(aya,nooutline,nolink,nonumber){{
"10+2は" + (10+2) + "です。"
}}
最初に10+2が整数として計算され、結果12が得られます。残り...
**ブラケット( )による演算順序制御 [#q7b01c6f]
ブラケット( )で囲んだ部分は演算順序が最優先扱いになります...
( ) はいくつでも重ねて指定可能で、深くなるほど優先度が上...
平たく言えば「かっこで囲んだところを先に計算する」という...
数式の書き方によってはなかなかややこしいこともあります。~
以下の例を見てください。
#code(aya,nooutline,nolink,nonumber){{
answer = (_i = 10) + (2*(_i + 10))
}}
文の演算則をよく理解している人でないと、answerに何が代入...
answerには文字列の"10"が入ります。決して整数50ではありま...
最初に計算されるのはどこでしょう。ブラケットが一番深いと...
ここまで説明すれば結果が文字列の"10"になる理由は明白でし...
さて、こちらの意図ではまず_i = 10の代入を先にしてもらいた...
このような場合、文では以下のようにブラケットを過剰に付与...
#code(aya,nooutline,nolink,nonumber){{
answer = (((_i = 10))) + (2*(_i + 10))
}}
これで代入部分の優先度が一気に引き上げられました。今度は...
なお、代入部分を囲むブラケットは2段で十分ではないかと思わ...
**フィードバック演算子& [#a2371f18]
フィードバック演算子&は、他の演算子とは使い方がまったく異...
#code(aya,nooutline,nolink,nonumber){{
request
{
_i = 1
foo(&_i)
}
foo
{
_argv[0] = 100
}
}}
関数呼び出しの際に引数として変数を与える場合、その先頭に&...
先頭に&を付けられた変数は、呼び出し先関数の_argvの対応す...
上の例では、fooを実行すると _i の値が100に書き換わります。
フィードバック演算子は好きな位置にいくつでも使用可能です。
#code(aya,nooutline,nolink,nonumber){{
request
{
foo(1, 2, &_value, "Hello", &_value2)
_value + _value2
}
foo
{
_argv[2] = _argv[0] + _argv[1]
_argv[4] = _argv[3] + " World"
}
}}
関数requestは "3Hello World" を出力します。
当然のことですが、フィードバック演算子は変数にしか付けら...
*配列 [#g4feb8c1]
演算子[ ]は配列要素にアクセスするための演算子です。
配列には文字列スプリットを擬似的に配列と見なす「簡易配列...
**簡易配列 [#u1e86766]
文字列に含まれるカンマをデリミタ(区切り文字)と解釈して...
#code(aya,nooutline,nolink,nonumber){{
request
{
_a = "this,is,a,pen"
_a[1]
}
}}
requestは"is"を出力します。
[ ]演算子が処理する対象は変数である必要はありません。即値...
上の例は以下のように書いても同じです。
#code(aya,nooutline,nolink,nonumber){{
request
{
"this,is,a,pen"[1]
}
}}
序数の後ろにカンマ区切りでデリミタを指定することにより、...
#code(aya,nooutline,nolink,nonumber){{
request
{
"This is a island."[2,"is"]
}
}}
"is"で区切るわけですから、文字列は以下のように分解されま...
[0] "Th"~
[1] " "~
[2] " a "~
[3] "land."~
したがってrequestは" a "を返します。
デリミタ指定をうまく使うと、多次元配列風に値を取り出すこ...
#code(aya,nooutline,nolink,nonumber){{
request
{
_ar = "taro|male,ayame|female,hotaru|female"
_ar[2][1,"|"]
}
}}
_ar[2]は"hotaru|female"です。さらに"|"を区切り文字として...
このように、階層毎にユニークなデリミタを適用することによ...
範囲外の序数を指定した場合の出力は、存在しない変数の値を...
ここからは変数限定の機能を解説します。
要素に代入が可能です。
#code(aya,nooutline,nolink,nonumber){{
request
{
_a = "this,is,a,pen"
_a[3] = "eraser"
_a
}
}}
"pen"を"eraser"に書き換えています。requestの実行結果は"th...
デリミタ指定しても正しく機能します。
#code(aya,nooutline,nolink,nonumber){{
request
{
_s = "This is a island."
_s[2,"is"] = " beautiful "
_s
}
}}
requestは"This is beautiful island."を出力します。
多次元配列風に[ ]演算子を連結して使用している場合、代入は...
#code(aya,nooutline,nolink,nonumber){{
request
{
_ar = "taro|male,ayame|female,hotaru|female"
_ar[1][1,"|"] = "male"
}
}}
ayameの性別をmaleに書き換えようとしていますが、この操作は...
現在の要素数を越える位置へも問題なく代入できます。デリミ...
#code(aya,nooutline,nolink,nonumber){{
request
{
_m = "fuji/asama/tanigawa"
_m[5,"/"] = "daisen"
_m
}
}}
requestは"fuji/asama/tanigawa///daisen"を出力します。
SETDELIMという関数を使用すると、「デフォルトのデリミタ」...
先に示した例をSETDELIMを使用して書き換えたものを以下に示...
#code(aya,nooutline,nolink,nonumber){{
request
{
_m = "fuji/asama/tanigawa"
SETDELIM(_m, "/")
_m[5] = "daisen"
_m
}
}}
SETDELIMすることにより、単純に_m[5]と書くことができるよう...
多次元配列風に[ ]演算子を連結して使用している場合、SETDEL...
**汎用配列 [#r1f9d606]
汎用配列はさまざまな型の値を混在して格納できる配列構造で...
一般的なアクセスでは簡易配列より高速に動作します。
***初期化 [#z1cfbf85]
#code(aya,nooutline,nolink,nonumber){{
i = (100,"test",-1.5)
}}
要素をカンマで列挙して記述します。~
代入する場合は上のように要素の集合を( )で囲んでください。...
#code(aya,nooutline,nolink,nonumber){{
(i = 100),"test",-1.5
}}
このように解釈されてしまいます。
配列を空の状態で初期化するには、IARRAYという関数を使用し...
#code(aya,nooutline,nolink,nonumber){{
i = IARRAY
}}
初期化時に要素をひとつだけ代入したい場合は工夫が要ります...
以下のように記述します。
#code(aya,nooutline,nolink,nonumber){{
i = (IARRAY,100)
}}
***要素追加 [#ua3a26fe]
#code(aya,nooutline,nolink,nonumber){{
i = (i,"add")
}}
とすると配列の後端に"add"が追加されます。
配列を追加することもできます。~
#code(aya,nooutline,nolink,nonumber){{
i = (i,("add",123,0.0))
}}
a = a + 1 を a += 1と略せるように、上の例は下のようにも書...
#code(aya,nooutline,nolink,nonumber){{
i ,= ("add",123,0.0)
}}
先頭への挿入も同じ書式で可能です。
#code(aya,nooutline,nolink,nonumber){{
i = ("first",i)
}}
中途への挿入もできます。
#code(aya,nooutline,nolink,nonumber){{
i = (100,200,300,400,500,600)
i[2] ,= "insertion"
}}
iは(100,200,300,"insertion",400,500,600)となります。~
挿入対象は[2]でなく[3]に入ることに注意してください。
i[2]へ挿入したい場合は
#code(aya,nooutline,nolink,nonumber){{
i[2] = ("insertion",i[2])
}}
とします。
***要素削除 [#f152b05f]
削除したい要素へIARRAYを代入します。
#code(aya,nooutline,nolink,nonumber){{
i = (100,200,300,400,500,600)
i[2] = IARRAY
}}
300が削除され、iは(100,200,400,500,600)となります。
***値の更新 [#n6fd0d08]
単純に要素へ代入できます。
現在の要素数を越える位置へも問題なく代入できます。必要な...
***値の取り出し [#u9fd841d]
通常の変数と同様、序数を指定して記述すればそのまま出力さ...
範囲外の序数を指定した場合の出力は、存在しない変数の値を...
#code(aya,nooutline,nolink,nonumber){{
i = (100,200,300,400,500,600)
i[4]
}}
500が出力されます。
[ ]演算子が処理する対象は変数である必要はありません。即値...
#code(aya,nooutline,nolink,nonumber){{
(100,200,300,400,500,600)[4]
}}
500が出力されます。
汎用配列をそのまま関数の出力にできます。
#code(aya,nooutline,nolink,nonumber){{
request
{
river[2]
}
river
{
"tenryu","bandou-tarou","ishikari","shimanto"
}
}}
requestは"ishikari"を出力します。
***多次元化はできない [#e6240c23]
汎用配列は多次元配列を構成できません。
#code(aya,nooutline,nolink,nonumber){{
(100,200,(300,400),500,600)
}}
このように書いても、内包されたブラケット部分が副次的な配...
結局以下のように単純に結合されてしまいます。
#code(aya,nooutline,nolink,nonumber){{
(100,200,300,400,500,600)
}}
***演算 [#z99403e7]
要素単位の演算は通常に行うことが出来ます。
汎用配列と単項値との演算は、「全要素へ単項値が演算される...
#code(aya,nooutline,nolink,nonumber){{
pref = "gunnma","ohsaka","hokkaido"
pref += "-ken"
answer = (2*(1,2,3))[1]
}}
prefは "gunnma-ken","ohsaka-ken","hokkaido-ken" となりま...
answerには4が代入されます。~
2*(1,2,3)の計算結果が(2,4,6)となるからです。
***関数の引数 [#se6e58da]
文において関数の引数は汎用配列です。_argvの内容は、呼び出...
つまり
#code(aya,nooutline,nolink,nonumber){{
func(1, 2, "test")
}}
という関数の呼び出しは、
#code(aya,nooutline,nolink,nonumber){{
_i = (1,2,"test")
func(_i)
}}
とも書けます。非常にトリッキーな表記ですが、これで意図ど...
注意してください。書き直したスクリプトにおいても、引数の...
この構造をうまく利用すると、可変長の引数を他の関数へ簡単...
#code(aya,nooutline,nolink,nonumber){{
request
{
total(1,2,3,4,5,6)
}
total
{
calc_total(_argv)
}
calc_total
{
_answer = 0;
foreach _argv; _val { _answer += _val }
_answer
}
}}
totalは自分では何もせず、すべての引数をそのままcalc_total...
この例では単純に引き渡していますが、もちろん必要に応じて...
引数の指定方法が複雑になっている場合は注意すべきです。
#code(aya,nooutline,nolink,nonumber){{
_i = (1,2,"test")
func("sky", _i, "sun")
}}
上の呼び出しは以下と等価です。汎用配列は多次元化できない...
#code(aya,nooutline,nolink,nonumber){{
func("sky", 1, 2, "test", "sun")
}}
***デリミタ/取得数指定 [#o22fa826]
#code(aya,nooutline,nolink,nonumber){{
_i = (2,"is")
"This is a island."[_i]
}}
簡易配列のデリミタ指定の部分も汎用配列です。したがって上...
#code(aya,nooutline,nolink,nonumber){{
"This is a island."[2,"is"]
}}
**範囲指定 [#rce6669c]
簡易配列/汎用配列とも、序数を範囲で指定できます。取得、代...
範囲は汎用配列で指定します。たとえば i[a,b] は「iの要素a...
#code(aya,nooutline,nolink,nonumber){{
name = ("さくら","せりこ","奈留","まゆら","毒子","美耳")
i = name[1,3]
name[3,4] = "奎子"
j = name
name[0,2] = IARRAY
k = name
}}
iには ("せりこ","奈留","まゆら") が格納されます。~
jは ("さくら","せりこ","奈留","奎子","美耳") 、~
kは ("奎子","美耳") となります。
範囲外は無視されます。
#code(aya,nooutline,nolink,nonumber){{
n = (1,2,3,4)
n[-2,1] *= 5
}}
nは (5,10,3,4) です。
対象が簡易配列の場合でも書式は同じです。
#code(aya,nooutline,nolink,nonumber){{
name = "さくら,せりこ,奈留,まゆら,毒子,美耳"
i = name[1,3]
name[3,4] = "奎子"
j = name
}}
iは "せりこ,奈留,まゆら" 、jは "さくら,せりこ,奈留,奎子,...
デリミタ指定も可能です。範囲指定のすぐ後ろに続けて指定し...
#code(aya,nooutline,nolink,nonumber){{
animal = "くま!うさぎ!ねこ!いぬ!わに"
i = animal[0,2,"!"]
animal[2,4,"!"] = "ぶた"
j = animal
}}
iは "くま!うさぎ!ねこ" 、jは "くま!うさぎ!ぶた" です。
**汎用配列のパラレル出力 [#j8feade9]
すべての式/値の前に「parallel」を書くことができます。~
parallelは出力候補値が汎用配列だった場合、
要素のそれぞれを出力候補値にする機能を持っています。
#code(aya,nooutline,nolink,nonumber){{
foo0
{
("A","B","C")
"地球"
}
foo1
{
parallel ("A","B","C")
"地球"
}
}}
foo0の出力は、("A", "B", "C") もしくは "地球"。~
foo1の出力は、"A"、"B"、"C"、"地球" のいずれかとなります。
汎用配列以外にparallelを使っても意味がなく、書かないのと...
#code(aya,nooutline,nolink,nonumber){{
parallel STRLEN("earth")
STRLEN("earth")
}}
択一メソッドarrayとparallelを利用することにより、関数の出...
さまざまな応用が考えられます。たとえば以下の非常に簡潔な...
#code(aya,nooutline,nolink,nonumber){{
cyclic : sequential
{
parallel _argv
}
}}
*文字列内埋め込み要素の展開 [#x744505a]
文字列の中に変数や関数を埋め込んで、これらの実行結果を当...
**範囲付き展開 [#a0bd2710]
要素を%( )で囲んで埋め込みます。
#code(aya,nooutline,nolink,nonumber){{
request
{
_i = "pen"
"This is a %(_i)."
}
}}
requestを実行すると、"This is a pen."が出力されます。
%( )はいわゆるeval(文字列をスクリプトコードと解釈して実...
単一の関数や変数だけでなく、数式を埋め込むことができます。
#code(aya,nooutline,nolink,nonumber){{
request
{
"1+2+3は%(1+2+3)です。"
}
}}
requestは"1+2+3は6です。"を出力します。
文の文字列は内部にダブルクォートを含むことが出来ない点に...
#code(aya,nooutline,nolink,nonumber){{
request
{
"This is a %(_i = "pen")."
}
}}
このような場合は、埋め込みを使用せず通常の数式として結合...
#code(aya,nooutline,nolink,nonumber){{
request
{
"This is a " + (_i = "pen") + "."
}
}}
ブラケット( )による演算順序制御は範囲付き展開でも同様に働...
#code(aya,nooutline,nolink,nonumber){{
request
{
"遊星「%(_i = planet)」は遠い。この遊星は%(color(_i))...
}
planet
{
"mars"
"saturn"
"pluto"
}
color
{
case _argv[0] {
when "mars"; "red"
when "saturn"; "yerrow"
when "pluto"; "blue"
others; "unknown"
}
}
}}
最も( )が深いのはcolor(_i)の引数ですので、_i = planetの前...
ブラケットを過剰付与して演算順序を調整してください。
#code(aya,nooutline,nolink,nonumber){{
"遊星「%((_i = planet))」は遠い。この遊星は%(color(_i))色...
}}
これで矛盾の無い文字列が得られるようになります。
**名称最長一致展開 [#u078e2e3]
( )を付与せず、単に%のみでも埋め込み展開は機能します。
#code(aya,nooutline,nolink,nonumber){{
request
{
o = "pen"
obj = "eraser"
object = "world"
"This is a %object."
}
obje
{
"television"
}
}}
展開対象は%以降の文字列に一致する最も長い名前を持った変数...
結果は"This is a world."となります。
変数は刻々と作成されたり消えたりしますから、展開対象が状...
これは範囲付き展開には見られない特徴です。
#code(aya,nooutline,nolink,nonumber){{
request
{
val = "red"
trans
--
value = "blue"
trans
}
trans
{
"%value"
}
}}
transは二度実行されますが、最初と二度目では"%value"の動き...
requestの出力は"redueblue"です。
%[ ]という書式で過去の展開結果を再利用できます。
#code(aya,nooutline,nolink,nonumber){{
request
{
"「%planet」は遠い。「%city」も遠い。もっとも%[1]にな...
}
planet
{
"mars"
"saturn"
"pluto"
}
city
{
"newyork"
"moscow"
"madrid"
}
}}
%[i]は0オリジンでi番目の展開結果を得ます。~
つまり上の例では、%[0]が%planetの、%[1]が%cityの展開結果...
%[ ]は範囲付き展開では使えません。範囲付き展開で過去の結...
名称最長一致による展開は実行する度に展開対象を検索しなお...
本当に必要な場合は別ですが、通常は範囲付き展開を利用すべ...
*フロー制御 [#r383aae0]
**ifによる分岐 [#s7f37fda]
式の結果が真であれば以降に続く{ }内を処理します。
#code(aya,nooutline,nolink,nonumber){{
request
{
if !i {
"iは0である。"
}
}
}}
すぐ後にelseif節を付加することができます。これはifの判定...
いくつでも連結できます。~
また、if~elseifの最終端にはelse節を置くことができます。...
処理されます。
#code(aya,nooutline,nolink,nonumber){{
request
{
if !i {
"iは0である。"
}
elseif i == 5 {
"iは5である。"
}
elseif "A" _in_ TOUPPER(i) {
"iは文字列で、aもしくはAを含んでいる。"
}
else {
"iは0でも5でもaを含む文字列でもない何物かである。"
}
}
}}
if、elseif、elseが処理する{ }内にスクリプトが1つしか存在...
下のように書きなおすことが出来ます。
#code(aya,nooutline,nolink,nonumber){{
request
{
if !i
"iは0である。"
elseif i == 5
"iは5である。"
elseif "A" _in_ TOUPPER(i)
"iは文字列で、aもしくはAを含んでいる。"
else
"iは0でも5でもaを含む文字列でもない何物かである。"
}
}}
ただしifが重なっている場合は{ }の省略は出来ません。以下は...
#code(aya,nooutline,nolink,nonumber){{
if i == 0
if j == 0
"iとjはともに0である。"
}}
以下のように{ }が必要です。
#code(aya,nooutline,nolink,nonumber){{
if i == 0 {
if j == 0
"iとjはともに0である。"
}
}}
C言語と同様に、ifの判定式は全体をブラケット( )で囲むこと...
動作は囲まない場合と変わりません。~
if、elseif、case、while、for、switchの判定式で使用できま...
**caseによる分岐 [#l73d8c0f]
caseはラベル分岐構造を実現します。
#code(aya,nooutline,nolink,nonumber){{
request
{
case i {
when 0 {
"iは0である。"
}
when "A"
"iは文字列Aである。"
others {
"iは0でもAでもない。"
}
}
}
}}
caseに与えられた判定式の結果に一致するラベル値を持ったwhe...
others節は、すべてのラベルに合致しなかった場合に実行され...
ヒットさせるラベル値はカンマで列挙可能です。またマイナス...
#code(aya,nooutline,nolink,nonumber){{
request
{
case name+(i+1) {
when "Pentium3","Pentium4"
"Pen!!!は1999年、Pen4は2000年発売発売。"
when "Pentium5"-"PentiumX" {
"まだ無い。"
}
others
"分からない。"
}
}
}}
whenに記述するラベル値は必ず即値でなければなりません。変...
when、othersが処理する{ }内にスクリプトが1つしか存在しな...
**switchによる分岐 [#eded24e4]
{ }内の出力候補から出力は無作為に選ばれますが、switchを使...
#code(aya,nooutline,nolink,nonumber){{
request
{
switch id {
"idは0である。"
"idは1である。"
{
"idは2である。"
"idはtwoである。"
}
"idは"3である。"
}
}
}}
変数idの値によって出力される文字列が指定されます。指定は0...
idが2の時は、"idは2である。"もしくは"idはtwoである。"が出...
switchが評価する値に対応する候補が{ }内に存在しない場合は...
switch内に出力確定子がある場合は、各ブロックの該位置にあ...
#code(aya,nooutline,nolink,nonumber){{
request
{
switch 1 {
"かわいい"
"天才"
"サル"
--
"とは言い難い"
--
"ですね。"
"かもしれません。"
}
}
}}
requestの出力は"天才かもしれません。"となります。~
中間のブロックには指定位置に候補が無いので、出力が空の文...
**ループ [#hb9f85fc]
while、for、foreachの3種類のループ構造があります。~
***while [#j24fd024]
whileが評価する式が真である間は{ }内を繰り返し処理します。
#code(aya,nooutline,nolink,nonumber){{
request
{
_i = 1
_j = 0
while _i < 11 {
_j += _i
_i++
}
"1から10をすべて足すと%(_j)である。"
}
}}
上の例はwhileの機能を簡単に説明しています。
下の例では異なる10個の文字列を発生しています。requestの出...
#code(aya,nooutline,nolink,nonumber){{
request
{
_i = 1
while _i < 11 {
"%(_i)の平方根は%(SQRT(_i))である。"
_i++
}
}
}}
***for [#hb029288]
forはwhileと同様の先判定ループ構造ですが、初期化式、脱出...
以下は、whileで挙げた平方根を報告する例をforで書き直した...
#code(aya,nooutline,nolink,nonumber){{
request
{
for _i = 1; _i < 11; _i++ {
"%(_i)の平方根は%(SQRT(_i))である。"
}
}
}}
_i = 1はループを始める直前に実行されます。_i < 11はル...
戻る際に実行される式です。
C言語では for ( ; ; ) とすることで無限ループとできますが...
無限ループを作る場合は
#code(aya,nooutline,nolink,nonumber){{
for 1;1;1
}}
などとしてください。ただ、whileなら
#code(aya,nooutline,nolink,nonumber){{
while 1
}}
で済むため、文で無限ループを作る際は、可読性の点からも、...
***foreach [#a44ed835]
簡易配列、もしくは汎用配列の各要素値を順番に取り出します。
以下では簡易配列の要素値を取り出して数値へ変換し、すべて...
#code(aya,nooutline,nolink,nonumber){{
request
{
_str = "1,3,5,7,9"
_t = 0
foreach _str; _i {
_t += TOINT(_i)
}
_t
}
}}
foreachに続いて処理対象を記述します。上の例では簡易配列_s...
必ず変数でなければなりません。
処理対象の変数のデリミタがSETDELIMによって変更されていて...
foreachは汎用配列も処理できます。
#code(aya,nooutline,nolink,nonumber){{
request
{
_sent = ("I", "am", 31, "years", "old.")
_t = ""
foreach _sent; _i {
_t += (_i + " ")
}
_t
}
}}
requestは"I am 31 years old. "を出力します。
foreachループ内において要素取り出し対象の簡易配列、汎用配...
変更は正常に反映されます。~
***break [#h5c17692]
ループ中にbreakが現れると、現在実行中の最も深いループから...
#code(aya,nooutline,nolink,nonumber){{
request
{
_j = 0
for _i = 0; _i < 100; _i++ {
_j = _i*_i
if _j >= 100
break
}
_i - 1
}
}}
上の例では、forは初期値0の_iが100に達するまでループを実行...
requestは_iから1を減じた価を返しています。つまりrequestは...
***continue [#badbffd1]
ループ中にcontinueが現れると、その位置からすぐにループ先...
#code(aya,nooutline,nolink,nonumber){{
request
{
_j = ""
for _i = 0; _i < 3; _i++
{
_j += "go "
if _i > 0
continue
_j += "ahead "
}
_j
}
}}
_iは0、1、2と変化しますが、1、2ではcontinueが働くので、_j...
したがってrequestの出力は"go ahead go go "となります。
**return [#ad085d7a]
returnが現れると、その関数の実行はそこで終わります。~
関数の出力はそれまでに蓄積された候補から選ばれます。
#code(aya,nooutline,nolink,nonumber){{
to_rad
{
if GETTYPE(_argv[0]) == 3 {
-1
return
}
_argv[0]*2.0*3.14/360.0
}
}}
関数to_radはdegreeをradianへ変換します。~
引数に文字列が与えられた場合は、if判定でそれを発見して-1...
ありませんから、これが出力されることになります。
*プリプロセス [#m573754f]
プリプロセスは辞書ファイルを読み込んでいる段階で実行され...
***#define [#y197e4c0]
辞書ファイルから読み込んだ(パース前の)生の文字列に対し...
#code(aya,nooutline,nolink,nonumber){{
#define before after
}}
とすると、これを記述した行より後ろにbeforeが見つかるたび...
#define の有効範囲は、宣言した次の行から、そのファイルの...
置換は記述順に行われますので、先に変換しておきたいものを...
***#globaldefine [#r4820e57]
#code(aya,nooutline,nolink,nonumber){{
#globaldefine before after
}}
機能は #define ディレクティブと同じです。ただし、有効範囲...
~#globaldefine を宣言すると、次の行以降の全ての範囲(その...
たとえば最初に読み込む辞書ファイルの先頭に #globaldefine ...
~#defineが先に処理されます。。#globaldefine は、#define ...
#code(aya,nooutline,nolink,nonumber){{
#globaldefine tea green
#define tea milk
"teacup"
}}
置換結果は"milkcup"となります。
*予約語 [#wc1ef9d2]
以下の単語はシステム関数名、及び制御命令名です。~
これらの名前は文システムで予約されています。これらと完全...
***システム関数 [#w9fbee0d]
[[../システム関数]]で記述されている関数は全て利用できませ...
今後の拡張も考えると、大文字+アンダースコアのみで構成さ...
***制御構造キーワード [#y0131224]
>if elseif else case when others switch while for...
***演算子 [#a6b3280c]
以下の単語/文字は演算子です。~
これらと完全に一致する名称の変数や関数をユーザー側で作成...
>( ) [ ] ! ++ -- * / % + - & == != <...
*謝辞 [#o6562354]
以下のライブラリを利用もしくは参考にさせていただきました...
-マルチバイト文字列 - ワイド文字列変換クラス CUnicodeF~
http://kamoland.com/comp/unicode.html
-正規表現ライブラリ Boost::Regex~
本家~
http://www.boost.org/libs/regex/doc/index.html~
日本語訳~
http://boost.cppll.jp/HEAD/libs/regex/index.htm~
VC6へのインストール方法~
http://village.infoweb.ne.jp/~fwhk9290/behind/regex.htm~
基本的な使用方法~
http://www.s34.co.jp/cpptechdoc/article/regexpp/~
終了行:
*AYA Version5 マニュアル [#z8a62102]
このマニュアルは、HTML形式で配布されているものを、すぐに...
[[AYA Version5 システム関数>../システム関数]]も参照してく...
#contents
*概要 [#ja5d0838]
「あや」と読みます。文字列処理を行なうためのDLLです。
C言語に似た文法を使用して、
-与えられた文字列を加工する
-プログラムした規則に拠って文字列を生成する
といった処理を行なうことが出来ます。
文はWindows DLLですので、直接利用するためには、プログラミ...
*環境 [#ca7d9a37]
Windows用です。
開発のごく初期に98SE、2000、xpで動作確認しましたが、最終...
報告をいただけると助かります。
*利用規定 [#d695caea]
-使途を限定せず自由に利用することが出来ます。~
-配布パッケージに含まれているすべてのファイルを自由に取り...
-このプログラムを使用した結果、あなたに何らかの損害が発生...
-ソースコードを改変して自由に異版を作成し、配布することが...
その際、配布者はその意志に基づいたライセンスを独自に策定...
*主な変更点 [#i6200e2f]
version 4系列の文をお使いの方は、この項を読むことでversio...
**新機能/改善された機能 [#r7165c5b]
-UTF-8に対応~
version 4で扱える文字コードはShift_JISのみでしたが、versi...
-数式書式の制限撤廃~
関数の引数に数式を記述できない、代入演算子や比較演算子を...
-if等の真偽判定が0/非0判定へ~
version 4ではif等の判定式のために特別の書式が必要でした。...
-汎用配列機能を追加~
型を混在して格納可能な配列構造が追加になりました。~文字列...
-範囲付き埋め込み展開~
"hello, %username" を "hello, %(username)" のように書けま...
-各種システム関数追加~
正規表現、ランダム選択、書式化出力など、従来不可能だった...
-foreach~
簡易配列、汎用配列に対してforeachが使えます。
-動作速度の向上~
実行するスクリプトに強く依存しますが、ループや変数展開な...
-version 4が抱える問題の解決~
version 4はパーサがぬるく、これに起因する種々の不安定動作...
version 5ではそのような不安定要因は極力排除されています。
-エラーログ改善~
ログに記録されえるエラーの内容が詳細化されました。エラー...
**変更された機能 [#dcaed67a]
version 5の開発においては、version 4が抱える不具合や仕様...
互換性の確保にも配慮が無かったわけではありませんが、それ...
以下の点で互換性が崩れています。移植の際には注意が必要で...
-上位/下位インタフェース変更~
重要で本質的な変更です。version 4ではHTTP風リクエストヘッ...
-システム関数全面見直し~
version 4が持つシステム関数のうち、完全に同一機能のまま引...
最も注意を要するのは文字列処理系の関数です。~
version 4 STR*系(バイト数単位)、MSTR*系(文字数単位)...
version 5 STR*系(文字数単位)~
STR*系関数が残されましたが、動作はMSTR*系のものになってい...
-システム変数全廃~
_argv、_argc以外のシステム変数は廃止されました。ただし同...
-空の文字列~
version 4では空の文字列と値無しの区別が不明確でした。vers...
-関数/変数名の先頭に数値を使えない~
version 4では使用可能でした(そもそも12hourというシステム...
他にも変数名/関数名として使用不可能になった文字が存在しま...
-機能制限設定機能は未搭載~
考えた結果、とりあえず未実装としました。
-そのほか...~
version 4のパーサが弱かったおかげで見逃されていたエラーが...
*エクスポートしている関数 [#ye0e5ed7]
文は以下の公開された関数を持っています。
文を利用するプログラムは、文をLoadLibraryした後にこれらの...
#code(c,nooutline,nolink,nonumber){{
extern "C" __declspec(dllexport) BOOL __cdecl load(HGLOBA...
}}
文に初期化を指示します。~
文をLoadLibraryして使用を開始する直前に、この関数を一度だ...
hには「文がカレントとして認識するディレクトリ絶対パス」を...
hの領域開放は文側で行ないますので、呼び出し側では使い放し...
#code(c,nooutline,nolink,nonumber){{
extern "C" __declspec(dllexport) BOOL __cdecl unload()
}}
文に終了を指示します。~
文をFreeLibraryする直前に一度だけ実行してください。
#code(c,nooutline,nolink,nonumber){{
extern "C" __declspec(dllexport) HGLOBAL __cdecl request(...
}}
文に処理を指示し、結果を得ます。~
hには処理対象の文字列を、*lenにhの長さを渡してください。
渡したhの領域開放は文側で行ないますので、呼び出し側では使...
処理結果は戻り値で得られます。処理結果の長さは*lenに格納...
戻り値を取得した後、領域を*lenで示されるサイズで開放(Glob...
なお、これはデスクトップマスコットソフトウェア「伺か」で...
のインタフェース規格と完全に同一のものです。
*基礎設定 [#nc75848b]
文 ver.5のデフォルトのDLLファイル名は「aya5.dll」です。~
主ファイル名「aya5」は他の名前に自由に変更することができ...
文を動作させるためには「基礎設定ファイル」と呼ばれるファ...
基礎設定ファイルのファイル名は「主ファイル名.txt」です。...
「hoge.dll」に変更したなら、基礎設定ファイルは「hoge.txt...
基礎設定ファイルはテキストファイルで、実行されるOSのデフ...
もし国際化に関して考慮しなければならないなら、マルチバイ...
以下に例を示します。
#code(aya,nooutline,nolink,nonumber){{
// dics
dic, basis.dic
dic, control./*doc*/ayc
// option parameters
charset, UTF-8
msglang, english
log, executelog.txt
iolog, off
fncdepth, 16
}}
設定はコマンドとパラメータをカンマで区切って指定します。~
空行(改行のみの行)、"//"以降、および"/*"と"*/"で囲まれ...
コマンドとその意味は以下の通りです。
***charset, name [#lfff9e83]
標準の文字コードを設定します。~
以下の予約値からいずれかを指定します。指定が無い場合はShi...
-Shift_JIS / ShiftJIS / SJIS~
シフトJISコード。
-UTF-8~
UTF-8。
-default~
実行OSのデフォルト文字コード。
***dic, filename [#rbfd65d8]
辞書ファイルfilenameをロードします。~
辞書ファイルは文スクリプトが記述されたプログラムソースフ...
辞書ファイルはいくつでも指定し、読み込むことができます。
filenameはloadで指定されたパス位置からの相対パスで指定し...
標準の辞書ファイルはcharsetで指定した文字コードで記述され...
暗号化ファイルを読み込むことができます。
***msglang, language [#ba19005d]
ログに記録されるエラーメッセージ類の言語を選択します。~
以下の予約値からいずれかを指定します。指定が無い場合はjap...
-japanese~
日本語。
-english~
英語。
***log, logfilename [#m583923d]
実行ログをファイルlogfilenameに記録します。~
charsetで指定した文字コードで書き込まれます。
logfilenameはloadで指定されたパス位置からの相対パスで指定...
***iolog, [on|off] [#pb05622c]
load、unload、request実行時の入出力文字列と処理時間をログ...
onで記録します。デフォルトではonになっていますので、不要...
***fncdepth, depth [#p6bb4967]
関数呼び出しの深さ上限を数値で指定します。~
デフォルト値は32です。最低値は2で、これより小さな値や不正...
*文スクリプトリファレンス [#p83ee35b]
文スクリプトの書式はC言語のそれを踏襲しています。~
したがってあらかじめC言語、およびC言語に類似する言語を習...
*関数 [#r29732f5]
**基礎 [#r94d7456]
request実行時に"Hello World"という文字列を返すプログラム...
#code(aya,nooutline,nolink,nonumber){{
request
{
"Hello World"
}
}}
文をロードしたモジュールがHGLOBAL request(HGLOBAL h, long...
返されます。
loadとunloadも同様です。~
ただしloadとunloadは値を返さないので、出力文字列を書いて...
unloadには逆にその後始末をするコードを書きます。
必要な関数だけ書けばよいです。不要なものは省けます。~
たとえば上の例ではloadとunloadは書いていませんが、これは...
極端な例を挙げるなら、辞書ファイルがまったく無くてもエラ...
requestは空の文字列を返します。
loadとrequestはひとつの引数を持っています。これは変数で取...
変数の名前は_argcと_argvで、これはC言語のmain関数のインタ...
***_argc [#f09b1d74]
引数の数。loadとrequestでは引数はひとつの文字列ですから1...
***_argv [#v1dd42c9]
引数の実体が格納されています。これは_argc個の要素を持つ配...
序数iは0オリジン指定です。たとえば_argcが1の場合は_argv[0...
基礎編のまとめとして、loadでは変数strに"Hello"を格納し、r...
示します。~これまでの説明を踏まえて読んでみてください。
#code(aya,nooutline,nolink,nonumber){{
load
{
str = "Hello"
}
request
{
str + " " + _argv[0] + "!"
}
}}
処理対象文字列を"World"としてrequestを実行すると、結果と...
**書式 [#s79234f5]
以下の則があります。
-空行(改行のみの行)、"//"以降、および"/*"と"*/"で囲まれ...
-1行の終わりがスラッシュ("/")の場合は、次の行がこの行の...
-行頭、および単語間には自由に空白文字を入れることが出来ま...
-複数のステートメントを1行に詰めて書きたい場合は、セミコ...
つまり先に挙げたHello Worldコードは以下のように1行に詰め...
#code(aya,nooutline,nolink,nonumber){{
request{"Hello World"}
}}
では以下のように書いてもいいのか? もちろん。問題なく動...
#code(aya,nooutline,nolink,nonumber){{
req/
uest {
"/
Hello World" }
}}
/の次の行(新たに結合される行)先頭にある空白文字はインデ...
したがって以下の文字列の結合結果は "ABCDEFG" であり、決し...
#code(aya,nooutline,nolink,nonumber){{
"ABCD
EFG"
}}
第4項を説明します。~
以下のrequestは1+2の答えを求め、日本語の文章にして返して...
#code(aya,nooutline,nolink,nonumber){{
request
{
answer = 1 + 2
"答えは" + answer + "です。"
}
}}
セミコロンを使用して以下のように書けます。
#code(aya,nooutline,nolink,nonumber){{
request
{
answer = 1 + 2; "答えは" + answer + "です。"
}
}}
セミコロンは過剰に書いても問題ありません。それらは無視さ...
したがって、あなたがC言語の書式に慣れているなら、各行の終...
**ユーザー関数の定義と実行 [#f5f27796]
load、unload、request以外に好きな名前の関数を作成できます...
作成した関数は、その名前を書くだけで実行できます。
#code(aya,nooutline,nolink,nonumber){{
request
{
hello
}
hello
{
"Hello World"
}
}}
上に示したのはもっとも単純な例です。requestは結果として"H...
同じ結果が得られるもう少し複雑な例を、以下に示します。
#code(aya,nooutline,nolink,nonumber){{
request
{
combine("Hello", "World")
}
combine
{
_argv[0] + " " + _argv[1]
}
}}
関数名の後ろに( )をつけて、その中にカンマで値を並べて書く...
すなわち変数_argvと_argcに値が格納されて、該関数内で参照...
ここで挙げた例では、combine関数内において_argcは2、_argv[...
関数名は自由につけられますが、以下に抵触する名前はエラー...
-数字0~9で始まる。
--定数の数字として解釈される可能性があります。
-アンダースコア("_")で始まる。
--アンダースコアで始まる名前はローカル変数で使われていま...
-以下の文字を含む。~
空白 ! " # $ % & ( ) * + , - / : ; <...
--アンダースコア以外の記号は使わないほうが良いでしょう。
-予約語と完全に一致する。
--アルファベット大文字+アンダースコアはシステム関数で使...
--forやwhile、ifなど、制御構造に使われるものも避けなけれ...
関数は再帰呼び出しが可能です。~
もっともありふれた例として階乗計算を行った例を挙げます。
#code(aya,nooutline,nolink,nonumber){{
request
{
factorial(5)
}
factorial
{
if !_argv[0]
1
else
factorial(_argv[0] - 1)*_argv[0]
}
}}
requestは120を返します。
**択一 [#vce5bec3]
#code(aya,nooutline,nolink,nonumber){{
request
{
"Hello World"
"こんにちは世界"
"Hallo Welt"
}
}}
このように列挙すると、これらは平等な「出力候補」として扱...
5種類の選択方法が用意されており、いずれかを選ぶことができ...
***なにもなし [#c8db39e4]
デフォルトでは無作為に選択します。
***nonoverlap [#y4e0c799]
すべての候補が出力されるまでは、同じ候補を選択しなくなり...
#code(aya,nooutline,nolink,nonumber){{
request : nonoverlap
{
"Hello World"
"こんにちは世界"
"Hallo Welt"
}
}}
上のように、関数名の後ろに": nonoverlap"を付け加えます。
***sequential [#m0d8b091]
記述された順に出力します。最後まで出力したらまた先頭に戻...
#code(aya,nooutline,nolink,nonumber){{
request : sequential
{
"Hello World"
"こんにちは世界"
"Hallo Welt"
}
}}
上のように、関数名の後ろに": sequential"を付け加えます。
***void [#sd2e95a2]
何も出力しなくなります。~
以下の例の場合、requestは3つの候補のどれも出力しません。
#code(aya,nooutline,nolink,nonumber){{
request : void
{
"Hello World"
"こんにちは世界"
"Hallo Welt"
}
}}
「何も実行しない」ではなく、「何も出力しない」であること...
内部に書かれた関数や数式は処理されます。
#code(aya,nooutline,nolink,nonumber){{
increment_i : void
{
i++
i
}
}}
上の関数increment_iはiに1を加算します。voidが無い場合、こ...
ただ加算を行うのみとなります。
***array [#b6965d54]
出力候補をすべて結合した汎用配列を関数の返値とします。~
#code(aya,nooutline,nolink,nonumber){{
request : array
{
"This is a pen."
("A","B","C")
3.14
}
}}
出力は汎用配列 ("This is a pen.", "A", "B", "C", 3.14) と...
nonoverlapとsequentialは、出力確定子が存在する場合でも取...
たとえばsequentialを例に挙げると、
#code(aya,nooutline,nolink,nonumber){{
request : sequential
{
"1"
"2"
"3"
--
"A"
"B"
}
}}
requestは以下の順序で出力を発生します。
#code(aya,nooutline,nolink,nonumber){{
"1A" "2A" "3A" "1B" "2B" "3B" "1A" "2A" …
}}
関数によっては実行毎に出力候補の数が変動します。~たとえば...
#code(aya,nooutline,nolink,nonumber){{
request : sequential
{
if i {
"1"
"2"
}
"3"
"4"
}
}}
候補数が変化した場合、nonoverlapとsequentialの巡回順序は...
出力されることはあり得ます。
**入れ子 [#icb3830b]
#code(aya,nooutline,nolink,nonumber){{
request
{
{
"Hello World"
"こんにちは世界"
}
"Hallo Welt"
}
}}
{ } は階層的にいくつでも重ねて書くことが出来ます。動きは...
ただし選択方法は無作為抽出のみで、最上層のようにnonoverla...
上の例では、{ }の有無にかかわらず結果は同じであるように思...
{ }が無い場合、それぞれが出力される確率は平等に1/3です。...
**出力確定子 [#bc934c88]
#code(aya,nooutline,nolink,nonumber){{
request
{
"Hello"
"Perfect"
"Peaceful"
--
" Wor"
--
"ld"
"th"
}
}}
--は出力確定子というもので、選択候補はここを区切りとして...
したがって上のrequestを実行すると、以下のいずれかが出力さ...
#code(aya,nooutline,nolink,nonumber){{
"Hello World"
"Perfect World"
"Peaceful World"
"Hello Worth"
"Perfect Worth"
"Peaceful Worth"
}}
nonoverlap、sequentialと組み合わせて使用した場合、(グル...
出力確定子はどこでも問題なく使用できます。{ }入れ子の深い...
文は文字列のほかに数値なども扱えますが、出力確定子は結合...
*値と変数 [#n1ee12d5]
**即値 [#g354a67e]
文が扱える値は整数、実数、文字列の3種類です。
***整数 [#l7eb7352]
符号付き32bit整数です。
10進数値はそのまま記述します。~
先頭に"0b"を付加することにより、2進数値を記述できます。~
先頭に"0x"を付加することにより、16進数値を記述できます。
以下の関数int10は整数10を返します。3つの記述はいずれも10...
#code(aya,nooutline,nolink,nonumber){{
int10
{
10
0b1010
0xa
}
}}
***実数 [#e2e3fb8f]
符号付き64bit浮動小数点数です。小数点以下の桁がある場合や...
整数との区別は小数点の有無です。文は数値に小数点を見つけ...
***文字列 [#db427a23]
ダブルクォート(")で囲まれた値は文字列です。
文字列の中にダブルクォートが含まれてはいけません。
***文字列(展開なし) [#ea52b392]
シングルクォート(')で囲まれた値は、展開されない単純な文...
文では文字列中に変数や関数を埋め込むことが出来ますが、こ...
文字列の中にシングルクォートが含まれてはいけません。
**変数 [#xb7e9ffb]
変数は値を格納するための領域です。~
ひとつの変数には、
-整数、実数、文字列
-要素ごとに上記のいずれかを格納可能な汎用配列
を格納することができます。
名前は以下の禁止条項に抵触しない限りは自由につけることが...
-数字0~9で始まる。
-以下の文字を含む。~
空白 ! " # $ % & ( ) * + , - / : ; <...
-予約語と完全に一致する。
-関数名と完全に一致する。
値の格納(代入)は代入演算子 = で行ないます。内容を出力す...
#code(aya,nooutline,nolink,nonumber){{
request
{
str = "こんにちは"
str
}
}}
上は単純な例で、変数strに文字列を格納し、そのまま出力して...
まだ値が代入されていない変数は、空の文字列を出力します。~...
#code(aya,nooutline,nolink,nonumber){{
request
{
"Hello World"
i
}
}}
i は存在しません。これは空の文字列になりますから、結局上...
#code(aya,nooutline,nolink,nonumber){{
request
{
"Hello World"
""
}
}}
**変数のスコープと寿命 [#b50694fc]
変数はスコープ(有効範囲)の違いによって2種類存在します。
-グローバル変数~
すべての関数で共通に使用できる変数。寿命は永遠。
-ローカル変数~
現在の{ }内、およびそれより深い入れ子階層のみで使用できる...
両者を区別するのは変数の名前です。変数名の先頭がアンダー...
「必要な範囲だけで有効な変数」であるローカル変数をうまく...
#code(aya,nooutline,nolink,nonumber){{
request
{
_i = "3*2は"
_j = multi(3)
_i +_j + "です"
}
multi
{
_i = _argv[0]
_i * 2
}
}}
requestとmultiが同じ名前の変数 _i を使っていますが、それ...
関数の引数を扱う変数_argcと_argvも実はローカル変数である...
ローカル変数になっているわけです。
ローカル変数が「現在の関数内で使用可能な変数」ではなく、...
#code(aya,nooutline,nolink,nonumber){{
request
{
{
_str = "Hello World"
}
_str
}
}}
このプログラムは期待通りには動作しません。~
_strは{ }内のみで有効ですから、出力を取り出そうとしている...
したがって、この関数requestは空の文字列を出力します。
グローバル変数とローカル変数の違いはもうひとつあります。...
ローカル変数は上で見たとおり、変数を使用している{ }から外...
対してグローバル変数はどこでも使用可能、さらにunloadでそ...
*演算 [#q3ea1bb9]
**基本 [#v84b1e7f]
C言語と同様の書式で四則演算、比較演算、代入、その他が可能...
演算の順序は演算子毎に重み付けされた演算優先度に基づいて...
演算子の種類と演算優先度は以下の通りです。
演算子 意味 ...
( ) [ ] ブラケ...
! 否定
++ -- ポスト...
* / % 乗除算...
+ - 加減算
& フィー...
== != >= <= > < _in_ !_in_ 比較
&& 論理積
|| 論理和
= := 代入
+= -= *= /= %= +:= -:= *:= /:= %:= ,= 演算し...
, 汎用配...
コロン(":")付きの代入演算子は過去互換性を保持するために...
~*は単項演算子です。
ブラケット( )については次項で詳説します。~
カンマ演算子(",")、およびスクウェアブラケット[ ]につい...
フィードバック演算子&については別項で詳説しています。
_in_と!_in_は文字列の包含チェックに使用する演算子です。
#code(aya,nooutline,nolink,nonumber){{
foo
{
"or" _in_ "World"
}
}}
_in_は左辺の文字列が右辺の文字列に含まれていれば1、含まれ...
上の関数fooは1を返します。
比較演算子は結果が真であれば整数1を、偽であれば0を返しま...
これらの演算子は文字列に対しても正しく機能します。値の大...
論理の真偽は以下で判断されます。~
偽 整数0、実数0.0、空の文字列、空の汎用配列~
真 上記以外のすべて
代入でない演算は結果がそのまま出力となります。
#code(aya,nooutline,nolink,nonumber){{
foo
{
(3+2)*4
}
}}
この関数fooは20を出力します。
同じ優先度の演算子が連続している場合は、常に左から結合さ...
#code(aya,nooutline,nolink,nonumber){{
1+2-3
}}
たとえば上の式は
+ 1+2
+ 3-3
の順に計算されます。
#code(aya,nooutline,nolink,nonumber){{
i = j = 10
}}
これはどうなるでしょう。C言語では代入演算子は右から結合さ...
しかし文では結合は常に左からです。すなわち
+ i = j
+ j = 10
の順に計算されます。したがって、iには10は入らないのです。
#code(aya,nooutline,nolink,nonumber){{
i = (j = 10)
}}
これで i にも10が入るようになります。
演算対象の項の型が一致していない場合、結果の型は以下のよ...
-整数と実数の演算~
結果は実数となります。
-整数/実数と文字列の加算~
数値は文字列に変換された後、もう一方の文字列に結合されま...
-整数/実数と文字列の演算(加算以外)~
演算不能ですがエラーとはなりません。結果は空の文字列とな...
ひとつの演算式内で型が混在していても構いません。~
必要に応じて、上記の法則により型変換が起こります。
#code(aya,nooutline,nolink,nonumber){{
"10+2は" + (10+2) + "です。"
}}
最初に10+2が整数として計算され、結果12が得られます。残り...
**ブラケット( )による演算順序制御 [#q7b01c6f]
ブラケット( )で囲んだ部分は演算順序が最優先扱いになります...
( ) はいくつでも重ねて指定可能で、深くなるほど優先度が上...
平たく言えば「かっこで囲んだところを先に計算する」という...
数式の書き方によってはなかなかややこしいこともあります。~
以下の例を見てください。
#code(aya,nooutline,nolink,nonumber){{
answer = (_i = 10) + (2*(_i + 10))
}}
文の演算則をよく理解している人でないと、answerに何が代入...
answerには文字列の"10"が入ります。決して整数50ではありま...
最初に計算されるのはどこでしょう。ブラケットが一番深いと...
ここまで説明すれば結果が文字列の"10"になる理由は明白でし...
さて、こちらの意図ではまず_i = 10の代入を先にしてもらいた...
このような場合、文では以下のようにブラケットを過剰に付与...
#code(aya,nooutline,nolink,nonumber){{
answer = (((_i = 10))) + (2*(_i + 10))
}}
これで代入部分の優先度が一気に引き上げられました。今度は...
なお、代入部分を囲むブラケットは2段で十分ではないかと思わ...
**フィードバック演算子& [#a2371f18]
フィードバック演算子&は、他の演算子とは使い方がまったく異...
#code(aya,nooutline,nolink,nonumber){{
request
{
_i = 1
foo(&_i)
}
foo
{
_argv[0] = 100
}
}}
関数呼び出しの際に引数として変数を与える場合、その先頭に&...
先頭に&を付けられた変数は、呼び出し先関数の_argvの対応す...
上の例では、fooを実行すると _i の値が100に書き換わります。
フィードバック演算子は好きな位置にいくつでも使用可能です。
#code(aya,nooutline,nolink,nonumber){{
request
{
foo(1, 2, &_value, "Hello", &_value2)
_value + _value2
}
foo
{
_argv[2] = _argv[0] + _argv[1]
_argv[4] = _argv[3] + " World"
}
}}
関数requestは "3Hello World" を出力します。
当然のことですが、フィードバック演算子は変数にしか付けら...
*配列 [#g4feb8c1]
演算子[ ]は配列要素にアクセスするための演算子です。
配列には文字列スプリットを擬似的に配列と見なす「簡易配列...
**簡易配列 [#u1e86766]
文字列に含まれるカンマをデリミタ(区切り文字)と解釈して...
#code(aya,nooutline,nolink,nonumber){{
request
{
_a = "this,is,a,pen"
_a[1]
}
}}
requestは"is"を出力します。
[ ]演算子が処理する対象は変数である必要はありません。即値...
上の例は以下のように書いても同じです。
#code(aya,nooutline,nolink,nonumber){{
request
{
"this,is,a,pen"[1]
}
}}
序数の後ろにカンマ区切りでデリミタを指定することにより、...
#code(aya,nooutline,nolink,nonumber){{
request
{
"This is a island."[2,"is"]
}
}}
"is"で区切るわけですから、文字列は以下のように分解されま...
[0] "Th"~
[1] " "~
[2] " a "~
[3] "land."~
したがってrequestは" a "を返します。
デリミタ指定をうまく使うと、多次元配列風に値を取り出すこ...
#code(aya,nooutline,nolink,nonumber){{
request
{
_ar = "taro|male,ayame|female,hotaru|female"
_ar[2][1,"|"]
}
}}
_ar[2]は"hotaru|female"です。さらに"|"を区切り文字として...
このように、階層毎にユニークなデリミタを適用することによ...
範囲外の序数を指定した場合の出力は、存在しない変数の値を...
ここからは変数限定の機能を解説します。
要素に代入が可能です。
#code(aya,nooutline,nolink,nonumber){{
request
{
_a = "this,is,a,pen"
_a[3] = "eraser"
_a
}
}}
"pen"を"eraser"に書き換えています。requestの実行結果は"th...
デリミタ指定しても正しく機能します。
#code(aya,nooutline,nolink,nonumber){{
request
{
_s = "This is a island."
_s[2,"is"] = " beautiful "
_s
}
}}
requestは"This is beautiful island."を出力します。
多次元配列風に[ ]演算子を連結して使用している場合、代入は...
#code(aya,nooutline,nolink,nonumber){{
request
{
_ar = "taro|male,ayame|female,hotaru|female"
_ar[1][1,"|"] = "male"
}
}}
ayameの性別をmaleに書き換えようとしていますが、この操作は...
現在の要素数を越える位置へも問題なく代入できます。デリミ...
#code(aya,nooutline,nolink,nonumber){{
request
{
_m = "fuji/asama/tanigawa"
_m[5,"/"] = "daisen"
_m
}
}}
requestは"fuji/asama/tanigawa///daisen"を出力します。
SETDELIMという関数を使用すると、「デフォルトのデリミタ」...
先に示した例をSETDELIMを使用して書き換えたものを以下に示...
#code(aya,nooutline,nolink,nonumber){{
request
{
_m = "fuji/asama/tanigawa"
SETDELIM(_m, "/")
_m[5] = "daisen"
_m
}
}}
SETDELIMすることにより、単純に_m[5]と書くことができるよう...
多次元配列風に[ ]演算子を連結して使用している場合、SETDEL...
**汎用配列 [#r1f9d606]
汎用配列はさまざまな型の値を混在して格納できる配列構造で...
一般的なアクセスでは簡易配列より高速に動作します。
***初期化 [#z1cfbf85]
#code(aya,nooutline,nolink,nonumber){{
i = (100,"test",-1.5)
}}
要素をカンマで列挙して記述します。~
代入する場合は上のように要素の集合を( )で囲んでください。...
#code(aya,nooutline,nolink,nonumber){{
(i = 100),"test",-1.5
}}
このように解釈されてしまいます。
配列を空の状態で初期化するには、IARRAYという関数を使用し...
#code(aya,nooutline,nolink,nonumber){{
i = IARRAY
}}
初期化時に要素をひとつだけ代入したい場合は工夫が要ります...
以下のように記述します。
#code(aya,nooutline,nolink,nonumber){{
i = (IARRAY,100)
}}
***要素追加 [#ua3a26fe]
#code(aya,nooutline,nolink,nonumber){{
i = (i,"add")
}}
とすると配列の後端に"add"が追加されます。
配列を追加することもできます。~
#code(aya,nooutline,nolink,nonumber){{
i = (i,("add",123,0.0))
}}
a = a + 1 を a += 1と略せるように、上の例は下のようにも書...
#code(aya,nooutline,nolink,nonumber){{
i ,= ("add",123,0.0)
}}
先頭への挿入も同じ書式で可能です。
#code(aya,nooutline,nolink,nonumber){{
i = ("first",i)
}}
中途への挿入もできます。
#code(aya,nooutline,nolink,nonumber){{
i = (100,200,300,400,500,600)
i[2] ,= "insertion"
}}
iは(100,200,300,"insertion",400,500,600)となります。~
挿入対象は[2]でなく[3]に入ることに注意してください。
i[2]へ挿入したい場合は
#code(aya,nooutline,nolink,nonumber){{
i[2] = ("insertion",i[2])
}}
とします。
***要素削除 [#f152b05f]
削除したい要素へIARRAYを代入します。
#code(aya,nooutline,nolink,nonumber){{
i = (100,200,300,400,500,600)
i[2] = IARRAY
}}
300が削除され、iは(100,200,400,500,600)となります。
***値の更新 [#n6fd0d08]
単純に要素へ代入できます。
現在の要素数を越える位置へも問題なく代入できます。必要な...
***値の取り出し [#u9fd841d]
通常の変数と同様、序数を指定して記述すればそのまま出力さ...
範囲外の序数を指定した場合の出力は、存在しない変数の値を...
#code(aya,nooutline,nolink,nonumber){{
i = (100,200,300,400,500,600)
i[4]
}}
500が出力されます。
[ ]演算子が処理する対象は変数である必要はありません。即値...
#code(aya,nooutline,nolink,nonumber){{
(100,200,300,400,500,600)[4]
}}
500が出力されます。
汎用配列をそのまま関数の出力にできます。
#code(aya,nooutline,nolink,nonumber){{
request
{
river[2]
}
river
{
"tenryu","bandou-tarou","ishikari","shimanto"
}
}}
requestは"ishikari"を出力します。
***多次元化はできない [#e6240c23]
汎用配列は多次元配列を構成できません。
#code(aya,nooutline,nolink,nonumber){{
(100,200,(300,400),500,600)
}}
このように書いても、内包されたブラケット部分が副次的な配...
結局以下のように単純に結合されてしまいます。
#code(aya,nooutline,nolink,nonumber){{
(100,200,300,400,500,600)
}}
***演算 [#z99403e7]
要素単位の演算は通常に行うことが出来ます。
汎用配列と単項値との演算は、「全要素へ単項値が演算される...
#code(aya,nooutline,nolink,nonumber){{
pref = "gunnma","ohsaka","hokkaido"
pref += "-ken"
answer = (2*(1,2,3))[1]
}}
prefは "gunnma-ken","ohsaka-ken","hokkaido-ken" となりま...
answerには4が代入されます。~
2*(1,2,3)の計算結果が(2,4,6)となるからです。
***関数の引数 [#se6e58da]
文において関数の引数は汎用配列です。_argvの内容は、呼び出...
つまり
#code(aya,nooutline,nolink,nonumber){{
func(1, 2, "test")
}}
という関数の呼び出しは、
#code(aya,nooutline,nolink,nonumber){{
_i = (1,2,"test")
func(_i)
}}
とも書けます。非常にトリッキーな表記ですが、これで意図ど...
注意してください。書き直したスクリプトにおいても、引数の...
この構造をうまく利用すると、可変長の引数を他の関数へ簡単...
#code(aya,nooutline,nolink,nonumber){{
request
{
total(1,2,3,4,5,6)
}
total
{
calc_total(_argv)
}
calc_total
{
_answer = 0;
foreach _argv; _val { _answer += _val }
_answer
}
}}
totalは自分では何もせず、すべての引数をそのままcalc_total...
この例では単純に引き渡していますが、もちろん必要に応じて...
引数の指定方法が複雑になっている場合は注意すべきです。
#code(aya,nooutline,nolink,nonumber){{
_i = (1,2,"test")
func("sky", _i, "sun")
}}
上の呼び出しは以下と等価です。汎用配列は多次元化できない...
#code(aya,nooutline,nolink,nonumber){{
func("sky", 1, 2, "test", "sun")
}}
***デリミタ/取得数指定 [#o22fa826]
#code(aya,nooutline,nolink,nonumber){{
_i = (2,"is")
"This is a island."[_i]
}}
簡易配列のデリミタ指定の部分も汎用配列です。したがって上...
#code(aya,nooutline,nolink,nonumber){{
"This is a island."[2,"is"]
}}
**範囲指定 [#rce6669c]
簡易配列/汎用配列とも、序数を範囲で指定できます。取得、代...
範囲は汎用配列で指定します。たとえば i[a,b] は「iの要素a...
#code(aya,nooutline,nolink,nonumber){{
name = ("さくら","せりこ","奈留","まゆら","毒子","美耳")
i = name[1,3]
name[3,4] = "奎子"
j = name
name[0,2] = IARRAY
k = name
}}
iには ("せりこ","奈留","まゆら") が格納されます。~
jは ("さくら","せりこ","奈留","奎子","美耳") 、~
kは ("奎子","美耳") となります。
範囲外は無視されます。
#code(aya,nooutline,nolink,nonumber){{
n = (1,2,3,4)
n[-2,1] *= 5
}}
nは (5,10,3,4) です。
対象が簡易配列の場合でも書式は同じです。
#code(aya,nooutline,nolink,nonumber){{
name = "さくら,せりこ,奈留,まゆら,毒子,美耳"
i = name[1,3]
name[3,4] = "奎子"
j = name
}}
iは "せりこ,奈留,まゆら" 、jは "さくら,せりこ,奈留,奎子,...
デリミタ指定も可能です。範囲指定のすぐ後ろに続けて指定し...
#code(aya,nooutline,nolink,nonumber){{
animal = "くま!うさぎ!ねこ!いぬ!わに"
i = animal[0,2,"!"]
animal[2,4,"!"] = "ぶた"
j = animal
}}
iは "くま!うさぎ!ねこ" 、jは "くま!うさぎ!ぶた" です。
**汎用配列のパラレル出力 [#j8feade9]
すべての式/値の前に「parallel」を書くことができます。~
parallelは出力候補値が汎用配列だった場合、
要素のそれぞれを出力候補値にする機能を持っています。
#code(aya,nooutline,nolink,nonumber){{
foo0
{
("A","B","C")
"地球"
}
foo1
{
parallel ("A","B","C")
"地球"
}
}}
foo0の出力は、("A", "B", "C") もしくは "地球"。~
foo1の出力は、"A"、"B"、"C"、"地球" のいずれかとなります。
汎用配列以外にparallelを使っても意味がなく、書かないのと...
#code(aya,nooutline,nolink,nonumber){{
parallel STRLEN("earth")
STRLEN("earth")
}}
択一メソッドarrayとparallelを利用することにより、関数の出...
さまざまな応用が考えられます。たとえば以下の非常に簡潔な...
#code(aya,nooutline,nolink,nonumber){{
cyclic : sequential
{
parallel _argv
}
}}
*文字列内埋め込み要素の展開 [#x744505a]
文字列の中に変数や関数を埋め込んで、これらの実行結果を当...
**範囲付き展開 [#a0bd2710]
要素を%( )で囲んで埋め込みます。
#code(aya,nooutline,nolink,nonumber){{
request
{
_i = "pen"
"This is a %(_i)."
}
}}
requestを実行すると、"This is a pen."が出力されます。
%( )はいわゆるeval(文字列をスクリプトコードと解釈して実...
単一の関数や変数だけでなく、数式を埋め込むことができます。
#code(aya,nooutline,nolink,nonumber){{
request
{
"1+2+3は%(1+2+3)です。"
}
}}
requestは"1+2+3は6です。"を出力します。
文の文字列は内部にダブルクォートを含むことが出来ない点に...
#code(aya,nooutline,nolink,nonumber){{
request
{
"This is a %(_i = "pen")."
}
}}
このような場合は、埋め込みを使用せず通常の数式として結合...
#code(aya,nooutline,nolink,nonumber){{
request
{
"This is a " + (_i = "pen") + "."
}
}}
ブラケット( )による演算順序制御は範囲付き展開でも同様に働...
#code(aya,nooutline,nolink,nonumber){{
request
{
"遊星「%(_i = planet)」は遠い。この遊星は%(color(_i))...
}
planet
{
"mars"
"saturn"
"pluto"
}
color
{
case _argv[0] {
when "mars"; "red"
when "saturn"; "yerrow"
when "pluto"; "blue"
others; "unknown"
}
}
}}
最も( )が深いのはcolor(_i)の引数ですので、_i = planetの前...
ブラケットを過剰付与して演算順序を調整してください。
#code(aya,nooutline,nolink,nonumber){{
"遊星「%((_i = planet))」は遠い。この遊星は%(color(_i))色...
}}
これで矛盾の無い文字列が得られるようになります。
**名称最長一致展開 [#u078e2e3]
( )を付与せず、単に%のみでも埋め込み展開は機能します。
#code(aya,nooutline,nolink,nonumber){{
request
{
o = "pen"
obj = "eraser"
object = "world"
"This is a %object."
}
obje
{
"television"
}
}}
展開対象は%以降の文字列に一致する最も長い名前を持った変数...
結果は"This is a world."となります。
変数は刻々と作成されたり消えたりしますから、展開対象が状...
これは範囲付き展開には見られない特徴です。
#code(aya,nooutline,nolink,nonumber){{
request
{
val = "red"
trans
--
value = "blue"
trans
}
trans
{
"%value"
}
}}
transは二度実行されますが、最初と二度目では"%value"の動き...
requestの出力は"redueblue"です。
%[ ]という書式で過去の展開結果を再利用できます。
#code(aya,nooutline,nolink,nonumber){{
request
{
"「%planet」は遠い。「%city」も遠い。もっとも%[1]にな...
}
planet
{
"mars"
"saturn"
"pluto"
}
city
{
"newyork"
"moscow"
"madrid"
}
}}
%[i]は0オリジンでi番目の展開結果を得ます。~
つまり上の例では、%[0]が%planetの、%[1]が%cityの展開結果...
%[ ]は範囲付き展開では使えません。範囲付き展開で過去の結...
名称最長一致による展開は実行する度に展開対象を検索しなお...
本当に必要な場合は別ですが、通常は範囲付き展開を利用すべ...
*フロー制御 [#r383aae0]
**ifによる分岐 [#s7f37fda]
式の結果が真であれば以降に続く{ }内を処理します。
#code(aya,nooutline,nolink,nonumber){{
request
{
if !i {
"iは0である。"
}
}
}}
すぐ後にelseif節を付加することができます。これはifの判定...
いくつでも連結できます。~
また、if~elseifの最終端にはelse節を置くことができます。...
処理されます。
#code(aya,nooutline,nolink,nonumber){{
request
{
if !i {
"iは0である。"
}
elseif i == 5 {
"iは5である。"
}
elseif "A" _in_ TOUPPER(i) {
"iは文字列で、aもしくはAを含んでいる。"
}
else {
"iは0でも5でもaを含む文字列でもない何物かである。"
}
}
}}
if、elseif、elseが処理する{ }内にスクリプトが1つしか存在...
下のように書きなおすことが出来ます。
#code(aya,nooutline,nolink,nonumber){{
request
{
if !i
"iは0である。"
elseif i == 5
"iは5である。"
elseif "A" _in_ TOUPPER(i)
"iは文字列で、aもしくはAを含んでいる。"
else
"iは0でも5でもaを含む文字列でもない何物かである。"
}
}}
ただしifが重なっている場合は{ }の省略は出来ません。以下は...
#code(aya,nooutline,nolink,nonumber){{
if i == 0
if j == 0
"iとjはともに0である。"
}}
以下のように{ }が必要です。
#code(aya,nooutline,nolink,nonumber){{
if i == 0 {
if j == 0
"iとjはともに0である。"
}
}}
C言語と同様に、ifの判定式は全体をブラケット( )で囲むこと...
動作は囲まない場合と変わりません。~
if、elseif、case、while、for、switchの判定式で使用できま...
**caseによる分岐 [#l73d8c0f]
caseはラベル分岐構造を実現します。
#code(aya,nooutline,nolink,nonumber){{
request
{
case i {
when 0 {
"iは0である。"
}
when "A"
"iは文字列Aである。"
others {
"iは0でもAでもない。"
}
}
}
}}
caseに与えられた判定式の結果に一致するラベル値を持ったwhe...
others節は、すべてのラベルに合致しなかった場合に実行され...
ヒットさせるラベル値はカンマで列挙可能です。またマイナス...
#code(aya,nooutline,nolink,nonumber){{
request
{
case name+(i+1) {
when "Pentium3","Pentium4"
"Pen!!!は1999年、Pen4は2000年発売発売。"
when "Pentium5"-"PentiumX" {
"まだ無い。"
}
others
"分からない。"
}
}
}}
whenに記述するラベル値は必ず即値でなければなりません。変...
when、othersが処理する{ }内にスクリプトが1つしか存在しな...
**switchによる分岐 [#eded24e4]
{ }内の出力候補から出力は無作為に選ばれますが、switchを使...
#code(aya,nooutline,nolink,nonumber){{
request
{
switch id {
"idは0である。"
"idは1である。"
{
"idは2である。"
"idはtwoである。"
}
"idは"3である。"
}
}
}}
変数idの値によって出力される文字列が指定されます。指定は0...
idが2の時は、"idは2である。"もしくは"idはtwoである。"が出...
switchが評価する値に対応する候補が{ }内に存在しない場合は...
switch内に出力確定子がある場合は、各ブロックの該位置にあ...
#code(aya,nooutline,nolink,nonumber){{
request
{
switch 1 {
"かわいい"
"天才"
"サル"
--
"とは言い難い"
--
"ですね。"
"かもしれません。"
}
}
}}
requestの出力は"天才かもしれません。"となります。~
中間のブロックには指定位置に候補が無いので、出力が空の文...
**ループ [#hb9f85fc]
while、for、foreachの3種類のループ構造があります。~
***while [#j24fd024]
whileが評価する式が真である間は{ }内を繰り返し処理します。
#code(aya,nooutline,nolink,nonumber){{
request
{
_i = 1
_j = 0
while _i < 11 {
_j += _i
_i++
}
"1から10をすべて足すと%(_j)である。"
}
}}
上の例はwhileの機能を簡単に説明しています。
下の例では異なる10個の文字列を発生しています。requestの出...
#code(aya,nooutline,nolink,nonumber){{
request
{
_i = 1
while _i < 11 {
"%(_i)の平方根は%(SQRT(_i))である。"
_i++
}
}
}}
***for [#hb029288]
forはwhileと同様の先判定ループ構造ですが、初期化式、脱出...
以下は、whileで挙げた平方根を報告する例をforで書き直した...
#code(aya,nooutline,nolink,nonumber){{
request
{
for _i = 1; _i < 11; _i++ {
"%(_i)の平方根は%(SQRT(_i))である。"
}
}
}}
_i = 1はループを始める直前に実行されます。_i < 11はル...
戻る際に実行される式です。
C言語では for ( ; ; ) とすることで無限ループとできますが...
無限ループを作る場合は
#code(aya,nooutline,nolink,nonumber){{
for 1;1;1
}}
などとしてください。ただ、whileなら
#code(aya,nooutline,nolink,nonumber){{
while 1
}}
で済むため、文で無限ループを作る際は、可読性の点からも、...
***foreach [#a44ed835]
簡易配列、もしくは汎用配列の各要素値を順番に取り出します。
以下では簡易配列の要素値を取り出して数値へ変換し、すべて...
#code(aya,nooutline,nolink,nonumber){{
request
{
_str = "1,3,5,7,9"
_t = 0
foreach _str; _i {
_t += TOINT(_i)
}
_t
}
}}
foreachに続いて処理対象を記述します。上の例では簡易配列_s...
必ず変数でなければなりません。
処理対象の変数のデリミタがSETDELIMによって変更されていて...
foreachは汎用配列も処理できます。
#code(aya,nooutline,nolink,nonumber){{
request
{
_sent = ("I", "am", 31, "years", "old.")
_t = ""
foreach _sent; _i {
_t += (_i + " ")
}
_t
}
}}
requestは"I am 31 years old. "を出力します。
foreachループ内において要素取り出し対象の簡易配列、汎用配...
変更は正常に反映されます。~
***break [#h5c17692]
ループ中にbreakが現れると、現在実行中の最も深いループから...
#code(aya,nooutline,nolink,nonumber){{
request
{
_j = 0
for _i = 0; _i < 100; _i++ {
_j = _i*_i
if _j >= 100
break
}
_i - 1
}
}}
上の例では、forは初期値0の_iが100に達するまでループを実行...
requestは_iから1を減じた価を返しています。つまりrequestは...
***continue [#badbffd1]
ループ中にcontinueが現れると、その位置からすぐにループ先...
#code(aya,nooutline,nolink,nonumber){{
request
{
_j = ""
for _i = 0; _i < 3; _i++
{
_j += "go "
if _i > 0
continue
_j += "ahead "
}
_j
}
}}
_iは0、1、2と変化しますが、1、2ではcontinueが働くので、_j...
したがってrequestの出力は"go ahead go go "となります。
**return [#ad085d7a]
returnが現れると、その関数の実行はそこで終わります。~
関数の出力はそれまでに蓄積された候補から選ばれます。
#code(aya,nooutline,nolink,nonumber){{
to_rad
{
if GETTYPE(_argv[0]) == 3 {
-1
return
}
_argv[0]*2.0*3.14/360.0
}
}}
関数to_radはdegreeをradianへ変換します。~
引数に文字列が与えられた場合は、if判定でそれを発見して-1...
ありませんから、これが出力されることになります。
*プリプロセス [#m573754f]
プリプロセスは辞書ファイルを読み込んでいる段階で実行され...
***#define [#y197e4c0]
辞書ファイルから読み込んだ(パース前の)生の文字列に対し...
#code(aya,nooutline,nolink,nonumber){{
#define before after
}}
とすると、これを記述した行より後ろにbeforeが見つかるたび...
#define の有効範囲は、宣言した次の行から、そのファイルの...
置換は記述順に行われますので、先に変換しておきたいものを...
***#globaldefine [#r4820e57]
#code(aya,nooutline,nolink,nonumber){{
#globaldefine before after
}}
機能は #define ディレクティブと同じです。ただし、有効範囲...
~#globaldefine を宣言すると、次の行以降の全ての範囲(その...
たとえば最初に読み込む辞書ファイルの先頭に #globaldefine ...
~#defineが先に処理されます。。#globaldefine は、#define ...
#code(aya,nooutline,nolink,nonumber){{
#globaldefine tea green
#define tea milk
"teacup"
}}
置換結果は"milkcup"となります。
*予約語 [#wc1ef9d2]
以下の単語はシステム関数名、及び制御命令名です。~
これらの名前は文システムで予約されています。これらと完全...
***システム関数 [#w9fbee0d]
[[../システム関数]]で記述されている関数は全て利用できませ...
今後の拡張も考えると、大文字+アンダースコアのみで構成さ...
***制御構造キーワード [#y0131224]
>if elseif else case when others switch while for...
***演算子 [#a6b3280c]
以下の単語/文字は演算子です。~
これらと完全に一致する名称の変数や関数をユーザー側で作成...
>( ) [ ] ! ++ -- * / % + - & == != <...
*謝辞 [#o6562354]
以下のライブラリを利用もしくは参考にさせていただきました...
-マルチバイト文字列 - ワイド文字列変換クラス CUnicodeF~
http://kamoland.com/comp/unicode.html
-正規表現ライブラリ Boost::Regex~
本家~
http://www.boost.org/libs/regex/doc/index.html~
日本語訳~
http://boost.cppll.jp/HEAD/libs/regex/index.htm~
VC6へのインストール方法~
http://village.infoweb.ne.jp/~fwhk9290/behind/regex.htm~
基本的な使用方法~
http://www.s34.co.jp/cpptechdoc/article/regexpp/~
ページ名: