GSOC 12: Coming to an end

While I didn't implement everything I thought I would, there is now a basic framework for bytecode generation in the nqp_pct branch. I'm uncertain if it should be merged... While the bytecode generation doesn't fully work, it doesn't interfere with the existing usage of PCT and does have the nice feature that PAST::Compiler is now written in NQP for ease of hacking. I'll leave that up to the rest of the community to decide. The rest of this blog post is the contents of docs/pct/bytecode.pod, which I hope will be helpful if anyone want to explore what I've been working on all summer.

NAME

Compiling to Bytecode with the Parrot Compiler Tools


DESCRIPTION

This document describes the steps needed to use the Parrot Compiler Tools
(PCT) to directly generate bytecode files (.pbc). This feature is both
experimental and incomplete, but assistance from experienced language
authors is requested to help find the limitations.


GETTING STARTED

If you have created a high-level language with PCT via
mk_language_shell.pl or by hand, then you're most of the way towards
using this new feature. It requires no changes to the grammar or actions,
as all the changes to the process occur after you hand off a PAST tree to
the library.

To generate bytecode directly, you need to alter the stages that your
compiler runs. Generally this is found in src/HLLName/Compiler.pm (in
this, and all further examples, replace HLLName with the name of
your language (i.e. src/Squaak/Compiler.pm). This file contains
all the configuration for your compiler inside an INIT block. To change
from the default compilation chain to the new chain, add the following
line:

    HLLName::Compiler.stages(<parse past newpost pbc>);

This assumes that your language is written in NQP, as generated by
mk_language_shell.pl. If you have replaced this file with another
language or created your compiler by hand, you need to do the equivalent of
the following PIR:

    $P0 = get_hll_global ['HLLName'], 'Compiler' # Get compiler object
    $P1 = split ' ', 'parse past newpost pbc'
    $P0.'stages'($P1)

NEW STAGES

The above code replaces the post, pir, and evalpmc stages with two new
ones described below:

  • newpost

    Uses PAST::NewCompiler to convert the PAST tree from your actions into a
    "newPOST" tree. newPOST contains additional information required to
    generate bytecode and is not supposed to contain any raw PIR source.

  • pbc

    Uses POST::PBCCompiler to create a Packfile from the PAST tree. This
    returns the main method from the source for execution by the compiler.
    Using --output file.pbc will allow you to save the generated packfile to
    a file.


KNOWN ISSUES

newPOST is known to only compile fairly simple PAST trees at the moment.
As more specific issues are found, they should be added to this list, and
as features are implemented, they should be removed.

  • Exceptions

    Null PMC access in find_method('new') in PAST::Compiler.try

  • Inline PIR

    Because PIR is not generated when using these stages, inline PIR can not be
    used. To add this, a more fine-grained PIR parser would need to be addthat
    outputs newPOST trees.


UNKNOWN ISSUES

If attempting to compile your program, you encounter an error message and
the backtrace includes parrot;POST;PBCCompiler, then likely you have
attempted to use something not yet implemented. Here are a few of the
common errors: