Virgil Tools Reference: VPC options

This page contains an overview of the options available to the Virgil Prototype Compiler as well as a short tutorial about its usage. This page also covers options, including selecting a device and a linkage model for the C code outputted by the prototype compiler.

VPC - The Virgil Prototype Compiler

Virgil is designed to be a statically compiled language, and the first release [B-01] includes a prototype compiler that parses, typechecks, and compiles Virgil source programs and emits C source code. The C source code can then be compiled using any C compiler for the platform. Currently, VPC is tested on the x86-linux, ppc-darwin, and the AVR platforms, but the C code emitted by the compiler is not inherently limited to these platforms.

Virgil Interpreter

The Virgil language includes the notion of initialization time, where an application can execute an initialization routine consisting of arbitrary Virgil code during the compilation process. To support this, every Virgil compiler must include an interpreter for the complete language. For experimentation purposes, one can write any Virgil code and run it through the compiler's interpreter by simply calling it in any constructor in any component of the program. This makes it easy to prototype algorithms and test them inside the compiler, before they ever execute on the device! Thus, you can make programs that test themselves as they are compiled, and the test code is automatically thrown away by the compiler's dead code elimination pass. You can also see a trace of the initialization code as it executes by can supplying the -trace option to the compiler.

Basic Usage

VPC is a whole-program compiler, and thus requires all of the code of your Virgil program in order to produce C output code. This is because the concept of initialization time, where your program initializes itself and allocates its data structures during compilation, may transitively reference any part of the program. At the command line, you must supply VPC with all of the files that contain your program, which can be done manually or through the use of a build tool such as make. Virgil then parses them all together, typechecks, initializes, optimizes, and generates code that implements the program into a single standalone C file.

% vpc my_files

The result is a C program output.c which contains the translated, optimized program, including the entire initialized heap. This file can then be compiled with a standard compiler such as gcc (or avr-gcc for the AVR platform). In order for this program to compile correctly, the Virgil program must include a master program declaration that declares an entrypoint method in the Virgil program. The entrypoint will correspond to the main() method of the C program.

Linkage Model

The C code generator can generate code for the program to run directly on a device such as the AVR, which has no notion of parameters to the main method. Or the code generator can produce a program intended to run on a UNIX system that provides parameters to the main method. To select between these two C environments, VPC accepts a -linkage option that can be set to one of c:unix or c:avr. These linkage models also differ in how a failure of a safety check (such as null checks or bounds checks) are reported, because Virgil's exception model is not fully developed yet.

% vpc -linkage=c:avr my_files

Device Selection

The Virgil Language also exposes device registers and hardware interrupts to the program. The selection of the device for which to compile the program is done through a compiler option that specifies a HIL specification file that describes the device. You can find an example of a HIL specification here, as well as in the source release of VPC or in the applications section. A HIL specification is only required if your program accesses hardware state or handles hardware interrupts directly.

% vpc -device=atmega128.hil -linkage=c:avr my_files