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
CHAPTER 14. IMPLEMENTING A SIMPLE DSL 122 (L.map (fun a → (a.argVi.vname¢"addr"), Fe (AddrOf(var a.argVi))) al)@ (L.map (fun a → (a.argVi.vname¢"l"), Fl(var a.argVi)) al)@ (L.map (fun a → (a.argGot.vname), Fl(var a.argGot)) al)) The function initArgs generates statements that initialize the global variables for arguments with their default values. let initArgs (al : argument list) : stmt list = L.map (fun a → i2s(Set(var a.argVi, a.argDef, locUnknown))) al The function printHelp generates statements using printf that print the help text for the arguments to standard out. The help text gives the short version, the long version, the default value, and tells whether the argument is mandatory. The statements generated by printHelp will be used in case some checks on the runtime argument values fails. let printHelp (f : file) (al : argument list) : stmt list = let print = findOrCreateFunc f "printf" intType in let s s = mkString s in [i2s(Call(None, v2e print, [s "Improper arguemnts\n"], locUnknown))]@ (L.map (fun a → let af = if a.argFmt ≠ "" then a.argFmt else "%d" in let fmt = if a.argOpt then s ("\t-%s,--%s\t%s ("¢af¢")\n") else s "\t-%s,--%s\t%s (mandatory)\n" in let args = if a.argOpt then [fmt; s a.argShort; s a.argName; s a.argHelp; a.argDef] else [fmt; s a.argShort; s a.argName; s a.argHelp] in i2s (Call(None, v2e print, args, locUnknown)) ) al) @ [mkStmt (Return(Some mone, locUnknown))] The function makeArgChecks generates an if statement that checks two things. First, it checks that all mandatory arguments have been given. Second, it checks that all assertions stipulated by the programmer on the arguments are true. If either of these fails, the statements given by printHelp are used to print the help messages, and exit from the program with a failure code.
CHAPTER 14. IMPLEMENTING A SIMPLE DSL 123 let makeArgChecks (f : file) (al : argument list) : stmt = let got arg a = if a.argOpt then one else v2e a.argGot in let bexp, mexp = L.fold left (fun b a → BinOp(LAnd, b, a.argReq, intType)) one al, L.fold left (fun b a → BinOp(LAnd, b, (got arg a), intType)) one al in mkStmt (If(BinOp(LOr, UnOp(LNot, mexp, intType), UnOp(LNot, bexp, intType), intType), mkBlock (printHelp f al), mkBlock[ ], locUnknown)) If we have found the main function, then the function processFunction inserts the code for processing command line arguments at the top of the function. let processFunction (f : file) (al : argument list) (fd : fundec) (loc : location) : unit = if fd.svar.vname = "main" then fd.sbody.bstmts ← (initArgs al) @ (makeArgStmts f fd al) @ [makeArgChecks f al] @ fd.sbody.bstmts Finally, the function tut14 gathers the argument specications using gatherArguments before calling processFunction, which generates the argument parsing code. let tut14 (f : file) : unit = f | > gatherArguments |> processFunction f |> onlyFunctions |> iterGlobals f; eraseAttrs f 14.2 test/tut14.c This C code demonstrates the language extension we wrote for generating code to process command line arguments. It will accept one argument called boolarg, and another called intarg. ../test/tut14.c # include # include # include // This is where the argument macro is #define'd The boolarg argument can be passed with --boolarg or -b, and its value can be accessed in the program through the global variable boolarg of type int. When not given, the default value is 0 or false.
- Page 73 and 74: Chapter 9 Type Qualier Inference In
- Page 75 and 76: CHAPTER 9. TYPE QUALIFIER INFERENCE
- Page 77 and 78: CHAPTER 9. TYPE QUALIFIER INFERENCE
- Page 79 and 80: CHAPTER 9. TYPE QUALIFIER INFERENCE
- Page 81 and 82: CHAPTER 9. TYPE QUALIFIER INFERENCE
- Page 83 and 84: Chapter 10 Adding a New Kind of Sta
- Page 85 and 86: CHAPTER 10. ADDING A NEW KIND OF ST
- Page 87 and 88: CHAPTER 10. ADDING A NEW KIND OF ST
- Page 89 and 90: CHAPTER 10. ADDING A NEW KIND OF ST
- Page 91 and 92: CHAPTER 10. ADDING A NEW KIND OF ST
- Page 93 and 94: Chapter 11 Program Verication In th
- Page 95 and 96: CHAPTER 11. PROGRAM VERIFICATION 93
- Page 97 and 98: CHAPTER 11. PROGRAM VERIFICATION 95
- Page 99 and 100: CHAPTER 11. PROGRAM VERIFICATION 97
- Page 101 and 102: CHAPTER 11. PROGRAM VERIFICATION 99
- Page 103 and 104: CHAPTER 11. PROGRAM VERIFICATION 10
- Page 105 and 106: CHAPTER 11. PROGRAM VERIFICATION 10
- Page 107 and 108: Chapter 12 Comments CIL has a very
- Page 109 and 110: CHAPTER 12. COMMENTS 107 let printC
- Page 111 and 112: References [1] Lin Tan, Ding Yuan,
- Page 113 and 114: CHAPTER 13. WHOLE-PROGRAM ANALYSIS
- Page 115 and 116: CHAPTER 13. WHOLE-PROGRAM ANALYSIS
- Page 117 and 118: CHAPTER 14. IMPLEMENTING A SIMPLE D
- Page 119 and 120: CHAPTER 14. IMPLEMENTING A SIMPLE D
- Page 121 and 122: CHAPTER 14. IMPLEMENTING A SIMPLE D
- Page 123: CHAPTER 14. IMPLEMENTING A SIMPLE D
- Page 127 and 128: Chapter 15 Automated Test Generatio
- Page 129 and 130: CHAPTER 15. AUTOMATED TEST GENERATI
- Page 131 and 132: CHAPTER 15. AUTOMATED TEST GENERATI
- Page 133 and 134: CHAPTER 15. AUTOMATED TEST GENERATI
- Page 135 and 136: Index A (module), 10, 13, 15, 10, 1
- Page 137 and 138: INDEX 135 isCacheReportType, 11, 11
CHAPTER 14. IMPLEMENTING A SIMPLE DSL 122<br />
(L.map (fun a → (a.argVi.vname¢"addr"), Fe (AddrOf(var a.argVi))) al)@<br />
(L.map (fun a → (a.argVi.vname¢"l"), Fl(var a.argVi)) al)@<br />
(L.map (fun a → (a.argGot.vname), Fl(var a.argGot)) al))<br />
The function initArgs generates statements that initialize the global variables for arguments with<br />
their default values.<br />
let initArgs (al : argument list) : stmt list =<br />
L.map (fun a → i2s(Set(var a.argVi, a.argDef, locUnknown))) al<br />
The function printHelp generates statements using printf that print the help text for the arguments<br />
to standard out. The help text gives the short version, the long version, the default value,<br />
and tells whether the argument is mandatory. The statements generated by printHelp will be used<br />
in case some checks on the runtime argument values fails.<br />
let printHelp (f : file) (al : argument list) : stmt list =<br />
let print = findOrCreateFunc f "printf" intType in<br />
let s s = mkString s in<br />
[i2s(Call(None, v2e print, [s "Improper arguemnts\n"], locUnknown))]@<br />
(L.map (fun a →<br />
let af = if a.argFmt ≠ "" then a.argFmt else "%d" in<br />
let fmt = if a.argOpt<br />
then s ("\t-%s,--%s\t%s ("¢af¢")\n")<br />
else s "\t-%s,--%s\t%s (mandatory)\n"<br />
in<br />
let args = if a.argOpt<br />
then [fmt; s a.argShort; s a.argName; s a.argHelp; a.argDef]<br />
else [fmt; s a.argShort; s a.argName; s a.argHelp]<br />
in<br />
i2s (Call(None, v2e print, args, locUnknown))<br />
) al) @<br />
[mkStmt (Return(Some mone, locUnknown))]<br />
The function makeArgChecks generates an if statement that checks two things. First, it checks that<br />
all mandatory arguments have been given. Second, it checks that all assertions stipulated by the<br />
programmer on the arguments are true. If either <strong>of</strong> these fails, the statements given by printHelp<br />
are used to print the help messages, and exit from the program with a failure code.