<?php
namespace Tlf\Lexer2\StdLib;
/**
* An interface for programs to interact with the AST on the top of the ast stack.
*/
class Buffer {
public \Tlf\Lexer2\Buffer $stored_buffer;
public function __construct(
protected \Tlf\Lexer2\Program $program,
protected \Tlf\Lexer2\Buffer $buffer,
){
}
/**
* Stop execution if the current buffer does not end with $text
*/
public function ends_with(string $text): bool {
if ($this->buffer->ends_with($text))return true;
$this->program->execute_commands = false;
return false;
}
/**
* Clears the buffer. Does not change any other state.
*/
public function clear() {
$this->buffer->clearBuffer();
}
/**
* Prepend one or more spaces to the left side of the current buffer
*/
public function padLeft(int $num_spaces = 1) {
$this->buffer->prepend(str_repeat(" ", $num_spaces));
}
/**
* Remove characters from the left of the buffer
*/
public function removeLeft(int $num_chars_to_remove = 1){
$this->buffer->removeLeft($num_chars_to_remove);
}
/**
* If the current buffer does not match the $string_or_pattern, stop execution of the current instruction set.
* Sets local variables from each match
*
* @param $string_or_pattern a string or regex pattern. Any string starting and ending with `/` will be treated as regex.
*
* @return bool whether the current buffer matches or not
*/
public function match(string $string_or_pattern): bool {
//echo "\nbuffer.match $string_or_pattern";
//echo "\n CurBuffer: '".$this->buffer->buffer()."'";
if ($string_or_pattern[0] == '/'
&& $string_or_pattern[-1] == '/'){
$does_match = preg_match($string_or_pattern, $this->buffer->buffer(), $matches);
} else {
$does_match = $this->buffer->buffer() == $string_or_pattern;
if ($does_match) $matches = [$string_or_pattern];
}
if (!$does_match){
$this->program->execute_commands = false;
return false;
}
foreach ($matches as $index=>$match){
$this->program->set_local_var($index, $match);
}
return true;
}
/**
* Move the buffer forward by $num_chars
*
*/
public function next(int $num_chars = 1){
$this->buffer->forward($num_chars);
}
/**
* Remove characters from the right-most end of the Buffer.
*
*/
public function rewind(int $num_chars = 1){
$this->buffer->rewind($num_chars);
}
/**
* Store the buffer's current state. The next call to reset() will restore that state.
* State is automatically stored before running each instruction set.
*/
public function store_state(){
$this->stored_buffer = clone $this->buffer;
}
/**
* Reset the buffer to the stored state.
* State is automatically stored before each instruction set is run.
* State can be manually stored by calling buffer.store_state
*/
public function reset(){
$this->buffer = $this->stored_buffer;
$this->program->objects['lexer']->buffer = $this->buffer;
//$this->program->setObject('buffer', $this->buffer);
}
}