Browse Source

Move cfnpp code out from under engine namespace

master
Adam Pippin 3 years ago
parent
commit
01b036b284
  1. 72
      app/Cfnpp/Compiler.php
  2. 5
      app/Cfnpp/Expression/Expression.php
  3. 2
      app/Cfnpp/Expression/Parser.php
  4. 2
      app/Cfnpp/Expression/Token.php
  5. 2
      app/Cfnpp/Expression/TokenFunction.php
  6. 2
      app/Cfnpp/Expression/TokenNumericLiteral.php
  7. 5
      app/Cfnpp/Expression/TokenOperator.php
  8. 2
      app/Cfnpp/Expression/TokenStringLiteral.php
  9. 2
      app/Cfnpp/Expression/TokenVariable.php
  10. 19
      app/Cfnpp/Functions.php
  11. 2
      app/Cfnpp/Options.php
  12. 4
      app/Commands/Stack/Compile.php

72
app/Engine/Cfnpp/Compiler.php → app/Cfnpp/Compiler.php

@ -2,7 +2,7 @@
declare(strict_types=1);
namespace App\Engine\Cfnpp;
namespace App\Cfnpp;
use App\Dom\Document;
use App\Dom\Node;
@ -171,8 +171,8 @@ class Compiler implements \App\Engine\ICompile
}
/**
* Compiler Pass 1 - Grab all variables, build dependency graph of
* dependencies between variable values, resolve variables values. Then
* Compiler Pass 1 - Grab all variables and parameters, build dependency
* graph of dependencies between values, resolve values. Then
* set them on $options to include them in program state.
*
* @param Document $document
@ -182,32 +182,61 @@ class Compiler implements \App\Engine\ICompile
protected function pass_1(Document $document, IOptions $options): void
{
$variables_node = $document->getChildByPath('cfnpp.variables');
// If there are no variables, we're done here.
if (!isset($variables_node))
$parameters_node = $document->getChildByPath('cfnpp.parameters');
// If there are no variables or parameters, we're done here.
if (!isset($variables_node) && !isset($parameters_node))
{
return;
}
$variables_raw = [];
$nodes = [];
$graph = new DependencyGraph();
foreach ($variables_node as $variable_node)
if (isset($parameters_node))
{
$variables_raw[$variable_node->getName()] = $variable_node;
$graph->add($variable_node->getName(), $this->pass_1_getVariableDependencies($variable_node));
foreach ($parameters_node as $parameter_node)
{
$nodes[$parameter_node->getName()] = $parameter_node;
$graph->add($parameter_node->getName(), $this->pass_1_getDependencies($parameter_node));
}
}
if (isset($variables_node))
{
foreach ($variables_node as $variable_node)
{
if (isset($nodes[$variable_node->getName()]))
{
throw new \Exception("Variables and parameters cannot share the same name.");
}
$nodes[$variable_node->getName()] = $variable_node;
$graph->add($variable_node->getName(), $this->pass_1_getDependencies($variable_node));
}
}
$variables_ordered = $graph->solve();
$nodes_ordered = $graph->solve();
foreach ($variables_ordered as $variable)
foreach ($nodes_ordered as $node_name)
{
$this->runFunctions($variables_raw[$variable]);
$variable_node = $variables_node->getChildByName($variable);
// By all accounts this _should_ still exist, but this accounts for the
// case where, say, someone had used !unset on a variable for some reason.
if (isset($variable_node))
$this->runFunctions($nodes[$node_name]);
$type = $nodes[$node_name]->getParent()->getName();
if ($type == 'parameters')
{
$parameter_node = $parameters_node->getChildByName($node_name);
if (isset($parameter_node))
{
$options->setParameter($parameter_node->getName(), Node::toPhp($parameter_node));
}
}
else if ($type == 'variables')
{
$options->setVariable($variable, Node::toPhp($variable_node));
$variable_node = $variables_node->getChildByName($node_name);
if (isset($variable_node))
{
$options->setVariable($variable_node->getName(), Node::toPhp($variable_node));
}
}
}
}
@ -220,7 +249,7 @@ class Compiler implements \App\Engine\ICompile
* @param Node $node
* @return string[]
*/
protected function pass_1_getVariableDependencies(Node $node): array
protected function pass_1_getDependencies(Node $node): array
{
$stack = [$node];
@ -240,10 +269,15 @@ class Compiler implements \App\Engine\ICompile
{
$variables[] = $node->getValue();
}
else if ($node instanceof NodeFunctionValue &&
$node->getName() == 'param')
{
$variables[] = $node->getValue();
}
elseif ($node instanceof NodeFunctionValue &&
$node->getName() == 'expr')
{
$parser = new \App\Engine\Cfnpp\Expression\Parser();
$parser = new \App\Cfnpp\Expression\Parser();
$expression = $parser->parse($node->getValue());
$variables = array_merge($variables, $expression->getReferencedVariables());
}

5
app/Engine/Cfnpp/Expression/Expression.php → app/Cfnpp/Expression/Expression.php

@ -2,7 +2,7 @@
declare(strict_types=1);
namespace App\Engine\Cfnpp\Expression;
namespace App\Cfnpp\Expression;
/**
* Expression that can be evaluated.
@ -158,6 +158,9 @@ class Expression
$var2 = $this->pop();
$this->push($var1 || $var2);
break;
case 'not':
$this->push(!$this->pop());
break;
default:
throw new \Exception('Unhandled comparison operator: '.$token->getOperator());
}

2
app/Engine/Cfnpp/Expression/Parser.php → app/Cfnpp/Expression/Parser.php

@ -2,7 +2,7 @@
declare(strict_types=1);
namespace App\Engine\Cfnpp\Expression;
namespace App\Cfnpp\Expression;
/**
* Parse a string into a series of expression tokens.

2
app/Engine/Cfnpp/Expression/Token.php → app/Cfnpp/Expression/Token.php

@ -2,7 +2,7 @@
declare(strict_types=1);
namespace App\Engine\Cfnpp\Expression;
namespace App\Cfnpp\Expression;
/**
* Token representing a distinct part of an expression.

2
app/Engine/Cfnpp/Expression/TokenFunction.php → app/Cfnpp/Expression/TokenFunction.php

@ -2,7 +2,7 @@
declare(strict_types=1);
namespace App\Engine\Cfnpp\Expression;
namespace App\Cfnpp\Expression;
/**
* Token representing a function.

2
app/Engine/Cfnpp/Expression/TokenNumericLiteral.php → app/Cfnpp/Expression/TokenNumericLiteral.php

@ -2,7 +2,7 @@
declare(strict_types=1);
namespace App\Engine\Cfnpp\Expression;
namespace App\Cfnpp\Expression;
/**
* Token representing a numeric (integer or float) literal.

5
app/Engine/Cfnpp/Expression/TokenOperator.php → app/Cfnpp/Expression/TokenOperator.php

@ -2,7 +2,7 @@
declare(strict_types=1);
namespace App\Engine\Cfnpp\Expression;
namespace App\Cfnpp\Expression;
/**
* Token representing a comparison operator.
@ -23,7 +23,8 @@ class TokenOperator extends Token
'lt',
'lte',
'and',
'or'
'or',
'not'
];
/**

2
app/Engine/Cfnpp/Expression/TokenStringLiteral.php → app/Cfnpp/Expression/TokenStringLiteral.php

@ -2,7 +2,7 @@
declare(strict_types=1);
namespace App\Engine\Cfnpp\Expression;
namespace App\Cfnpp\Expression;
/**
* Token representing a string literal.

2
app/Engine/Cfnpp/Expression/TokenVariable.php → app/Cfnpp/Expression/TokenVariable.php

@ -2,7 +2,7 @@
declare(strict_types=1);
namespace App\Engine\Cfnpp\Expression;
namespace App\Cfnpp\Expression;
/**
* Expression token referencing a variable.

19
app/Engine/Cfnpp/Functions.php → app/Cfnpp/Functions.php

@ -2,7 +2,7 @@
declare(strict_types=1);
namespace App\Engine\Cfnpp;
namespace App\Cfnpp;
use App\Dom\Node;
use App\Dom\NodeValue;
@ -112,6 +112,18 @@ class Functions
return new NodeValue(null, $node->hasName() ? $node->getName() : null, $value);
}
public function f_param(Node $node, NodeFunction $function): ?Node
{
if (!($function instanceof NodeFunctionValue))
{
throw new \Exception('!param requires scalar argument');
}
$node = new Node(null, $node->hasName() ? $node->getName() : null);
$ref = new NodeValue($node, 'Ref', $function->getValue());
$node->addChild($ref);
return $node;
}
/**
* Conditionally include part of the file.
*
@ -137,7 +149,7 @@ class Functions
$if_true = $nodes[1];
$if_false = sizeof($nodes) == 3 ? $nodes[2] : null;
$parser = new \App\Engine\Cfnpp\Expression\Parser();
$parser = new \App\Cfnpp\Expression\Parser();
$expression = $parser->parse($condition->getValue());
$result = $expression->evaluate($this->options->getVariables());
@ -173,7 +185,7 @@ class Functions
throw new \Exception('!if requires scalar argument');
}
$parser = new \App\Engine\Cfnpp\Expression\Parser();
$parser = new \App\Cfnpp\Expression\Parser();
$expression = $parser->parse($function->getValue());
$result = $expression->evaluate($this->options->getVariables());
@ -182,4 +194,5 @@ class Functions
return $result;
}
}

2
app/Engine/Cfnpp/Options.php → app/Cfnpp/Options.php

@ -2,7 +2,7 @@
declare(strict_types=1);
namespace App\Engine\Cfnpp;
namespace App\Cfnpp;
/**
* Options for controlling the Cfnpp compilation process.

4
app/Commands/Stack/Compile.php

@ -39,8 +39,8 @@ class Compile extends Command
$serializer = $this->getSerializer();
$unserializer = $this->getUnserializer();
$engine->setSerializer($serializer)->setUnserializer($unserializer)->setCompiler(new \App\Engine\Cfnpp\Compiler());
$options = new \App\Engine\Cfnpp\Options();
$engine->setSerializer($serializer)->setUnserializer($unserializer)->setCompiler(new \App\Cfnpp\Compiler());
$options = new \App\Cfnpp\Options();
$output = $engine->process($this->argument('in_file'), $options);

Loading…
Cancel
Save