-
-
Save SerafimArts/ce7e0ca28b325e4c8794aede4ffd8a74 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Class ExampleVm | |
*/ | |
class ExampleVm | |
{ | |
public const OP_ALLOC = 0x00; | |
public const OP_ADD = 0x01; | |
public const OP_GOTO = 0x02; | |
public const OP_ASSERT = 0x03; | |
public const OP_ASSERT_LTE = 0x04; | |
public const OP_INC = 0x05; | |
public const OP_ECHO = 0x06; | |
public array $symbols = []; | |
public function run(array $program): void | |
{ | |
for ($state = 0, $len = \count($program); $state < $len; ++$state) { | |
[$code, $args] = $program[$state]; | |
switch ($code) { | |
case self::OP_ALLOC: | |
$this->symbols[$args[0]] = $args[1]; | |
break; | |
case self::OP_INC: | |
++$this->symbols[$args[0]]; | |
break; | |
case self::OP_ADD: | |
if (\is_array($this->symbols[$args[0]])) { | |
$this->symbols[$args[0]][] = $this->symbols[$args[1]]; | |
break; | |
} | |
throw new \RuntimeException('Bad type'); | |
case self::OP_GOTO: | |
$state = ($args[0] - 1); | |
break; | |
case self::OP_ASSERT: | |
if (! $this->symbols[$args[0]]) { | |
$state = $args[1]; | |
} | |
break; | |
case self::OP_ASSERT_LTE: | |
if ($this->symbols[$args[0]] > $args[1]) { | |
$state = $args[1]; | |
} | |
break; | |
case self::OP_ECHO: | |
echo $this->symbols[$args[0]]; | |
break; | |
} | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
$vm = new ExampleVm(); | |
$before = \microtime(true); | |
$vm->run([ | |
0 => [ExampleVm::OP_ALLOC, ['a', []]], | |
1 => [ExampleVm::OP_ALLOC, ['i', 0]], | |
2 => [ExampleVm::OP_ASSERT_LTE, ['i', 1000, 99]], | |
3 => [ExampleVm::OP_ADD, ['a', 'i']], | |
4 => [ExampleVm::OP_INC, ['i']], | |
5 => [ExampleVm::OP_GOTO, [2]], | |
6 => [ExampleVm::OP_ECHO, ['i']], | |
]); | |
echo number_format(\microtime(true) - $before, 6) . 's'; | |
// 0.000354s |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment