Claire,  attached is a new .ml version that has some additional code
to check on some special cases (since the original one you gave me
doesn't work with these cases).   I feel it might be incorrect or
might have side effects.  Could you look at it and let me know if it's
OK ?

thanks


VN -



On Sat, Apr 10, 2010 at 4:21 PM, ThanhVu (Vu) Nguyen
<nguyenthanh...@gmail.com> wrote:
> I made some progress with this using different kind of Visitors.   The
> attached ml seems to do what I want  (i.e., putting a s1: printf
> "hello"  at the outter most if and a s2: printf "world" at the inner
> most if).    I still feel it might have some side effects  and
> incorrect though  --
>
>
> To summarize I want  to change
>
> if (cond1){
>   if (cond 2) {
>   something;
>    if (cond3){
>    }
>  }
> }
>
> into
>
> printf "hello"
> if (cond1){
>   if (cond 2) {
>   printf "world"
>   something;
>
>    printf "hello"
>    if (cond3){
>     printf"world"
>    }
>  }
> }
>
>
>
>
> VN -
>
>
>
> On Sat, Apr 10, 2010 at 2:27 PM, ThanhVu (Vu) Nguyen
> <nguyenthanh...@gmail.com> wrote:
>> Hi, I am trying to add a statement s1 outside of an if and another
>> statement s2 inside of the if as below
>>
>> s1;
>> if  (cond1 && cond2 && cond3){
>>      s2;
>> }
>>
>> CIL breaks that into multiple nested if's  so it will look like
>> s1;
>> if(cond1){
>>     if(cond2){
>>         if (cond3){
>>            s2;
>>         }
>>     }
>> }
>>
>>
>> I wrote the following simple code for this purpose but it's not
>> correct -- it enters an infinite loop and I think the reason is at the
>> line (**problem here**)   --- because it adds the new statement s1 to
>> the current if stuff ... then Do the children ,  so again revisit the
>> current if stuff   .
>>
>>
>> (*check if there's no more if's*)
>> let isInnerMostBlock b =
>>  let isIfTheFirst stmt = match stmt.skind with If(cond,b1,b2,l) ->
>> true |_ -> false in
>>  match b.bstmts with  [] -> true |(fst_stmt::_) -> not (isIfTheFirst 
>> fst_stmt)
>>
>> class nestedIfConds () = object
>>  inherit nopCilVisitor
>>  val mutable inNestedIf  = false
>>
>>  method vstmt s = (
>>        match s.skind with
>>          |If(cond,b1,b2,l)-> (
>>                  if inNestedIf = false then (
>>                        debug "Entering if\n";
>>                        inNestedIf <- true;
>>                        let s1 = mkEmptyStmt () in
>>                        s.skind <- Block(mkBlock([s1;{s with labels = []}]))  
>> (** problem here**)
>>                  );
>>
>>                  if (isInnerMostBlock b1) then (
>>                        inNestedIf <- false;
>>
>>                        let s2 = mkEmptyStmt () in
>>                        b1.bstmts <- s2::b1.bstmts
>>                  );
>>                  DoChildren
>>                )
>>
>>
>>          |_ -> DoChildren
>>  )
>> end
>>
>>  I am not sure how to do this correctly ? e.g., using different
>> Visitor action like ChangeTo  or DoChildren Post etc ?   I don't think
>> DoChildrenPost does what I want because it travels all the ways down
>> to if(cond3) and returns back from there.    Greatly appreciate all
>> the helps  !
>>
>>
>>
>>
>>
>> VN -
>>
>
int main(){
  int a = 1;
  int b = 2;
  int c = 3;

  if (a == c){
	printf("1");
  }

  if (a == b && b ==c || c == a){
	printf("1");
	if (a == c){
	}
	
  }
  else{
  }



  return 0;
}
open Printf
open Cil

let isInnerMostBlock b =
  let isIfTheFirst stmt =
	match stmt.skind with If(cond,b1,b2,l) -> true |_ -> false
  in
  match b.bstmts with  [] -> true |(fst_stmt::_) -> not (isIfTheFirst fst_stmt)

let mkPrintf str = 
  let fprintf = Lval((Var (makeVarinfo true "fprintf" (TVoid []))), NoOffset) in 
  let hello_str = Const(CStr(str)) in 
  let instr = Call(None,fprintf,[hello_str],!currentLoc) in 
  mkStmtOneInstr(instr)



			(* ChangeDoChildrenPost( *)
			(*   s, *)
			(*   fun s -> ( *)
			(* 	inNestedIf <- false; *)
			(* 	s(\*mkStmt (Block(mkBlock([s1;{s with labels = []}])))*\) *)
			(*   ) *)
			(* )(\*CDCP*\) *)

			(* if isInnerMostBlock b1 then ( *)
			(*   let s2 = mkPrintf "world" in *)
			(*   let b1' = mkBlock (s2::b1.bstmts) in *)
			(*   ChangeTo (If(cond,b1',b2,l)) *)
			(* )  *)
			(* else DoChildren *)


class nestedIfConds () = object
																	  
  inherit nopCilVisitor
  val mutable inNestedIf  = false

  method vstmt s = (
	match s.skind with
	  |If(cond,b1,b2,l)-> (
		  if not inNestedIf then (
			inNestedIf <- true;
			let s1 = mkPrintf "hello" in

			if isInnerMostBlock b1 then (
			  inNestedIf <- false;
			  let s2 = mkPrintf "world" in 
			  b1.bstmts <- s2::b1.bstmts
			);

			ChangeDoChildrenPost(
			  s, fun s -> (
				mkStmt(Block(mkBlock([s1;{s with labels = []}])))
			  )
			)
		  ) else (
			if isInnerMostBlock b1 then (
			  inNestedIf <- false;
			  let s2 = mkPrintf "world" in 
			  b1.bstmts <- s2::b1.bstmts;
			);
			DoChildren
		  )
		)
      |_ -> DoChildren
  )
end


let main () = begin 
  if Array.length Sys.argv < 2 then begin
    printf "usage: vu [file.c]\n" ;    exit 1 
  end ;
  Cil.initCIL () ; 

  let filename = Sys.argv.(1) in 
  let ast = Frontc.parse filename () in 

  visitCilFileSameGlobals (new nestedIfConds()) ast;

  iterGlobals ast (fun glob -> dumpGlobal defaultCilPrinter stdout glob ; ) ; 
  exit 0 

end 
;;
main () ;; 

------------------------------------------------------------------------------
Download Intel&#174; Parallel Studio Eval
Try the new software tools for yourself. Speed compiling, find bugs
proactively, and fine-tune applications for parallel performance.
See why Intel Parallel Studio got high marks during beta.
http://p.sf.net/sfu/intel-sw-dev
_______________________________________________
CIL-users mailing list
CIL-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/cil-users

Reply via email to