简体   繁体   English

错误:此变体模式应具有 prim1 类型。 构造函数 ID 不属于 prim1 类型

[英]Error: This variant pattern is expected to have type prim1. The constructor Id does not belong to type prim1

I don't have much experience with ocmal and the compiler error message isn't very helpful.我对 ocmal 没有太多经验,编译器错误消息也不是很有帮助。 I don't see any obvious problem with the code.我没有看到代码有任何明显的问题。 I have the full code and the error message below.我有完整的代码和下面的错误消息。 Thank you.谢谢你。

Full compiler error message:完整的编译器错误消息:

File "compile.ml", 
     | Id(x) ->
       ^^

Error: This variant pattern is expected to have type prim1 The constructor Id does not belong to type prim1错误:此变体模式应具有类型 prim1 构造函数 ID 不属于类型 prim1

type reg =
    | EAX
    | ESP

type arg =
    | Const of int
    | Reg of reg
    | RegOffset of int * reg

type instruction =
    | IMov of arg * arg
    | IAdd of arg * arg
    | IRet

type prim1 =
    | Add1
    | Sub1

type expr =
    | Number of int
    | Prim1 of prim1 * expr
    | Let of (string * expr) list * expr
    | Id of string

let rec find (ls : (string * int) list) (x : string) =
    match ls with
    | [] -> None
    | (y,v)::rest ->
      if y = x then Some(v) else find rest x

let rec compile_env (p : expr) (stack_index : int) (env : (string * int) list) : instruction list =
    match p with
       | Number(n) -> [ IMov(Reg(EAX), Const(n)) ]
       | Prim1(op, e) ->
            match op with
            | Add1 -> (compile_env e stack_index env) @ [ IAdd(Reg(EAX), Const(1)) ]
            | Sub1 -> (compile_env e stack_index env) @ [ IAdd(Reg(EAX), Const(-1)) ]
       | Id(x) ->
            match find env x with
            | None -> failwith "%s not in scope" x
            | Some value -> [IMov(Reg(EAX), RegOffset(value, Reg(ESP)))]
       | Let(binds, body) ->
            match binds with
            | [] -> [] @ (compile_env body stack_index env)
            | (str, exp)::rest ->
                    let new_env = env @ [(str, -4*stack_index)] in
                    let eval_expr = (compile_env exp stack_index env) in
                    let eval_tail = (compile_env Let(rest, body) stack_index+1 new_env) in
                    eval_expr @ [IMov(RegOffset(-4*stack_index, Reg(ESP)), Reg(EAX))] @ eval_tail

It looks like your problem is that you have nested match expressions.看起来您的问题是您嵌套了match表达式。 The difficulty is that the compiler is thinking that the next case of the outer match is in fact the next case of the inner match .困难在于编译器认为外部match的下一个案例实际上是内部match的下一个案例。

The solution is to parenthesize all of the the inner match expressions.解决方案是将所有内部匹配表达式括起来。

It should look something like this:它应该是这样的:

match p with
   | Number(n) -> [ IMov(Reg(EAX), Const(n)) ]
   | Prim1(op, e) ->
        (match op with
        | Add1 -> (compile_env e stack_index env) @ [ IAdd(Reg(EAX), Const(1)) ]
        | Sub1 -> (compile_env e stack_index env) @ [ IAdd(Reg(EAX), Const(-1)) ]
        )
    . . .

You need to do this for all of the nested match expressions (I see 3 of them).您需要对所有嵌套的match表达式(我看到其中的 3 个)执行此操作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM