スクリプト構文 - stuncloud/UWSCR GitHub Wiki

識別子

識別子とは変数、定数、関数などの名前を示す文字列です
以下の文字の組み合わせで命名できます

  • 英字 (大文字・小文字の区別はしません)
  • 数字
  • 記号
    • _
  • 全角文字

キーワード一覧

識別子 (変数名、定数名、関数名など) に使用できないキーワード

  • 特殊構文キーワード
    • call
    • async
    • await
  • 特殊な値を示すもの
    • null
    • empty
    • nothing
    • true, false
    • NaN
  • 演算子
    • mod
    • and, andL, andB
    • or, orL, orB
    • xor, xorL, xorB

変数定義

dim

対応バージョン: 0.0.3

ローカル変数を定義します

dim hoge     // 変数 hoge を定義
dim fuga = 1 // 値の代入も同時に行える
piyo = 1     // 未宣言変数への代入式で新たな変数が定義される(dim省略)

public

対応バージョン: 0.0.3

グローバル変数を定義します

public hoge = 1
hoge() // 1
hoge = 2
hoge() // 2

procedure fuag()
    print hoge
fend

const

対応バージョン: 0.0.3

定数を定義します
再代入ができません

const hoge = 1
hoge = 2 // これはダメ

一括定義

対応バージョン: 0.0.5

,区切りで変数を一括定義できます

dim a = 1, b = 2, c, d[3], e[] = 1,2,3,4,5
public f = 1, g = 2
const h = 1, i = 2

UWSCではエラーになっていたconstの一括定義も可能

以下はダメ (UWSCでもダメ)

dim foo[] = 1,2,3 , a = 1 // a = 1 は定義できない

配列

対応バージョン: 0.0.1

配列の定義はdimを使った方法と、配列リテラル(※)を使う方法があります
※ 新機能

dim hoge[] = 1, 2, 3 // 従来の配列定義
print hoge[0]

fuga = [1, 2, 3]     // 配列リテラル
print fuga[0]

print [4, 5, 6][0]   // 配列リテラルにインデックスを指定することも可能

+演算子による要素の追加

対応バージョン: 0.1.6

+演算子で配列の末尾に要素を追加できます

print [1, 2, 3] + 4
// [1, 2, 3, 4]
dim arr = [5, 6, 7]
arr += 8
print arr
// [5, 6, 7, 8]

多次元配列

対応バージョン: 0.1.7

// 2次元
dim 配列名[要素数][要素数] = 値, 値, 値, 値 ...
// 3次元
dim 配列名[要素数][要素数][要素数] = 値, 値, 値, 値 ...

// 以下の書式も可能
dim 配列名[要素数, 要素数] = 値, 値, 値, 値 ...
dim 配列名[要素数, 要素数, 要素数] = 値, 値, 値, 値 ...

// 一番左の要素数のみ省略可能
dim 配列名[][要素数][要素数] = 値, 値, 値, 値 ...
dim 配列名[, 要素数, 要素数] = 値, 値, 値, 値 ...

// 呼び出しは次元数分だけ[]をつける

print 配列名[0][0][0] // 3次元配列の1つ目の要素
// 不足分はEMPTYで埋められる
dim sample1[2][1] = 0, 1, 2, 3
print sample1 // [[0, 1], [2, 3], [, ]]

// 超過分は捨てられる
dim sample2[1, 1] = 0, 1, 2, 3, 4, 5
print sample2 // [[0, 1], [2, 3]]

// 要素数省略
dim sample3[][1] = 1,2,3,4,5,6,7,8
print sample3 // [[1,2] ,[3,4], [5,6], [7,8]]

// 一番左以外は省略不可
dim bad_sample[][][1] // エラー

配列リテラルを使って多次元配列を作ることもできます

dim sample4[] = [1,2], [3,4], [5,6], [7,8]
sample5 = [[1,2] ,[3,4], [5,6], [7,8]]

連想配列

対応バージョン: 0.1.5

hashtbl 連想配列変数                              // 連想配列を宣言
hashtbl 連想配列変数 = HASH_CASECARE              // キーの大文字小文字を区別
hashtbl 連想配列変数 = HASH_SORT                  // キーでソート(※1)
hashtbl 連想配列変数 = HASH_CASECARE or HASH_SORT // 大小文字区別かつソート

連想配列変数[キー] = 値                  // 任意のキー名で値を代入、数値のキーは文字列に変換される
値 = 連想配列変数[キー]                  // キー名で値を読み出す、キーがない場合はEMPTY
真偽値 = 連想配列変数[キー, HASH_EXISTS] // キーが存在するかどうか ※2
真偽値 = 連想配列変数[キー, HASH_REMOVE] // キーを削除、成功時はTRUE
キー = 連想配列変数[i, HASH_KEY]         // i番目の要素のキーを取得 ※3
値 = 連想配列変数[i, HASH_VAL]           // i番目の要素の値を取得 ※3

連想配列変数 = HASH_REMOVEALL  // 要素をすべて消す

// カンマ区切りで一括定義可能、オプションも指定できる
hashtbl 変数1, 変数2 = HASH_CASECARE, 変数3 = HASH_SORT
  • ※1 HASH_SORTによるキーソート順はUWSCと異なる場合があります
  • ※2 UWSCとは異なり変数で受けなくてもエラーになりません
  • ※3 iは0から
    HASH_CASECAREがない場合は代入した順序
    HASH_CASECAREがある場合はキーによりソートされた順序
hashtbl hoge
hoge["foo"] = 100
print hoge["foo"] // 100
hoge["FOO"] = 200
print hoge["foo"] // 200 大小文字区別がないため上書きされた
hoge["bar"] = 400
hoge["baz"] = 600

for i = 0 to length(hoge) - 1
    print hoge[i, HASH_KEY] // foo, bar, baz の順で表示される
    print hoge[i, HASH_VAL] // 200, 400, 600
next

print hoge["bar", HASH_EXISTS] // true
print hoge["qux", HASH_EXISTS] // false
hoge["bar", HASH_REMOVE] // 変数で受けなくてもOK
print hoge["bar", HASH_EXISTS] // false

hashtbl fuga = HASH_CASECARE
fuga["foo"] = 1
fuga["Foo"] = 2
fuga["FOO"] = 3
print fuga // {"foo": 1, "Foo": 2, "FOO": 3}

hashtbl piyo = HASH_SORT
piyo["b"] = ""
piyo["z"] = ""
piyo["a"] = ""
print piyo // {"A": , "B": , "Z": }

連想配列一括定義

hash-endhash で連想配列を一括定義できます

hash [public] 変数名 [=オプション]
    [キー = 値]
endhash
  • public
    • 指定するとグローバル変数
    • 省略時はローカル変数
  • オプション
    • HASH_SORTHASH_CASECARE を指定可能
    • 省略時はオプションなし
  • キー = 値
    • キーと値の組み合わせを指定する
    • 複数指定可
    • キーは文字列だが''""は省略可能
    • 一つも指定しない場合空の連想配列ができる
// 一括定義
hash foobar
    'foo' = 1 // キー = 値形式で記述
    bar   = 2 // キーは文字列でなくても良い
endhash
// 以下と同じ
// hashtbl foobar
// foobar['foo'] = 1
// foobar['bar'] = 2

// グローバル変数にする
hash public pub
endhash
// 以下と同じ
// public hashtbl pub

// オプション指定
hash with_option = HASH_CASECARE or HASH_SORT
endhash
// 以下と同じ
// hashtbl with_option = HASH_CASECARE or HASH_SORT

enum

対応バージョン: 0.1.7

列挙体を定義します
グローバルスコープの定数として定義されます

// 定義
enum 定数名
    メンバ名
    メンバ名 [ = 数値]
endenum

// 呼び出し
定数名.メンバ名

メンバには上から順に数値が割り当てられます (0から)
メンバ名 = 数値とすることで任意の値を割り当てられます
ただし前のメンバより大きな値のみ有効です

// 0から順に割り当てられる
enum E
    foo // 0
    bar // 1
    baz // 2
endenum

// 呼び出しは定数名.メンバ名
print E.foo // 0
print E.bar // 1
print E.baz // 2

// 数値を指定
enum E
    foo = 10 // 10
    bar = 20 // 20
endenum

// 一箇所指定するとそれ以降はその値から加算されていく
enum E
    foo = 10 // 10
    bar      // 11 (上の10 に +1される)
    baz      // 12
endenum

// 途中も可
enum E
    foo      // 0
    bar = 10 // 10
    baz      // 11
endenum
enum E
    foo = 100    // 100
    bar          // 101
    baz = 200    // 200
    qux          // 201
endenum

// 以下はNG

enum E
    foo
    foo // 同じ名前はダメ
endenum

// 前の数値より大きくないとダメ
enum E
    foo // 0
    bar // 1
    baz = 1 // 2以上じゃないとダメ
endenum
enum E
    foo = 50
    bar = 1 // 51以上じゃないとダメ
endenum

関数定義

関数名には英数字、一部記号、全角文字列が使えます
英字の大文字小文字は区別しません

procedure

function

対応バージョン: 0.1.2

procedure 関数名([引数, 引数, …])
    処理
fend

function 関数名([引数, 引数, …])
    [result = 戻り値]
fend

procedureは戻り値がありません
functionresult変数の値が戻り値となります
resultの初期値はEMPTYです resultの記述がない場合はEMPTYを返します

hoge(1,2,3) // 6
print fuga(1,2,3) // 6

procedure hoge(a, b, c)
    print a + b + c
fend
function fuga(a, b, c)
    result = a + b + c
fend

関数定義の入れ子はダメ

// エラーになる
procedure p()
    procedure q()
    fend
fend

特殊な引数

参照渡し

引数の前に var または ref キーワードをつけることで参照渡しが可能な引数になります
引数に変数を渡すとその変数に関数実行中の変更が反映されます
変数以外の式を渡した場合は通常の引数と同様に振る舞います

a = 2
print a // 2
p(a)
print a // 6
q(a)
print a // 16

procedure p(ref r)
    r *= 3
fend

procedure q(var v)
    v += 10
fend
配列表記

引数[] とすることで配列変数または連想配列変数を受ける引数にできます
変数以外が渡されるとエラーになります (互換性のため配列ではない変数も渡せる)

dim a[] = 1,2,3
p(a) // 3

// 配列ではない変数も受けられる
b = 12345
p(b) // 5

p("abc") // 変数じゃないのでダメ

procedure p(arr[])
    print length(arr)
fend
デフォルト値

引数 = 値 とすることで引数のデフォルト値を指定できます
値を省略した場合はEMPTYがデフォルト値になります
呼び出し時に引数を渡さなかった場合デフォルト値が適用されます

print f(2)    // 0
print f(2, 3) // 6

function f(n, m = 0)
    result = n * m
fend

// デフォルト値を省略した場合はEMPTYが入る
procedure p(arg = )
    print arg == EMPTY // True
fend

デフォルト値を持つ引数のあとに別の種類の引数は指定できません

procedure p(a = 1, b = 2, c = 3) // ok 
fend
procedure q(a = 1, b, c = 3)     // エラー 
fend
procedure r(a, b = 2, c = 3)     // 前ならok 
fend
可変長引数

引数の前に args または prms キーワードをつけることで可変長の引数を受けられるようになります
関数内ではその引数が配列になります
可変長引数は最後の引数でなくてはいけません

print f(1)         // 1
print f(1,2,3,4,5) // 5

function f(args v)
    result = length(v)
fend

可変長引数のあとに引数があるとエラーになります

procedure p(prms a, b)    // エラー
fend
procedure q(a, b, prms c) // ok
fend
特殊な引数の組み合わせ

原則として組み合わせられません
配列表記の参照渡しのみOK

procedure p(ref foo[]) // これはOK

// こういうのはダメ
procedure p(ref foo = 1) // 参照 + デフォルト値
procedure p(ref params bar) // 参照 + 可変長
procedure p(params bar = 1) // 可変長 + デフォルト値

引数の型チェック

対応バージョン: 0.4.0

function 関数名(引数名: 型, var 引数名: 型, 引数名: 型 = デフォルト値)

通常の引数、参照渡し、デフォルト値を持つ引数であれば受ける型を指定できます
関数呼び出し時に指定した型が渡されなかった場合は実行時エラーになります

指定可能な型

型名 データ型
string 文字列
number 数値
bool 真偽値(TRUE/FALSE)
array 配列
hash 連想配列
func 関数 (ユーザー定義、無名関数)
uobject UObject
クラス名 クラスオブジェクトのインスタンス
列挙体名 列挙体(enum)メンバの値(数値)
function f(str: string)
    result = str
fend

print f("hoge") // OK
print f(123)    // 数値なのでエラー

// 列挙体名指定の場合
enum Hoge
    foo
    bar
    baz
endenum

function f2(n: Hoge)
    select n
        case Hoge.foo
            result = 'foo!'
        case Hoge.bar
            result = 'bar!'
        case Hoge.baz
            result = 'baz!'
    selend
fend

print f2(Hoge.foo) // OK
print f2("Hoge")   // 文字列はエラー
print f2(0)        // OK ※Hoge.fooに一致するため
print f2(100)      // Hogeに含まれない値なのでエラー

module

対応バージョン: 0.1.0

機能のモジュール化
モジュール名.メンバ名で各機能を利用可能にします

module モジュール名
    const 定数名 = 式      // モジュール名.定数名 で外部からアクセス可
    public 変数名[ = 式]   // モジュール名.変数名 で外部からアクセス可
    dim 変数名[ = 式]      // 外部からアクセス不可
    procedure モジュール名 // コンストラクタ、module定義の評価直後に実行される
    procedure 関数名()     // モジュール名.関数名() で外部からアクセス可
    function 関数名()      // モジュール名.関数名() で外部からアクセス可
    textblock 定数名       // モジュール名.定数名 で外部からアクセス可
endmodule

module関数内でのみ使える特殊な書式

  • this.変数名this.関数名() 自module内のメンバの呼び出しを明示する
  • global.変数名global.関数名() グローバル変数および関数を呼び出す(ビルトイン含む)
    (本家と異なり変数や定数も可)
module sample
    dim d = 1
    public p = 2
    const c = 3

    function f1()
        // 各メンバーには以下のようにアクセス可能
        print d
        print this.d
        print sample.d

        print p
        print this.p
        print sample.p

        print c
        print this.c
        print sample.c

        print f2()
        print this.f2()
        print sample.f2()
    fend

    function f2()
        result = 4
    fend

    function f3()
        print this.f4()   // in   メンバ関数が呼ばれる
        print global.f4() // out  module外の関数が呼ばれる
        print f4()        // in   メンバ関数が呼ばれる
    fend

    function f4()
        result = "in"
    fend
endmodule

function f4()
    result = "out"
fend

プライベート関数

無名関数を用いたプライベート関数の実装例

Sample.Private() // エラー
Sample.Func()    // OK

module Sample
    function Func()
        result = Private()
    fend

    dim Private = function()
        result = "OK"
    fend
endmodule

class

対応バージョン: 0.1.3

classを定義します
class名()を実行することによりインスタンスを作成します
※ 注意: UWSCのclassとは互換性がありません

class class名
    procedure class名()    // コンストラクタ (必須)
    procedure _class名_()  // デストラクタ (オプション)
    const 定数名 = 式      // classインスタンス.定数名 で呼び出し可
    public 変数名[ = 式]   // classインスタンス.変数名 で呼び出し可
    dim 変数名[ = 式]      // class内からのみ呼び出し可
    procedure 関数名()     // classインスタンス.関数名() で呼び出し可
    function 関数名()      // classインスタンス.関数名() で呼び出し可
    textblock 定数名       // classインスタンス.定数名 で呼び出し可
endclass

h1 = hoge(3, 5)
print h1.Total() // 8

h2 = hoge(8, 10)
print h2.Total() // 18

print hoge(11, 22).Total() // 33

class hoge
    dim a = 1, b = 2
    procedure hoge(a, b)
        this.a = a
        this.b = b
    fend
    function Total()
        result = this.a + this.b
    fend
endclass

moduleと異なりclass名から直接メンバにアクセスすることはできません

print hoge.p() // エラー

デストラクタ

デストラクタはインスタンスへの参照がなくなった際に実行される関数です
_class名_() で命名された関数がデストラクタとして定義されます
デストラクタに引数は指定できません

デストラクタが実行されるタイミング

  • すべての参照が失われたとき
  • いずれかのインスタンス変数にNOTHINGを代入したとき (明示的に破棄する)
    • インスタンス変数はNOTHINGになります
  • withに渡す式でインスタンスを作成した場合でendwithに到達したとき
  • 関数スコープを抜ける際に削除されるこローカルスコープ変数だった場合
  • スクリプト終了時に削除されるローカル・グローバル定数だった場合
class Sample
    dim msg
    procedure Sample(msg)
        this.msg = msg
    fend
    procedure _Sample_()
        print msg
    fend
endclass

obj1 = Sample("すべての参照が失われた")
obj2 = obj1
obj3 = obj1

obj1 = 1
obj2 = 1
obj3 = 1 // すべての参照が失われた がprintされる

obj1 = Sample("NOTHINGが代入された")
obj2 = obj1
obj3 = obj1

obj1 = NOTHING // NOTHINGが代入された がprintされる
print obj1 // NOTHING
print obj2 // NOTHING
print obj3 // NOTHING

with Sample("withを抜けた")
endwith // withを抜けた がprintされる

procedure p()
    obj = Sample("関数スコープを抜けた")
fend

p() // 関数スコープを抜けた がprintされる

UObject

対応バージョン: 0.1.7

json互換のオブジェクト

オブジェクトの作成

  1. UObjectリテラル: jsonを@で括る
  2. FROMJSON関数
obj = @{
    "foo": "fooooo",
    "bar": {
        "baz": true
    },
    "qux": [
        {"quux": 1},
        {"quux": 2},
        {"quux": 3}
    ]
}@

arr = @[1, 2, 3]@

有効な値は

  • 数値
  • 文字列
  • 真偽値
  • NULL
  • 配列
  • オブジェクト

値の呼び出し、変更

print obj.foo // fooooo
obj.foo = "FOOOOO"
print obj.foo // FOOOOO
print obj["foo"] // 配列の添字にしてもOK

print obj.bar.baz ? "baz is true!": "baz is fasle!" // baz is true!

obj.qux[1].quux = 5
print obj.qux[1].quux // 5

obj.qux[2] = "overwrite!"
print obj.qux[2] // overwrite!

obj.corge = 1 // エラー、追加はできない

// オブジェクトを作って代入ならOK
obj.foo = fromjson('{"hoge": 1, "fuga": 2}')
print obj.foo

無名関数

対応バージョン: 0.1.0

変数 = function([引数, ...])
    [result = 戻り値]
fend
変数 = procedure([引数, ...])
fend

変数に関数を代入できます

hoge = function(x, y)
    result = x + y
fend

print hoge(2, 3) // 5

変数への代入は可能ですが即時関数のようなことはできません

// こういうのは無理
print (function(n)
    result = n * 2
fend)(5)

無名関数の中でpublic/constを宣言した場合は実行時に初めて評価されます

print x // エラー

proc = procedure()
    public x = 5
fend

print x // エラー

proc()

print x // 5

通常の関数と同様に特殊な引数も定義できます

f = function(a, b[], var c, d = 0)
fend
p = procedure(args e)
fend

簡易関数式

対応バージョン: 0.1.6

無名関数を単行の式で記述できます
通常の無名関数と異なり処理部に文は書けません(式のみ)
その代わりに即時関数として利用できます

関数 = | 引数 [, 引数, …] => 式 [; 式; …] |

引数は,区切りで複数指定可能
resultは省略可能です

func = | a, b => a + b |
print func(1, 2) // 3

式は ; 区切りで複数書けます
この場合一番最後の式が戻り値となります

func = | a, b => a *= 2; b *= 3; a + b |
print func(1, 2) // 8

即時関数

print | n, m => n * m |(7, 6) // 42
// 値だけ返す
print |=> 42|() // 42

// 関数の引数にする
function f(fn)
    result = fn("world!")
fend
print f(| s => "hello " + s |) // hello world!

特殊な引数にも対応

print | args a => length(a) |(1,2,3,4,5,6) // 6

評価の順序

対応バージョン: 0.1.0

グローバル変数や定数、関数定義は実行より先に評価されます

  1. public, const, textblockを記述順に評価
  2. function, procedure, moduleを記述順に評価
    • 関数内で宣言されているpublicやconstも評価
  3. 残りの構文を評価/実行する

スコープ

対応バージョン: 0.1.0

スコープは大きくわけて

  • スクリプト本文
  • 関数内

で分かれています
変数にはローカルとグローバルという区分があり、

  • スクリプト本文のローカル変数はスクリプト本文内でしかアクセスできない
  • 関数のローカル変数は関数内でしかアクセスできない
  • グローバル変数はいずれからでもアクセスできる

という特徴があります

  • ローカル
    • dim宣言した変数
      • 宣言省略した変数も含む
    • hashtbl宣言した連想配列
  • グローバル
    • public宣言した変数
      • public hashtbl
    • const宣言した定数
    • 定義した関数 (変数ではないが扱いはグローバル)
public global1 = "グローバル変数1"
dim local = "本文ローカル"

print global1 // ok
print global2 // ok
print local // ok
print proc_local // ng
print func() // ok

procedure proc()
    public global2 = "グローバル変数2"
    dim proc_local = "関数ローカル"
    print global1 // ok
    print global2 // ok
    print local // ng
    print proc_local // ok
    print func() // ok
fend

function func()
    result = "関数"
fend

無名関数のスコープ

無名関数の中はスコープが分かれていません
ローカル変数がそのまま使えます

dim local = 1
dim func = function(n)
    result = local + n
fend

print func(1) // 2

moduleのスコープ

moduleメンバに関しては独自のスコープを持ちます
module関数内で定義したpublic, const, function/procedureはグローバル空間には置かれず、
moduleメンバのみがアクセスできるmoduleローカル空間に配置されます

これらはmodule名.メンバ名でアクセスできます

文字列

対応バージョン: 0.1.1

文字列リテラルは""または''で括ります
" で括った文字列では特殊文字が展開されます
' で括った文字列では特殊文字が展開されません

str = "文字列"
str = '文字列'

文字列の結合は+演算子を使います

str = "文字列" + "の" + "結合"
print str // 文字列の結合

特殊文字の展開

" で括った文字列中にある以下の特殊文字は、それぞれ該当する別の文字に変換されます

  • <#CR>: 改行 (CRLF)
  • <#TAB>: タブ文字
  • <#DBL>: ダブルクォーテーション (")
  • <#変数名>: 変数が存在する場合、その値
print "hoge<#CR>fuga<#CR>piyo"
// hoge
// fuga
// piyo
print "hoge<#TAB>fuga<#TAB>piyo"
// hoge    fuga    piyo
print "<#DBL>hoge<#DBL>"
// "hoge"

dim a = 123
print "a is <#a>"
// a is 123
print "b is <#b>" // 変数が存在しない場合は展開されない
// b is <#b>
print "length of a is <#length(a)>" // 式はダメ、変数のみ展開される
// length of a is <#length(a)>

print 'a is <#a>' // シングルクォーテーション文字列は展開しない
// a is <#a>

ホワイトスペース

  • 半角スペース
  • タブ文字
  • 全角スペース

はホワイトスペース扱いです
式と式の区切りとして機能します

改行(CRLF、CR、LF)は行末扱いです

演算子

対応バージョン: 0.1.9

演算子 処理
+ 数値の加算、文字列の結合、配列要素の追加
+= +演算して代入
- 数値の減算
-= 減算して代入
* 数値の乗算、文字列の繰り返し
*= 乗算して代入
/ 数値の除算 ※ 0で割ると0を返す
/= 除算して代入
mod 数値の剰余演算 (割った余りを返す)
! 論理否定
?: 三項演算子 b ? t : f
:= 代入 (代入した値を返す)
= 代入、等価演算
== 等価演算
<> != 不等価演算
and 数値のAND演算(ビット演算)、真偽値の論理演算
or 数値のOR演算(ビット演算)、真偽値の論理演算
xor 数値のXOR演算(ビット演算)、真偽値の論理演算
andL 論理演算 (両辺の真偽性評価を行う)
orL 論理演算 (両辺の真偽性評価を行う)
xorL 論理演算 (両辺の真偽性評価を行う)
andB ビット演算 (両辺を数値とみなし評価を行う)
orB ビット演算 (両辺を数値とみなし評価を行う)
xorB ビット演算 (両辺を数値とみなし評価を行う)
< 小なり
<= 小なりイコール
> 大なり
>= 大なりイコール
. moduleやオブジェクトのメンバへのアクセス

演算式の優先順位

対応バージョン: 0.1.9

優先順位の高いものから先に演算を行います

  1. ()
  2. .
  3. !
  4. * / mod
  5. + -
  6. =(等価比較) == <> !=
  7. and (L,Bを含む)
  8. or xor (L,Bを含む)
  9. ?:
  10. :=

代入系演算子は順位判定とは別に代入処理判定を行っています

  • =
  • +=
  • -=
  • *=
  • /=
// 2つ目の = は代入ではなく比較になるので a にはboolが入る
a = b = c

// こういうのはダメ、演算中に代入はしない
a + b + c += d 

例外として:=による代入があります
:=による代入は式であり、変数に代入された値を返します

print n := 1               // 1 (代入した値が返る)
print n                    // 1
print 1 + 2 + (n := 3) + 4 // 10 (代入した値が返り、その値で計算が行われる)
print n                    // 3

特殊な演算

数値以外を含む演算には一部特殊な仕様があります
型に対して不適切な演算子が用いられた場合はエラーになります

左辺 演算子 右辺 演算結果 補足
数値 + 文字列 数値 右辺の文字列が数値変換可能な場合 1 + '2' // 3
文字列 右辺の文字列が数値変換できない場合 1 + 'a' // 1a
数値 すべて EMPTY 数値 EMPTYは0になります 3 * EMPTY // 0
数値 すべて 真偽値 数値 TRUEは1、FALSEは0になります 3 + TRUE // 4
文字列 + 数値 文字列 左辺の文字列が数値に変換できない場合右辺の数値を文字列にします 'a' + 3 // a3
数値 左辺の文字列が数値変換可能な場合数値にします '1' + 2 // 3
文字列 * 数値 文字列 左辺の文字列を数値分繰り返します 'a' * 3 // aaa
数値 左辺の文字列が数値変換可能な場合数値にします '1' * 3 // 3
文字列 +* 以外 数値 数値 左辺の文字列が数値変換可能な場合数値にします
エラー 左辺の文字列が数値に変換できない場合演算不可 'a' / 3
文字列 + NULL 文字列 文字列の末尾にNULL文字(chr(0))を付与します 'a' + TRUE // aTrue
文字列 + 文字列 右辺が上記以外であれば文字列として扱います 'a' + TRUE // aTrue
配列 + 配列 配列の末尾に値を追加します [1,2,3] + 4 // [1,2,3,4]

真偽判定

対応バージョン: 0.1.9

真偽性の評価が行われる場合(ifの条件式など)に

  • FALSE
  • EMPTY
  • 0
  • NOTHING
  • 長さ0の文字列
  • 長さ0の配列
  • NULLハンドル

は偽となります
それ以外は真です

print NOTHING ? '真' : '偽' //
print "" ? '真' : '偽' //
print "空ではない文字列" ? '真' : '偽' //
print [1,2,3] ? '真' : '偽' //
print [] ? '真' : '偽' //

コメント

// 以降は行末までコメントです (構文解析されない)
// があった時点で行末扱いになります

a = 1
// a = a + 1
print a // 1 が出力される

行結合

対応バージョン: 0.1.3

行末に _ を記述することで次の行と結合させます

a = 1 + 2 + _
3 + 4

print a // 10

マルチステートメント

対応バージョン: 未定

; をつけることで複数の文を1行に記述できます

a = 1; a = a + 1; print a // 2

組み込み定数

対応バージョン: 0.1.6

  • TRUE // true または 1
  • FALSE // false または 0
  • NULL // 振る舞い未実装
  • EMPTY // 空文字
  • NOTHING // オブジェクトがない状態
  • NaN // Not a number

NaNについて

NaNNaN自身を含めあらゆる値と等価ではありません
またNaNとの大小の比較結果も必ず偽です

print NaN == NaN // False
print n   == NaN // False (nは何かしらの値)
print NaN != NaN // True 
print NaN <  n   // False 
print NaN <= n   // False 
print NaN >  n   // False 
print NaN >= n   // False 

16進数

対応バージョン: 0.0.1

16進数リテラル表記は $ を使います

print $FF // 255

起動時パラメータ

対応バージョン: 0.1.2

スクリプトにパラメータを付与した場合にそれらがPARAM_STR[]に格納されます

OPTION

対応バージョン: 0.1.7

// bool値指定は省略可能で、省略時はtrueになります
// 例:
// OPTION EXPLICIT // explicit設定をtrueにする
// もともと設定がtrueになっているものをfalseに設定したい場合に値指定を使う
// OPTION SHORTCIRCUIT=FALSE // デフォルトtrueなのでfalseにする

// コメントアウトされているものは非対応か現時点では動作しないものです

OPTION EXPLICIT[=bool]             // ローカル変数初期化時にdim宣言が必須かどうか (初期値:false)
// OPTION SAMESTR[=bool]           // 文字列の比較等で大文字小文字を区別するかどうか (初期値:false)
// OPTION OPTPUBLIC[=bool]         // public変数の重複定義を禁止するかどうか (初期値:false)
OPTION OPTFINALLY[=bool]           // tryで強制終了時にfinally部を実行するかどうか (初期値:false)
// OPTION SPECIALCHAR[=bool]       // 互換性のため設定は可能ですが機能しません ※1
// OPTION SHORTCIRCUIT[=bool]      // 論理演算で短絡評価を行うかどうか (初期値:true)
// OPTION NOSTOPHOTKEY[=bool]      // 停止ホットキーを無効にするかどうか (初期値:false)
// OPTION TOPSTOPFORM[=bool]       // 停止ボタン実装の予定がありません
// OPTION FIXBALLOON[=bool]        // 吹き出しを仮想デスクトップにも表示するかどうか (初期値:false)
// OPTION DEFAULTFONT="name,n"     // ダイアログ等のフォント指定  (初期値:"MS Gothic,12")
// OPTION POSITION=x,y             // メインGUIの座標指定 (初期値:0, 0)
OPTION LOGPATH="path"              // ログ保存フォルダを指定 ※2 (初期値:スクリプトのあるフォルダ)
// OPTION LOGLINES=n               // ログファイルの最大行数を指定 (初期値:400)
OPTION LOGFILE=n                   // ログファイルの出力方法 ※3 (初期値:1)
// OPTION DLGTITLE="title"         // ダイアログのタイトル (初期値:"UWSCR - スクリプト名")

// ※1 '文字列'を使ってください
// ※2 存在するディレクトリを指定するとそこに`uwscr.log`を出力
//     それ以外はファイルパスとして扱われます
// ※3 現時点では細かい設定ができません
//     1: ログ出力なし
//     2: ログ出力あり
//     3: ログ出力あり
//     4: ログ出力あり
//     それ以外: ログ出力なし

def_dll

対応バージョン: 0.1.9

DLL関数 (Win32 APIなど) を呼び出せるようにします
32bit版UWSCRでは32bitのDLL、64bit版では64bitのDLLに対応します

def_dll 関数名(型, 型, ...): 戻り型: DLLパス
def_dll 関数名(型, 型, ...): DLLパス // 戻り値がvoidの場合省略できる

型定義について

以下の型を指定できます
一部の型はx86/x64でサイズが変わります
一部の型は引数定義、または戻り値定義でのみ指定可能です

型名 サイズ 詳細 対応する値型 引数 戻り値 備考
int, long, bool 4 符号あり32ビット整数 数値
uint, dword 4 符号なし32ビット整数 数値
hwnd 4 / 8 ウィンドウハンドル 数値
float 4 単精度浮動小数点数 数値(小数)
double 8 倍精度浮動小数点数 数値(小数) UWSCRの標準数値型
word, wchar 2 符号なし16ビット整数 数値
byte, char, boolean 1 符号なし8ビット整数 数値
longlong 8 符号あり64ビット整数 数値
string 4 / 8 ANSI文字列のポインタ 文字列, NULL OSの現在のANSIコードによる
pchar 4 / 8 ANSI文字列のポインタ 文字列, NULL NULL含む
wstring 4 / 8 ワイド文字列のポインタ 文字列, NULL Unicode文字列
pwchar 4 / 8 ワイド文字列のポインタ 文字列, NULL NULL含む
pointer 4 / 8 ポインタを示す数値(符号なし) 数値 新規
struct 4 / 8 ユーザー定義構造体のポインタ 構造体インスタンス 新規 struct-endstructで定義
callback 4 / 8 コールバック関数のポインタ 新規 動作未定義
safearray SafeArray型 SafeArray 動作未定義
void 型がないことを示す

特殊な型定義

参照渡し

var 型 で参照渡しになります
DLL関数により引数が書き換えられる場合にvarを付与することにより変更後の値を渡した変数で受けられる

注意 ポインタになるわけではありません (内部処理により元の変数の値を書き換える)

配列の定義

型[] で配列変数を受ける型になります
varの有無に関わらずDLL関数により値が変更される場合があります
配列変数はポインタになるためサイズは4または8です

構造体の定義

{型, 型, ...} で構造体を定義します
構造体定義内ではvarの有無に関わらずDLL関数により値が変更される場合があります
構造体定義はポインタになるためサイズは4または8です

構造体定義のネストはできません
平の定義に展開されます

def_dll hoge({long, {long, long}}):hoge:dll
// ↑同じ↓
def_dll hoge({long, long, long}):hoge:dll

DLL関数定義例

// Win32のA関数ではstringかpcharを使う
def_dll MessageBoxA(hwnd, string, string, uint):int:user32.dll
// Win32のW関数ではwstringかpwcharを使う
def_dll MessageBoxW(hwnd, wstring, wstring, uint):int:user32.dll

// 構造体定義は{}
def_dll SetWindowPlacement(hwnd, {uint, uint, uint, long, long, long, long, long, long, long, long}):bool:user32.dll

// 参照渡し
def_dll GetPrivateProfileStringA(string, string, string, var pchar, dword, string):dword:kernel32

// 構造体で実行後の値を受ける場合にvarは不要
def_dll GetCursorPos({long, long}):bool:user32.dll
// 構造体はそのサイズに合う配列でも代用可能
def_dll GetCursorPos(long[]):bool:user32.dll

DLL関数定義例およびその呼び出し方

// Win32のA関数ではstringかpcharを使う
def_dll MessageBoxA(hwnd, string, pchar, uint):int:user32.dll
// Win32のW関数ではwstringかpwcharを使う
def_dll MessageBoxW(hwnd, wstring, pwchar, uint):int:user32.dll

// 呼び出す際は単に文字列を渡すだけで良い
print MessageBoxA(0, 'メッセージ', 'タイトル', 0)
print MessageBoxW(0, 'メッセージ', 'タイトル', 0)

// 構造体定義は{}
def_dll SetWindowPlacement(hwnd, {uint, uint, uint, long, long, long, long, long, long, long, long}):bool:user32.dll
id = getid("メモ帳")
h = idtohnd(id)
// 構造体を渡すときは定義した型の数だけ値を並べる
SetWindowPlacement(h, 44, 0, 1, 0, 0, 0, 0, 200, 200, 600, 600)

// 参照渡し
def_dll GetPrivateProfileStringA(string, string, string, var pchar, dword, string):dword:kernel32
buffer = '                                                     '
// bufferがpcharなのでNULLを含んだ文字列が返ってくる
print GetPrivateProfileStringA(NULL, NULL, "default", buffer, length(buffer), "test.ini")
print buffer
def_dll GetPrivateProfileStringA(string, string, string, var string, dword, string):dword:kernel32
buffer = '                                                     '
// bufferをstringにすると最初のNULL以前の文字列のみ返ってくる
print GetPrivateProfileStringA(NULL, NULL, "default", buffer, length(buffer), "test.ini")
print buffer

// 構造体で値を受ける
// varは不要
def_dll GetCursorPos({long, long}):bool:user32.dll
dim x, y
print GetCursorPos(x, y)
print [x, y]

// 構造体はそのサイズに合う配列でも代用可能
// varは不要
def_dll GetCursorPos(long[]):bool:user32.dll
dim point = [0, 0] // long, long
print GetCursorPos(point)
print point

// 戻り値の型の制限
def_dll PathAddBackslashW(var string):string:ShlwApi.dll
path = "d:\hoge"
print PathAddBackslashW(path)
print path
// このような場合UWSCでは戻り値も文字列になりましたが、UWSCRでは安全のためこれをサポートしません
// この場合ポインタ(の数値)が返ります (その際警告文が標準出力されます)

構造体定義

対応バージョン: 0.1.9

def_dllのstruct型に渡す構造体を定義します

struct 構造体名
    メンバ名: 型
    メンバ名: 構造体名
    ︙
endstruct

はdef_dll定義で使うものと同等です(一部使用不可※)
構造体名は別に定義した構造体の名前です

構造体名()で構造体のインスタンスを作成します
インスタンス作成時に数値型は0、文字列型はNULLで初期化されます

struct Point
    x: long
    y: long
endstruct

dim p = Point()
// xとyは0で初期化されるため以下のような初期化処理は記述不要
// p.x = 0
// p.y = 0

def_dll GetCursorPos(struct):bool:user32.dll
GetCursorPos(p)
print [p.x, p.y]


struct Hoge
    id: uint
    point: Point // 構造体名を指定
endstruct

h = Hoge()
print h.id // 0
// Pointも初期化される
print h.point.x // 0
print h.point.y // 0

※ 利用可能な型

型名 サイズ 詳細 対応する値型
int, long, bool 4 符号あり32ビット整数 数値
uint, dword 4 符号なし32ビット整数 数値
hwnd 4 / 8 ウィンドウハンドル 数値
float 4 単精度浮動小数点数 数値(小数)
double 8 倍精度浮動小数点数 数値(小数)
word, wchar 2 符号なし16ビット整数 数値
byte, char, boolean 1 符号なし8ビット整数 数値
longlong 8 符号あり64ビット整数 数値
string 4 / 8 ANSI文字列のポインタ 文字列, NULL
pchar 4 / 8 ANSI文字列のポインタ 文字列, NULL
wstring 4 / 8 ワイド文字列のポインタ 文字列, NULL
pwchar 4 / 8 ワイド文字列のポインタ 文字列, NULL
pointer 4 / 8 ポインタを示す数値(符号なし) 数値

ポインタから構造体インスタンスを作る

DLL関数が作成した構造体のポインタを返す場合に、その構造体と同等の構造体を定義しておくことで値を受け取れます

struct SomeStruct
    foo: long
    bar: long
    baz: long
endstruct

// 
s = SomeStruct(pointer)
print s.foo

スレッド

thread

対応バージョン: 0.1.8

関数を別のスレッドで実行します

thread func()
  • スレッドスコープで実行されます
    • (その中でさらに関数スコープに入ります)
  • グローバルスコープへのアクセスは可能
    • public, const, function/procedure, module/class
  • 呼び出した関数内でエラーが発生(raise()等)するとそのスレッドで標準エラーを出力します
    UWSCとは異なりメインスレッドは続行します (0.1.8時点での仕様)

タスク

対応バージョン: 0.1.8

関数を非同期実行します
threadとは異なり関数が完了し次第戻り値を受け取れます

async

タスクを返す関数を宣言します

// function宣言の前に async キーワードを付与
async function 関数名()
fend
async function MyFuncAsync(n)
    sleep(n)
    result = "<#n>秒待ちました"
fend

task = MyFuncAsync(5) // resultの値ではなくタスクを返す

// 以下と同じ結果になります
function MyFuncAsync(n)
    sleep(n)
    result = "<#n>秒待ちました"
fend

task = Task(MyFuncAsync, 5)

await

async宣言した関数の終了を待ち、resultの値を得ます

async function MyFuncAsync(n)
    sleep(n)
    result = "<#n>秒待ちました"
fend

// MyFuncAsync()の処理が終了するまで待つ
print await MyFuncAsync(5) // 5秒待ちました

with

対応バージョン: 0.1.1

.演算子の左辺(module名やオブジェクト)を省略できます

with foo
    print .bar // foo.bar
    .baz()     // foo.baz()
endwith

ネストも可

with m
    print .p // m.p
    with .f() // m.f() のwithでネスト
        print .p // m2.p
    endwith
    print .p // m.p
endwith

module m
    public p = "m.p"
    function f()
        result = m2
    fend
endmodule

module m2
    public p = "m2.p"
endmodule

textblock

対応バージョン: 0.1.1

複数行文字列の定数を定義します
改行は<#CR>と一致します
特殊文字(<#CR>,<#DBL>,<#TAB>)はtextblock文の評価時に展開されます

textblock [定数名]
(複数行文字列)
endtextblock

定数名が省略された場合は複数行コメントとなり、スクリプトの一部として扱われません
(構文木が作られない)

// 定数hogeが作られる
textblock hoge
foo
bar
baz
endtextblock

// 定数省略時はコメント扱い
// 値を呼び出すことができない
textblock
ここはコメントです
endtextblock

textblockex

対応バージョン: 0.1.3

変数展開が可能なtextblockです
textblockex変数の評価時に展開されます

textblockex hoge
<#fuga>
endtextblock

fuga = 123
print hoge // 123
fuga = 456
print hoge // 456

call

対応バージョン: 0.6.0

他のスクリプトを取り込みます

call hoge.uws          // 実行するスクリプトからの相対パス
call hoge              // 拡張子のないファイルもOK、見つからない場合は.uwsを付けて開く
call fuga.uws(1, 2, 3) // 引数を渡すと PARAM_STR にはboolが入る

// urlから読み込み
call url[https://example.com/hoge.uws]        // url[ ] の中でurlを指定
call url[https://example.com/hoge.uws](1,2,3) // url[ ] の後に()をつけて引数を渡せる
  • グローバル定義はスクリプト実行前に処理されます
    • public
    • const
    • textblock
    • function
    • procedure
    • module
    • class
  • それ以外の処理部分はcall文が呼ばれる際に実行されます
    • 呼び出し元とは異なるスコープで実行されます
    • 呼び出し元のPARAM_STRにはアクセスできません (独自のPARAM_STRを持つため)

uwslファイルの読み込み

対応バージョン: 0.1.7

uwslファイルをcallして使えます

call mylib.uwsl // 拡張子はuwslのみ (省略不可)

uwslファイルについて

構文木をバイナリとして保存したものです
以下のコマンドでバイナリファイルを生成できます
ファイルはスクリプトと同じディレクトリに作成されます
拡張子は.uwslになります

uwscr --lib path\to\script.uws

callでの呼び出しにのみ対応しており、直接実行することはできません

uwscr hoge.uwsl // ng

uwslファイル作成の流れ

  1. 指定されたスクリプトを読み出す
  2. 構文解析を行い構文木を生成する
  3. 構文木をバイナリデータとしてファイルに書き出す

使用例

  1. 多段callしているファイルをまとめてバイナリ化

    // ファイル構成例
    main.uws (mylib.uwsをcall)
    
    // 多段call、これらがすべて解析され単一ファイルになる
    mylib.uws (module1 ~ 3 をcall)
      |_ module1.uws
      |_ module2.uws (submodule1, 2 をcall)
      | |_ submodule1.uws
      | |_ submodule2.uws
      |_ module3.uws
    
    uwscr -l mylib.uws // mylib.uwslが出力される
    
  2. uwslファイルをcallして使う

    // 総ファイル数を減らせる
    main.uws
    mylib.uwsl
    
    // main.uws
    call mylib.uwsl
    
    MyLib.DoSomething()
    Module1.DoSomethingElse()
    Module2.DoSomethingWithSubmodule(Submodule1.DoSomething)

例外処理

対応バージョン: 0.2.1

  • try-except-endtry
  • try-finally-endtry
  • try-except-finally-endtry

try部で発生した実行エラーを抑制し、以下の特殊変数にエラー情報を格納します

  • TRY_ERRMSG: エラーメッセージ
  • TRY_ERRLINE: エラー行

except部はtryでエラーが発生した場合のみ実行されます
finally部は必ず実行されます
finally部ではcontinue, break, exitが使えません (構文解析エラーになる)
try-except-finally-endtry

try
    try
    except
    endtry
finally
endtry

と同等です

except例

try
    print 1
    raise("エラー") // ここでエラー
    print 2 // 実行されない
except
    print TRY_ERRMSG // 実行される
endtry

try
    // エラーが発生しない場合
except
    print 1 // 実行されない
endtry

finally例

try
    print 1
    raise("エラー") // ここでエラー
    print 2 // 実行されない
finally
    print TRY_ERRMSG // 実行される
endtry

try
    // エラーが発生しない場合
finally
    print 1 // 実行される
endtry

except-finally例

try
    print 1
    raise("エラー") // ここでエラー
    print 2 // 実行されない
except
    print TRY_ERRMSG // 実行される
finally
    print TRY_ERRMSG // 実行される
endtry

try
    // エラーが発生しない場合
except
    print 1 // 実行されない
finally
    print 2 // 実行される
endtry

制御文

説明文中のとは主に値を返す演算式や関数など
は制御文のことです
ブロック文が複数行ある状態です

if

対応バージョン: 0.0.1 ※

ififbが区別されません
どちらも同じものとして扱われます

単行if

if 式 then 文 [else 文]

if foo then bar // `foo`が真の場合`bar`が実行され、偽の場合なにもしない
if foo then bar else baz// `foo`が真の場合`bar`、偽の場合`baz`が実行される

// ifb でもエラーにならない
ifb foo then bar

複数行if

if 式 [then]
    ブロック文
[elseif 式 [then]]
    ブロック文
[else 式]    
    ブロック文
endif

elseifは複数回記述できる

if foo then
    fooが真なら実行され偽ならなにもしない()
endif

if foo then
    fooが真なら実行される()
else
    fooが偽なら実行される()
endif


if foo then
    fooが真なら実行される()
elseif bar then
    fooが偽かつbarが真なら実行される()
elseif baz then
    fooが偽かつbazが真なら実行される()
else
    foobarbazいずれも偽なら実行される()
endif

for

対応バージョン: 0.0.1

for 変数 = 式1 to 式2 [step 式3]
    ブロック文
next

式1式3はいずれも数値を返す必要があります
step 式3 が省略された場合式31として扱われます
小数が渡された場合は整数に丸められます (UWSCとは仕様が異なります)

  1. 変数式1を代入した状態でブロック文を処理
  2. 変数の値に式3を加算したものを再代入しブロック文を処理
  3. 変数式2を超える値が代入されたら終了
  4. 終了後も変数の値は維持されます
for i = 0 to 2
    print i // 順に 0 1 2 が出力される
next
print i // 3

for i = 0 to 5 step 2
    print i // 順に 0 2 4 が出力される
next
print i // 6

// stepは減算も可能
for i = 5 to 0 step -1
    print i
next

// ループ変数に代入した場合
for i = 0 to 0
    print i // 0
    i = 10
    print i // 10
next
print i     // 1

// UWSCでは小数が利用可能でしたがUWSCRでは整数値に変換されます
for i = 0.1 to 1.9 step 0.1 // 0.1 -> 0, 1.9 -> 2 に丸められます
next

for-in

対応バージョン: 0.0.1 ※

※ 配列、連想配列、文字列のみ対応

for 変数 in 式
    ブロック文
next

は以下を返す必要があります

  • 配列
  • 連想配列
  • 文字列
  • COMのコレクション (未対応)

が返す値をその種類に応じて分解し、変数に代入していきます

// 文字列は1文字ずつ分解
for char in "あいうえお"
    print char // あ い う え お が順に出力される
next

// 配列は各要素
for value in ["あ", "い", "う", "え", "お"]
    print value // あ い う え お が順に出力される
next

// 連想配列はキーを返す
hashtbl hoge = HASH_SORT
hoge["b"] = 2
hoge["a"] = 1
hoge["d"] = 3
hoge["c"] = 4

for key in hoge
    print key        // a b c d の順に出力される
    print hoge[key]  // 1 2 3 4 の順に出力される
next

for-else

対応バージョン 0.9.0

for i = a to b
    ブロック文
else
    ブロック文
endfor

for a in b
    ブロック文
else
    ブロック文
endfor

forループをbreakで抜けなかった場合にelse句以降が実行されます

for i = 0 to length(items) - 1
    if items[i] == target then
        // 要素のいずれかがtargetと一致した場合break
        target_found()
        break
    endif
else
    // いずれの要素もtargetと一致しない場合はbreakしないのでこちらが実行される
    target_not_found()
endfor

// for-inにも対応
for item in items
    if item == target then
        target_found()
        break
    endif
else
    target_not_found()
endfor

// ループ内の処理が行われない場合でもelseが実行される
for i = 0 to -1
    print 1 // 実行されないため表示もされない
else
    print 2 // 2と表示される
endfor
for a in []
    print 3 // 実行されない
else
    print 4 // 4と表示される
endfor

while

対応バージョン: 0.0.1

while 式
    ブロック文
wend

が真である限りブロック文を繰り返し処理します
(ループ中に式を偽にしない限り無限ループする)

a = TRUE
while a
    a = DoSomething() // 偽値を返せばループ終了
wend

while false
    式が偽なら何も実行されない()
wend

while TRUE
    print "無限ループ"
wend

repeat

対応バージョン: 0.0.1

repeat
    ブロック文
until 式

が偽である限りブロック文を繰り返し処理します
(ループ中に式を真にしない限り無限ループする)

a = false
repeat
    a = DoSomething() // 真値を返せばループ終了
until a

repeat
    式が真でも一度は必ず実行される()
until TRUE

repeat
    print "無限ループ"
until FALSE

continue

対応バージョン: 0.0.1

continue [式]

ループ文(for, while, repet)にてループの先頭に戻ります
は正の整数を指定します
省略した場合1として扱われます
多重ループで複数のループをcontinueしたい場合に2以上(ループの数分)を指定します

for i = 0 to 2
    print "3回出力される"
    continue
    print "出力されない"
next

a = 1
b = 1
while a < 5
    while TRUE
        a = a + 1
        continue 2
        b = b + 1
    wend
wend
print a // 5
print b // 1

break

対応バージョン: 0.0.1

break [式]

ループ文(for, while, repet)にてループを抜けます
は正の整数を指定します
省略した場合1として扱われます
多重ループで複数のループをbreakしたい場合に2以上(ループの数分)を指定します

for i = 0 to 2
    print "1回だけ出力される"
    break
    print "出力されない"
next    

a = 0
repeat
    repeat
        repeat
            break 3
            a = a + 1
        until false
        a = a + 1
    until false
    a = a + 1
until false
print a // 0

select

対応バージョン: 0.0.1

select 式
    case 式
        ブロック文
    [case 式, 式 …]
        ブロック文
    [default]
        ブロック文
selend

select式を評価し、その結果とcase式が一致した場合にそのcase以下のブロック文が処理されます
caseに,区切りで式を複数指定した場合、いずれかが一致すればそのブロック文が処理されます

  1. select式を評価し結果を得る
  2. case式を評価しselect式の結果と比較
    • 一致した場合: その下のブロック文を処理しselectを終了する
    • 不一致の場合: 次のcaseまたはdefaultに進む
  3. defaultに到達した場合必ずその下のブロック文を処理する
  4. defaultがなくいずれのcaseにも一致しない場合なにも行わない
select hoge
    case 1
        hogeが1なら実行される()
    case 2, 3
        hogeが2か3なら実行される()
    case 3
        hogeが3でも上のcaseが該当してるので実行されない()
    default
        hogeが1~3以外なら実行される()
selend

select hoge
    default
        必ず実行される()
selend

select 1
    case 2
        なにも実行されない()
selend

exit

対応バージョン: 0.0.3

  • スクリプト本文に記述した場合
    スクリプト実行を終了します
  • 関数内に記述した場合
    関数を抜けます
  • REPLで記述した場合
    REPLを終了します
hoge() // 2 は出力されない

procedure hoge()
    print 1
    exit
    print 2
fend

exitexit

対応バージョン: 0.1.5

exitexit [数値]

数値を指定した場合はUWSCRの終了コードになります
(省略時は終了コード0)

print

対応バージョン: 0.4.0

評価した式を文字列として出力します
またそれをログファイルに記録します

print 式

以下の処理が行われます

  • 可能であればprintウィンドウに出力
    • 通常実行時かつlogprint(FALSE)が呼ばれていない
    • コンソール実行時にlogprint(TRUE)が呼ばれたあと
  • 可能であればコンソールに出力
    • コンソール実行時のみ
  • 可能であればログファイルに記録
    • ログを記録する設定の場合

COMオブジェクト

対応バージョン: 0.2.0

書式について

COMオブジェクトのメンバへのアクセス方法

  • プロパティ

    // 値の取得
    print obj.foo
    // 代入
    obj.foo = "hoge"
  • 引数付きプロパティ
    []または()に添え字を入れる

    // 値の取得
    print obj.foo[0]
    print obj.foo(0)
    print obj.bar["fuga"]
    print obj.bar("fuga")
    // 代入は[]のみ
    obj.foo[0] = "hoge"
    obj.bar["fuga"] = "fuga"
    // ()の場合は取得した値との比較になるため代入できない
    obj.foo(0) = "hoge" // true or false
  • メソッド

    print obj.baz()
    print obj.qux(hoge)
    dim fuga
    print obj.quux(var fuga) // fugaで値を受ける
    print fuga
  • Item()プロパティの糖衣構文
    COMオブジェクトに直接[]または()をつけた場合Item()と同等

    print obj.Item(0)
    // ↑同じ↓
    print obj(0)
    
    // []の場合代入もできる
    obj.Item[0] = "hoge"
    // ↑同じ↓
    obj[0] = "hoge"

COM_ERR_IGN-COM_ERR_RET

COMエラーの発生を無視して処理を続行させることができます

COM_ERR_IGNでCOMエラーを抑制します
COM_ERR_RETでCOMエラーの抑制を解除します

COM_ERR_IGNからCOM_ERR_RETの間でCOMエラーが発生した場合
実行時エラーで終了することなく処理を続行します
その際にCOM_ERR_FLGTRUEになります

COM_ERR_FLGCOM_ERR_IGNを呼んだ際にFALSEに初期化されます
COM_ERR_RETを呼んだ場合は値がそのまま維持されます

COM_ERR_IGNによるCOMエラーの抑制はスレッド単位で有効です

// 通常はCOMエラーで動作停止する
obj = createoleobj("Some.ComObject")
obj.FireError() // COMエラー!

// COMエラーを抑制するパターン
obj = createoleobj("Some.ComObject")
// COMエラー抑制開始
COM_ERR_IGN

print COM_ERR_FLG // False
obj.FireError() // エラーになるがスクリプトは停止しない
print COM_ERR_FLG // Trueになる

// COMエラー抑制終了
COM_ERR_RET

print COM_ERR_FLG // True; COM_ERR_RETでは初期化されない

obj.FireError() // 抑制していないのでCOMエラー

リストの改行表記

対応バージョン: 0.5.0

一部リスト表記 (, 区切りの式) で改行を含めることができます
従来では _ による行連結が必要だったところを簡潔に記述できるようになりました

// 従来
hoge = [ _
    "foo", _
    "bar", _
    "baz"  _
]
// 0.5.0以降
hoge = [
    "foo",
    "bar",
    "baz"
]
  • 改行を含めることができる構文
    • 配列リテラル
    • 関数呼び出し時の引数
    • 関数定義の引数
    • def_dllの引数型指定時
  • 改行を含めることができない構文
    • dim配列定義
    • select文case句の複数条件
// 配列リテラル
print [     // [ の後の改行
    "foo",  // カンマの後の改行
    "bar"   // 式の後の改行
    ,"baz"  // カンマを式の前に書いてもいい
]           // ] 前の改行

// 関数呼び出し
print func( // ( の後の改行
    foo,    // カンマの後の改行
    ,       // 引数省略
    bar     // 式の後の改行
    ,baz    // カンマを式の前に書いてもいい
)           // ) 前の改行

// 関数定義
function hoge(
    a,
    ref b,
    c: string,
    d = 1
)
    b = do_something_with(a)
    do_something_with(c, d)
fend

// def_dll
def_dll MessageBoxA(
    hwnd,
    string,
    string,
    uint
):int:user32

// 以下は対象外

// dim配列宣言で改行するとエラーになる
dim fuga[] = 1,
             2,
             3
// 必ず一行で書く
dim hoge[] = 1,2,3

// select文case句の複数条件で改行するとエラー
select fuga
    case 1,
         2,
         3
        print "ng"
selend
// 必ず一行で書く
select hoge
    case 1,2,3
        print "ok"
selend

値型

UWSCRで使われる値の型

詳細 参照
数値 double (倍精度浮動小数点型)
文字列 文字列
真偽値 TRUE/FALSE
配列 要素として異なる値型を格納できる
連想配列 連想配列
無名関数 名前なしで定義されたfunction/procedure
関数 名前ありで定義されたfunction/procedure
非同期関数 async宣言した関数
組み込み関数 組み込み関数
モジュール module定義
クラス定義 class定義
クラスインスタンス クラス名()で得られる
NULL def_dllにおけるNULL文字(chr(0))、UObjectのnull値
EMPTY 空の値、場合により空文字や0として扱われる
NOTHING 空オブジェクト
正規表現 正規表現パターン
UObject UObject
列挙型 enum定義
タスク 非同期に行われる処理
DLL関数 def_dll定義
構造体 struct定義
構造体インスタンス 構造体名()で得られる
COMオブジェクト createoleobj/getactiveoleobj
VARIANT COMで使われる値型
SafeArray COMで使われる配列
Browserオブジェクト BrowserControl
Browser関数 Browserオブジェクトの関数
Elementオブジェクト WebElementを示すオブジェクト
Element関数 Elementオブジェクトの関数
Elementプロパティ Elementオブジェクトのプロパティ
ファイルID fopen
バイト配列 encode
⚠️ **GitHub.com Fallback** ⚠️