vm2gol v2 (63) sub_sp 命令を廃止 / panic



sub_sp 命令を廃止

VM命令 sub_sp を廃止しました。 オペランドを負の値にすれば add_sp で代用できるので。 これで VM のコードが5行減って、実装の量の面でも、仕様の面でも、またちょっとコンパクトになりました。

VM命令がいっぱいあると、入門者視点では「えー、こんなにいっぱい覚えないといけないの……」となりそうなので、少ない数で済ませられるならその方がいいかなと。

ちなみに sub_sp を使っているのは変数宣言のときだけ。

--- a/vgcodegen.rb
+++ b/vgcodegen.rb
@@ -290,7 +290,7 @@ def gen_stmts(fn_arg_names, lvar_names, stmts)
 end
 
 def gen_var(fn_arg_names, lvar_names, stmt)
-  puts "  sub_sp 1"
+  puts "  add_sp -1"
 
   if stmt.size == 3
     _, dest, expr = stmt

panic

たとえばコンパイラが完成するまでのこういう状態だったら、

# 例: vgcodegen.rb: _gen_expr_binary

  case operator
  when "+"  then _gen_expr_add()
  else
    raise not_yet_impl("operator", operator)
  end

"not yet implemented" というメッセージも間違いではありませんでした。 まだ + 演算子しか実装していないが、これから *== などの場合の処理も実装していく予定である、という表明になっています(そのつもり)。

しかし、今は完成してだいぶ落ち着いている状況であり、 新たな演算子を追加する予定は今のところありません。

  case operator
  when "+"  then _gen_expr_add()
  when "*"  then _gen_expr_mult()
  when "==" then _gen_expr_eq()
  when "!=" then _gen_expr_neq()
  else
    raise not_yet_impl("operator", operator)
  end

こうなってくると、 "not yet implemented" というメッセージと実装者(私)の意図とのずれが気になってきます。

というわけで、 not_yet_impl を使っていた箇所は一律で panic に置き換えました。

あわせて、パーサで使っていた ParseError クラスをなくしました。

その他


sub_sp をなくしたのでサイズはちょっと減りました。

$ wc -l vg*.rb common.rb
   66 vgasm.rb
  375 vgcodegen.rb
   57 vglexer.rb
  368 vgparser.rb
  442 vgvm.rb
   52 common.rb
 1360 合計

  # コメントを除いたサイズ:
$ cat vg*.rb common.rb | grep -v '^ *#' | wc -l
1324