Skip to content
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,4 @@
"bin": [
"bin/php-cfg"
]
}
}
2 changes: 1 addition & 1 deletion lib/PHPCfg/Op/Terminal/StaticVar.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class StaticVar extends Terminal

public ?Block $defaultBlock;

public ?Operand $defaultVar;
public ?Operand $defaultVar = null;

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bug fix not related to printer


public function __construct(Operand $var, ?Block $defaultBlock = null, ?Operand $defaultVar = null, array $attributes = [])
{
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
18 changes: 8 additions & 10 deletions lib/PHPCfg/ParserHandler/Expr/ConstFetch.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,14 @@ class ConstFetch extends ParserHandler implements Expr
{
public function handleExpr(Node\Expr $expr): Operand
{
if ($expr->name->isUnqualified()) {

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bug fix not related to printer

$lcname = strtolower($expr->name->toString());
switch ($lcname) {
case 'null':
return new Operand\Literal(null);
case 'true':
return new Operand\Literal(true);
case 'false':
return new Operand\Literal(false);
}
$lcname = strtolower($expr->name->toString());
switch ($lcname) {
case 'null':
return new Operand\NullOperand();
case 'true':
return new Operand\Literal(true);
case 'false':
return new Operand\Literal(false);
}

$nsName = null;
Expand Down
82 changes: 30 additions & 52 deletions lib/PHPCfg/Printer/Printer.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

namespace PHPCfg\Printer;

use FilesystemIterator;
use LogicException;
use PHPCfg\Block;
use PHPCfg\Func;
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 @@ -121,17 +129,14 @@ public function renderOp(Op $op): array
$childblocks = $result['childblocks'];
return [
'op' => $op,
'kind' => $kind,
'label' => $this->renderOpLabel($result),
'childBlocks' => $childblocks,
];
}
}

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

protected function indent($str, $levels = 1): string
Expand All @@ -145,7 +150,7 @@ protected function indent($str, $levels = 1): string

public function enqueueBlock(Block $block): void
{
if (! $this->blocks->contains($block)) {
if (! $this->blocks->offsetExists($block)) {
$this->blocks[$block] = count($this->blocks) + 1;
$this->blockQueue->enqueue($block);
}
Expand All @@ -163,14 +168,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 +220,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;
}
}
55 changes: 25 additions & 30 deletions lib/PHPCfg/Printer/Renderer/GenericOp.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,46 +30,52 @@ public function reset(): void {}
public function renderOp(Op $op): ?array
{
$result = [
'attributes' => $this->renderAttributes($op->getAttributes()),
'attrGroups' => [],
'childblocks' => [],
'kind' => $op->getType(),
'types' => [],
'vars' => [],
'attributes' => $this->renderAttributes($op->getAttributes()),
'childblocks' => [],
];

if ($op instanceof Op\AttributableOp) {
$result['attrGroups'] = $this->renderAttrGroups($op);
}

if ($op instanceof Op\CallableOp) {
$func = $op->getFunc();
$result['vars'][] = "name: {$func->name}";
$result['vars']['name'] = $func->name;
}

if ($op instanceof Op\Stmt\Property || $op instanceof Op\Stmt\ClassMethod) {
$result['vars'][] = "flags: " . $this->renderFlags($op);
$result['vars']['flags'] = $this->renderFlags($op);
}


foreach ($op->getTypeNames() as $typeName => $type) {
if (is_array($type)) {
$result['types'][$typeName] = [];
foreach ($type as $key => $subType) {
if (! $subType) {
continue;
}
$result['types'][] = "{$typeName}[{$key}]: " . $this->printer->renderType($subType);
$result['types'][$typeName][$key] = $this->printer->renderType($subType);
}
} elseif ($type) {
$result['types'][] = "{$typeName}: " . $this->printer->renderType($type);
$result['types'][$typeName] = $this->printer->renderType($type);
}
}

foreach ($op->getVariableNames() as $varName => $vars) {
if (is_array($vars)) {
$result['vars'][$varName] = [];
foreach ($vars as $key => $var) {
if (! $var) {
continue;
}
$result['vars'][] = "{$varName}[{$key}]: " . $this->printer->renderOperand($var);
$result['vars'][$varName][$key] = $this->printer->renderOperand($var);
}
} elseif ($vars) {
$result['vars'][] = "{$varName}: " . $this->printer->renderOperand($vars);
$result['vars'][$varName] = $this->printer->renderOperand($vars);
}
}

Expand All @@ -91,12 +97,6 @@ public function renderOp(Op $op): ?array
}
}

if ($op instanceof Op\AttributableOp) {
$result['attrGroups'] = $this->renderAttrGroups($op);
}



return $result;
}

Expand All @@ -105,8 +105,6 @@ public function renderOperand(Operand $operand): ?array
return null;
}



protected function renderAttributes(array $attributes): array
{
if (!$this->printer->renderAttributes) {
Expand All @@ -115,38 +113,36 @@ protected function renderAttributes(array $attributes): array
$result = [];
foreach ($attributes as $key => $value) {
if (is_string($value) || is_numeric($value)) {
$result[] = "attribute['" . $key . "']: " . $value;
$result['attribute'][$key] = $value;
}
}
return $result;
}


protected function renderAttrGroups(Op\AttributableOp $op): array
{
$result = [];
$result['attrGroup'] = [];
foreach ($op->getAttributeGroups() as $indexGroup => $attrGroup) {
$result[$indexGroup] = [];
$result[$indexGroup][] = "attrGroup[$indexGroup]: ";
foreach ($this->renderAttributes($attrGroup->getAttributes()) as $attr) {
$result[$indexGroup][] = " {$attr}";
$result['attrGroup'][$indexGroup] = [];
foreach ($this->renderAttributes($attrGroup->getAttributes()) as $i => $attr) {
$result['attrGroup'][$indexGroup][$i] = $attr;
}
foreach ($attrGroup->attrs as $indexAttr => $attr) {
$result[$indexGroup][] = " attr[$indexAttr]: ";
foreach ($this->renderAttributes($attr->getAttributes()) as $rendered) {
$result[$indexGroup][] = " {$rendered}";
$result['attrGroup'][$indexGroup][$indexAttr] = [];
foreach ($this->renderAttributes($attr->getAttributes()) as $j => $rendered) {
$result['attrGroup'][$indexGroup][$indexAttr][$j] = $rendered;
}
$result[$indexGroup][] = " name: " . $this->printer->renderOperand($attr->name);
$result['attrGroup'][$indexGroup][$indexAttr]['name'] = $this->printer->renderOperand($attr->name);
foreach ($attr->args as $indexArg => $arg) {
$result[$indexGroup][] = " args[$indexArg]: " . $this->printer->renderOperand($arg);
$result['attrGroup'][$indexGroup][$indexAttr]['args'][$indexArg] = $this->printer->renderOperand($arg);
}
}
}

return $result;
}


protected function renderFlags(Op\Stmt $stmt): string
{
$result = '';
Expand Down Expand Up @@ -178,5 +174,4 @@ protected function renderFlags(Op\Stmt $stmt): string

return $result;
}

}
Loading
Loading