繁体   English   中英

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

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

我对 ocmal 没有太多经验,编译器错误消息也不是很有帮助。 我没有看到代码有任何明显的问题。 我有完整的代码和下面的错误消息。 谢谢你。

完整的编译器错误消息:

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

错误:此变体模式应具有类型 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

看起来您的问题是您嵌套了match表达式。 困难在于编译器认为外部match的下一个案例实际上是内部match的下一个案例。

解决方案是将所有内部匹配表达式括起来。

它应该是这样的:

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)) ]
        )
    . . .

您需要对所有嵌套的match表达式(我看到其中的 3 个)执行此操作。

暂无
暂无

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

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