2
2

More than 3 years have passed since last update.

CrystalでLLVMを扱ってみる (1)

Last updated at Posted at 2020-05-15

こんにちわみなさん!
スクリプトとコンパイルが両方そなわり最強に見えるCrystalやってますか?!

Crystal

CrystalはRubyみたいなのに、Cレベルに低水準な操作ができるというなんつーか最強と言うしかない言語です!
CrystalにはLLVMが使われていますが、セルフホスティングするためか標準でLLVMバインディングがついています。
これは使うっきゃないでしょって感じなので早速使ってみましょう!

Ex1 和を出力する

コード

add.cr
require "llvm"

ctx = LLVM::Context.new
mod = ctx.new_module "examples"

# add(a, b : int32) : int32
func = mod.functions.add("add", [ctx.int32, ctx.int32], ctx.int32)
func.basic_blocks.append do |builder|
  params = func.params
  sum = builder.add params.unsafe_fetch(0), params.unsafe_fetch(1)
  builder.ret sum
end

# output ll
puts mod.to_s

ctx.finalize
出力
; ModuleID = 'examples'
source_filename = "examples"

define i32 @add(i32, i32) {
  %3 = add i32 %0, %1
  ret i32 %3
}

解説

それでは解説します!

require "llvm"

ctx = LLVM::Context.new
mod = ctx.new_module "examples"

↑おまじないです!(迫真)
多分moduleはコリジョンドメインのことだと思いますよ(???)!

func = mod.functions.add("add", [ctx.int32, ctx.int32], ctx.int32)

関数を作ってます!第2引数は引数の型、第3引数は返り値の型ですよ。

  sum = builder.add params.unsafe_fetch(0), params.unsafe_fetch(1)

引数同士の和を計算してます!params.unsafe_fetch(n)n番目の引数を取得するメソッドです!!

  builder.ret sum

計算した和を返してます!簡単ですね!

puts mod.to_s

LLVMのコードに変換して出力してます!そのまんまですね!!
ファイルに出力するときは↓みたいにするといいみたいです!!!

begin
  mod.print_to_file("add.ll")
rescue
  puts "ファイルに出力できない!"
end
ctx.finalize

忘れないようにしましょう!moduleの方も自動でdisposeしてくれます!

おわり

終わりです!次回をお楽しみに!

追伸

参考にしたのはこのページです!
https://8128.jp/notebooks/llvm-c-api
書くの忘れてましたごめんなさい!許してくださいなんでもしますから!

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2