Compiler

General syntax for calling the compiler: pilc -i inputfile.pil [options]

Options:

  • -d target_dir Generate code to a particular directory, default is "out"
  • --gen-external-classinfos Generate type classes for external classes and definitions (internal use only)
  • --gen-builtin-types Generate type classes for builtin types (internal use only)
  • --java Generate Java code
  • --python Generate Python code
  • --php Generate PHP code

How it works

The PIL compiler operates in a number of stages. The stages are as follows:

  • Parse the input file
  • Import/compile references modules
  • Typecheck
  • Desugar
  • Generate code

For every compiled module (file), the compiler will generate a header (.h) file, listing all external definitions in that file. These header files are used when the given module is imported by another PIL program to realize separate compilation.

Example: Let's say we have two PIL modules:

a.pil:

    class A {
       void sayHello() {
         println("Helo!");
       }
    }

b.pil:

    import "a.pil"
    void main(Array<String> args) {
      var a = new A();
      a.sayHello();
    }

We now invoke the PIL compiler on b.pil:

    pilc -i b.pil --java

The compiler will first parse file b.pil, and find the import of a.pil, since no a.pil.h file exists, it will first compile a.pil. The compilation of a.pil results in a number of (in this case) Java files, and the a.pil.h file that contains the following definition:

    external class A {
      void sayHello();
    }

The compiler parses this header file and exposes its defintions to the code in b.pil, which will now be aware of the existence and interface of the A class. Java code is generated for the b.pil program and a b.pil.h file is written.