aiscript icon indicating copy to clipboard operation
aiscript copied to clipboard

ラッパーとしてのreturn,break,continueが残ってしまっている

Open salano-ym opened this issue 2 years ago • 3 comments

if式・match式・ブロック式で、return文・break文・continue文を使用するとラッパーが外れずに残ってしまう。 break文・continue文は普通の関数でも残ってしまう。

<: eval { return 1 } // == return
<: eval { break } // == break
<: eval { continue } // == continue
<: if true { return 1 } // == return
<: if true { break } // == break
<: if true { continue } // == continue

@r() { return 1 }
@b() { break }
@c() { continue }
<: r() // == 1 (これが正常)
<: b() // == break
<: c() // == continue

解決案

return文に関しては関数呼び出しでしているのと同様に~~ブロック式の処理に~~外すべき場所でunWrapRetを挟む。 if式のブロックとブロック式のブロックが同じノードでreturnをどう処理すべきか区別できないので、ブロックの呼び出し元(代入文等)で処理する?

https://github.com/syuilo/aiscript/blob/master/src/interpreter/index.ts#L427-L429

salano-ym avatar Feb 19 '23 15:02 salano-ym

グローバルスコープ直下のifやブロック式にreturn、関数の直下にbreakやcontinueが存在していること自体がおかしいのでエラーにしてもいいような気がします…

FineArchs avatar May 18 '23 16:05 FineArchs

returnに関しては関数内でも普通に取り出せてしまうけどどう扱うべきだろう 禁止するとして構文解析レベルで処理するかプラグインの段階で処理するか

@fff() {
  let a = eval {
    return 1
  }
  <: a // return<null>

  let b = if true {
    return 1
  }
  <: b // return<null>
}

salano-ym avatar May 18 '23 17:05 salano-ym

  1. グローバルスコープ直下にreturn|break|continueがあったらエラー
  2. 関数スコープ直下にbreak|continueがあったらエラー
  3. return|break|continueを含むif|evalがexprとして扱われていたらエラー

これらを実装できればよさそうですかね? 個人的には、1.と2.はreturn文の処理内でスコープ名をチェックするような処理で済ませられるならそれがシンプルでいいと思います。 3.に関しては構文解析レベルのエラーにしたほうが早い気がします。

FineArchs avatar May 19 '23 09:05 FineArchs