A CIL Tutorial - Department of Computer Science - ETH Zürich

A CIL Tutorial - Department of Computer Science - ETH Zürich A CIL Tutorial - Department of Computer Science - ETH Zürich

29.01.2014 Views

CHAPTER 12. COMMENTS 106 adjacent to the given source location. The indexes are into the the array returned as the second element of the return value. let commentsAdjacent (cca : comment array) (l : location) : int list × comment array = if l = locUnknown then [ ], cca else let cca = prepareCommentArray cca l.file in (cca | > array bin search comment compare (comment of cilloc l)), cca The function commentsBetween returns a list of indexes into the array returned as the second element of the return value. The indexes indicate the comments lying between source locations l1 and l2. If the exact location is not in the comments array, the binary search function returns the two closest elements. Therefore commentsBetween returns the highest of the lower bounds, and the smallest of the upper bounds, so that only the indexes for the comments between the two locations are returned. let commentsBetween (cca : comment array) (l1 : location) (l2 : location) : int list × comment array = if l1 = locUnknown then commentsAdjacent cca l2 else if l1.file ≠ l2.file then commentsAdjacent cca l2 else begin let cca = prepareCommentArray cca l1.file in let ll = array bin search comment compare (comment of cilloc l1) cca in let hl = array bin search comment compare (comment of cilloc l2) cca in let l, h = match ll, hl with | ([l] | [ ; l]), h :: → l, h | → E.s(E.bug "bad result from array bin search") in (Array.init (h − l + 1) (fun i → i + l) | > Array.to list), cca end The function markComment searches a comment array for an exact source location, and marks the third element of the tuple for that location as true, indicating in this example that the comment has been printed by printComments. let markComment (l : A.cabsloc) (cca : comment array) : unit = Array.iteri (fun i (l', s, b) → if compare l l' = 0 then cca.(i) ← (l', s,true) ) cca The function printComments prints the comments from the array cca' indicated by the indexes in il and marks the comments as having been printed in cca. The location l is used to indicate the source location being inspected by an instance of the commentVisitorClass that triggered the call to printComments.

CHAPTER 12. COMMENTS 107 let printComments (cca : comment array) (l : location) ((il, cca') : int list × comment array) : location = L.iter (fun i → let c = cca'.(i) in if ¬(thd3 c) then begin markComment (fst3 c) cca; E.log "%a: Comment: %a -> %s\n" d loc l d loc (cilloc of cabsloc (fst3 c)) (snd3 c) end ) il; if il ≠ [ ] then il | > L.rev | > L.hd | > Array.get cca' | > fst3 | > cilloc of cabsloc else l The commentVisitorClass visitor visits the AST, printing comments nearby instructions and statements. class commentVisitorClass (cca : comment array) = object(self) inherit nopCilVisitor val mutable last = locUnknown method vinst (i : instr) = last ← i | > get instrLoc |> commentsBetween cca last |> printComments cca (get instrLoc i); DoChildren method vstmt (s : stmt) = last ← s.skind | > get stmtLoc |> commentsBetween cca last |> printComments cca (get stmtLoc s.skind); DoChildren end The function tut12 is the entry point for this module. First it copies the GrowArray.t of comments into an array. Then, it instantiates the commentVisitorClass visitor, and runs it over the Cil.file passed as an argument. let tut12 (f : file) : unit = let cca = array of growarray CH.commentsGA in let vis = new commentVisitorClass cca in visitCilFile vis f

CHAPTER 12. COMMENTS 107<br />

let printComments (cca : comment array) (l : location)<br />

((il, cca') : int list × comment array) : location =<br />

L.iter (fun i → let c = cca'.(i) in<br />

if ¬(thd3 c) then begin<br />

markComment (fst3 c) cca;<br />

E.log "%a: Comment: %a -> %s\n"<br />

d loc l d loc (cilloc <strong>of</strong> cabsloc (fst3 c)) (snd3 c)<br />

end<br />

) il;<br />

if il ≠ [ ]<br />

then il | > L.rev | > L.hd | > Array.get cca' | > fst3 | > cilloc <strong>of</strong> cabsloc<br />

else l<br />

The commentVisitorClass visitor visits the AST, printing comments nearby instructions and statements.<br />

class commentVisitorClass (cca : comment array) = object(self)<br />

inherit nopCilVisitor<br />

val mutable last = locUnknown<br />

method vinst (i : instr) =<br />

last ← i | > get instrLoc<br />

|> commentsBetween cca last<br />

|> printComments cca (get instrLoc i);<br />

DoChildren<br />

method vstmt (s : stmt) =<br />

last ← s.skind | > get stmtLoc<br />

|> commentsBetween cca last<br />

|> printComments cca (get stmtLoc s.skind);<br />

DoChildren<br />

end<br />

The function tut12 is the entry point for this module. First it copies the GrowArray.t <strong>of</strong> comments<br />

into an array. Then, it instantiates the commentVisitorClass visitor, and runs it over the Cil.file<br />

passed as an argument.<br />

let tut12 (f : file) : unit =<br />

let cca = array <strong>of</strong> growarray CH.commentsGA in<br />

let vis = new commentVisitorClass cca in<br />

visitCilFile vis f

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!