Skip to content
A compiler toolkit. For PHP (yes, I am creative at naming things)...
Branch: master
Clone or download
Type Name Latest commit message Commit time
Failed to load latest commit information.
examples Update wording on readme Apr 2, 2019
lib Adjust printer to add semicolon to output for structures Apr 2, 2019
test/Generic Get tests passing again Mar 29, 2019
.gitignore Initial commit for the toolkit Mar 21, 2019
composer.lock A little housekeeping Apr 1, 2019
phpunit.xml.dist Starting to pull it together Mar 27, 2019
rebuild.php A little housekeeping Apr 1, 2019

A compiler toolkit for PHP

This attempts to be a pretty heavy abstraction on top of (initially) three libraries:

It also includes a PHP backend for compiling to PHP itself (though this will be slower than native PHP and should only really be used for debug purposes).

As each project differs quite a bit once you get beyond the initial level, I'm not sure how useful a high level abstraction will be.

However, this project aims to be a pluggable backend for PHP-Compiler. The primary goal is to assess performance of each compiler and resulting code.

As such, the performance of this library isn't incredibly important today. Over time, it may become critical.

How to use?

So, here's a "basic" example for a function which adds two numbers:

use PHPCompilerToolkit\Context;
use PHPCompilerToolkit\Builder\GlobalBuilder;
use PHPCompilerToolkit\IR\Parameter;

$context = new Context;
$builder = new GlobalBuilder($context);

// long long add(long long a, long long b) {
//     return a + b;
// }

// First, let's get a reference to the type we want to use:
$type = $builder->type()->longLong()    ;
// Next, we need to create the function: name, returnType, isVariadic, Parameter ...
$func = $builder->createFunction('add', $type, false, new Parameter($type, 'a'), new Parameter($type, 'b'));
// We need a block in the function (blocks contain code)
$main = $func->createBlock('main');
// We want the block to return the result of addition of the two args:
$main->returnValue($main->add($func->arg(0), $func->arg(1)));
// We are done building everything

Notice how we haven't picked a backend yet. Now we can:

$libjit = new PHPCompilerToolkit\Backend\LIBJIT;

$add = $libjit->compile($context)->getCallable('add');

Or if we wanted to use libgccjit:

$libgccjit = new PHPCompilerToolkit\Backend\LIBGCCJIT;

$add = $libgccjit->compile($context)->getCallable('add');

Or if we wanted to use LLVM:

$llvm = new PHPCompilerToolkit\Backend\LLVM;

$add3 = $llvm->compile($context)->getCallable('add');

And since they are just normal PHP closures at this point:

var_dump($add(1, 1), $add2(2, 2), $add3(4, 4);
// int(2), int(4), int(8)
You can’t perform that action at this time.