2

如何在解释器上实现try/catch/finally功能(目前我在F#上)?如何在带有goto或类似语言的组合语言解释器中实现Try/Except/Finally?

我怀疑可以使用GOTO(但是,在解释器中为它提供功能也是必要的,对于如何提供它的功能不是很了解),但是我从未在我的生活中使用过GOTO(只知道是邪恶的!)也不了解如何保护环境。 P.D:我已经知道CPS(Continuations)可以用来模拟异常和其他控制流。然而,它使其余的语言实现和requiere优化过程复杂化以消除它的开销,并且对于这个问题,我希望了解替代方法做到这一点。

PD2:存在另一种替代CPS的方法,自定义控制流的实现?或者为此推广GOTO?

+1

其实没有人尝试/除了/最后。这是真的尝试/除了和尝试/最后,他们可以嵌套在另一个,例如(最后尝试(尝试例外))。这使得它更容易处理。 –

+1

我不确定,但怀疑您可以在[类型和编程语言](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节错误。 –

回答

2

控制可以逃脱一个“尝试”块许多方面:

  • 后藤在一围框的标签(注:转到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操作,然后执行块转义。