簡體   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