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