minrubyコンパイラ / 複文を実行できるようにする
#MinRuby
from MinRubyコンパイラ
以下の対応を行った。
複文をを実行できるようにした
プリント関数(p 関数)を追加(現時点では整数のみ対応)
直前のコードとの差分はこちら。
code:diff
diff --git a/minrubyc.rb b/minrubyc.rb
index f729657..aa7a93c 100644
--- a/minrubyc.rb
+++ b/minrubyc.rb
@@ -38,6 +38,14 @@ def gen(tree)
# スタックを破棄
puts "\tadd sp, sp, #16"
+ elsif tree0 == "func_call" && tree1 == "p"
+ expr = tree2
+ gen(expr)
+ puts "\tbl _p"
+ elsif tree0 == "stmts"
+ tree1...each do |stmt|
+ gen(stmt)
+ end
else
raise "invalid AST: #{tree}"
end
@@ -54,9 +62,6 @@ puts "\tstp fp, lr, sp, #0"
gen(tree)
-# 入力した整数をプリントする
-puts "\tbl _p"
-
puts "\tmov w0, #0"
puts "\tldp fp, lr, sp, #0"
puts "\tadd sp, sp, #16"
diff --git a/test.sh b/test.sh
index 118a8c0..204047b 100755
--- a/test.sh
+++ b/test.sh
@@ -20,12 +20,13 @@ assert() {
fi
}
-assert "305" "(10+20*30)/2"
-assert "5" "30/6"
-assert "72" "8*9"
-assert "20" "30-10"
-assert "30" "10+20"
-assert "-10" "-10"
-assert "4649" "4649"
+assert "10\n20\n" "p 10; p 20"
+assert "305" "p((10+20*30)/2)"
+assert "5" "p 30/6"
+assert "72" "p 8*9"
+assert "20" "p 30-10"
+assert "30" "p 10+20"
+assert "-10" "p(-10)"
+assert "4649" "p 4649"
echo OK
いい感じに動いてそう。
https://gyazo.com/08a17b88730120d481ee5a971c32bf45
全体のコードはこちら。
code:minrubyc.rb
require "minruby"
def gen(tree)
if tree0 == "lit"
puts "\tmov x0, ##{tree1}"
elsif %w(+ - * /).include?(tree0)
op = tree0
expr1 = tree1
expr2 = tree2
# 評価結果一時保持用のスタック領域を確保
puts "\tsub sp, sp, #16"
# 左辺を評価した結果をスタックへ積む
gen(expr1)
puts "\tstr x0, sp, #0"
# 右辺を評価した結果をスタックへ積む
gen(expr2)
puts "\tstr x0, sp, #8"
# 演算
puts "\tldr x1, sp, #8"
puts "\tldr x0, sp, #0"
case op
when "+"
puts "\tadd x0, x0, x1"
when "-"
puts "\tsub x0, x0, x1"
when "*"
puts "\tmul x0, x0, x1"
when "/"
puts "\tsdiv x0, x0, x1"
else
raise "invalid operator: #{op}"
end
# スタックを破棄
puts "\tadd sp, sp, #16"
elsif tree0 == "func_call" && tree1 == "p"
expr = tree2
gen(expr)
puts "\tbl _p"
elsif tree0 == "stmts"
tree1...each do |stmt|
gen(stmt)
end
else
raise "invalid AST: #{tree}"
end
end
tree = minruby_parse(ARGF.read)
puts "\t.text"
puts "\t.align 2"
puts "\t.globl _main"
puts "_main:"
puts "\tsub sp, sp, #16"
puts "\tstp fp, lr, sp, #0"
gen(tree)
puts "\tmov w0, #0"
puts "\tldp fp, lr, sp, #0"
puts "\tadd sp, sp, #16"
puts "\tret"