Ocaml 解释器
Interpreter with Ocaml
我用 Ocaml 编写了一个解释器,但是当我尝试时:
sem(Let("Somma",Fun("x",Sum(Den "x",Eint(5))),Let("pipa",Pipe(Seq(Den "Somma",Nil)),Apply(Den "pipa",Eint(42)))),(emptyenv Unbound));;
结果是错误的:"Exception: Match_failure ("",1,41)
我认为错误出在 applyPipe 中,但我不明白错误在哪里以及为什么会出现
我哪里错了?
这是我的代码:
type exp =
.
.
.
| Fun of ide * exp
| Apply of exp * exp
| Letrec of ide * ide * exp * exp
| Etup of tuple (*Tupla come espressione*)
| Pipe of tuple (*Concatenazione di funzioni*)
| ManyTimes of int * exp (*Esecuzione iterata di una funzione*)
and tuple =
| Nil (*Tupla vuota*)
| Seq of exp * tuple (*Tupla di espressioni*)
;;
type eval=
| Int of int
| Bool of bool
| Unbound
| RecFunVal of ide * ide * exp * eval env
| Funval of efun
| ValTup of etuple
and efun = ide * exp * eval env
and etuple =
| Nil
| Seq of eval * etuple
;;
let rec sem ((ex: exp), (r: eval env)) = match ex with
.
.
.
| Let(i, e1, e2) -> sem(e2, bind (r, i, sem(e1, r)))
| Fun(i,a) -> Funval(i,a,r)
| Letrec(f, i, fBody, letBody) ->
let benv = bind(r, f, (RecFunVal(f, i, fBody, r)))
in sem(letBody, benv)
| Etup(tup) -> (match tup with
| Seq(ex1, tupla) ->
let evex1 = sem(ex1, r) in
let ValTup(etupl) = sem(Etup(tupla), r) in
ValTup(Seq(evex1, etupl))
| Nil -> ValTup(Nil))
| Apply(Den f, arg1) ->
(let fclosure= sem(Den f, r) in
match fclosure with
| Funval(arg, fbody, fDecEnv) ->
sem(fbody, bind(fDecEnv, arg, sem(arg1, r)))
| RecFunVal(f, arg, fbody, fDecEnv) ->
let aVal= sem(arg1, r) in
let rEnv= bind(fDecEnv, f, fclosure) in
let aEnv= bind(rEnv, arg, aVal) in
sem(fbody, aEnv)
| _ -> failwith("non functional value"))
| Apply(Pipe tup, arg) -> applyPipe tup arg r
| Apply(_,_) -> failwith("not function")
| _ -> failwith("non implementato")
and applyPipe tup argo r = (match tup with
| Seq(Den f, tupla) ->
let appf = Apply(Den f,argo) in
applyPipe tupla appf r
| Nil -> sem(argo,r)
| _ -> failwith("Not a valid Pipe"))
;;
完整的代码在那里:http://pastebin.com/VgpanX51
请帮帮我谢谢
当您编译(或在顶层评估)OCaml 程序时,类型检查器将发出关于所有不可反驳的模式匹配的警告,即可能引发 Match_failure
异常的模式。
您应该做的是检查所有警告并修复它们。
你的代码中有很多无可辩驳的匹配,例如,sem
函数最终匹配 Apply(_,_) -> failwith("not function")
只会捕获 Apply
个术语,但不会捕获所有其他术语,添加_ -> failwith "unimplemented"
之类的东西会修复它。
质量检查
the error is in the try-code or in my interpreter?
它在解释器中,您没有在 pattern-matching 代码中包含所有可能的情况。
.I do extend the typechecker
你不需要。 typechecker 验证你是否预料到所有可能的情况,例如,让我们举个简单的例子:
type abc = A | B | C
let string_of_abc abc = match abc with
| A -> "A"
| B -> "B"
当您尝试编译(或解释)上述代码时,类型检查器会告诉您:
Warning 8: this pattern-matching is not exhaustive.
Here is an example of a value that is not matched:
C
type abc = A | B | C
所以,它给了你一个提示,你忘记了与 C
构造函数匹配,所以表达式 string_of_abc C
将以 Match_failure
异常终止。
您可以按照提示添加案例one-by-one。鉴于您的示例,sema 函数中的模式匹配不完整,类型检查器会用以下内容命中您:
Warning 8: this pattern-matching is not exhaustive.
Here is an example of a value that is not matched:
(Pipe _|ManyTimes (_, _))
确实,你错过了 Pipe
的情况,所以当解释器看到
Pipe(...)
找不到匹配项,因为根据您的代码,您期望 Pipe
构造函数仅作为 Apply
的第一个参数,而在您的示例中,您实际上是将其作为第二个参数传递给 Let
。
我用 Ocaml 编写了一个解释器,但是当我尝试时:
sem(Let("Somma",Fun("x",Sum(Den "x",Eint(5))),Let("pipa",Pipe(Seq(Den "Somma",Nil)),Apply(Den "pipa",Eint(42)))),(emptyenv Unbound));;
结果是错误的:"Exception: Match_failure ("",1,41)
我认为错误出在 applyPipe 中,但我不明白错误在哪里以及为什么会出现 我哪里错了?
这是我的代码:
type exp =
.
.
.
| Fun of ide * exp
| Apply of exp * exp
| Letrec of ide * ide * exp * exp
| Etup of tuple (*Tupla come espressione*)
| Pipe of tuple (*Concatenazione di funzioni*)
| ManyTimes of int * exp (*Esecuzione iterata di una funzione*)
and tuple =
| Nil (*Tupla vuota*)
| Seq of exp * tuple (*Tupla di espressioni*)
;;
type eval=
| Int of int
| Bool of bool
| Unbound
| RecFunVal of ide * ide * exp * eval env
| Funval of efun
| ValTup of etuple
and efun = ide * exp * eval env
and etuple =
| Nil
| Seq of eval * etuple
;;
let rec sem ((ex: exp), (r: eval env)) = match ex with
.
.
.
| Let(i, e1, e2) -> sem(e2, bind (r, i, sem(e1, r)))
| Fun(i,a) -> Funval(i,a,r)
| Letrec(f, i, fBody, letBody) ->
let benv = bind(r, f, (RecFunVal(f, i, fBody, r)))
in sem(letBody, benv)
| Etup(tup) -> (match tup with
| Seq(ex1, tupla) ->
let evex1 = sem(ex1, r) in
let ValTup(etupl) = sem(Etup(tupla), r) in
ValTup(Seq(evex1, etupl))
| Nil -> ValTup(Nil))
| Apply(Den f, arg1) ->
(let fclosure= sem(Den f, r) in
match fclosure with
| Funval(arg, fbody, fDecEnv) ->
sem(fbody, bind(fDecEnv, arg, sem(arg1, r)))
| RecFunVal(f, arg, fbody, fDecEnv) ->
let aVal= sem(arg1, r) in
let rEnv= bind(fDecEnv, f, fclosure) in
let aEnv= bind(rEnv, arg, aVal) in
sem(fbody, aEnv)
| _ -> failwith("non functional value"))
| Apply(Pipe tup, arg) -> applyPipe tup arg r
| Apply(_,_) -> failwith("not function")
| _ -> failwith("non implementato")
and applyPipe tup argo r = (match tup with
| Seq(Den f, tupla) ->
let appf = Apply(Den f,argo) in
applyPipe tupla appf r
| Nil -> sem(argo,r)
| _ -> failwith("Not a valid Pipe"))
;;
完整的代码在那里:http://pastebin.com/VgpanX51 请帮帮我谢谢
当您编译(或在顶层评估)OCaml 程序时,类型检查器将发出关于所有不可反驳的模式匹配的警告,即可能引发 Match_failure
异常的模式。
您应该做的是检查所有警告并修复它们。
你的代码中有很多无可辩驳的匹配,例如,sem
函数最终匹配 Apply(_,_) -> failwith("not function")
只会捕获 Apply
个术语,但不会捕获所有其他术语,添加_ -> failwith "unimplemented"
之类的东西会修复它。
质量检查
the error is in the try-code or in my interpreter?
它在解释器中,您没有在 pattern-matching 代码中包含所有可能的情况。
.I do extend the typechecker
你不需要。 typechecker 验证你是否预料到所有可能的情况,例如,让我们举个简单的例子:
type abc = A | B | C
let string_of_abc abc = match abc with
| A -> "A"
| B -> "B"
当您尝试编译(或解释)上述代码时,类型检查器会告诉您:
Warning 8: this pattern-matching is not exhaustive.
Here is an example of a value that is not matched:
C
type abc = A | B | C
所以,它给了你一个提示,你忘记了与 C
构造函数匹配,所以表达式 string_of_abc C
将以 Match_failure
异常终止。
您可以按照提示添加案例one-by-one。鉴于您的示例,sema 函数中的模式匹配不完整,类型检查器会用以下内容命中您:
Warning 8: this pattern-matching is not exhaustive.
Here is an example of a value that is not matched:
(Pipe _|ManyTimes (_, _))
确实,你错过了 Pipe
的情况,所以当解释器看到
Pipe(...)
找不到匹配项,因为根据您的代码,您期望 Pipe
构造函数仅作为 Apply
的第一个参数,而在您的示例中,您实际上是将其作为第二个参数传递给 Let
。