Try   HackMD

Compiler 作業三 Java Assembly Code

作業描述

我把作業三 input 的 C++ 全部轉成 Java Assembly Code 了

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

需要的自行取用 ~

會做這個的原因是因為 ChatGPT 有時候會搞事, javac Main.java && javap -c -v Main 會 optimize 過再加上有點難看懂。

所以就想說把我寫完的 + ChatGPT + javac Main.java && javap -c -v Main 三方生成的 Assembly code 拿來參考完之後融合成適合的版本。

不一定要照著我的版本寫,只要你的 Assembly Code 有辦法輸出正確的測資就行了。

如果哪裡有錯可以直接跟我說

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

Assembly Code 的註解長這樣 :

; 這行是註解

subtask01-helloworld

testcase01

.class public Main
.super java/lang/Object
.method public static main([Ljava/lang/String;)V
.limit stack 100
.limit locals 100

getstatic java/lang/System/out Ljava/io/PrintStream;
ldc "Hello World"
invokevirtual java/io/PrintStream/println(Ljava/lang/String;)V

return
.end method

.class public Main
.super java/lang/Object
.method public static main([Ljava/lang/String;)V
.limit stack 100
.limit locals 100

getstatic java/lang/System/out Ljava/io/PrintStream;
ldc "Hello World"
invokevirtual java/io/PrintStream/print(Ljava/lang/String;)V

getstatic java/lang/System/out Ljava/io/PrintStream;
invokevirtual java/io/PrintStream/println()V

return
.end method

第一種寫法 :
我輸出完 "Hello World" 之後還要輸出 endl (要換行)。
所以輸出 "Hello World" 的 Assembly Code 就要改成 println

第二種寫法 :
我要輸出什麼就呼叫一次 getstatic java/lang/System/out Ljava/io/PrintStream; 然後輸出什麼。
我要輸出 "Hello World" 就呼叫一次,要輸出 endl 就呼叫一次。

第一種寫法看起來像是第二種寫法的優化版本,但是我不管優化只要最後輸出的結果是對的就行了,再加上第二種寫法感覺比較好寫,所以我基本上全部的 subtask 都是用第二種寫法在處裡輸出。

testcase04

.class public Main
.super java/lang/Object
.method public static main([Ljava/lang/String;)V
.limit stack 100
.limit locals 100

getstatic java/lang/System/out Ljava/io/PrintStream;
ldc "Hello "
invokevirtual java/io/PrintStream/print(Ljava/lang/String;)V

getstatic java/lang/System/out Ljava/io/PrintStream;
ldc "World"
invokevirtual java/io/PrintStream/print(Ljava/lang/String;)V

getstatic java/lang/System/out Ljava/io/PrintStream;
invokevirtual java/io/PrintStream/println()V

return
.end method

subtask02-comment

testcase01

.class public Main
.super java/lang/Object
.method public static main([Ljava/lang/String;)V
.limit stack 100
.limit locals 100

getstatic java/lang/System/out Ljava/io/PrintStream;
bipush 72
invokevirtual java/io/PrintStream/print(C)V

getstatic java/lang/System/out Ljava/io/PrintStream;
bipush 101
invokevirtual java/io/PrintStream/print(C)V

getstatic java/lang/System/out Ljava/io/PrintStream;
bipush 108
invokevirtual java/io/PrintStream/print(C)V

getstatic java/lang/System/out Ljava/io/PrintStream;
bipush 108
invokevirtual java/io/PrintStream/print(C)V

getstatic java/lang/System/out Ljava/io/PrintStream;
bipush 111
invokevirtual java/io/PrintStream/print(C)V

getstatic java/lang/System/out Ljava/io/PrintStream;
bipush 32
invokevirtual java/io/PrintStream/print(C)V

getstatic java/lang/System/out Ljava/io/PrintStream;
bipush 119
invokevirtual java/io/PrintStream/print(C)V

getstatic java/lang/System/out Ljava/io/PrintStream;
bipush 111
invokevirtual java/io/PrintStream/print(C)V

getstatic java/lang/System/out Ljava/io/PrintStream;
bipush 114
invokevirtual java/io/PrintStream/print(C)V

getstatic java/lang/System/out Ljava/io/PrintStream;
bipush 108
invokevirtual java/io/PrintStream/print(C)V

getstatic java/lang/System/out Ljava/io/PrintStream;
bipush 100
invokevirtual java/io/PrintStream/print(C)V

getstatic java/lang/System/out Ljava/io/PrintStream;
bipush 33
invokevirtual java/io/PrintStream/print(C)V

getstatic java/lang/System/out Ljava/io/PrintStream;
invokevirtual java/io/PrintStream/println()V

return
.end method

testcase02

.class public Main
.super java/lang/Object
.method public static main([Ljava/lang/String;)V
.limit stack 100
.limit locals 100

getstatic java/lang/System/out Ljava/io/PrintStream;
ldc "Hell"
invokevirtual java/io/PrintStream/print(Ljava/lang/String;)V

getstatic java/lang/System/out Ljava/io/PrintStream;
bipush 111
invokevirtual java/io/PrintStream/print(C)V

getstatic java/lang/System/out Ljava/io/PrintStream;
ldc " w"
invokevirtual java/io/PrintStream/print(Ljava/lang/String;)V

getstatic java/lang/System/out Ljava/io/PrintStream;
ldc "o"
invokevirtual java/io/PrintStream/print(Ljava/lang/String;)V

getstatic java/lang/System/out Ljava/io/PrintStream;
ldc "rld"
invokevirtual java/io/PrintStream/print(Ljava/lang/String;)V

getstatic java/lang/System/out Ljava/io/PrintStream;
invokevirtual java/io/PrintStream/println()V

return
.end method

testcase03

.class public Main
.super java/lang/Object
.method public static main([Ljava/lang/String;)V
.limit stack 100
.limit locals 100

getstatic java/lang/System/out Ljava/io/PrintStream;
ldc "Hello World!"
invokevirtual java/io/PrintStream/print(Ljava/lang/String;)V

return
.end method

subtask03-precedenc

testcase01

.class public Main
.super java/lang/Object
.method public static main([Ljava/lang/String;)V
.limit stack 100
.limit locals 100

;( 3 - 4 * (5 + -8) - 10 / 7)
getstatic java/lang/System/out Ljava/io/PrintStream;
ldc 3
ldc 4
ldc 5
ldc 8
ineg
iadd
imul
isub
ldc 10
ldc 7
idiv
isub
invokevirtual java/io/PrintStream/print(I)V
getstatic java/lang/System/out Ljava/io/PrintStream;
invokevirtual java/io/PrintStream/println()V

;( 3 - 4 * (5 + -8) - 10 / 7 > -4 % 3 || !true && !!false)
getstatic java/lang/System/out Ljava/io/PrintStream;
ldc 3
ldc 4
ldc 5
ldc 8
ineg
iadd
imul
isub
ldc 10
ldc 7
idiv
isub
ldc 4
ineg
ldc 3
irem
if_icmpgt greaterThanLabel0
iconst_0
goto endLabel0
greaterThanLabel0:
iconst_1
endLabel0:
iconst_1
iconst_1
ixor
iconst_0
iconst_1
ixor
iconst_1
ixor
iand
ior
invokevirtual java/io/PrintStream/print(Z)V
getstatic java/lang/System/out Ljava/io/PrintStream;
invokevirtual java/io/PrintStream/println()V

;( 3.0 - 4.0 * (5.0 + -8.0) - 10.0 / 7.0)
getstatic java/lang/System/out Ljava/io/PrintStream;
ldc 3.000000
ldc 4.000000
ldc 5.000000
ldc 8.000000
fneg
fadd
fmul
fsub
ldc 10.000000
ldc 7.000000
fdiv
fsub
invokevirtual java/io/PrintStream/print(F)V
getstatic java/lang/System/out Ljava/io/PrintStream;
invokevirtual java/io/PrintStream/println()V

;( 3.0 - 4.0 * (5.0 + -8.0) - 10.0 / 7.0 > -4.0 || !true && !!false)
getstatic java/lang/System/out Ljava/io/PrintStream;
ldc 3.000000
ldc 4.000000
ldc 5.000000
ldc 8.000000
fneg
fadd
fmul
fsub
ldc 10.000000
ldc 7.000000
fdiv
fsub
ldc 4.000000
fneg
fcmpg
ifgt greaterThanLabel1
iconst_0
goto endLabel1
greaterThanLabel1:
iconst_1
endLabel1:
iconst_1
iconst_1
ixor
iconst_0
iconst_1
ixor
iconst_1
ixor
iand
ior
invokevirtual java/io/PrintStream/print(Z)V
getstatic java/lang/System/out Ljava/io/PrintStream;
invokevirtual java/io/PrintStream/println()V

return
.end method

testcase02

.class public Main
.super java/lang/Object
.method public static main([Ljava/lang/String;)V
.limit stack 100
.limit locals 100

;( 3 - 4 * (5 + -8) - 10 / 7)
getstatic java/lang/System/out Ljava/io/PrintStream;
ldc 3
ldc 4
ldc 5
ldc 8
ineg
iadd
imul
isub
ldc 10
ldc 7
idiv
isub
invokevirtual java/io/PrintStream/print(I)V
getstatic java/lang/System/out Ljava/io/PrintStream;
invokevirtual java/io/PrintStream/println()V

;cout << ( 3 - 4 * (5 + -8) - 10 / 7 > -4 % 3 || !true && !!false) << endl
getstatic java/lang/System/out Ljava/io/PrintStream;
ldc 3
ldc 4
ldc 5
ldc 8
ineg
iadd
imul
isub
ldc 10
ldc 7
idiv
isub
ldc 4
ineg
ldc 3
irem
if_icmpgt greaterThanLabel0
iconst_0
goto endLabel0
greaterThanLabel0:
iconst_1
endLabel0:
iconst_1
iconst_1
ixor
iconst_0
iconst_1
ixor
iconst_1
ixor
iand
ior
invokevirtual java/io/PrintStream/print(Z)V
getstatic java/lang/System/out Ljava/io/PrintStream;
invokevirtual java/io/PrintStream/println()V

;(3.0 - 4.0 * (5.0 + -8.0) - 10.0 / 7.0)
getstatic java/lang/System/out Ljava/io/PrintStream;
ldc 3.000000
ldc 4.000000
ldc 5.000000
ldc 8.000000
fneg
fadd
fmul
fsub
ldc 10.000000
ldc 7.000000
fdiv
fsub
invokevirtual java/io/PrintStream/print(F)V
getstatic java/lang/System/out Ljava/io/PrintStream;
invokevirtual java/io/PrintStream/println()V

;( 3.0 - 4.0 * (5.0 + -8.0) - 10.0 / 7.0 > -4.0 || !true && !!false)
getstatic java/lang/System/out Ljava/io/PrintStream;
ldc 3.000000
ldc 4.000000
ldc 5.000000
ldc 8.000000
fneg
fadd
fmul
fsub
ldc 10.000000
ldc 7.000000
fdiv
fsub
ldc 4.000000
fneg
fcmpg
ifgt greaterThanLabel1
iconst_0
goto endLabel1
greaterThanLabel1:
iconst_1
endLabel1:
iconst_1
iconst_1
ixor
iconst_0
iconst_1
ixor
iconst_1
ixor
iand
ior
invokevirtual java/io/PrintStream/print(Z)V
getstatic java/lang/System/out Ljava/io/PrintStream;
invokevirtual java/io/PrintStream/println()V

;1000000 + 9 * 1 -1 + 2024 + ( -398 ) + ( 88 % 2 != 0 ) + ( 8888889 % 2 != 0 )
getstatic java/lang/System/out Ljava/io/PrintStream;
ldc 1000000
ldc 9
ldc 1
imul
iadd
ldc 1
isub
ldc 2024
iadd
ldc 398
ineg
iadd
ldc 88
ldc 2
irem
ldc 0
if_icmpne notEqualToLabel2
iconst_0
goto endLabel2
notEqualToLabel2:
iconst_1
endLabel2:
iadd
ldc 8888889
ldc 2
irem
ldc 0
if_icmpne notEqualToLabel3
iconst_0
goto endLabel3
notEqualToLabel3:
iconst_1
endLabel3:
iadd
invokevirtual java/io/PrintStream/print(I)V
getstatic java/lang/System/out Ljava/io/PrintStream;
invokevirtual java/io/PrintStream/println()V

return
.end method

subtask04-assigment

testcase01

.class public Main
.super java/lang/Object
.method public static main([Ljava/lang/String;)V
.limit stack 100
.limit locals 100

;int x = 0;
ldc 0
istore 1
                            
getstatic java/lang/System/out Ljava/io/PrintStream;
iload 1
invokevirtual java/io/PrintStream/print(I)V
getstatic java/lang/System/out Ljava/io/PrintStream;
invokevirtual java/io/PrintStream/println()V

;x = 10
ldc 10
istore 1
                            
getstatic java/lang/System/out Ljava/io/PrintStream;
iload 1
invokevirtual java/io/PrintStream/print(I)V
getstatic java/lang/System/out Ljava/io/PrintStream;
invokevirtual java/io/PrintStream/println()V

;x += 2
iload 1
ldc 2
iadd
istore 1
                            
getstatic java/lang/System/out Ljava/io/PrintStream;
iload 1
invokevirtual java/io/PrintStream/print(I)V
getstatic java/lang/System/out Ljava/io/PrintStream;
invokevirtual java/io/PrintStream/println()V

;x -= 3
iload 1
ldc 3
isub
istore 1
                            
getstatic java/lang/System/out Ljava/io/PrintStream;
iload 1
invokevirtual java/io/PrintStream/print(I)V
getstatic java/lang/System/out Ljava/io/PrintStream;
invokevirtual java/io/PrintStream/println()V

;x *= 4
iload 1
ldc 4
imul
istore 1
                            
getstatic java/lang/System/out Ljava/io/PrintStream;
iload 1
invokevirtual java/io/PrintStream/print(I)V
getstatic java/lang/System/out Ljava/io/PrintStream;
invokevirtual java/io/PrintStream/println()V

;x /= 5
iload 1
ldc 5
idiv
istore 1
                            
getstatic java/lang/System/out Ljava/io/PrintStream;
iload 1
invokevirtual java/io/PrintStream/print(I)V
getstatic java/lang/System/out Ljava/io/PrintStream;
invokevirtual java/io/PrintStream/println()V

;x %= 6
iload 1
ldc 6
irem
istore 1
                            
getstatic java/lang/System/out Ljava/io/PrintStream;
iload 1
invokevirtual java/io/PrintStream/print(I)V
getstatic java/lang/System/out Ljava/io/PrintStream;
invokevirtual java/io/PrintStream/println()V

;x |= 4092
iload 1
ldc 4092
ior
istore 1
                            
getstatic java/lang/System/out Ljava/io/PrintStream;
iload 1
invokevirtual java/io/PrintStream/print(I)V
getstatic java/lang/System/out Ljava/io/PrintStream;
invokevirtual java/io/PrintStream/println()V

;x &= 255
iload 1
ldc 255
iand
istore 1
                            
getstatic java/lang/System/out Ljava/io/PrintStream;
iload 1
invokevirtual java/io/PrintStream/print(I)V
getstatic java/lang/System/out Ljava/io/PrintStream;
invokevirtual java/io/PrintStream/println()V

;float yy = 3.14
ldc 3.140000
fstore 2
                            
getstatic java/lang/System/out Ljava/io/PrintStream;
fload 2
invokevirtual java/io/PrintStream/print(F)V
getstatic java/lang/System/out Ljava/io/PrintStream;
invokevirtual java/io/PrintStream/println()V

;yy = 10.4
ldc 10.400000
fstore 2
                            
getstatic java/lang/System/out Ljava/io/PrintStream;
fload 2
invokevirtual java/io/PrintStream/print(F)V
getstatic java/lang/System/out Ljava/io/PrintStream;
invokevirtual java/io/PrintStream/println()V

;yy += 2.0
fload 2
ldc 2.000000
fadd
fstore 2
                            
getstatic java/lang/System/out Ljava/io/PrintStream;
fload 2
invokevirtual java/io/PrintStream/print(F)V
getstatic java/lang/System/out Ljava/io/PrintStream;
invokevirtual java/io/PrintStream/println()V

;yy -= 3.0
fload 2
ldc 3.000000
fsub
fstore 2
                            
getstatic java/lang/System/out Ljava/io/PrintStream;
fload 2
invokevirtual java/io/PrintStream/print(F)V
getstatic java/lang/System/out Ljava/io/PrintStream;
invokevirtual java/io/PrintStream/println()V

;yy *= 4.0
fload 2
ldc 4.000000
fmul
fstore 2
                            
getstatic java/lang/System/out Ljava/io/PrintStream;
fload 2
invokevirtual java/io/PrintStream/print(F)V
getstatic java/lang/System/out Ljava/io/PrintStream;
invokevirtual java/io/PrintStream/println()V

;yy /= 5.0
fload 2
ldc 5.000000
fdiv
fstore 2
                            
getstatic java/lang/System/out Ljava/io/PrintStream;
fload 2
invokevirtual java/io/PrintStream/print(F)V
getstatic java/lang/System/out Ljava/io/PrintStream;
invokevirtual java/io/PrintStream/println()V

;string s = ""
ldc ""
astore 3
                            
getstatic java/lang/System/out Ljava/io/PrintStream;
aload 3
invokevirtual java/io/PrintStream/print(Ljava/lang/String;)V
getstatic java/lang/System/out Ljava/io/PrintStream;
invokevirtual java/io/PrintStream/println()V

;s = "Hello"
ldc "Hello"
astore 3
                            
getstatic java/lang/System/out Ljava/io/PrintStream;
aload 3
invokevirtual java/io/PrintStream/print(Ljava/lang/String;)V
getstatic java/lang/System/out Ljava/io/PrintStream;
invokevirtual java/io/PrintStream/println()V

;bool bbb = false
iconst_0
istore 4
                            
getstatic java/lang/System/out Ljava/io/PrintStream;
iload 4
invokevirtual java/io/PrintStream/print(Z)V
getstatic java/lang/System/out Ljava/io/PrintStream;
invokevirtual java/io/PrintStream/println()V

;bbb = true
iconst_1
istore 4
                            
getstatic java/lang/System/out Ljava/io/PrintStream;
iload 4
invokevirtual java/io/PrintStream/print(Z)V
getstatic java/lang/System/out Ljava/io/PrintStream;
invokevirtual java/io/PrintStream/println()V

return
.end method

testcase02

.class public Main
.super java/lang/Object
.method public static main([Ljava/lang/String;)V
.limit stack 100
.limit locals 100

;a = ~243 & 15
ldc 243
iconst_m1
ixor
ldc 15
iand
istore 1

;b = a >> 1
iload 1
ldc 1
ishr
istore 2

;c = a
iload 1
istore 3

;d = b | 9
iload 2
ldc 9
ior
istore 4

;e = b                            
iload 2
istore 5
 
;a += a
iload 1
iload 1
iadd
istore 1
   
;b += b
iload 2
iload 2
iadd
istore 2

;c /= c
iload 3
iload 3
idiv
istore 3
                            
getstatic java/lang/System/out Ljava/io/PrintStream;
iload 1
invokevirtual java/io/PrintStream/print(I)V
getstatic java/lang/System/out Ljava/io/PrintStream;
ldc " "
invokevirtual java/io/PrintStream/print(Ljava/lang/String;)V
getstatic java/lang/System/out Ljava/io/PrintStream;
iload 2
invokevirtual java/io/PrintStream/print(I)V
getstatic java/lang/System/out Ljava/io/PrintStream;
ldc " "
invokevirtual java/io/PrintStream/print(Ljava/lang/String;)V
getstatic java/lang/System/out Ljava/io/PrintStream;
iload 3
invokevirtual java/io/PrintStream/print(I)V
getstatic java/lang/System/out Ljava/io/PrintStream;
ldc " "
invokevirtual java/io/PrintStream/print(Ljava/lang/String;)V
getstatic java/lang/System/out Ljava/io/PrintStream;
iload 4
invokevirtual java/io/PrintStream/print(I)V
getstatic java/lang/System/out Ljava/io/PrintStream;
ldc " "
invokevirtual java/io/PrintStream/print(Ljava/lang/String;)V
getstatic java/lang/System/out Ljava/io/PrintStream;
iload 5
invokevirtual java/io/PrintStream/print(I)V
getstatic java/lang/System/out Ljava/io/PrintStream;
invokevirtual java/io/PrintStream/println()V

;e = 100 ^ 255
ldc 100
ldc 255
ixor
istore 5
   
e <<= 2;   
iload 5
ldc 2
ishl
istore 5
                            
getstatic java/lang/System/out Ljava/io/PrintStream;
iload 5
invokevirtual java/io/PrintStream/print(I)V
getstatic java/lang/System/out Ljava/io/PrintStream;
invokevirtual java/io/PrintStream/println()V

;e >>= 4
iload 5
ldc 4
ishr
istore 5
                            
getstatic java/lang/System/out Ljava/io/PrintStream;
iload 5
invokevirtual java/io/PrintStream/print(I)V
getstatic java/lang/System/out Ljava/io/PrintStream;
invokevirtual java/io/PrintStream/println()V

return
.end method

subtask05-casting

testcase01

.class public Main
.super java/lang/Object
.method public static main([Ljava/lang/String;)V
.limit stack 100
.limit locals 100

;int x = 3
ldc 3
istore 1
                  
;float y = 3.14
ldc 3.140000
fstore 2

;z1 = x + (int)(y)
iload 1
fload 2
f2i
iadd
istore 3

;z2 = (float)x + y
iload 1
i2f
fload 2
fadd
f2i
istore 4
                            
getstatic java/lang/System/out Ljava/io/PrintStream;
iload 3
invokevirtual java/io/PrintStream/print(I)V
getstatic java/lang/System/out Ljava/io/PrintStream;
ldc " "
invokevirtual java/io/PrintStream/print(Ljava/lang/String;)V
getstatic java/lang/System/out Ljava/io/PrintStream;
iload 4
invokevirtual java/io/PrintStream/print(I)V
getstatic java/lang/System/out Ljava/io/PrintStream;
invokevirtual java/io/PrintStream/println()V

; z1 = x + (int)(6.28)
iload 1
ldc 6.280000
f2i
iadd
istore 3
      
;z2 = (float)(6) + y
ldc 6
i2f
fload 2
fadd
f2i
istore 4
                            
getstatic java/lang/System/out Ljava/io/PrintStream;
iload 3
invokevirtual java/io/PrintStream/print(I)V
getstatic java/lang/System/out Ljava/io/PrintStream;
invokevirtual java/io/PrintStream/println()V

getstatic java/lang/System/out Ljava/io/PrintStream;
iload 4
invokevirtual java/io/PrintStream/print(I)V
getstatic java/lang/System/out Ljava/io/PrintStream;
invokevirtual java/io/PrintStream/println()V

return
.end method

testcase02

.class public Main
.super java/lang/Object
.method public static main([Ljava/lang/String;)V
.limit stack 100
.limit locals 100

;int a = 0, b = 0
ldc 0
istore 1
ldc 0
istore 2

;a += b
iload 1
iload 2
iadd
istore 1

;float c = 3.14
ldc 3.140000
fstore 3

;int d = (int)(c) + (int)2024.3934
fload 3
f2i
ldc 2024.393433
f2i
iadd
istore 4

getstatic java/lang/System/out Ljava/io/PrintStream;
iload 4
invokevirtual java/io/PrintStream/print(I)V
getstatic java/lang/System/out Ljava/io/PrintStream;
invokevirtual java/io/PrintStream/println()V

getstatic java/lang/System/out Ljava/io/PrintStream;
iload 1
invokevirtual java/io/PrintStream/print(I)V
getstatic java/lang/System/out Ljava/io/PrintStream;
invokevirtual java/io/PrintStream/println()V

getstatic java/lang/System/out Ljava/io/PrintStream;
iload 2
invokevirtual java/io/PrintStream/print(I)V
getstatic java/lang/System/out Ljava/io/PrintStream;
invokevirtual java/io/PrintStream/println()V

getstatic java/lang/System/out Ljava/io/PrintStream;
fload 3
invokevirtual java/io/PrintStream/print(F)V
getstatic java/lang/System/out Ljava/io/PrintStream;
invokevirtual java/io/PrintStream/println()V

return
.end method

subtask06-if

testcase01

.class public Main
.super java/lang/Object
.method public static main([Ljava/lang/String;)V
.limit stack 100
.limit locals 100

ldc 0
istore 1
                            
iload 1
ifne ifEnd0
getstatic java/lang/System/out Ljava/io/PrintStream;
ldc "Hello"
invokevirtual java/io/PrintStream/print(Ljava/lang/String;)V
getstatic java/lang/System/out Ljava/io/PrintStream;
invokevirtual java/io/PrintStream/println()V

ifEnd0:
                            
iload 1
ifeq elseBegin0

getstatic java/lang/System/out Ljava/io/PrintStream;
ldc "Hello"
invokevirtual java/io/PrintStream/print(Ljava/lang/String;)V
getstatic java/lang/System/out Ljava/io/PrintStream;
invokevirtual java/io/PrintStream/println()V

goto ifEnd1

elseBegin0:
                            
getstatic java/lang/System/out Ljava/io/PrintStream;
ldc "Bye"
invokevirtual java/io/PrintStream/print(Ljava/lang/String;)V
getstatic java/lang/System/out Ljava/io/PrintStream;
invokevirtual java/io/PrintStream/println()V

ifEnd1:
                            
return
.end method

testcase02

.class public Main
.super java/lang/Object
.method public static main([Ljava/lang/String;)V
.limit stack 100
.limit locals 100

; int a = 0,b = 0,c = 10
ldc 0
istore 1
ldc 0
istore 2
ldc 10
istore 3

; a == 0
iload 1
ldc 0
if_icmpeq equalToLabel0
iconst_0
goto endLabel0
equalToLabel0:
iconst_1
endLabel0:

; b == 0
iload 2
ldc 0
if_icmpeq equalToLabel1
iconst_0
goto endLabel1
equalToLabel1:
iconst_1
endLabel1:

; a == 0 && b == 0
iand

; if( a == 0 && b == 0 )
ifeq ifEnd0
getstatic java/lang/System/out Ljava/io/PrintStream;
iload 1
invokevirtual java/io/PrintStream/print(I)V
getstatic java/lang/System/out Ljava/io/PrintStream;
iload 2
invokevirtual java/io/PrintStream/print(I)V
getstatic java/lang/System/out Ljava/io/PrintStream;
iload 3
invokevirtual java/io/PrintStream/print(I)V
getstatic java/lang/System/out Ljava/io/PrintStream;
invokevirtual java/io/PrintStream/println()V

ifEnd0:
      
; c - b
iload 3
iload 2
isub

; c - b >= 0
ldc 0
if_icmpge greaterThanOrEqualToLabel2
iconst_0
goto endLabel2
greaterThanOrEqualToLabel2:
iconst_1
endLabel2:

; if(c - b >= 0)
ifeq ifEnd1
getstatic java/lang/System/out Ljava/io/PrintStream;
ldc "OK!"
invokevirtual java/io/PrintStream/print(Ljava/lang/String;)V
getstatic java/lang/System/out Ljava/io/PrintStream;
invokevirtual java/io/PrintStream/println()V

ifEnd1:
                            
; a == 0
iload 1
ldc 0
if_icmpeq equalToLabel3
iconst_0
goto endLabel3
equalToLabel3:
iconst_1
endLabel3:

; b != 0
iload 2
ldc 0
if_icmpne notEqualToLabel4
iconst_0
goto endLabel4
notEqualToLabel4:
iconst_1
endLabel4:

; a == 0 && b != 0
iand

; c == 10
iload 3
ldc 10
if_icmpeq equalToLabel5
iconst_0
goto endLabel5
equalToLabel5:
iconst_1
endLabel5:
                            
; ( a == 0 && b != 0 ) || c == 10
ior

; if( ( a == 0 && b != 0 ) || c == 10 )
ifeq elseBegin0
getstatic java/lang/System/out Ljava/io/PrintStream;
ldc "test1"
invokevirtual java/io/PrintStream/print(Ljava/lang/String;)V
getstatic java/lang/System/out Ljava/io/PrintStream;
invokevirtual java/io/PrintStream/println()V

goto ifEnd2

; else
elseBegin0:

; c == 10
iload 3
ldc 10
if_icmpeq equalToLabel6
iconst_0
goto endLabel6
equalToLabel6:
iconst_1
endLabel6:
        
; a != 0
iload 1
ldc 0
if_icmpne notEqualToLabel7
iconst_0
goto endLabel7
notEqualToLabel7:
iconst_1
endLabel7:

; c == 10 || a != 0
ior

; a == 0
iload 1
ldc 0
if_icmpeq equalToLabel8
iconst_0
goto endLabel8
equalToLabel8:
iconst_1
endLabel8:
     
; b == 0
iload 2
ldc 0
if_icmpeq equalToLabel9
iconst_0
goto endLabel9
equalToLabel9:
iconst_1
endLabel9:

; a == 0 && b == 0
iand

; c == 0
iload 3
ldc 0
if_icmpeq equalToLabel10
iconst_0
goto endLabel10
equalToLabel10:
iconst_1
endLabel10:
                            
; a == 0 && b == 0 && c == 0
iand

; c == 10
iload 3
ldc 10
if_icmpeq equalToLabel11
iconst_0
goto endLabel11
equalToLabel11:
iconst_1
endLabel11:

; (a) == 0
iload 1
ldc 0
if_icmpeq equalToLabel12
iconst_0
goto endLabel12
equalToLabel12:
iconst_1
endLabel12:
                            
; c == 10 || (a) == 0
ior

; a == 0 && b == 0 && c == 0 && ( c == 10 || (a) == 0 )
iand

; ( c == 10 || a != 0 ) && ( ( a == 0 && b == 0 && c == 0 && ( c == 10 || (a) == 0 ) ) )
iand

if( ( c == 10 || a != 0 ) && ( ( a == 0 && b == 0 && c == 0 && ( c == 10 || (a) == 0 ) ) ) )
ifeq elseBegin1

getstatic java/lang/System/out Ljava/io/PrintStream;
ldc "test2"
invokevirtual java/io/PrintStream/print(Ljava/lang/String;)V
getstatic java/lang/System/out Ljava/io/PrintStream;
invokevirtual java/io/PrintStream/println()V

goto ifEnd3

; else
elseBegin1:
                            
getstatic java/lang/System/out Ljava/io/PrintStream;
ldc "test3"
invokevirtual java/io/PrintStream/print(Ljava/lang/String;)V
getstatic java/lang/System/out Ljava/io/PrintStream;
invokevirtual java/io/PrintStream/println()V

;if(true)
iconst_1
ifeq ifEnd4

getstatic java/lang/System/out Ljava/io/PrintStream;
ldc "test4"
invokevirtual java/io/PrintStream/print(Ljava/lang/String;)V
getstatic java/lang/System/out Ljava/io/PrintStream;
invokevirtual java/io/PrintStream/println()V

ifEnd4:
                            
ifEnd3:
                            
ifEnd2:
                            
; if(true)
iconst_1
ifeq ifEnd5
getstatic java/lang/System/out Ljava/io/PrintStream;
ldc "test6"
invokevirtual java/io/PrintStream/print(Ljava/lang/String;)V
getstatic java/lang/System/out Ljava/io/PrintStream;
invokevirtual java/io/PrintStream/println()V

ifEnd5:

return
.end method

subtask07-while

testcase01

.class public Main
.super java/lang/Object
.method public static main([Ljava/lang/String;)V
.limit stack 100
.limit locals 100

; int a = 0, b = 0, c = 10
ldc 0
istore 1
ldc 0
istore 2
ldc 10
istore 3

Loop0Start:
            
; c != 0
iload 3
ldc 0
if_icmpne notEqualToLabel0
iconst_0
goto endLabel0
notEqualToLabel0:
iconst_1
endLabel0:

; while( c != 0 )
ifeq Loop0End

; c -= 1
iload 3
ldc 1
isub
istore 3
goto Loop0Start

Loop0End:
                            
Loop1Start:
                            
; (a) == 0
iload 1
ldc 0
if_icmpeq equalToLabel1
iconst_0
goto endLabel1
equalToLabel1:
iconst_1
endLabel1:
                            
; (b) == 0
iload 2
ldc 0
if_icmpeq equalToLabel2
iconst_0
goto endLabel2
equalToLabel2:
iconst_1
endLabel2:
                            
; (a) == 0 || (b) == 0
ior

; a == 0
iload 1
ldc 0
if_icmpeq equalToLabel3
iconst_0
goto endLabel3
equalToLabel3:
iconst_1
endLabel3:
                            
; b == 10
iload 2
ldc 10
if_icmpeq equalToLabel4
iconst_0
goto endLabel4
equalToLabel4:
iconst_1
endLabel4:
                            
; a == 0 || b == 10
ior

; c == 0
iload 3
ldc 0
if_icmpeq equalToLabel5
iconst_0
goto endLabel5
equalToLabel5:
iconst_1
endLabel5:
                            
; ( a == 0 || b == 10 || c == 0 )
ior

; (a) == 0 || (b) == 0 || ( a == 0 || b == 10 || c == 0 )
ior

; while( (a) == 0 || (b) == 0 || ( a == 0 || b == 10 || c == 0 ) )
ifeq Loop1End

; a -= 1
iload 1
ldc 1
isub
istore 1
                            
; b -= 1
iload 2
ldc 1
isub
istore 2
                            
; c -= 1
iload 3
ldc 1
isub
istore 3
                            
goto Loop1Start
Loop1End:
                            
getstatic java/lang/System/out Ljava/io/PrintStream;
iload 1
invokevirtual java/io/PrintStream/print(I)V
getstatic java/lang/System/out Ljava/io/PrintStream;
bipush 32
invokevirtual java/io/PrintStream/print(C)V
getstatic java/lang/System/out Ljava/io/PrintStream;
iload 2
invokevirtual java/io/PrintStream/print(I)V
getstatic java/lang/System/out Ljava/io/PrintStream;
bipush 32
invokevirtual java/io/PrintStream/print(C)V
getstatic java/lang/System/out Ljava/io/PrintStream;
iload 3
invokevirtual java/io/PrintStream/print(I)V
getstatic java/lang/System/out Ljava/io/PrintStream;
invokevirtual java/io/PrintStream/println()V

return
.end method

subtask08-for

testcase01

.class public Main
.super java/lang/Object
.method public static main([Ljava/lang/String;)V
.limit stack 100
.limit locals 100

; int c = 10
ldc 10
istore 1

; int i = 0
ldc 0
istore 2
      
; for()
Loop0Start:
          
; i < c
iload 2
iload 1
if_icmplt lessThanLabel0
iconst_0
goto endLabel0
lessThanLabel0:
iconst_1
endLabel0:
               
ifeq Loop0End
                            
getstatic java/lang/System/out Ljava/io/PrintStream;
ldc "Hello world"
invokevirtual java/io/PrintStream/print(Ljava/lang/String;)V
getstatic java/lang/System/out Ljava/io/PrintStream;
invokevirtual java/io/PrintStream/println()V

; i++
iinc 2 1

goto Loop0Start

Loop0End:
            
; for()
Loop1Start:
  
; c >= 0
iload 1
ldc 0
if_icmpge greaterThanOrEqualToLabel1
iconst_0
goto endLabel1
greaterThanOrEqualToLabel1:
iconst_1
endLabel1:

ifeq Loop1End

getstatic java/lang/System/out Ljava/io/PrintStream;
ldc "apple!"
invokevirtual java/io/PrintStream/print(Ljava/lang/String;)V
getstatic java/lang/System/out Ljava/io/PrintStream;
invokevirtual java/io/PrintStream/println()V

; c -= 1
iload 1
ldc 1
isub
istore 1

goto Loop1Start

Loop1End:
                            
return
.end method
}

subtask09-function

testcase01

.class public Main
.super java/lang/Object

; bool check(int a,int b,string s,bool c)
.method public static check(IILjava/lang/String;Z)Z
.limit stack 100
.limit locals 100

getstatic java/lang/System/out Ljava/io/PrintStream;
aload 2
invokevirtual java/io/PrintStream/print(Ljava/lang/String;)V
getstatic java/lang/System/out Ljava/io/PrintStream;
invokevirtual java/io/PrintStream/println()V

getstatic java/lang/System/out Ljava/io/PrintStream;
iload 0
invokevirtual java/io/PrintStream/print(I)V
getstatic java/lang/System/out Ljava/io/PrintStream;
ldc " "
invokevirtual java/io/PrintStream/print(Ljava/lang/String;)V
getstatic java/lang/System/out Ljava/io/PrintStream;
iload 1
invokevirtual java/io/PrintStream/print(I)V
getstatic java/lang/System/out Ljava/io/PrintStream;
ldc " "
invokevirtual java/io/PrintStream/print(Ljava/lang/String;)V
getstatic java/lang/System/out Ljava/io/PrintStream;
aload 2
invokevirtual java/io/PrintStream/print(Ljava/lang/String;)V
getstatic java/lang/System/out Ljava/io/PrintStream;
invokevirtual java/io/PrintStream/println()V

; c == true
iload 3
iconst_1
if_icmpeq equalToLabel0
iconst_0
goto endLabel0
equalToLabel0:
iconst_1
endLabel0:

ireturn
.end method

; int main(string argv[])
.method public static main([Ljava/lang/String;)V
.limit stack 100
.limit locals 100

; check(1,2,"apple",true)
ldc 1
ldc 2
ldc "apple"
iconst_1
invokestatic Main/check(IILjava/lang/String;Z)Z

; bool result = check(1,2,"apple",true)
istore 1
                            
; int num = result + 7               
iload 1
ldc 7
iadd
istore 2
                            
getstatic java/lang/System/out Ljava/io/PrintStream;
iload 2
invokevirtual java/io/PrintStream/print(I)V
getstatic java/lang/System/out Ljava/io/PrintStream;
invokevirtual java/io/PrintStream/println()V

return
.end method

subtask10-array

testcase01

.class public Main
.super java/lang/Object
.method public static main([Ljava/lang/String;)V
.limit stack 100
.limit locals 100

; int a[5] = {10, 20, 30, 40, 50}
ldc 5
newarray int
dup
ldc 0
ldc 10                
iastore
dup
ldc 1
ldc 20
iastore
dup
ldc 2
ldc 30
iastore
dup
ldc 3
ldc 40
iastore
dup
ldc 4
ldc 50
iastore
astore 1
                            
getstatic java/lang/System/out Ljava/io/PrintStream;
aload 1
ldc 0
iaload
invokevirtual java/io/PrintStream/print(I)V
getstatic java/lang/System/out Ljava/io/PrintStream;
ldc " "
invokevirtual java/io/PrintStream/print(Ljava/lang/String;)V
getstatic java/lang/System/out Ljava/io/PrintStream;
aload 1
ldc 1
iaload
invokevirtual java/io/PrintStream/print(I)V
getstatic java/lang/System/out Ljava/io/PrintStream;
ldc " "
invokevirtual java/io/PrintStream/print(Ljava/lang/String;)V
getstatic java/lang/System/out Ljava/io/PrintStream;
aload 1
ldc 2
iaload
invokevirtual java/io/PrintStream/print(I)V
getstatic java/lang/System/out Ljava/io/PrintStream;
ldc " "
invokevirtual java/io/PrintStream/print(Ljava/lang/String;)V
getstatic java/lang/System/out Ljava/io/PrintStream;
aload 1
ldc 3
iaload
invokevirtual java/io/PrintStream/print(I)V
getstatic java/lang/System/out Ljava/io/PrintStream;
ldc " "
invokevirtual java/io/PrintStream/print(Ljava/lang/String;)V
getstatic java/lang/System/out Ljava/io/PrintStream;
aload 1
ldc 4
iaload
invokevirtual java/io/PrintStream/print(I)V
getstatic java/lang/System/out Ljava/io/PrintStream;
invokevirtual java/io/PrintStream/println()V

return
.end method

testcase02

.class public Main
.super java/lang/Object
.method public static main([Ljava/lang/String;)V
.limit stack 100
.limit locals 100

; int a[5] = {10, 20, 30, 40, 50}
ldc 5
newarray int
dup
ldc 0
ldc 10
iastore
dup
ldc 1
ldc 20
iastore
dup
ldc 2
ldc 30
iastore
dup
ldc 3
ldc 40
iastore
dup
ldc 4
ldc 50
iastore
astore 1
                            
getstatic java/lang/System/out Ljava/io/PrintStream;
aload 1
ldc 0
iaload
invokevirtual java/io/PrintStream/print(I)V
getstatic java/lang/System/out Ljava/io/PrintStream;
ldc " "
invokevirtual java/io/PrintStream/print(Ljava/lang/String;)V
getstatic java/lang/System/out Ljava/io/PrintStream;
aload 1
ldc 1
iaload
invokevirtual java/io/PrintStream/print(I)V
getstatic java/lang/System/out Ljava/io/PrintStream;
ldc " "
invokevirtual java/io/PrintStream/print(Ljava/lang/String;)V
getstatic java/lang/System/out Ljava/io/PrintStream;
aload 1
ldc 2
iaload
invokevirtual java/io/PrintStream/print(I)V
getstatic java/lang/System/out Ljava/io/PrintStream;
ldc " "
invokevirtual java/io/PrintStream/print(Ljava/lang/String;)V
getstatic java/lang/System/out Ljava/io/PrintStream;
aload 1
ldc 3
iaload
invokevirtual java/io/PrintStream/print(I)V
getstatic java/lang/System/out Ljava/io/PrintStream;
ldc " "
invokevirtual java/io/PrintStream/print(Ljava/lang/String;)V
getstatic java/lang/System/out Ljava/io/PrintStream;
aload 1
ldc 4
iaload
invokevirtual java/io/PrintStream/print(I)V
getstatic java/lang/System/out Ljava/io/PrintStream;
invokevirtual java/io/PrintStream/println()V

; int b[1001]
ldc 1001
newarray int
astore 2
       
; b[3] = 9
aload 2                   
ldc 3
ldc 9
iastore

; b[1000] = 1000
aload 2                   
ldc 1000
ldc 1000
iastore

getstatic java/lang/System/out Ljava/io/PrintStream;
aload 2
ldc 3
iaload
invokevirtual java/io/PrintStream/print(I)V
getstatic java/lang/System/out Ljava/io/PrintStream;
ldc " "
invokevirtual java/io/PrintStream/print(Ljava/lang/String;)V
getstatic java/lang/System/out Ljava/io/PrintStream;
aload 2
ldc 1000
iaload
invokevirtual java/io/PrintStream/print(I)V
getstatic java/lang/System/out Ljava/io/PrintStream;
invokevirtual java/io/PrintStream/println()V

return
.end method

subtask11-autotype

testcase01

.class public Main
.super java/lang/Object
.method public static main([Ljava/lang/String;)V
.limit stack 100
.limit locals 100

; auto x = 6.0;
ldc 6.000000
fstore 1
                  
; auto y = true;
iconst_1
istore 2
                            
getstatic java/lang/System/out Ljava/io/PrintStream;
fload 1
invokevirtual java/io/PrintStream/print(F)V
getstatic java/lang/System/out Ljava/io/PrintStream;
ldc " "
invokevirtual java/io/PrintStream/print(Ljava/lang/String;)V
getstatic java/lang/System/out Ljava/io/PrintStream;
iload 2
invokevirtual java/io/PrintStream/print(Z)V
getstatic java/lang/System/out Ljava/io/PrintStream;
invokevirtual java/io/PrintStream/println()V

return
.end method

subtask12-loop2

testcase01

.class public Main
.super java/lang/Object
.method public static main([Ljava/lang/String;)V
.limit stack 100
.limit locals 100

; int counter = 0
ldc 0
istore 1
             
; while()
Loop0Start:
         
; counter < 100
iload 1
ldc 100
if_icmplt lessThanLabel0
iconst_0
goto endLabel0
lessThanLabel0:
iconst_1
endLabel0:
                            
ifeq Loop0End

; counter += 1
iload 1
ldc 1
iadd
istore 1
           
; counter == 99
iload 1
ldc 99
if_icmpeq equalToLabel1
iconst_0
goto endLabel1
equalToLabel1:
iconst_1
endLabel1:
             
; if( counter == 99 )
ifeq ifEnd1

; break
goto Loop0End

ifEnd1:
       
; counter % 9 == 0
iload 1
ldc 9
irem
ldc 0
if_icmpeq equalToLabel2
iconst_0
goto endLabel2
equalToLabel2:
iconst_1
endLabel2:
     
; if( counter % 9 == 0 )
ifeq ifEnd2

getstatic java/lang/System/out Ljava/io/PrintStream;
ldc "Hello World "
invokevirtual java/io/PrintStream/print(Ljava/lang/String;)V
getstatic java/lang/System/out Ljava/io/PrintStream;
iload 1
ldc 2
irem
invokevirtual java/io/PrintStream/print(I)V
getstatic java/lang/System/out Ljava/io/PrintStream;
invokevirtual java/io/PrintStream/println()V

ifEnd2:
                            
getstatic java/lang/System/out Ljava/io/PrintStream;
ldc 998244353
iload 1
irem
invokevirtual java/io/PrintStream/print(I)V
getstatic java/lang/System/out Ljava/io/PrintStream;
invokevirtual java/io/PrintStream/println()V

goto Loop0Start

Loop0End:
                            
getstatic java/lang/System/out Ljava/io/PrintStream;
iload 1
invokevirtual java/io/PrintStream/print(I)V
getstatic java/lang/System/out Ljava/io/PrintStream;
invokevirtual java/io/PrintStream/println()V

return
.end method

testcase02

.class public Main
.super java/lang/Object
.method public static main([Ljava/lang/String;)V
.limit stack 100
.limit locals 100

; int a[10] = { 10, 21, 30, 41, 50 }
ldc 10
newarray int
dup
ldc 0
ldc 10
iastore
dup
ldc 1
ldc 21
iastore
dup
ldc 2
ldc 30
iastore
dup
ldc 3
ldc 41
iastore
dup
ldc 4
ldc 50
iastore
astore 1
                            
; int i = 0
ldc 0
istore 2
                            
; for()
Loop0Start:
                            
; i < 9
iload 2
ldc 9
if_icmplt lessThanLabel0
iconst_0
goto endLabel0
lessThanLabel0:
iconst_1
endLabel0:
                            
ifeq Loop0End

; int j = a[i]
aload 1
iload 2
iaload
istore 3
                            
getstatic java/lang/System/out Ljava/io/PrintStream;
aload 1
iload 2
iaload
invokevirtual java/io/PrintStream/print(I)V
getstatic java/lang/System/out Ljava/io/PrintStream;
invokevirtual java/io/PrintStream/println()V

; j % 2 == 0
iload 3
ldc 2
irem
ldc 0
if_icmpeq equalToLabel1
iconst_0
goto endLabel1
equalToLabel1:
iconst_1
endLabel1:
        
; if()
ifeq ifEnd0

getstatic java/lang/System/out Ljava/io/PrintStream;
ldc "Even"
invokevirtual java/io/PrintStream/print(Ljava/lang/String;)V
getstatic java/lang/System/out Ljava/io/PrintStream;
invokevirtual java/io/PrintStream/println()V

ifEnd0:

; i++
iinc 2 1
                            
goto Loop0Start

Loop0End:
                            
return
.end method

subtask13-2Darray

testcase01

.class public Main
.super java/lang/Object
.method public static main([Ljava/lang/String;)V
.limit stack 100
.limit locals 100

; int a[3][3]
ldc 3
ldc 3
multianewarray [[I 2
astore 1
                 
; a[0][0] = 1
aload 1
ldc 0
aaload
ldc 0
ldc 1
iastore

; a[0][1] = 2
aload 1
ldc 0
aaload
ldc 1
ldc 2
iastore

; a[0][2] = 3
aload 1
ldc 0
aaload
ldc 2
ldc 3
iastore

; a[1][0] = 4
aload 1
ldc 1
aaload
ldc 0
ldc 4
iastore

; a[1][1] = 5
aload 1
ldc 1
aaload
ldc 1
ldc 5
iastore

; a[2][2] = 6
aload 1
ldc 2
aaload
ldc 2
ldc 6
iastore

getstatic java/lang/System/out Ljava/io/PrintStream;
aload 1
ldc 1
aaload
ldc 0
iaload
invokevirtual java/io/PrintStream/print(I)V
getstatic java/lang/System/out Ljava/io/PrintStream;
invokevirtual java/io/PrintStream/println()V

getstatic java/lang/System/out Ljava/io/PrintStream;
aload 1
ldc 1
aaload
ldc 1
iaload
invokevirtual java/io/PrintStream/print(I)V
getstatic java/lang/System/out Ljava/io/PrintStream;
invokevirtual java/io/PrintStream/println()V

getstatic java/lang/System/out Ljava/io/PrintStream;
aload 1
ldc 2
aaload
ldc 2
iaload
invokevirtual java/io/PrintStream/print(I)V
getstatic java/lang/System/out Ljava/io/PrintStream;
invokevirtual java/io/PrintStream/println()V

getstatic java/lang/System/out Ljava/io/PrintStream;
aload 1
ldc 0
aaload
ldc 0
iaload
invokevirtual java/io/PrintStream/print(I)V
getstatic java/lang/System/out Ljava/io/PrintStream;
invokevirtual java/io/PrintStream/println()V

getstatic java/lang/System/out Ljava/io/PrintStream;
aload 1
ldc 0
aaload
ldc 1
iaload
invokevirtual java/io/PrintStream/print(I)V
getstatic java/lang/System/out Ljava/io/PrintStream;
invokevirtual java/io/PrintStream/println()V

getstatic java/lang/System/out Ljava/io/PrintStream;
aload 1
ldc 0
aaload
ldc 2
iaload
invokevirtual java/io/PrintStream/print(I)V
getstatic java/lang/System/out Ljava/io/PrintStream;
invokevirtual java/io/PrintStream/println()V

getstatic java/lang/System/out Ljava/io/PrintStream;
aload 1
ldc 1
aaload
ldc 2
iaload
invokevirtual java/io/PrintStream/print(I)V
getstatic java/lang/System/out Ljava/io/PrintStream;
invokevirtual java/io/PrintStream/println()V

return
.end method

subtask14-forall

testcase01

.class public Main
.super java/lang/Object

; int mod(int num,int mod)
.method public static mod(II)I
.limit stack 100
.limit locals 100

; num < 0
iload 0
ldc 0
if_icmplt lessThanLabel0
iconst_0
goto endLabel0
lessThanLabel0:
iconst_1
endLabel0:

; if()
ifeq ifEnd0

iload 0
iload 0
ldc 1
ineg
imul
iload 1
idiv
ldc 1
iadd
iload 1
imul
iadd

ireturn

ifEnd0:

iload 0
iload 1
irem
ireturn

.end method

; void nothing_function(string s)
.method public static nothing_function(Ljava/lang/String;)V
.limit stack 100
.limit locals 100

getstatic java/lang/System/out Ljava/io/PrintStream;
aload 0
invokevirtual java/io/PrintStream/print(Ljava/lang/String;)V
getstatic java/lang/System/out Ljava/io/PrintStream;
invokevirtual java/io/PrintStream/println()V

getstatic java/lang/System/out Ljava/io/PrintStream;
ldc 1000000007
ldc 99824353
invokestatic Main/mod(II)I
invokevirtual java/io/PrintStream/print(I)V
getstatic java/lang/System/out Ljava/io/PrintStream;
invokevirtual java/io/PrintStream/println()V

getstatic java/lang/System/out Ljava/io/PrintStream;
ldc 10
ineg
ldc 2
invokestatic Main/mod(II)I
invokevirtual java/io/PrintStream/print(I)V
getstatic java/lang/System/out Ljava/io/PrintStream;
invokevirtual java/io/PrintStream/println()V

return
.end method

; int main(string argv[])
.method public static main([Ljava/lang/String;)V
.limit stack 100
.limit locals 100

; nothing_function("Hello world");
ldc "Hello world"
invokestatic Main/nothing_function(Ljava/lang/String;)V

; int apple = 99824353
ldc 99824353
istore 1
                            
; nothing_function("apple!")
ldc "apple!"
invokestatic Main/nothing_function(Ljava/lang/String;)V

; mod(apple,2)
iload 1
ldc 2
invokestatic Main/mod(II)I

ldc 2
                            
; mod(apple,2) % 2
irem

ldc 1
                   
; mod(apple,2) % 2 == 1
if_icmpeq equalToLabel1
iconst_0
goto endLabel1
equalToLabel1:
iconst_1
endLabel1:
                            
; if()                            
ifeq ifEnd1

; apple == 998244353
iload 1
ldc 998244353            
if_icmpeq equalToLabel2
iconst_0
goto endLabel2
equalToLabel2:
iconst_1
endLabel2:
                            
; if()                           
ifeq elseBegin2

; int i = 0
ldc 0
istore 2
                            
; for()
Loop3Start:

; i < 10
iload 2
ldc 10
if_icmplt lessThanLabel3
iconst_0
goto endLabel3
lessThanLabel3:
iconst_1
endLabel3:
                            
ifeq Loop3End

; int q = 10
ldc 10
istore 3
                            
; while()
Loop4Start:
           
; q != 0
iload 3
ldc 0
if_icmpne notEqualToLabel4
iconst_0
goto endLabel4
notEqualToLabel4:
iconst_1
endLabel4:
                            
ifeq Loop4End

; q -= 1
iload 3
ldc 1
isub
istore 3
                            
getstatic java/lang/System/out Ljava/io/PrintStream;
ldc "OK!"
invokevirtual java/io/PrintStream/print(Ljava/lang/String;)V
getstatic java/lang/System/out Ljava/io/PrintStream;
invokevirtual java/io/PrintStream/println()V

goto Loop4Start
Loop4End:

; i += 1
iload 2
ldc 1
iadd
istore 2

goto Loop3Start
Loop3End:

; int i=0
ldc 0
istore 2
                            
; for()
Loop5Start:
                            
; i < 20
iload 2
ldc 20
if_icmplt lessThanLabel5
iconst_0
goto endLabel5
lessThanLabel5:
iconst_1
endLabel5:
                            
ifeq Loop5End

; int q = mod(apple,2)
iload 1
ldc 2
invokestatic Main/mod(II)I
istore 3
             
; while()
Loop6Start:
                            
; q > 0
iload 3
ldc 0
if_icmpgt greaterThanLabel6
iconst_0
goto endLabel6
greaterThanLabel6:
iconst_1
endLabel6:
                            
ifeq Loop6End

; q -= 1
iload 3
ldc 1
isub
istore 3
                            
getstatic java/lang/System/out Ljava/io/PrintStream;
ldc "OK!"
invokevirtual java/io/PrintStream/print(Ljava/lang/String;)V
getstatic java/lang/System/out Ljava/io/PrintStream;
invokevirtual java/io/PrintStream/println()V

goto Loop6Start
Loop6End:

; i += 2
iload 2
ldc 2
iadd
istore 2                

goto Loop5Start

Loop5End:
                            
goto elseEnd2

; else
elseBegin2:
                 
; nothing_function("something wrong");
ldc "something wrong"
invokestatic Main/nothing_function(Ljava/lang/String;)V

ifEnd2:
                            
ifEnd1:
                            
getstatic java/lang/System/out Ljava/io/PrintStream;
iload 1
ldc 2
invokestatic Main/mod(II)I
invokevirtual java/io/PrintStream/print(I)V
getstatic java/lang/System/out Ljava/io/PrintStream;
invokevirtual java/io/PrintStream/println()V

return
.end method

testcase02

.class public Main
.super java/lang/Object
.method public static main([Ljava/lang/String;)V
.limit stack 100
.limit locals 100

; int a[3][3]
ldc 3
ldc 3
multianewarray [[I 2
astore 1
    
; int i = 0
ldc 0
istore 2

; for()
Loop0Start:
         
; i < 3
iload 2
ldc 3
if_icmplt lessThanLabel0
iconst_0
goto endLabel0
lessThanLabel0:
iconst_1
endLabel0:
                 
ifeq Loop0End

; int j = 0
ldc 0
istore 3
          
; for()
Loop1Start:
    
; j < 3
iload 3
ldc 3
if_icmplt lessThanLabel1
iconst_0
goto endLabel1
lessThanLabel1:
iconst_1
endLabel1:
                 
ifeq Loop1End

; a[i][j]
aload 1
iload 2
aaload
iload 3

; ( i + j + 998244353 ) % 82781
iload 2
iload 3
iadd
ldc 998244353
iadd
ldc 82781
irem

; a[i][j] = ( i + j + 998244353 ) % 82781
iastore

; j++
iinc 3 1

goto Loop1Start

Loop1End:

; i++
iinc 2 1
        
goto Loop0Start

Loop0End:
       
; int i = 2
ldc 2
istore 2

; for()
Loop2Start:
                 
; i >= 0
iload 2
ldc 0
if_icmpge greaterThanOrEqualToLabel2
iconst_0
goto endLabel2
greaterThanOrEqualToLabel2:
iconst_1
endLabel2:
                 
ifeq Loop2End

; int j = 0
ldc 0
istore 3
                 
; for()
Loop3Start:
                 
; j < 3
iload 3
ldc 3
if_icmplt lessThanLabel3
iconst_0
goto endLabel3
lessThanLabel3:
iconst_1
endLabel3:
                 
ifeq Loop3End

getstatic java/lang/System/out Ljava/io/PrintStream;
iload 2
invokevirtual java/io/PrintStream/print(I)V
getstatic java/lang/System/out Ljava/io/PrintStream;
bipush 32
invokevirtual java/io/PrintStream/print(C)V
getstatic java/lang/System/out Ljava/io/PrintStream;
iload 3
invokevirtual java/io/PrintStream/print(I)V
getstatic java/lang/System/out Ljava/io/PrintStream;
bipush 32
invokevirtual java/io/PrintStream/print(C)V
getstatic java/lang/System/out Ljava/io/PrintStream;
aload 1
iload 2
aaload
iload 3
iaload
invokevirtual java/io/PrintStream/print(I)V
getstatic java/lang/System/out Ljava/io/PrintStream;
invokevirtual java/io/PrintStream/println()V

; j++
iinc 3 1
                 
goto Loop3Start

Loop3End:
               
; i--
iinc 2 -1
                 
goto Loop2Start

Loop2End:
                 
return
.end method

subtask15-bonus

testcase01

.class public Main
.super java/lang/Object

; float calculate_pi(int terms)
.method public static calculate_pi(I)F
.limit stack 100
.limit locals 100

; float pi = 3.0;
ldc 3.000000
fstore 1
    
; float two = 2.0;
ldc 2.000000
fstore 2
  
; bool add = true
iconst_1
istore 3
    
; int k = 1
ldc 1
istore 4
    
; for()
Loop0Start:

; k < terms
iload 4
iload 0
if_icmplt lessThanLabel0
iconst_0
goto endLabel0
lessThanLabel0:
iconst_1
endLabel0:

ifeq Loop0End

; float term = (float)4 / (two * (float)k * (two * (float)k + 1.0) * (two * (float)k + two))
ldc 4
i2f
fload 2
iload 4
i2f
fmul
fload 2
iload 4
i2f
fmul
ldc 1.000000
fadd
fmul
fload 2
iload 4
i2f
fmul
fload 2
fadd
fmul
fdiv
fstore 5
    
; if (add)
iload 3
ifeq elseBegin1

; pi += term
fload 1
fload 5
fadd
fstore 1
    
; add = false
iconst_0
istore 3
    
goto ifEnd1

elseBegin1:

; pi -= term
fload 1
fload 5
fsub
fstore 1
    
; add = true;
iconst_1
istore 3
    
ifEnd1:

; k++
iinc 4 1

goto Loop0Start

Loop0End:

fload 1
freturn

.end method

; int main(string argv[])
.method public static main([Ljava/lang/String;)V
.limit stack 100
.limit locals 100

; int terms = 100
ldc 100
istore 1
            
; float pi = calculate_pi(terms)
iload 1
invokestatic Main/calculate_pi(I)F
fstore 2
                            
getstatic java/lang/System/out Ljava/io/PrintStream;
ldc "Approximation of Pi after "
invokevirtual java/io/PrintStream/print(Ljava/lang/String;)V
getstatic java/lang/System/out Ljava/io/PrintStream;
iload 1
invokevirtual java/io/PrintStream/print(I)V
getstatic java/lang/System/out Ljava/io/PrintStream;
ldc " terms: "
invokevirtual java/io/PrintStream/print(Ljava/lang/String;)V
getstatic java/lang/System/out Ljava/io/PrintStream;
fload 2
invokevirtual java/io/PrintStream/print(F)V
getstatic java/lang/System/out Ljava/io/PrintStream;
invokevirtual java/io/PrintStream/println()V

return
.end method

6/19 24分上分列車

compiler_common.h

#ifndef COMPILER_COMMON_H
#define COMPILER_COMMON_H

#include <stdbool.h>
#include <stdint.h>

#define getBool(val) (*(int8_t*)&((val)->value))
#define getByte(val) (*(int8_t*)&((val)->value))
#define getChar(val) (*(int8_t*)&((val)->value))
#define getShort(val) (*(int16_t*)&((val)->value))
#define getInt(val) (*(int32_t*)&((val)->value))
#define getLong(val) (*(int64_t*)&((val)->value))
#define getFloat(val) (*(float*)&((val)->value))
#define getDouble(val) (*(double*)&((val)->value))
#define getString(val) (*(char**)&((val)->value))

#define asVal(val) (*(int64_t*)&(val))

typedef enum _objectType {
    OBJECT_TYPE_UNDEFINED,
    OBJECT_TYPE_AUTO,
    OBJECT_TYPE_VOID,
    OBJECT_TYPE_BOOL,
    OBJECT_TYPE_BYTE,
    OBJECT_TYPE_CHAR,
    OBJECT_TYPE_SHORT,
    OBJECT_TYPE_INT,
    OBJECT_TYPE_LONG,
    OBJECT_TYPE_FLOAT,
    OBJECT_TYPE_DOUBLE,
    OBJECT_TYPE_STR,
} ObjectType;

typedef struct _symbolData {
    char* name;
    //int32_t index;
    int64_t addr;
    //int32_t lineno;
    char* func_sig;
} SymbolData;

typedef struct _object {
    ObjectType type;
    //uint32_t array;
    //uint64_t value;
    //uint8_t flag;
    SymbolData* symbol;
    //LinkedList* arraySubscript;
} Object;

extern int yylineno;
extern int funcLineNo;

#endif /* COMPILER_COMMON_H */

main.h

#ifndef MAIN_H
#define MAIN_H
#include "compiler_common.h"

#define code(format, ...) \
    fprintf(yyout, "%*s" format "\n", scopeLevel << 2, "", __VA_ARGS__)
#define codeRaw(code) \
    fprintf(yyout, "%*s" code "\n", scopeLevel << 2, "")

extern FILE* yyout;
extern FILE* yyin;
extern bool compileError;
extern int scopeLevel;
int yyparse();
int yylex();
int yylex_destroy();

void popStackObject();
void pushStackObject(ObjectType type, char* name);

void pushScope();
void dumpScope();

void createFuncSig(char* name);
void catFuncSig(char* name, ObjectType type, bool arr);
void createFunction(ObjectType type, char* funcName);

void loadOperation(char* name);

void stdoutPrint();

void returnOperation();
void functionEnd();

void objectExpBinary(char op);
void objectNegExpression();

void objectExpBoolean(int op);

#endif

main.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <inttypes.h>

#define WJCL_LINKED_LIST_IMPLEMENTATION
#include "main.h"
#define WJCL_HASH_MAP_IMPLEMENTATION

#define STACK_SIZE 100
#define FUNC_SIG_SIZE 200

#define debug printf("%s:%d: ############### debug\n", __FILE__, __LINE__)

#define iload(var) code("iload %" PRId64 " ; %s", (var)->symbol->addr, (var)->symbol->name)
#define lload(var) code("lload %" PRId64 " ; %s", (var)->symbol->addr, (var)->symbol->name)
#define fload(var) code("fload %" PRId64 " ; %s", (var)->symbol->addr, (var)->symbol->name)
#define dload(var) code("dload %" PRId64 " ; %s", (var)->symbol->addr, (var)->symbol->name)
#define aload(var) code("aload %" PRId64 " ; %s", (var)->symbol->addr, (var)->symbol->name)

#define istore(var) code("istore %" PRId64 " ; %s", (var)->symbol->addr, (var)->symbol->name)
#define lstore(var) code("lstore %" PRId64 " ; %s", (var)->symbol->addr, (var)->symbol->name)
#define fstore(var) code("fstore %" PRId64 " ; %s", (var)->symbol->addr, (var)->symbol->name)
#define dstore(var) code("dstore %" PRId64 " ; %s", (var)->symbol->addr, (var)->symbol->name)
#define astore(var) code("astore %" PRId64 " ; %s", (var)->symbol->addr, (var)->symbol->name)

#define ldz(val) code("ldc %d", getBool(val))
#define ldb(val) code("ldc %d", getByte(val))
#define ldc(val) code("ldc %d", getChar(val))
#define lds(val) code("ldc %d", getShort(val))
#define ldi(val) code("ldc %d", getInt(val))
#define ldl(val) code("ldc_w %" PRId64, getLong(val))
#define ldf(val) code("ldc %.6f", getFloat(val))
#define ldd(val) code("ldc_w %lf", getDouble(val))
#define ldt(val) code("ldc \"%s\"", getString(val))

const char* objectTypeName[] = {
    [OBJECT_TYPE_UNDEFINED] = "undefined",
    [OBJECT_TYPE_VOID] = "void",
    [OBJECT_TYPE_BOOL] = "bool",
    [OBJECT_TYPE_BYTE] = "byte",
    [OBJECT_TYPE_CHAR] = "char",
    [OBJECT_TYPE_SHORT] = "short",
    [OBJECT_TYPE_INT] = "int",
    [OBJECT_TYPE_LONG] = "long",
    [OBJECT_TYPE_FLOAT] = "float",
    [OBJECT_TYPE_DOUBLE] = "double",
    [OBJECT_TYPE_STR] = "string",
};
const char* objectJavaTypeName[] = {
    [OBJECT_TYPE_UNDEFINED] = "V",
    [OBJECT_TYPE_VOID] = "V",
    [OBJECT_TYPE_BOOL] = "Z",
    [OBJECT_TYPE_BYTE] = "B",
    [OBJECT_TYPE_CHAR] = "C",
    [OBJECT_TYPE_SHORT] = "S",
    [OBJECT_TYPE_INT] = "I",
    [OBJECT_TYPE_LONG] = "J",
    [OBJECT_TYPE_FLOAT] = "F",
    [OBJECT_TYPE_DOUBLE] = "D",
    [OBJECT_TYPE_STR] = "Ljava/lang/String;",
};

char* yyInputFileName;
bool compileError;

int scopeLevel = -1;
int currScopePointer = -1;

int stackPointer = -1;

int variableAddress = -1;

char funcSig[FUNC_SIG_SIZE] = "";

bool hasReturn = false;

int cmpLabel = 0;

ObjectType assignVariableType;

// stack
Object stack[STACK_SIZE];

// locals (Symbol Table)
Object symbolTable[10][10];

// 存現在的 function 的資訊
Object currFunc;

void setFunc(ObjectType type, char* funcName) {
    currFunc.type = (strcmp(funcName, "main") == 0 ? OBJECT_TYPE_VOID : type);
    currFunc.symbol = malloc(sizeof(SymbolData));
    currFunc.symbol->name = funcName;
    currFunc.symbol->func_sig = funcSig;
}

void clearFunc() {
    currFunc.type = OBJECT_TYPE_UNDEFINED;
    free(currFunc.symbol);
    strcpy(funcSig, "");
}

void popStackObject() {
    stack[stackPointer].type = OBJECT_TYPE_UNDEFINED;
    free(stack[stackPointer].symbol);
    stackPointer--;
}

void pushStackObject(ObjectType type, char* name) {
    stackPointer++;
    stack[stackPointer].symbol = malloc(sizeof(SymbolData));
    stack[stackPointer].type = type;
    stack[stackPointer].symbol->name = name;
}

void createFuncSig(char* name) {
    strcat(funcSig, name);
    strcat(funcSig, "(");
}

void catFuncSig(char* name, ObjectType type, bool arr) {
    if(arr)
        strcat(funcSig, "[");

    if(name != NULL) {
        strcat(funcSig, ")");
        if(strcmp(name, "main") == 0)
            strcat(funcSig, "V");
        else
            strcat(funcSig, objectJavaTypeName[type]);
    } else {
        strcat(funcSig, objectJavaTypeName[type]);
    }
}

void createFunction(ObjectType type, char* funcName) {
    setFunc(type, funcName);

    code(".method public static %s", funcSig);
    code(".limit stack %d", 100);
    code(".limit locals %d", 100);
}

void loadOperation(char* name) {
    if(name == NULL)
        return;

    if(strcmp(name, "endl") == 0) {
        pushStackObject(OBJECT_TYPE_UNDEFINED, name);
    }
}

void stdoutPrint() {
    if(stack[stackPointer].symbol->name != NULL) {
        if (strcmp(stack[stackPointer].symbol->name, "endl") == 0) {
            codeRaw("invokevirtual java/io/PrintStream/println()V");
        }
    } else {
        code("invokevirtual java/io/PrintStream/print(%s)V", objectJavaTypeName[stack[stackPointer].type]);
    }

    popStackObject();
}

void returnOperation() {
    if(strcmp(currFunc.symbol->name, "main") == 0 || currFunc.type == OBJECT_TYPE_VOID) {
        codeRaw("return");
    } else {
        if(currFunc.type == OBJECT_TYPE_INT || currFunc.type == OBJECT_TYPE_BOOL) {
            codeRaw("ireturn");
        } else if(currFunc.type == OBJECT_TYPE_FLOAT) {
            codeRaw("freturn");
        } else if(currFunc.type == OBJECT_TYPE_LONG) {
            codeRaw("lreturn");
        } else if(currFunc.type == OBJECT_TYPE_DOUBLE) {
            codeRaw("dreturn");
        } else if(currFunc.type == OBJECT_TYPE_STR) {
            codeRaw("areturn");
        }
    }

    popStackObject();
    hasReturn = true;
}

void functionEnd() {
    if(!hasReturn)
        codeRaw("return");

    codeRaw(".end method");

    while(stackPointer >= 0) {
        popStackObject();
    }

    clearFunc();
}

// 好用的工具 : 給 ObjectType 和你要做的運算就可以幫你印出對應的 jasmin code
void printArithmetic(ObjectType type, char op) {
    if(type == OBJECT_TYPE_BOOL || type == OBJECT_TYPE_CHAR || type == OBJECT_TYPE_INT) {
        if(op == '+')
            codeRaw("iadd");
        else if(op == '-')
            codeRaw("isub");
        else if(op == '*')
            codeRaw("imul");
        else if(op == '/')
            codeRaw("idiv");
        else if(op == '%')
            codeRaw("irem");
    } else if(type == OBJECT_TYPE_FLOAT) {
        if(op == '+')
            codeRaw("fadd");
        else if(op == '-')
            codeRaw("fsub");
        else if(op == '*')
            codeRaw("fmul");
        else if(op == '/')
            codeRaw("fdiv");
    } else if(type == OBJECT_TYPE_LONG) {
        if(op == '+')
            codeRaw("ladd");
        else if(op == '-')
            codeRaw("lsub");
        else if(op == '*')
            codeRaw("lmul");
        else if(op == '/')
            codeRaw("ldiv");
    } else if(type == OBJECT_TYPE_DOUBLE) {
        if(op == '+')
            codeRaw("dadd");
        else if(op == '-')
            codeRaw("dsub");
        else if(op == '*')
            codeRaw("dmul");
        else if(op == '/')
            codeRaw("ddiv");
    }
}

void objectExpBinary(char op) {
    // 處理隱含轉型的問題
    ObjectType resultType;
    if(stack[stackPointer - 1].type == OBJECT_TYPE_FLOAT || stack[stackPointer].type == OBJECT_TYPE_FLOAT) {
        stack[stackPointer - 1].type = OBJECT_TYPE_FLOAT;
        resultType = OBJECT_TYPE_FLOAT;
    } else if((stack[stackPointer - 1].type == OBJECT_TYPE_INT || stack[stackPointer - 1].type == OBJECT_TYPE_BOOL) \
                && (stack[stackPointer].type == OBJECT_TYPE_INT || stack[stackPointer].type == OBJECT_TYPE_BOOL)) {
        resultType = OBJECT_TYPE_INT;
    }

    printArithmetic(resultType, op);

    popStackObject(stackPointer);
    popStackObject(stackPointer);

    pushStackObject(resultType, NULL);
}

void objectNegExpression() {
    if(stack[stackPointer].type == OBJECT_TYPE_INT)
        codeRaw("ineg");
    else if(stack[stackPointer].type == OBJECT_TYPE_LONG)
        codeRaw("lneg");
    else if(stack[stackPointer].type == OBJECT_TYPE_FLOAT)
        codeRaw("fneg");
    else if(stack[stackPointer].type == OBJECT_TYPE_DOUBLE)
        codeRaw("dneg");
}

void objectExpBoolean(int op) {
    switch(op) {
        case 1: // ">"
            if(stack[stackPointer - 1].type == OBJECT_TYPE_FLOAT || stack[stackPointer].type == OBJECT_TYPE_FLOAT) {
                codeRaw("fcmpg");
                code("ifgt greaterThanLabel%d", cmpLabel);
            } else if((stack[stackPointer - 1].type == OBJECT_TYPE_INT || stack[stackPointer - 1].type == OBJECT_TYPE_BOOL) \
                        && (stack[stackPointer].type == OBJECT_TYPE_INT || stack[stackPointer].type == OBJECT_TYPE_BOOL)) {
                code("if_icmpgt greaterThanLabel%d", cmpLabel);
            }
            codeRaw("iconst_0");
            code("goto endLabel%d", cmpLabel);
            code("greaterThanLabel%d:", cmpLabel);
            codeRaw("iconst_1");
            code("endLabel%d:", cmpLabel);
            cmpLabel++;

            popStackObject(stackPointer);
            popStackObject(stackPointer);
            break;
        case 2: // "<"
            if(stack[stackPointer - 1].type == OBJECT_TYPE_FLOAT || stack[stackPointer].type == OBJECT_TYPE_FLOAT) {
                codeRaw("fcmpg");
                code("iflt lessThanLabel%d", cmpLabel);
            } else if((stack[stackPointer - 1].type == OBJECT_TYPE_INT || stack[stackPointer - 1].type == OBJECT_TYPE_BOOL) \
                        && (stack[stackPointer].type == OBJECT_TYPE_INT || stack[stackPointer].type == OBJECT_TYPE_BOOL)) {
                code("if_icmplt lessThanLabel%d", cmpLabel);
            }
            codeRaw("iconst_0");
            code("goto endLabel%d", cmpLabel);
            code("lessThanLabel%d:", cmpLabel);
            codeRaw("iconst_1");
            code("endLabel%d:", cmpLabel);
            cmpLabel++;

            popStackObject(stackPointer);
            popStackObject(stackPointer);
            break;
        case 3: // ">="
            if(stack[stackPointer - 1].type == OBJECT_TYPE_FLOAT || stack[stackPointer].type == OBJECT_TYPE_FLOAT) {
                codeRaw("fcmpg");
                code("ifge greaterThanOrEqualToLabel%d", cmpLabel);
            } else if((stack[stackPointer - 1].type == OBJECT_TYPE_INT || stack[stackPointer - 1].type == OBJECT_TYPE_BOOL) \
                        && (stack[stackPointer].type == OBJECT_TYPE_INT || stack[stackPointer].type == OBJECT_TYPE_BOOL)) {
                code("if_icmpge greaterThanOrEqualToLabel%d", cmpLabel);
            }
            codeRaw("iconst_0");
            code("goto endLabel%d", cmpLabel);
            code("greaterThanOrEqualToLabel%d:", cmpLabel);
            codeRaw("iconst_1");
            code("endLabel%d:", cmpLabel);
            cmpLabel++;

            popStackObject(stackPointer);
            popStackObject(stackPointer);
            break;
        case 4: // "<="
            if(stack[stackPointer - 1].type == OBJECT_TYPE_FLOAT || stack[stackPointer].type == OBJECT_TYPE_FLOAT) {
                codeRaw("fcmpg");
                code("ifle lessThanOrEqualToLabel%d", cmpLabel);
            } else if((stack[stackPointer - 1].type == OBJECT_TYPE_INT || stack[stackPointer - 1].type == OBJECT_TYPE_BOOL) \
                        && (stack[stackPointer].type == OBJECT_TYPE_INT || stack[stackPointer].type == OBJECT_TYPE_BOOL)) {
                code("if_icmple lessThanOrEqualToLabel%d", cmpLabel);
            }
            codeRaw("iconst_0");
            code("goto endLabel%d", cmpLabel);
            code("lessThanOrEqualToLabel%d:", cmpLabel);
            codeRaw("iconst_1");
            code("endLabel%d:", cmpLabel);
            cmpLabel++;

            popStackObject(stackPointer);
            popStackObject(stackPointer);
            break;
        case 5: // "=="
            if(stack[stackPointer - 1].type == OBJECT_TYPE_FLOAT || stack[stackPointer].type == OBJECT_TYPE_FLOAT) {
                codeRaw("fcmpg");
                code("ifeq equalToLabel%d", cmpLabel);
            } else if((stack[stackPointer - 1].type == OBJECT_TYPE_INT || stack[stackPointer - 1].type == OBJECT_TYPE_BOOL) \
                        && (stack[stackPointer].type == OBJECT_TYPE_INT || stack[stackPointer].type == OBJECT_TYPE_BOOL)) {
                code("if_icmpeq equalToLabel%d", cmpLabel);
            }
            codeRaw("iconst_0");
            code("goto endLabel%d", cmpLabel);
            code("equalToLabel%d:", cmpLabel);
            codeRaw("iconst_1");
            code("endLabel%d:", cmpLabel);
            cmpLabel++;

            popStackObject(stackPointer);
            popStackObject(stackPointer);
            break;
        case 6: // "!="
            if(stack[stackPointer - 1].type == OBJECT_TYPE_FLOAT || stack[stackPointer].type == OBJECT_TYPE_FLOAT) {
                codeRaw("fcmpg");
                code("ifne notEqualToLabel%d", cmpLabel);
            } else if((stack[stackPointer - 1].type == OBJECT_TYPE_INT || stack[stackPointer - 1].type == OBJECT_TYPE_BOOL) \
                        && (stack[stackPointer].type == OBJECT_TYPE_INT || stack[stackPointer].type == OBJECT_TYPE_BOOL)) {
                code("if_icmpne notEqualToLabel%d", cmpLabel);
            }
            codeRaw("iconst_0");
            code("goto endLabel%d", cmpLabel);
            code("notEqualToLabel%d:", cmpLabel);
            codeRaw("iconst_1");
            code("endLabel%d:", cmpLabel);
            cmpLabel++;

            popStackObject(stackPointer);
            popStackObject(stackPointer);
            break;
        case 7: // "&&"
            codeRaw("iand");
            popStackObject(stackPointer);
            popStackObject(stackPointer);
            break;
        case 8: // "||"
            codeRaw("ior");
            popStackObject(stackPointer);
            popStackObject(stackPointer);
            break;
        case 9: // "!"
            codeRaw("iconst_1");
            codeRaw("ixor");
            popStackObject(stackPointer);
            break;
        default:
    }

    pushStackObject(OBJECT_TYPE_BOOL, NULL);
}

int main(int argc, char* argv[]) {
    char* outputFileName = NULL;
    if (argc == 3) {
        yyin = fopen(yyInputFileName = argv[1], "r");
        yyout = fopen(outputFileName = argv[2], "w");
    } else if (argc == 2) {
        yyin = fopen(yyInputFileName = argv[1], "r");
        yyout = stdout;
    } else {
        printf("require input file");
        exit(1);
    }
    if (!yyin) {
        printf("file `%s` doesn't exists or cannot be opened\n", yyInputFileName);
        exit(1);
    }
    if (!yyout) {
        printf("file `%s` doesn't exists or cannot be opened\n", outputFileName);
        exit(1);
    }

    codeRaw(".class public Main");
    codeRaw(".super java/lang/Object");
    
    yyparse();
    printf("Total lines: %d\n", yylineno);
    fclose(yyin);

    yylex_destroy();
    return 0;
}

compiler.y

/* Definition section */
%{
    #include "compiler_util.h"
    #include "main.h"

    int yydebug = 1;
%}

/* Variable or self-defined structure */
%union {
    ObjectType var_type;

    bool b_var;
    char c_var;
    int32_t i_var;
    int64_t l_var;
    float f_var;
    double d_var;
    char *s_var;

    Object obj_val;

    // LinkList<Object*>
    //LinkedList* array_subscript;
}

/* Token without return */
%token COUT
%token SHR SHL BAN BOR BNT BXO ADD SUB MUL DIV REM NOT GTR LES GEQ LEQ EQL NEQ LAN LOR
%token VAL_ASSIGN ADD_ASSIGN SUB_ASSIGN MUL_ASSIGN DIV_ASSIGN REM_ASSIGN BAN_ASSIGN BOR_ASSIGN BXO_ASSIGN SHR_ASSIGN SHL_ASSIGN INC_ASSIGN DEC_ASSIGN
%token IF ELSE FOR WHILE RETURN BREAK CONTINUE

/* Token with return, which need to sepcify type */
%token <var_type> VARIABLE_T
%token <b_var> BOOL_LIT
%token <c_var> CHAR_LIT
%token <i_var> INT_LIT
%token <f_var> FLOAT_LIT
%token <s_var> STR_LIT
%token <s_var> IDENT

/* Nonterminal with return, which need to sepcify type */
%type <obj_val> Expression BinaryExpression BoolExpression
//%type <array_subscript> ArraySubscriptStmtList

%right VAL_ASSIGN ADD_ASSIGN SUB_ASSIGN MUL_ASSIGN DIV_ASSIGN REM_ASSIGN BAN_ASSIGN BOR_ASSIGN BXO_ASSIGN SHR_ASSIGN SHL_ASSIGN
%left LOR
%left LAN
%left BOR
%left BXO
%left BAN
%left EQL NEQ
%left GTR LES GEQ LEQ
%left SHR SHL
%left ADD SUB
%left MUL DIV REM
%nonassoc INC_ASSIGN DEC_ASSIGN NOT BNT UMINUS


/* Yacc will start at this nonterminal */
%start Program

%%
/* Grammar section */

Program
    : { pushScope(); } GlobalStmtList { dumpScope(); }
    | /* Empty file */
;

GlobalStmtList
    : GlobalStmtList GlobalStmt
    | GlobalStmt
;

GlobalStmt
    : DefineVariableStmt
    | FunctionDefStmt
;

DefineVariableStmt
    : VARIABLE_T IDENT VAL_ASSIGN Expression ';'
;

/* Function */
FunctionDefStmt
    : VARIABLE_T IDENT { createFuncSig($2); } '(' FunctionParameterStmtList ')' { catFuncSig($2, $1, false); createFunction($1, $2); } '{' StmtList '}' { functionEnd(); dumpScope(); }
;
FunctionParameterStmtList
    : FunctionParameterStmtList ',' FunctionParameterStmt
    | FunctionParameterStmt
    | /* Empty function parameter */
;
FunctionParameterStmt
    : VARIABLE_T IDENT { catFuncSig(NULL, $1, false); }
    | VARIABLE_T IDENT '[' ']' { catFuncSig(NULL, $1, true); }
;

/* Scope */
StmtList
    : StmtList Stmt
    | Stmt
;
Stmt
    : ';'
    | COUT CoutParmListStmt ';'
    | RETURN Expression ';' { returnOperation(); }
    | RETURN ';' { returnOperation(); }
;

CoutParmListStmt
    : CoutParmListStmt SHL { codeRaw("getstatic java/lang/System/out Ljava/io/PrintStream;"); } Expression { stdoutPrint(); }
    | SHL { codeRaw("getstatic java/lang/System/out Ljava/io/PrintStream;"); } Expression { stdoutPrint(); }
;

 BinaryExpression
    : Expression ADD Expression { objectExpBinary('+'); }
    | Expression SUB Expression { objectExpBinary('-'); }
    | Expression MUL Expression { objectExpBinary('*'); }
    | Expression DIV Expression { objectExpBinary('/'); }
    | Expression REM Expression { objectExpBinary('%'); }
    | SUB Expression %prec UMINUS { objectNegExpression(); }
;

BoolExpression
    : Expression GTR Expression { objectExpBoolean(1); }
    | Expression LES Expression { objectExpBoolean(2); }
    | Expression GEQ Expression { objectExpBoolean(3); }
    | Expression LEQ Expression { objectExpBoolean(4); }
    | Expression EQL Expression { objectExpBoolean(5); }
    | Expression NEQ Expression { objectExpBoolean(6); }
    | Expression LAN Expression { objectExpBoolean(7); }
    | Expression LOR Expression { objectExpBoolean(8); }
    | NOT BoolExpression %prec NOT { objectExpBoolean(9); }
    | BOOL_LIT { code("%s", ($1 == 0 ? "iconst_0" : "iconst_1")); objectExpBoolean(0); }
;

Expression
    : '(' Expression ')' { $$ = $2; }
    | BinaryExpression
    | BoolExpression
    | IDENT { loadOperation($1); }
    | STR_LIT { code("ldc \"%s\"", $1); pushStackObject(OBJECT_TYPE_STR, NULL); }
    | INT_LIT { code("ldc %d", $1); pushStackObject(OBJECT_TYPE_INT, NULL); }
    | FLOAT_LIT { code("ldc %f", $<f_var>1); pushStackObject(OBJECT_TYPE_FLOAT, NULL); }
    | CHAR_LIT { code("bipush %d", (int)$<c_var>1); pushStackObject(OBJECT_TYPE_CHAR, NULL); }
;

%%
/* C code section */