Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

関数の引数を省略してもexistsはtrueを返す #635

Open
taiyme opened this issue Apr 25, 2024 · 8 comments
Open

関数の引数を省略してもexistsはtrueを返す #635

taiyme opened this issue Apr 25, 2024 · 8 comments

Comments

@taiyme
Copy link

taiyme commented Apr 25, 2024

@func(arg) {
  return exists arg
}
func()

引数 arg を省略した場合でも、exists arg はtrueを返します。
(引数の省略は正式な構文ではないが……)

引数を省略した場合、そのまま扱うとエラーになってしまうので、existsで判定できると助かります。

@FineArchs
Copy link
Member

AiScriptはundefinedがないので、「existsがfalseを返す」ことが実質的にundefinedの代わりになれば色々便利そうですね

@FineArchs
Copy link
Member

破壊性低そうだから次のリリースに入れていいかも

@salano-ym
Copy link
Member

salano-ym commented Apr 25, 2024

原因

引数が足りない場合にargs[i]undefinedを返してしまう。(多い場合は単に捨てられる)
!が付いているので型チェックもすり抜ける。
想定外のundefinedを引数として受け取っているので、existstrueを返すが、参照するとエラーになる。

const _args = new Map<string, Variable>();
for (let i = 0; i < (fn.args ?? []).length; i++) {
_args.set(fn.args![i]!, {
isMutable: true,
value: args[i]!,
});
}

対策案

  • 引数の個数をチェックする
  • undefinedをチェックする
  • 変数管理の仕様を修正する
  • !の使い方を見直す

@salano-ym
Copy link
Member

AiScriptはundefinedがないので、「existsがfalseを返す」ことが実質的にundefinedの代わりになれば色々便利そうですね

exists obj.prop
exists arr[idx]

みたいなことができると便利かな?

@salano-ym
Copy link
Member

undefined自体をScopeに持たせるのは変更箇所が多くなりそうなので、ここは修正すべきかと思います。

@salano-ym
Copy link
Member

salano-ym commented Apr 25, 2024

とりあえずすぐにできそうな修正はこの2方法

  • 実引数と仮引数の個数が違う場合はエラーにする
    nextの省略方法との兼ね合いも要考慮
  • 足りない引数(=undefined)をScopeに追加せず無視する
    existsで判定可能になるが、引数の省略方法がnext予定のものと2つ存在することになる?

@FineArchs
Copy link
Member

aiscript/test/index.ts

Lines 1703 to 1714 in 1391781

test.concurrent('missing arg', async () => {
try {
await exe(`
@func(a){}
func()
`);
} catch (e) {
assert.ok(e instanceof AiScriptRuntimeError);
return;
}
assert.fail();
});

#475 では省略可能でない引数が省略されるとエラーになります

@salano-ym
Copy link
Member

salano-ym commented Apr 29, 2024

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants