MinCamlの中間コード出力方法まとめ
アセンブリコードの出力
min-caml.top を起動して(rlwrap はつけてもつけなくてもお好みで)
code:sh
$ rlwrap ./min-caml.top
以下のコードを実行
code:ml
let src = "let rec f x y = x + y in print_int (f 10 20)" in Emit.f stdout (RegAlloc.f (Simm.f (Virtual.f (Closure.f (Alpha.f (KNormal.f (Typing.f (Parser.exp Lexer.token (Lexing.from_string src)))))))));;
以下のようにアセンブリコードが出力される
code:ml
# let src = "let x = 4649 in print_int x" in Emit.f stdout (RegAlloc.f (Simm.f (Virtual.f (Closure.f (Alpha.f (KNormal.f (Typing.f (Parser.exp Lexer.token (Lexing.from_string src)))))))));;
free variable print_int assumed as external
register allocation: may take some time (up to a few minutes, depending on the size of functions)
generating assembly...
.text
.globl _min_caml_start
.align 2
_min_caml_start: # main entry point
# main program starts
mov x0, 4649
bl _min_caml_print_int
# main program ends
ret
ファイルを指定する方法もある。
code:ml
let ic = open_in "test/float.ml" in
let b = Buffer.create 0 in
let src = (Buffer.add_channel b ic (in_channel_length ic); Buffer.contents b) in
(Alpha.f (KNormal.f (Typing.f (Parser.exp Lexer.token (Lexing.from_string src)))));;
ワンライナ
code:ml
let ic = open_in "test/float.ml" in let b = Buffer.create 0 in let src = (Buffer.add_channel b ic (in_channel_length ic); Buffer.contents b) in (RegAlloc.f (Simm.f (Virtual.f (Closure.f (Alpha.f (KNormal.f (Typing.f (Parser.exp Lexer.token (Lexing.from_string src)))))))));;
仮想マシンコードの出力
code:ml
let src = "let x = 4649 in print_int x" in (RegAlloc.f (Simm.f (Virtual.f (Closure.f (Alpha.f (KNormal.f (Typing.f (Parser.exp Lexer.token (Lexing.from_string src)))))))));;
code:ml
# let src = "let x = 4649 in print_int x" in (RegAlloc.f (Simm.f (Virtual.f (Closure.f (Alpha.f (KNormal.f (Typing.f (Parser.exp Lexer.token (Lexing.from_string src)))))))));;
free variable print_int assumed as external
register allocation: may take some time (up to a few minutes, depending on the size of functions)
- : Asm.prog =
Asm.Prog ([], [],
Asm.Let (("%x0", Type.Int), Asm.Li 4649,
Asm.Ans (Asm.CallDir (Id.L "_min_caml_print_int", "%x0", [])))) #
クロージャ変換後の中間コード
code:ml
let src = "let x = 4649 in print_int x" in (Closure.f (Alpha.f (KNormal.f (Typing.f (Parser.exp Lexer.token (Lexing.from_string src))))));;
code:ml
# let src = "let x = 4649 in print_int x" in (Closure.f (Alpha.f (KNormal.f (Typing.f (Parser.exp Lexer.token (Lexing.from_string src))))));;
free variable print_int assumed as external
- : Closure.prog =
Closure.Prog ([],
Closure.Let (("x.25", Type.Int), Closure.Int 4649,
Closure.AppDir (Id.L "_min_caml_print_int", "x.25"))) K正規形
code:ml
let src = "let x = 4649 in print_int x" in (Alpha.f (KNormal.f (Typing.f (Parser.exp Lexer.token (Lexing.from_string src)))));;
code:ml
# let src = "let x = 4649 in print_int x" in (Alpha.f (KNormal.f (Typing.f (Parser.exp Lexer.token (Lexing.from_string src)))));;
free variable print_int assumed as external
- : KNormal.t =
KNormal.Let (("x.26", Type.Int), KNormal.Int 4649,
KNormal.ExtFunApp ("print_int", "x.26"))