- 目次ページに戻る / 前 / 次
- 前回からの差分:
https://github.com/sonota88/vm2gol-v2/compare/02...03
プログラムといえばループ! ですね(※1)。
ループをやりましょうということで、 jump
命令を追加して
regチカをやりましょう。
(※1 ……と書いてはいますが、実際は「次に簡単そうなのは何かな?」と考えて 何をやるのかを決めていました。 スモールステップでやっていきます。 )
regチカ(れぐちか)というのは今勝手に作った言葉で、 電子工作の Lチカのように、 レジスタの値を 0 にしたり 1 にしたりして チカチカするのを愛でるというものです。
BASIC風に書くとこんな感じでしょうか。
10 reg_a に 1 をセット 20 reg_a に 0 をセット 30 GOTO 10
これならすぐできそう。VM の case 式に jump
を追加して、
--- a/vgvm.rb +++ b/vgvm.rb @@ -30,6 +30,9 @@ class Vm n = @mem[@pc + 1] @reg_a = n @pc += 2 + when "jump" + addr = @mem[@pc + 1] + @pc = addr else raise "Unknown operator (#{op})" end
プログラム(@mem
の中身)を書き換えます。
--- a/vgvm.rb +++ b/vgvm.rb @@ -12,8 +12,10 @@ class Vm @reg_c = 0 @mem = [ + # ★1 "set_reg_a", 1, "set_reg_a", 0, + "jump", 0, # ★1 に戻る "exit" ] end
一番最初の set_reg_a
のアドレスが 0 なので、
0 にジャンプします。
これを動かすと……
$ ruby vgvm.rb #<Vm:0x005609a6b609d0 @mem=["set_reg_a", 1, "set_reg_a", 0, "jump", 0, "exit"], @pc=0, @reg_a=0, @reg_b=0, @reg_c=0> #<Vm:0x005609a6b609d0 @mem=["set_reg_a", 1, "set_reg_a", 0, "jump", 0, "exit"], @pc=2, @reg_a=1, @reg_b=0, @reg_c=0> #<Vm:0x005609a6b609d0 @mem=["set_reg_a", 1, "set_reg_a", 0, "jump", 0, "exit"], @pc=4, @reg_a=0, @reg_b=0, @reg_c=0> #<Vm:0x005609a6b609d0 @mem=["set_reg_a", 1, "set_reg_a", 0, "jump", 0, "exit"], @pc=0, @reg_a=0, @reg_b=0, @reg_c=0> #<Vm:0x005609a6b609d0 @mem=["set_reg_a", 1, "set_reg_a", 0, "jump", 0, "exit"], @pc=2, @reg_a=1, @reg_b=0, @reg_c=0> #<Vm:0x005609a6b609d0 @mem=["set_reg_a", 1, "set_reg_a", 0, "jump", 0, "exit"], @pc=4, @reg_a=0, @reg_b=0, @reg_c=0> #<Vm:0x005609a6b609d0 @mem=["set_reg_a", 1, "set_reg_a", 0, "jump", 0, "exit"], @pc=0, @reg_a=0, @reg_b=0, @reg_c=0> #<Vm:0x005609a6b609d0 @mem=["set_reg_a", 1, "set_reg_a", 0, "jump", 0, "exit"], @pc=2, @reg_a=1, @reg_b=0, @reg_c=0> (続く)
@reg_a=1
になったり @reg_a=0
になったりしてますね!
jump
命令で1ステップ使うので3拍子になっていますが。
ものすごく原始的なプログラムでものすごく原始的なループが動きました。 すばらしい……(しばしターミナルを眺めて愛でる)。