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 14 Implementing a simple DSL When writing C code, one of the tasks that annoys me a lot is writing code to handle command line arguments. Thus, in this chapter we'll use CIL to put together a simple DSL for describing command line arguments. The module below will analyze a description of the arguments provided by the programmer, and generate code for parsing the command line, and checking the arguments for consistency. In particular, the goal is for the programmer to give a description like the one below at global scope: argument(int, intarg) { .short form = "i", .help text = "An integer argument (>0)", .format = "%d", .def = 1, .requires = arg assert(intarg > 0), .has opt = ARG HAS OPT, }; We can provide this syntax using CIL's attribute syntax along with judicious use of pre-processor macros. The macros, which are dened in ciltut-include/ciltut.h, declare variables for storing the command line arguments and their options, along with a structure type with elds for storing the properties of the argument. The code above is essentially an initializer list for those structure elds. The CIL code below will generate code to parse the command line arguments according to the options specied in the structure eld using the getopt long C Library call. 14.1 tut14.ml First, we'll declare types for representing requirements for the command line arguments along with some utility functions. Then, we'll write functions for extracting the requirements from the syntax mentioned above. Finally, we'll use CIL's interpreted constructors to generate the loop that calls 114

CHAPTER 14. IMPLEMENTING A SIMPLE DSL 115 getopt long and uses sscanf to parse any options the arguemnts might have. 14.1.1 Specication Extraction The argument type is where we'll collect the information the programmer gives us about the command line arguments. type argument = { mutable argName : string; (∗ The name of the argument, i.e. -- ∗) mutable argType : typ; (∗ The type of the argument ∗) mutable argShort : string; (∗ The short form of the argument, i.e. -n ∗) mutable argHelp : string; (∗ The help message for the argument ∗) mutable argFmt : string; (∗ The format specier for sscanf ∗) mutable argDef : exp; (∗ The default value of the argument ∗) mutable argReq : exp; (∗ An assertion about the argument ∗) mutable argOpt : bool; (∗ Whether the argument is optional ∗) mutable argVi : varinfo; (∗ The global varialbe for the argument ∗) mutable argGot : varinfo; (∗ Global variable indicating whether the argument was given ∗) mutable argOption : bool; (∗ Whether the argument as a parameter ∗) } The function makeArgument makes a fresh argument initialized with dummy values. let makeArgument () = (∗ ... ∗) Now that we've dened the argument type, we can write utility functions for extracting information from type attributes. In particular, structure types that should be interpreted as argument speci- cations are annotated with the ciltutarg type attribute. Also, we extract the parameter to the ciltut assert attribute on the type of the requires eld of the argument structure to be used as an assertion that must be true of the argument, e.g. intarg > 0 in the example above. As usual, we begin by dening some global variables for the string constants, along with a list of the strings. let argStr = "ciltutarg" let assertStr = "ciltut assert" let mandatoryStr = "mandatory" let attr strings = [argStr; assertStr; mandatoryStr; ] The functions hasArgAttr, hasAssertAttr, and hasMandatoryAttr return true if their arguments have the indicated attributes.

CHAPTER 14. IMPLEMENTING A SIMPLE DSL 115<br />

getopt long and uses sscanf to parse any options the arguemnts might have.<br />

14.1.1 Specication Extraction<br />

The argument type is where we'll collect the information the programmer gives us about the command<br />

line arguments.<br />

type argument = {<br />

mutable argName : string; (∗ The name <strong>of</strong> the argument, i.e. -- ∗)<br />

mutable argType : typ; (∗ The type <strong>of</strong> the argument ∗)<br />

mutable argShort : string; (∗ The short form <strong>of</strong> the argument, i.e. -n ∗)<br />

mutable argHelp : string; (∗ The help message for the argument ∗)<br />

mutable argFmt : string; (∗ The format specier for sscanf ∗)<br />

mutable argDef : exp; (∗ The default value <strong>of</strong> the argument ∗)<br />

mutable argReq : exp; (∗ An assertion about the argument ∗)<br />

mutable argOpt : bool; (∗ Whether the argument is optional ∗)<br />

mutable argVi : varinfo; (∗ The global varialbe for the argument ∗)<br />

mutable argGot : varinfo; (∗ Global variable indicating whether the argument was given ∗)<br />

mutable argOption : bool; (∗ Whether the argument as a parameter ∗)<br />

}<br />

The function makeArgument makes a fresh argument initialized with dummy values.<br />

let makeArgument () = (∗ ... ∗)<br />

Now that we've dened the argument type, we can write utility functions for extracting information<br />

from type attributes. In particular, structure types that should be interpreted as argument speci-<br />

cations are annotated with the ciltutarg type attribute. Also, we extract the parameter to the<br />

ciltut assert attribute on the type <strong>of</strong> the requires eld <strong>of</strong> the argument structure to be used as<br />

an assertion that must be true <strong>of</strong> the argument, e.g. intarg > 0 in the example above.<br />

As usual, we begin by dening some global variables for the string constants, along with a list<br />

<strong>of</strong> the strings.<br />

let argStr = "ciltutarg"<br />

let assertStr = "ciltut assert"<br />

let mandatoryStr = "mandatory"<br />

let attr strings = [argStr; assertStr; mandatoryStr; ]<br />

The functions hasArgAttr, hasAssertAttr, and hasMandatoryAttr return true if their arguments<br />

have the indicated attributes.

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

Saved successfully!

Ooh no, something went wrong!