我是OCaml的新手,这是我的原始代码:
method vinst(i) =
match i with
| Set (lv , e, _) ->
let (host, _) = lv in
match host with
| Mem _ ->
( self#queueInstr [mkPtrLVal (addressOf lv) e];
ChangeTo [])
| _ -> SkipChildren
......
因为在Set (lv, e, _)
的模式匹配之后,我仍然需要在lv
和e
上进行模式匹配,所以我想以这种方式重写它(以摆脱它烦人的开始...结束块):
method vinst(i) =
match i with
| Set (lv , e, _) when (Mem _, _) = lv -> (* see I re-write it this way *)
( self#queueInstr [mkPtrLVal (addressOf lv) e];
ChangeTo [])
| Set (lv , e, _) when (Lval (Mem _, _)) = lv ->
( self#queueInstr [mkPtrE (addressOf lv) e];
ChangeTo [])
| Set (lv , e, _) when (TPtr _) = typeOf e->
(self#queueInstr [mkPtrE (addressOf lv) e];
ChangeTo [])
| _ -> DoChildren
我试图编译它但是
错误:语法错误:操作符期望。
...发生
所以基本上可以这样写吗?如果是这样,我应该调整哪一部分?
==================更新===============
以下是我刚刚做的事情:
method vinst(i) =
match i with
| Set ((Mem _, _), e, _) -> (* pattern 1 *)
let Set (lv, e, _) = i in
( self#queueInstr [mkPtrLVal (addressOf lv) e];
ChangeTo [])
| Set (_, Lval (Mem _, _), _) -> (* pattern 2 *)
let Set (lv, e, _) = i in
( self#queueInstr [mkPtrE (addressOf lv) e];
ChangeTo [])
| Set (lv , e, _) -> (* pattern 3 *)
begin
match typeOf e with
| TPtr _ ->
(self#queueInstr [mkPtrE (addressOf lv) e];
ChangeTo [])
| _ -> SkipChildren
end
| _ -> DoChildren
它够好吗?还有更优雅的方式吗?
答案 0 :(得分:4)
您可以使用带有i
关键字的别名,而不是再次解构lv
以获取e
或as
。您还可以定义一个函数isPtr
,它返回一个布尔值,而不是直接使用typeOf
:
method vinst i =
let isPtr e = match typeOf e with
| TPtr _ -> true
| _ -> false in
match i with
| Set (((Mem _, _) as lv), e, _) ->
( self#queueInstr [mkPtrLVal (addressOf lv) e];
ChangeTo [])
| Set ((_ as lv), (Lval (Mem _, _) as e), _) ->
( self#queueInstr [mkPtrE (addressOf lv) e];
ChangeTo [])
| Set (lv , e, _) when isPtr e ->
( self#queueInstr [mkPtrE (addressOf lv) e];
ChangeTo [])
| Set (lv , e, _) -> SkipChildren
| _ -> DoChildren
答案 1 :(得分:2)
你可以在when
的左边做进一步的模式匹配(右边应该是boolean
,这样就不适合进一步解构元组/构造函数了),
| Set ((Mem _,_), e, _) -> ...