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); declare(strict_types=1);
namespace App\Engine\Cfnpp; namespace App\Cfnpp;
use App\Dom\Document; use App\Dom\Document;
use App\Dom\Node; use App\Dom\Node;
@ -171,8 +171,8 @@ class Compiler implements \App\Engine\ICompile
} }
/** /**
* Compiler Pass 1 - Grab all variables, build dependency graph of * Compiler Pass 1 - Grab all variables and parameters, build dependency
* dependencies between variable values, resolve variables values. Then * graph of dependencies between values, resolve values. Then
* set them on $options to include them in program state. * set them on $options to include them in program state.
* *
* @param Document $document * @param Document $document
@ -182,32 +182,61 @@ class Compiler implements \App\Engine\ICompile
protected function pass_1(Document $document, IOptions $options): void protected function pass_1(Document $document, IOptions $options): void
{ {
$variables_node = $document->getChildByPath('cfnpp.variables'); $variables_node = $document->getChildByPath('cfnpp.variables');
// If there are no variables, we're done here. $parameters_node = $document->getChildByPath('cfnpp.parameters');
if (!isset($variables_node)) // If there are no variables or parameters, we're done here.
if (!isset($variables_node) && !isset($parameters_node))
{ {
return; return;
} }
$variables_raw = []; $nodes = [];
$graph = new DependencyGraph(); $graph = new DependencyGraph();
foreach ($variables_node as $variable_node) if (isset($parameters_node))
{ {
$variables_raw[$variable_node->getName()] = $variable_node; foreach ($parameters_node as $parameter_node)
$graph->add($variable_node->getName(), $this->pass_1_getVariableDependencies($variable_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]); $this->runFunctions($nodes[$node_name]);
$variable_node = $variables_node->getChildByName($variable);
// By all accounts this _should_ still exist, but this accounts for the $type = $nodes[$node_name]->getParent()->getName();
// case where, say, someone had used !unset on a variable for some reason.
if (isset($variable_node)) 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 * @param Node $node
* @return string[] * @return string[]
*/ */
protected function pass_1_getVariableDependencies(Node $node): array protected function pass_1_getDependencies(Node $node): array
{ {
$stack = [$node]; $stack = [$node];
@ -240,10 +269,15 @@ class Compiler implements \App\Engine\ICompile
{ {
$variables[] = $node->getValue(); $variables[] = $node->getValue();
} }
else if ($node instanceof NodeFunctionValue &&
$node->getName() == 'param')
{
$variables[] = $node->getValue();
}
elseif ($node instanceof NodeFunctionValue && elseif ($node instanceof NodeFunctionValue &&
$node->getName() == 'expr') $node->getName() == 'expr')
{ {
$parser = new \App\Engine\Cfnpp\Expression\Parser(); $parser = new \App\Cfnpp\Expression\Parser();
$expression = $parser->parse($node->getValue()); $expression = $parser->parse($node->getValue());
$variables = array_merge($variables, $expression->getReferencedVariables()); $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); declare(strict_types=1);
namespace App\Engine\Cfnpp\Expression; namespace App\Cfnpp\Expression;
/** /**
* Expression that can be evaluated. * Expression that can be evaluated.
@ -158,6 +158,9 @@ class Expression
$var2 = $this->pop(); $var2 = $this->pop();
$this->push($var1 || $var2); $this->push($var1 || $var2);
break; break;
case 'not':
$this->push(!$this->pop());
break;
default: default:
throw new \Exception('Unhandled comparison operator: '.$token->getOperator()); 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); declare(strict_types=1);
namespace App\Engine\Cfnpp\Expression; namespace App\Cfnpp\Expression;
/** /**
* Parse a string into a series of expression tokens. * 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); declare(strict_types=1);
namespace App\Engine\Cfnpp\Expression; namespace App\Cfnpp\Expression;
/** /**
* Token representing a distinct part of an 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); declare(strict_types=1);
namespace App\Engine\Cfnpp\Expression; namespace App\Cfnpp\Expression;
/** /**
* Token representing a function. * Token representing a function.

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

@ -2,7 +2,7 @@
declare(strict_types=1); declare(strict_types=1);
namespace App\Engine\Cfnpp\Expression; namespace App\Cfnpp\Expression;
/** /**
* Token representing a numeric (integer or float) literal. * 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); declare(strict_types=1);
namespace App\Engine\Cfnpp\Expression; namespace App\Cfnpp\Expression;
/** /**
* Token representing a comparison operator. * Token representing a comparison operator.
@ -23,7 +23,8 @@ class TokenOperator extends Token
'lt', 'lt',
'lte', 'lte',
'and', 'and',
'or' 'or',
'not'
]; ];
/** /**

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

@ -2,7 +2,7 @@
declare(strict_types=1); declare(strict_types=1);
namespace App\Engine\Cfnpp\Expression; namespace App\Cfnpp\Expression;
/** /**
* Token representing a string literal. * 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); declare(strict_types=1);
namespace App\Engine\Cfnpp\Expression; namespace App\Cfnpp\Expression;
/** /**
* Expression token referencing a variable. * Expression token referencing a variable.

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

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

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

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

4
app/Commands/Stack/Compile.php

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

Loading…
Cancel
Save