yhara.jp

Recent Posts

Rust + LLVM (inkwell)でHello World

2019-06-09
Tech

自作言語の処理系をRustで書いてLLVM IR生成をやろうとしているのですが、とりあえずHello Worldができたのでコードを載せておきます。

準備編は以下です。

Cargo.tomlに以下を追加

[dependencies]
inkwell = { git = "https://github.com/TheDan64/inkwell", branch = "llvm7-0" }
llvm-sys = "70"

LLVMの最新版は8ですが、inkwellの対応版がまだないのでLLVM 7を使います。homebrewの場合はbrew install llvm@7で入ります。

main.rs

use inkwell::context::Context;
use std::error::Error;

fn main() -> Result<(), Box<Error>> {
    let context = Context::create();
    let module = context.create_module("main");
    let builder = context.create_builder();
    let i32_type = context.i32_type();

    // declare i32 @putchar(i32)
    let putchar_type = i32_type.fn_type(&[i32_type.into()], false);
    module.add_function("putchar", putchar_type, None);

    // define i32 @main() {
    let main_type = i32_type.fn_type(&[], false);
    let function = module.add_function("main", main_type, None);
    let basic_block = context.append_basic_block(&function, "entry");
    builder.position_at_end(&basic_block);

    // call i32 @putchar(i32 72)
    let fun = module.get_function("putchar");
    builder.build_call(fun.unwrap(), &[i32_type.const_int(72, false).into()], "putchar");
    builder.build_call(fun.unwrap(), &[i32_type.const_int(105, false).into()], "putchar");

    // ret i32 0
    builder.build_return(Some(&i32_type.const_int(0, false)));

    module.print_to_stderr();

    Ok(())
}

出力

cargo runするとこんな感じでLLVM IRが出ます。

; ModuleID = 'main'
source_filename = "main"

declare i32 @putchar(i32)

define i32 @main() {
entry:
  %putchar = call i32 @putchar(i32 72)
  %putchar1 = call i32 @putchar(i32 105)
  ret i32 0
}

これをa.llとして保存→lli a.llで、画面に「Hi」と出たら成功です。「Hi」は、「Hello, world!」と出すのは文字数が多すぎて面倒なとき用の簡略版Hello Worldです。

More posts

Posts

(more...)

Articles

(more...)

Category

Ads

About

About the author