はじめに
AiScript(読み:あいすくりぷと)はMisskeyの開発者でもあるsyuiloさんが作成したプログラミング言語の一種です。
AiScript is a scripting language runing on JavaScript. Not altJS.
- ホストから変数や関数を提供することが出来ます
- 外の情報にはアクセス出来ないので安全にスクリプトを実行できます(サンドボックス環境)
ベースはTypeScript(JavaScript)で、Node.jsで動作します。
※この記事は2020年4月17日現在のものです。執筆時点では開発段階であるため、仕様変更がある場合がありますので予めご了承ください。
動作環境の構築
動作環境を構築するにはNode.js(LTS版で動作すると思います)が必要になります。
インストールしていない場合はインストールしておいてください。
- リポジトリをクローンします。:
git clone https://github.com/syuilo/aiscript.git
- リポジトリのディレクトリに移動し、依存パッケージをインストールします。:
cd aiscript; npm install
- AiScript環境をコンパイルをします。:
npm run build
Hello Worldを表示する
node console
でAiScriptのインタプリタを起動することができます。
起動したインタプリタで、下の関数を入力すると、Hello World!
と表示されます。
print("Hello World!")
ね、簡単でしょ。
インタプリタでは、返り値が表示されます。printは特に返すものはないため、nullとなります。
なお、printの関数は以下のようにしても同様に動作します。
<: "Hello World!"
インタプリタを抜けるにはCtrl-Cを押します。
注釈(コメント)
コメントはスラッシュ2文字で、改行するまで注釈扱いになります。
//
// これはコメントです。動作には影響しません
変数・定数
定数の定義は以下のようにして行います。
#constant = "This is a constant"
// #[定数名] = 代入する内容(項目:オブジェクト を参照)
変数の定義は以下のようにして行います。
$variable <- "This is a variable"
// $[変数名] <- 代入する内容(項目:オブジェクト を参照)
変数の内容を変更する場合は以下のようにして行います。
variable <- "It's changed variable"
// [変数名] <- 代入する内容(項目:オブジェクト を参照)
インタプリタ内であれば、定数や変数の中身を確認することができます。
> #hoge = "hoge"
> hoge
< "hoge"
オブジェクト
AiScirptには以下のオブジェクトがあります。
種類 | 型 | リテラル例 |
---|---|---|
文字列 | str | "kawaii" |
数値 | num | 42 |
真理値 | bool | yes /no |
配列 | arr | ["ai", "chan", "cute"] |
オブジェクト | obj | { foo: "bar"; a: 42; } |
null | null | _ |
関数 | fn | @(x) { x } |
配列について
配列のインデックスは1から始まります。つまり、こうなります。
#array = ["one", "two", "three"]
print(array[1]) // one
print(array[2]) // two
print(array[3]) // three
print(array[0]) // [ERROR!]
演算
演算は以下のようにして書くことができます。
(1 + 1)
以上のスクリプトは糖衣構文であり、AiScriptでは以下のように解釈されます。
Core:add(1, 1)
以下のような演算があります。
関数 | 演算子 | 意味 |
---|---|---|
Core:add | + | 加算 |
Core:sub | - | 減算 |
Core:mul | * | 乗算 |
Core:div | / | 除算 |
Core:mod | % | 剰余 |
Core:eq | = | 等しい |
Core:and | & | かつ |
Core:or | | | または |
Core:gt | > | 大きい |
Core:lt | < | 小さい |
※マークダウンのエスケープが上手く機能していないため、「|」は半角の|
として扱ってください。
ブロック
ブロックは処理のまとまりを書ける役割があります。ブロックの最後に書かれた式が値として返されます。
#foo = {
#a = 1
#b = 2
(a + b)
}
print(foo) // 3
なお、ブロック内の変数や定数はブロック外では使用できないみたいです(内部エラーが起きてるみたいなのでバグかもしれません)。
#foo = {
#a = 1
#b = 2
(a + b)
}
print(a) // [ERROR]
条件分岐
条件分岐は以下のように書きます。
? (a = b) { // ? ([演算式]) { [条件が合う場合の処理] }
<: "a is equal to b"
}
また、条件が一致しない場合の処理は以下のように書きます。
// ? ([演算式]) { [条件が合う場合の処理] } ... { [条件が合わない場合の処理] }
? (a = b) {
<: "a is equal to b"
} ... {
<: "a is not equal to b"
}
条件が一致しなかった場合、さらに条件を出す処理もできます。
// ? ([演算式1]) { [演算式1が合う場合の処理] } ...? ([演算式n]) { [演算式nが合う場合の処理] }
? (a = b) {
<: "a is equal to b"
} ...? (a > b) {
<: "a is grater than b"
} ... {
<: "a is less than b"
}
条件分岐は式として扱えるため、ブロック内で値を返すこともできます。
<: ? (a = b) {
"a is equal to b"
} ...? (a > b) {
"a is grater than b"
} ... {
"a is less than b"
}
繰り返し
繰り返し処理は以下のように書きます。
// ~ #[イテレータ名], [繰り返し回数] { [処理] }
~ #i, 100 {
<: i
}
// 1~100までprintされます。
なお、イテレーター名は省略可能です。
// ~ [繰り返し回数] { [処理] }
~ 100 {
<: "hoge"
}
配列を使った繰り返し処理も行えます。
#hoge = ["a", "b", "c"]
// ~~ #[イテレーター名], [配列定数(or 変数)] { [処理] }
~~ #h, hoge {
<: h
}
関数
関数を定義することもできます。以下のように書きます。
// @[関数名]([引数]) { [処理] }
@fun(x) {
(x + 3)
}
// 関数を実行
fun(2) // 5
最後の式が返り値として扱われます。
途中で返り値を出す場合は<<
を使用して値を返します。
@hoge(a) {
? (a = 2) {
<< (a * 2)
}
(a + 1)
}
hoge(2) // 4
テンプレート
文字列の中に変数や式を埋め込むことができます。以下のように書きます。
#hoge = "hoge"
<: `{hoge} is usually word used in programming`
スクリプトを実行
スクリプトを実行するには、test.is
を、AiScriptと同じディレクトリに設置してスクリプトを作成します。
作成したら、npm start
でスクリプトを実行することができます。
AiScriptはまだまだ開発段階であるため、
もしかしたら仕様が変わるかもしれません。
気が向いたらこの記事も変更するかもしれません。
また、このAiScriptは将来的にMisskeyに搭載される、とのことらしいので気になるところです。