我正在构建一个浮点计算器而且我被卡住了。 fp计算器有快速的形状,所以我的问题是,在我处理异常的地方,我留下了递归函数,使得提示出现并结束执行:
let initialDictionary = ref EmptyDictionary;;
let launcher () =
print_string ("Welcome");
let rec aux dic =
try
print_string ("->");
aux ( execute dic (s token (Lexing.from_string (read_line () ))));
with
End_of_exec -> print_endline ("closing")
Var_not_assigned s -> printf "var %s not assigned" s
in aux !initialDictionary;;
其中:
val exec : dictionary -> Instruction -> dictionary;
type dictionary = (string,float)list
这里的要点是,由于列表在ocaml上是不可变的,我必须保持我的字典堆栈变量及其值的唯一方法是应用递归从exec返回获取值字典。
那么关于如何在显示异常时不离开“提示式”执行的任何想法?
答案 0 :(得分:1)
read eval print loop解释器具有所有这些不同的阶段,必须单独处理,我认为您的实现试图在一个步骤中做太多。打破函数的第二部分将有助于解开不同的错误处理程序:
let launcher () =
let rec prompt dic =
print_string "->";
parse dic
and parse dic =
let res =
try
s token (Lexing.from_string @@ read_line ())
with End_of_exec -> (print_encline "closing"; raise End_of_exec)
in evalloop dic res
and evalloop dic rep =
let dic =
try execute dic rep
with Var_not_assigned s -> (printf "var %s not assigned\n" s; dic)
in prompt dic
in prompt !InitialDictionary;;
由于每个子函数都是tail call下一个或者因异常而失败,因此整个代码应该是尾递归并优化为循环。
关于这一点的好处是,现在您可以更好地了解正在发生的事情,并且可以更轻松地更改循环的单个步骤而不会触及其余部分。
顺便提一下,回想一下,read_line
也可能触发End_of_file
例外,但现在应该处理这个例子(作为练习留下来)。
答案 1 :(得分:1)
好吧,我的一个朋友给了我一个解决方案并思考它我无法找到一个更优雅的方式。
Let exec () =
Let _= print_string "->" in
( try
Let inst = s token (Lexing.from_string (read_line())) in
Try
Let r = exec_instruction !initialDictionary inst in
initialDictionary := r
With
| Var_not_assigned s -> printf "var %s not assigned. \n" s
| Com_not_implemented s -> printf " command %s not implemented. \n" s
| Function_not_implemented s -> printf " function %s not implemented. \n" s
With
| lexic_error -> print_endline "lexic error"
| Parsing. Parse_error -> print_endline "sintax error"
);;
Let rec program cont =
If cont then
Try
Exec (); program true
With
| End_of_exec -> print_endline "closing"; program false;;
Program true
唯一困扰我initialDictionary := r
赋值的东西,因为exec_instruction返回一个字典,所以它可以递归完成,但无论如何都可以工作,生病了哈哈。
感谢您的帮助,如果有人能看到一个解决方案让我知道。