Ocaml解释器

Ocaml解释器,ocaml,interpreter,Ocaml,Interpreter,我使用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));; 重新结果是一个错误:异常:匹配失败,1,41 我认为这个错误在applype中,但我不明白在哪里以及为什么会出现 我哪里做错了 这是我的代码: type exp = . .

我使用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));;
重新结果是一个错误:异常:匹配失败,1,41

我认为这个错误在applype中,但我不明白在哪里以及为什么会出现 我哪里做错了

这是我的代码:

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"))
    ;;
完整的代码在那里:
请帮助我检查

当您在顶级OCaml程序中编译或计算时,类型检查器将发出关于所有模式匹配的警告,这些模式都是无可辩驳的,即可能引发匹配失败异常的模式

您应该做的是检查所有警告并修复它们

你的代码中有很多不可辩驳的匹配项,例如,sem函数final match Apply,\uu->failwithnot函数将只捕获Apply术语,而不会捕获所有其他术语,添加类似于\u->failWithUnimplemented的内容将修复它

质量保证 错误在try代码或我的解释器中

在解释器中,您没有在模式匹配代码中包含所有可能的情况

.我确实扩展了打字机

你不需要。typechecker会验证您是否预期了所有可能的情况,例如,让我们举一个简单的例子:

type abc = A | B | C

let string_of_abc abc = match abc with
  | A -> "A"
  | B -> "B"
当您试图编译或解释上述代码时,typechecker将告诉您:

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构造函数匹配,因此_abcc的表达式字符串_将以match _failure异常终止

您可以按照提示逐一添加案例。在您的示例中,sema函数中的模式匹配不完整,类型检查器会提示您以下信息:

Warning 8: this pattern-matching is not exhaustive.
Here is an example of a value that is not matched:
(Pipe _|ManyTimes (_, _))
事实上,你错过了关于管道的案例,所以当口译员看到

Pipe(...)

它找不到匹配项,因为根据您的代码,您希望管道构造函数仅作为应用的第一个参数,而在您的示例中,您实际上是将其作为第二个参数传递给Let

看起来您没有显示相关代码,因为实际失败的代码将通过字符串值进行模式匹配,并且传递给它的字符串为空,这是代码没有预料到的,因此出现了错误。很抱歉,我忘记了一段代码…现在?我添加了[\u->failwithnon Implementation]现在错误不同了,它引发了异常……这是我在Ocaml上的第一个项目,我不明白你说的一切……错误在try代码或我的解释器中?……我扩展了typechecker?怎么做?你能解释一下我是怎么做的吗?我将完整的代码添加到我的第一个question@LorenzoMaffei,我已经为您的问题添加了答案,希望这将澄清情况:首先非常感谢您,您已经非常清楚:我希望我理解了所有内容,因此我用Pippetupla->match tupla扩展了我的sem。。。正如我为设置所做的那样,但管道中的tupla必须是一个函数,所以我将更改某些内容。。。我想我明白了,再次感谢你: