あなたの質問に対する私のコメントに加えて(ここにコードを貼り付けます):
var acc = 1
var n = 10
start:
if (n <= 1) return acc
else {
acc = n * acc
n = n - 1
goto start
}
fact
たまたま持っていた最近のビルドでメソッドをコンパイルしようとしましたがscalac -Xprint:all
、どういうわけかコンパイラがicode
ファイルを出力しました。したがって、これはテールコールを最適化する方法を実際に示しています。
// methods
def fact(acc: Int (INT), n: Int (INT)): Int {
locals: value acc, value n, value _$this
startBlock: 1
blocks: [1,2,3,4,5]
1:
2 JUMP 2
2: // huynhjl's comment: IF condition is here
3 LOAD_LOCAL(value n)
3 CONSTANT(1)
3 CJUMP (INT)LE ? 3 : 4
3: // huynhjl's comment: first branch of IF, will return acc
3 LOAD_LOCAL(value acc)
3 JUMP 5
5:
2 RETURN(INT)
4: // huynhjl's comment: else branch of IF, update acc and n and jump back
4 LOAD_LOCAL(value n)
4 LOAD_LOCAL(value acc)
4 CALL_PRIMITIVE(Arithmetic(MUL,INT))
4 LOAD_LOCAL(value n)
4 CONSTANT(1)
4 CALL_PRIMITIVE(Arithmetic(SUB,INT))
4 STORE_LOCAL(value n)
4 STORE_LOCAL(value acc)
4 JUMP 2
}