minrubyコンパイラ / 四則演算の結果を画面へプリントする
#MinRuby
from MinRubyコンパイラ
minrubyコンパイラで四則演算を計算できるようにした。
arg1とarg2の評価結果をどう持ち回ろうか悩んでたんだけど、x0 レジスタに格納されるリテラルや四則演算の評価結果を、呼び出し側で必要に応じてスタックへ格納するようにしてみた。
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"
# x0 へ格納された左辺評価結果をスタックへ積む
gen(expr1)
puts "\tstr x0, sp, #0"
# x0 へ格納された右辺評価結果をスタックへ積む
gen(expr2)
puts "\tstr x0, sp, #8"
# スタックへ積んだ評価結果を x1 レジスタと x0 レジスタへロード
puts "\tldr x1, sp, #8"
puts "\tldr x0, sp, #0"
# 演算結果を x0 へ格納
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"
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 "\tbl _p"
puts "\tmov w0, #0"
puts "\tldp fp, lr, sp, #0"
puts "\tadd sp, sp, #16"
puts "\tret"
いい感じに動いてるみたい。
https://gyazo.com/9de3376f283e5073cd031c5646d50f32