Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@
"php": ">=8.1",
"nikic/php-parser": "^5.0",
"phpdocumentor/graphviz": "^1.0.4",
"adhocore/cli": "^v1.0.0"
"adhocore/cli": "^v1.0.0",
"google/protobuf": "^4.32"
},
"require-dev": {
"phpunit/phpunit": ">=10.0",
Expand Down
9 changes: 5 additions & 4 deletions lib/PHPCfg/Parser.php
Original file line number Diff line number Diff line change
Expand Up @@ -91,9 +91,9 @@ protected function loadHandlers(): void
{
$it = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator(
__DIR__ . '/ParserHandler/',
RecursiveIteratorIterator::LEAVES_ONLY
)
__DIR__ . '/ParserHandler/'
),
RecursiveIteratorIterator::LEAVES_ONLY
);
$handlers = [];
foreach ($it as $file) {
Expand Down Expand Up @@ -310,7 +310,7 @@ public function parseExprNode($expr): ?Operand
if (isset($this->exprHandlers[$expr->getType()])) {
return $this->exprHandlers[$expr->getType()]->handleExpr($expr);
}
var_dump(array_keys($this->exprHandlers));

throw new RuntimeException('Unknown Expr Type ' . $expr->getType());
}

Expand Down Expand Up @@ -456,6 +456,7 @@ public function readVariableRecursive(string $name, Block $block): Operand

return $var;
}

$var = new Temporary(new Variable(new Literal($name)));
$phi = new Op\Phi($var, ['block' => $block]);
$this->ctx->addToIncompletePhis($block, $name, $phi);
Expand Down
1 change: 0 additions & 1 deletion lib/PHPCfg/ParserHandler/Batch/Scalar.php
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,6 @@ public function handleExpr(Node\Expr $scalar): Operand
// TODO
return new Operand\Literal('__FUNCTION__');
default:
var_dump($scalar);
throw new RuntimeException('Unknown how to deal with scalar type ' . $scalar->getType());
}
}
Expand Down
1 change: 1 addition & 0 deletions lib/PHPCfg/ParserHandler/Batch/Unary.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

namespace PHPCfg\ParserHandler\Batch;

use PHPCfg\Assertion;
use PHPCfg\Op;
use PHPCfg\Operand;
use PHPCfg\ParserHandler;
Expand Down
2 changes: 1 addition & 1 deletion lib/PHPCfg/ParserHandler/Expr/ConstFetch.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public function handleExpr(Node\Expr $expr): Operand
$lcname = strtolower($expr->name->toString());
switch ($lcname) {
case 'null':
return new Operand\Literal(null);
return new Operand\NullOperand();
case 'true':
return new Operand\Literal(true);
case 'false':
Expand Down
79 changes: 28 additions & 51 deletions lib/PHPCfg/Printer/Printer.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
use PHPCfg\Op;
use PHPCfg\Operand;
use PHPCfg\Script;
use FilesystemIterator;
use RecursiveDirectoryIterator;
use RecursiveIteratorIterator;
use SplObjectStorage;
Expand Down Expand Up @@ -59,10 +60,13 @@ protected function loadRenderers(): void
$it = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator(
__DIR__ . '/Renderer/',
RecursiveIteratorIterator::LEAVES_ONLY
)
FilesystemIterator::SKIP_DOTS
),
RecursiveIteratorIterator::LEAVES_ONLY
);

$handlers = [];
$classes = [];
foreach ($it as $file) {
if (!$file->isFile() || $file->getExtension() !== 'php') {
continue;
Expand All @@ -75,14 +79,32 @@ protected function loadRenderers(): void
continue;
}

$classes[] = $class;
}

usort($classes, function ($a, $b) {
$aParts = substr_count($a, '\\');
$bParts = substr_count($b, '\\');

if ($aParts == $bParts) {
return 0;
}
return ($aParts < $bParts) ? 1 : -1;
});

foreach ($classes as $class) {
$obj = new $class($this);
$this->addRenderer($obj);
}
}

abstract public function printScript(Script $script): string;
abstract public function printScript(Script $script): mixed;

abstract public function printFunc(Func $func): mixed;

abstract public function printFunc(Func $func): string;
abstract public function renderOperand(Operand $var): mixed;

abstract public function renderOpLabel(array $desc): mixed;

protected function reset(): void
{
Expand All @@ -98,20 +120,6 @@ protected function getBlockId(Block $block): int
return $this->blocks[$block];
}

public function renderOperand(Operand $var): string
{
foreach ($this->renderers as $renderer) {
$result = $renderer->renderOperand($var);
if ($result !== null) {
$kind = $result['kind'];
$type = $result['type'];
unset($result['kind'], $result['type']);
return strtoupper($kind) . $type . '(' . trim(implode(" ", $result)) . ')';
}
}
return 'UNKNOWN';
}

public function renderOp(Op $op): array
{
foreach ($this->renderers as $renderer) {
Expand All @@ -127,11 +135,7 @@ public function renderOp(Op $op): array
}
}

return [
'op' => $op,
'label' => 'UNKNOWN',
'childBlocks' => $childBlocks,
];
throw new LogicException("Unknown op rendering: " . get_class($op));
}

protected function indent($str, $levels = 1): string
Expand Down Expand Up @@ -163,14 +167,7 @@ protected function render(Func $func)
$block = $this->blockQueue->dequeue();
$ops = [];
foreach ($block->phi as $phi) {
$result = $this->indent($this->renderOperand($phi->result) . ' = Phi(');
$result .= implode(', ', array_map([$this, 'renderOperand'], $phi->vars));
$result .= ')';
$renderedOps[$phi] = $ops[] = [
'op' => $phi,
'label' => $result,
'childBlocks' => [],
];
$renderedOps[$phi] = $ops[] = $this->renderOp($phi);
}
foreach ($block->children as $child) {
$renderedOps[$child] = $ops[] = $this->renderOp($child);
Expand Down Expand Up @@ -222,24 +219,4 @@ public function renderType(?Op\Type $type): string
}
throw new LogicException("Unknown type rendering: " . get_class($type));
}

public function renderOpLabel(array $desc): string
{
$result = "{$desc['kind']}";
unset($desc['kind'], $desc['childblocks']);
foreach ($desc as $name => $val) {
if (is_array($val)) {
foreach ($val as $v) {
if (is_array($v)) {
$result .= $this->indent("\n" . implode("\n", $v));
} else {
$result .= $this->indent("\n{$v}");
}
}
} else {
$result .= $this->indent("\n{$val}");
}
}
return $result;
}
}
Loading