Domanda

I am new in OCaml and here is my original code:

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

Because after pattern matching of Set (lv, e, _), I still need to pattern match both on lv and e, so I am thinking to re-write it in this way ( to get rid of annoying begin...end block):

     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

I tried to compile it but

Error: Syntax error: operator expected.

occured...

So Basically it is possible to write it in this way? If so, which part should I adjust?

==================update===============

Here is what I did just now:

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

Is it good enough? Is there any more elegant way?

È stato utile?

Soluzione

Instead of deconstructing i again to get lv or e, you can use an alias with the as keyword. You can also define a function isPtr that returns a boolean instead of using typeOf directly:

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

Altri suggerimenti

You can do further pattern matching on the left of when (to the right should be a boolean, so that would be an inappropriate place for further deconstruction of the tuples/constructors),

| Set ((Mem _,_), e, _)  ->  ...
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top