<commit_before><?php

namespace Htsl\Parser\Node;

use Htsl\Htsl;
use Htsl\ReadingBuffer\Line;
use Htsl\Parser\Node\Contracts\ANode;

////////////////////////////////////////////////////////////////

class ControlNode extends ANode
{
	/**
	 * The name of the htsl control structure.
	 *
	 * @var string
	 */
	private $name;

	/**
	 * The name of the complied control structure.
	 *
	 * @var string
	 */
	private $structureName;

	/**
	 * The param.
	 *
	 * @var string
	 */
	private $param;

	protected function construct():parent
	{
		$name= $this->line->pregGet('/(?<=^~)[\w-]*/');
		$this->name=$name;

		$this->loadConfig($name,$this->htsl);

		$this->param= $this->line->pregGet('/^~[\w-]*\( (.*) \)/',1);

		$this->structureName=$this->config['name']??$name;

		return $this;
	}

	public function open():string
	{
		return $this->withParam($this->config['opener']);
	}

	public function getScope()
	{
		return $this->config['scope']??null;
	}


	public function close( Line$closerLine ):string
	{
		if( !isset($this->config['closer']) )
			{ return ''; }

		if( !is_array($this->config['closer']) )
			{ return $this->withParam($this->config['closer']); }

		foreach( $this->config['closer'] as $key=>$value ){
			if( $closerLine->pregMatch($key) ){
				return $this->withParam($value);
			}
		}
		return '';
	}

	private function withParam( string$input )
	{
		return preg_replace_callback('/(?<!%)%s(\\/.+?(?<!\\\\)\\/)?/',function( array$matches ){
			return ($matches[1]?
				(preg_match($matches[1],$this->param,$m)?
					$m[0]:
					''
				):
				$this->param
			);
		},$input);
	}
}<commit_msg>Add unique id for control node, and you can declare unique flag for each control node with $_FLAG_$<commit_after><?php

namespace Htsl\Parser\Node;

use Htsl\Htsl;
use Htsl\ReadingBuffer\Line;
use Htsl\Parser\Node\Contracts\ANode;

////////////////////////////////////////////////////////////////

class ControlNode extends ANode
{
	/**
	 * The name of the htsl control structure.
	 *
	 * @var string
	 */
	private $name;

	/**
	 * The name of the complied control structure.
	 *
	 * @var string
	 */
	private $structureName;

	/**
	 * The param.
	 *
	 * @var string
	 */
	private $param;

	protected function construct():parent
	{
		$name= $this->line->pregGet('/(?<=^~)[\w-]*/');
		$this->name=$name;

		$this->loadConfig($name,$this->htsl);

		$this->param= $this->line->pregGet('/^~[\w-]*\( (.*) \)/',1);

		$this->structureName=$this->config['name']??$name;

		$this->id=strtoupper(uniqid());

		return $this;
	}

	public function open():string
	{
		return $this->withParam($this->config['opener']);
	}

	public function getScope()
	{
		return $this->config['scope']??null;
	}


	public function close( Line$closerLine ):string
	{
		if( !isset($this->config['closer']) )
			{ return ''; }

		if( !is_array($this->config['closer']) )
			{ return $this->withParam($this->config['closer']); }

		foreach( $this->config['closer'] as $key=>$value ){
			if( $closerLine->pregMatch($key) ){
				return $this->withParam($value);
			}
		}
		return '';
	}

	private function withParam( string$input )
	{
		return str_replace('$_FLAG_$',"__HTSL_CTRL_FLAG_{$this->id}__",preg_replace_callback('/(?<!%)%s(\\/.+?(?<!\\\\)\\/)?/',function( array$matches ){
			return ($matches[1]?
				(preg_match($matches[1],$this->param,$m)?
					$m[0]:
					''
				):
				$this->param
			);
		},$input));
	}
}
{'fraction_non_alphanumeric': 0.2514740566037736, 'fraction_numerical': 0.0023584905660377358, 'mean_word_length': 3.039285714285714, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 51, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '950190', 'n_tokens_mistral': 1356, 'n_tokens_neox': 1190, 'n_words': 214}