75 lines
1.7 KiB
PHP
75 lines
1.7 KiB
PHP
<?php
|
|
|
|
namespace Automata;
|
|
|
|
use Automata\Storage\ProgramMemory;
|
|
use Automata\Storage\ToolMemory;
|
|
use Program\Program;
|
|
use Program\Word;
|
|
use RuntimeException;
|
|
use SplStack;
|
|
|
|
class Machine
|
|
{
|
|
public State $state;
|
|
public ToolMemory $toolMemory;
|
|
public ProgramMemory $subProgramMemory;
|
|
public ProgramMemory $partProgramMemory;
|
|
/** @var SplStack|Program[] */
|
|
private SplStack $programStack;
|
|
private ?Program $activeProgram = null;
|
|
private Definitions $definitions;
|
|
|
|
|
|
public function __construct()
|
|
{
|
|
$this->state = new State();
|
|
$this->definitions = new Definitions();
|
|
$this->toolMemory = new ToolMemory();
|
|
$this->subProgramMemory = new ProgramMemory();
|
|
$this->partProgramMemory = new ProgramMemory();
|
|
$this->programStack = new SplStack();
|
|
}
|
|
|
|
|
|
public function loadProgram(int $N): void
|
|
{
|
|
$this->programStack = new SplStack();
|
|
$program = $this->partProgramMemory->read($N);
|
|
$this->programStack->push($program);
|
|
}
|
|
|
|
|
|
public function start(): void
|
|
{
|
|
$this->activeProgram = $this->programStack->pop();
|
|
if (is_null($this->activeProgram)) {
|
|
throw new RuntimeException('No program loaded');
|
|
}
|
|
foreach ($this->activeProgram as $block) {
|
|
// Do we apply a block or a word?
|
|
// Answer: depends! Some commands need
|
|
// more information from other words.
|
|
// TODO: Interpret commands such as preparation of a work cycle
|
|
|
|
$words = array_map(fn(Word $w) => $w->toString(), $block->words);
|
|
$words = implode("\t", $words);
|
|
$words = "N{$block->N}\t$words";
|
|
|
|
foreach ($block->words as $word) {
|
|
$this->state->apply($word);
|
|
system('clear');
|
|
print("\n $words\n\n");
|
|
dump($this->state);
|
|
readline();
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
public function reset(): void
|
|
{
|
|
$this->activeProgram = null;
|
|
}
|
|
}
|