| 1 | <?php |
| 2 | namespace Std\Lib\Syntax; |
| 3 | |
| 4 | /** |
| 5 | * 「```asm」用の汎用アセンブリ |
| 6 | * 1つの記事でx86-64・AArch64・RISC-V・POWER等を全部「asm」で書く事があるので、 |
| 7 | * 主なアーキテクチャのレジスター・命令をまとめて使う。 |
| 8 | * |
| 9 | * 「#」はコメント(RISC-V・POWER・GAS)、「#数字」は即値(ARM)として扱う。 |
| 10 | */ |
| 11 | class Asm extends Assembly { |
| 12 | protected array $comment = [';', '//', '#']; |
| 13 | protected ?array $multiline = ['/*', '*/']; |
| 14 | protected string $immediatePrefix = ''; |
| 15 | protected bool $percentBinary = false; |
| 16 | protected bool $percentMacros = true; |
| 17 | |
| 18 | protected array $rules = [ |
| 19 | // ARMの即値(#64, #-1, #0x10)はコメントより先に確認する |
| 20 | ['re' => '#[-+]?(?:0[xX][0-9A-Fa-f]+|0[bB][01]+|\d+(?:\.\d+)?)', 'class' => 'number'], |
| 21 | ]; |
| 22 | |
| 23 | /** @var string[] まとめるアーキテクチャ(8ビット機等は単一文字のレジスターが多いので含めない) */ |
| 24 | protected array $archs = [AsmX8664::class, AsmAarch64::class, AsmAarch32::class, AsmRiscv::class, AsmMips::class, AsmPower::class]; |
| 25 | |
| 26 | public function prepare(string $code): void { |
| 27 | $words = []; |
| 28 | $suffixes = []; |
| 29 | $prefixes = []; |
| 30 | foreach ($this->archs as $class) { |
| 31 | $a = new $class(); |
| 32 | $a->prepare(''); |
| 33 | [$w2, $s2, $p2] = $a->getTables(); |
| 34 | foreach ($w2 as $w => $c) { |
| 35 | // 命令の色を優先(「and」等が他のアーキテクチャでキーワードの場合) |
| 36 | if (!isset($words[$w]) || $c === 'instruction') $words[$w] = $c; |
| 37 | } |
| 38 | $suffixes = array_merge($suffixes, $s2); |
| 39 | $prefixes = array_merge($prefixes, $p2); |
| 40 | } |
| 41 | $this->words = $words; |
| 42 | $this->suffixes = array_values(array_unique($suffixes)); |
| 43 | $this->prefixes = array_values(array_unique($prefixes)); |
| 44 | } |
| 45 | } |