控制可以逃脱一个“尝试”块许多方面:
- 后藤在一围框的标签(注:转到X和转到Y为2名不同的逃逸)从包含函数
- 返回在尝试
- 扔在一个异常的尝试
- 从被试体)中试机构,称为
- (检测)调用exit(函数传播异常
根据您的语言,您可能会有更多。
你的try-finally块必须做的是捕获所有这些,执行finally部分,然后继续预期的操作。
完成此操作的一种方法是为每个块转义创建一个转移岛。转移岛作为这些行动的目标;如果控制到达转换岛K,则发生块跳转K.什么是转移岛内确实是叫(无参数)子程序包含finally从句,然后执行一个动作,继续逃逸K.
想象一下以下try-finally块:
try
...goto X... // ... means some control structure wrapped around this
...raise Z...
...call q()... // throws exception
...goto Y...
...return 5...
finally
<some actions>
end
...return <exp>
此代码的编译如下:
// try
... goto TIX... // TIk ==> "tranfer island k"
...exception=Z; goto TIE ...
...try call q()
catch exception; goto TIE
end try
...result=5; goto TIR...
// finally
local subroutine finally()
{ <some actions> }
TIX: call finally();
goto X;
TIY: call finally();
goto Y;
TIR: call finally();
goto RETURN;
TIE: call finally();
propagate exception; // means "pass control to containing exception handler"
...
// end try
result=<exp>;
RETURN:
return result;
在此背景下,你必须做出解释进行操作,就好像这个代码存在。显然,解释者不需要实例化转移岛;它知道发生哪种类型的块转义,可以执行finally操作,然后执行块转义。
其实没有人尝试/除了/最后。这是真的尝试/除了和尝试/最后,他们可以嵌套在另一个,例如(最后尝试(尝试例外))。这使得它更容易处理。 –
我不确定,但怀疑您可以在[类型和编程语言](https://www.cis.upenn.edu/~bcpierce/tapl/)中找到有用的信息,该代码翻译为F# https://github.com/jackfoxy/fsharp-tapl](https://github.com/jackfoxy/fsharp-tapl)或[通过Lambda微积分函数式编程入门](https://www.cs.rochester 。edu /〜brown/173/readings/LCBook.pdf)的5.4节错误。 –