トップ «前の日記(2014-09-12 (Fri)) 最新 次の日記(2015-01-02 (Fri))» 編集

uDiary

海野秀之(うんのひでゆき)の外部記憶

Twitter (twilog) / RSS / アンテナ / ぶくま

2006|07|08|09|10|11|12|
2007|01|02|03|04|05|06|07|08|09|10|11|12|
2008|01|02|03|04|05|06|07|08|09|10|11|12|
2009|01|02|03|04|05|06|08|
2010|01|02|03|05|06|07|10|11|
2011|03|08|
2012|02|04|07|08|10|
2013|01|02|03|05|06|08|11|12|
2014|01|02|05|06|07|08|09|12|
2015|01|02|03|04|

2014-12-31 (Wed)

[Tiger][Haskell] Tiger Compiler を動かしてみる(一部人手)

そろそろ出来てきたので、というか、今年中に動かすのが目標だったので、ちょっと無理やりにでも動かしてみることにする。

Tiger 言語から Dalvik アセンブリ言語へのコンパイラはほぼできていて、Dalvik アセンブリ言語から APK ファイルをつくるあたりもだいたいできているので、ちょっと手を加えてやれば、動かしてみることができるはず、なのだ。

えーと、なにが未だかというと、レジスタ割付けがまだなので(まだ Tiger Book は10章途中なの)、今回は、そこだけ人手で。

(1) Hello, World!

Tiger 言語のソースはこちら:

print("Hello, world!")

これを、現状のコンパイラでコンパイルした結果がこちら:

.class public Luhideyuki/daat/DaatProg;
.super Ljava/lang/Object;

.method public constructor <init>()V
    .registers 1
    invoke-direct {p0}, Ljava/lang/Object;-><init>()V
    return-void
.end method


---- prog ----
:L1
const-string t4, "Hello, world!"
move-object v0, t4
invoke-static {v0}, Luhideyuki/daat/DaatRuntime;->print(Ljava/lang/String;)Ljava/lang/Integer;
move-result-object t5
const t7, 0
new-instance t6, Ljava/lang/Integer;
invoke-direct {t6, t7}, Ljava/lang/Integer;-><init>(I)V
return-object t6
goto :L0
:L0

まだ、関数の prologue (宣言部分とか) が出力されていなかったり、レジスタ番号が仮のまま(t4, t5 とかは一時変数の番号そのまま)です。そこで、今回は人手で少し手を加えてあげます:

.class public Luhideyuki/daat/DaatProg;
.super Ljava/lang/Object;

.method public constructor <init>()V
    .registers 1
    invoke-direct {p0}, Ljava/lang/Object;-><init>()V
    return-void
.end method


.method public static main([Ljava/lang/Object;Ljava/lang/Integer;)Ljava/lang/Integer;
    .locals 5

:L1
const-string v1, "Hello, world!"
move-object v0, v1
invoke-static {v0}, Luhideyuki/daat/DaatRuntime;->print(Ljava/lang/String;)Ljava/lang/Integer;
move-result-object v2

const v4, 0
new-instance v3, Ljava/lang/Integer;
invoke-direct {v3, v4}, Ljava/lang/Integer;-><init>(I)V
return-object v3
#goto :L0
#:L0

.end method

これを、別途用意したランタイム関数といっしょに assembly, apk builder etc. にかけて…

できました!:

Helo

(2) for 文で5回実行

Hello, world! だけではナンなので、もうちょっとだけプログラムっぽいのもやってみる。
これ:

for i := 1 to 5 do print("Hello! ")

これを、現状のコンパイラにかけたのがこれで、

.class public Luhideyuki/daat/DaatProg;
.super Ljava/lang/Object;

.method public constructor <init>()V
    .registers 1
    invoke-direct {p0}, Ljava/lang/Object;-><init>()V
    return-void
.end method


---- prog ----
:L4
const t7, 1
new-instance t6, Ljava/lang/Integer;
invoke-direct {t6, t7}, Ljava/lang/Integer;-><init>(I)V
move-object t4, t6
const t9, 5
new-instance t8, Ljava/lang/Integer;
invoke-direct {t8, t9}, Ljava/lang/Integer;-><init>(I)V
move-object t5, t8
:L1
check-cast t4, L/java/lang/Integer;
invoke-virtual {t4}, Ljava/lang/Integer;->intValue()I
move-result t10
check-cast t5, L/java/lang/Integer;
invoke-virtual {t5}, Ljava/lang/Integer;->intValue()I
move-result t11
if-le t10, t11, :L2
const t13, 0
new-instance t12, Ljava/lang/Integer;
invoke-direct {t12, t13}, Ljava/lang/Integer;-><init>(I)V
return-object t12
goto :L3
:L2
const-string t14, "Hello! "
move-object v0, t14
invoke-static {v0}, Luhideyuki/daat/DaatRuntime;->print(Ljava/lang/String;)Ljava/lang/Integer;
move-result-object t15
const t17, 1
new-instance t16, Ljava/lang/Integer;
invoke-direct {t16, t17}, Ljava/lang/Integer;-><init>(I)V
check-cast t4, Ljava/lang/Integer;
check-cast t16, Ljava/lang/Integer;
invoke-virtual {t4}, Ljava/lang/Integer;->intValue()I
move-result t19
invoke-virtual {t16}, Ljava/lang/Integer;->intValue()I
move-result t20
add-int t19, t19, t20
new-instance t18, Ljava/lang/Integer;
invoke-direct {t18, t19, Ljava/lang/Integer;-><init>(I)V
move-object t4, t18
goto :L1
:L3

手作業でレジスタ割付けなど少し手をくわえたのがこれ:

.class public Luhideyuki/daat/DaatProg;
.super Ljava/lang/Object;

.method public constructor <init>()V
    .registers 1
    invoke-direct {p0}, Ljava/lang/Object;-><init>()V
    return-void
.end method


.method public static main([Ljava/lang/Object;Ljava/lang/Integer;)Ljava/lang/Integer;
    .locals 21

:L4
const v7, 1
new-instance v6, Ljava/lang/Integer;
invoke-direct {v6, v7}, Ljava/lang/Integer;-><init>(I)V
move-object v4, v6
const v9, 5
new-instance v8, Ljava/lang/Integer;
invoke-direct {v8, v9}, Ljava/lang/Integer;-><init>(I)V
move-object v5, v8
:L1
check-cast v4, Ljava/lang/Integer;
invoke-virtual {v4}, Ljava/lang/Integer;->intValue()I
move-result v10
check-cast v5, Ljava/lang/Integer;
invoke-virtual {v5}, Ljava/lang/Integer;->intValue()I
move-result v11
if-le v10, v11, :L2
const v13, 0
new-instance v12, Ljava/lang/Integer;
invoke-direct {v12, v13}, Ljava/lang/Integer;-><init>(I)V
return-object v12
#goto :L3
:L2
const-string v14, "Hello! "
move-object v0, v14
invoke-static {v0}, Luhideyuki/daat/DaatRuntime;->print(Ljava/lang/String;)Ljava/lang/Integer;
move-result-object v15
const v7, 1
new-instance v6, Ljava/lang/Integer;
invoke-direct {v6, v7}, Ljava/lang/Integer;-><init>(I)V
check-cast v4, Ljava/lang/Integer;
check-cast v6, Ljava/lang/Integer;
invoke-virtual {v4}, Ljava/lang/Integer;->intValue()I
move-result v9
invoke-virtual {v6}, Ljava/lang/Integer;->intValue()I
move-result v2
add-int v9, v9, v2
new-instance v8, Ljava/lang/Integer;
invoke-direct {v8, v9}, Ljava/lang/Integer;-><init>(I)V
move-object v4, v8
goto :L1
#:L3

.end method

そして、実行結果がこちら:

Helo5

もうすこし複雑なプログラムを試すのは、レジスタ割付けを実装してからにしよう。

い、いちおう、今年中に動かした…かな?

https://github.com/unnohideyuki/Tiger-in-Haskell


2006|07|08|09|10|11|12|
2007|01|02|03|04|05|06|07|08|09|10|11|12|
2008|01|02|03|04|05|06|07|08|09|10|11|12|
2009|01|02|03|04|05|06|08|
2010|01|02|03|05|06|07|10|11|
2011|03|08|
2012|02|04|07|08|10|
2013|01|02|03|05|06|08|11|12|
2014|01|02|05|06|07|08|09|12|
2015|01|02|03|04|
Categories 3imp | Card | Cutter | Dalvik | Euler | Football | GAE/J | Hand | Haskell | Re:View | Ruby | Scheme | TQD | Tiger | TigerBook読 | UikiTeXi | Verilog | Violin | Web | parconc | tDiary | お勉強 | エントロピー | ツン読 | | 将棋 | 政治について | | 模写してみよう | 確率論 | 設定など | 雑文 | 音声