<?php
namespace Tlf\LexerTrait;
/**
* Manages the state of directives, including the different levels of directives and starting/stopping directives.
*/
trait Directives {
/**
* A stack of directives. Each layer of the stack has a 'started', 'unstarted', and 'directives' list.
*/
public $directiveStack = [];
public function newDirectivesLayer(){
$this->directiveStack[] = [
// 'directives'=>[],
'unstarted'=>[],
'started'=>[],
];
}
public function getTopDirectives(){
return $this->topDirectivesList();
}
protected function &topDirectivesList(){
return $this->directiveStack[count($this->directiveStack)-1];
}
/**
*
* @param $directive a previously unstarted directive
*/
public function directiveStarted(object $directive){
$list = &$this->topDirectivesList();
if (!isset($list['unstarted'][$directive->_name])){
$name = $directive->_name;
echo "\n -- '$name' cannot be started because it isn't in unstarted.";
return;
}
$list['started'][$directive->_name] = $directive;
unset($list['unstarted'][$directive->_name]);
}
/**
* Move a directive from started stack to unstarted
*
* @param $directive a directive that was stopped
*/
public function directiveStopped(object $directive){
$list = &$this->topDirectivesList();
if (!isset($list['started'][$directive->_name])){
$name = $directive->_name;
echo "\n -- '$name' cannot be stopped because it isn't started.";
return;
}
$list['unstarted'][$directive->_name] = $directive;
unset($list['started'][$directive->_name]);
}
/**
* Adds a directed to the list of unstarted directives on the top directive list.
* @note If the directive stack is empty, creates a new directive layer
*/
public function addDirective(object $directive, bool $is_started = false){
if (count($this->directiveStack)===0)$this->newDirectivesLayer();
$list = &$this->topDirectivesList();
if ($is_started)$list['started'][$directive->_name] = $directive;
else $list['unstarted'][$directive->_name] = $directive;
}
public function popDirectivesLayer(){
if (count($this->directiveStack)>0){
array_pop($this->directiveStack);
return;
}
throw new \Exception("\n\nThere must be at least one directive layer in order to pop one.\n");
}
}