[英]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.