This assignment is to generate Java assembly code (for Java Virtual Machines) of the given μGO program. The generated code will then be translated to the Java bytecode by the Java assembler, Jasmin. The generated Java bytecode should be run by the Java Virtual Machine (JVM) successfully.
Environmental Setup
Recommended OS: Ubuntu 18.04
Install dependencies: $ sudo apt install flex bison
Java Virtual Machine (JVM): $ sudo apt install default-jre Java Assembler (Jasmin) is included in the Compiler hw3 le. Judgmental tool: $ pip3 install local-judge
1. Java Assembly Code Generation
In this assignment, you have to build a μGO compiler. Figure 1 shows the big picture of this assignment and the descriptions for the execution steps are as follows.
Build your μGO compiler by injecting the Java assembly code into your ex/bison code developed in the previous assignments.
Run the compiler with the given μGO program (e.g., test.go le) to generate the corresponding Java assembly code (e.g., test.j le).
Run the Java assembler, Jasmin, to convert the Java assembly code into the Java bytecode (e.g., test.class le).
Run the generated Java bytecode (e.g., test.class le) with JVM and display the results.
1 / 13
2. Java Assembly Language (Jasmin Instructions)
In this section, we list the Jasmin instructions that you may use in developing your compiler.
2.1 Literals (Constants)
The table below lists the constants dened in μGO language. Also, the Jasmin instructions that we use to load the constants into the Java stack are given. More about the load instructions could be found in the course slides, Intermediate Representation.
Constant in μGO
94
"Hello world"
2.2 Operations
Jasmin Instruction
ldc 94
ldc "Hello world"
8.7 ldc 8.7
true / false iconst_1 / iconst_0 (or idc 1 / ldc 0 )
The tables below lists the μGO operators and the corresponding assembly code dened in Jasmin (i.e., Jasmin Instruction).
2.2.1 Unary Operators
μGO Operator Jasmin Instruction ( int32 )
+ – (ignore or a blank)
2.2.2 Binary Operators
Jasmin Instruction ( float32 ) – (ignore or a blank)
Jasmin Instruction ( float32 ) fadd
fmul
– ineg fneg
μGO Operator
+
*
Jasmin Instruction ( int32 ) iadd
imul
– isub fsub
/ idiv fdiv
%irem –
The following example shows the standard unary and binary arithmetic operations in μGO and the corresponding Jasmin instructions.
2 / 13
μGO Code:
-5 + 3 * 2
Jasmin Code (for reference only):
ldc 5 ineg ldc 3 ldc 2 imul iadd
2.2.3 Boolean Operators
μGO Operator
&&
||
Jasmin Instruction
iand
ior
ixor ( true xor b
!
equals to
not b )
μGO Code:
// Precedence: ! > && > ||
true || false && !false
Jasmin Code (for reference only):
iconst_1 iconst_0 iconst_1 iconst_0 ixor iand
ior
; true (1) ; false (2) ; load true for "not" operator ; false (3) ; get "not" result (4) from (3) ; get "and" result (5) from (2),(4) ; get "or" result from (1),(5)
2.2.4 Comparison operators
You need to use subtraction and jump instruction to complete comparison operations. For int32, you can use isub . For oat32, there is an instruction fcmpl is used to compare two oating-
3 / 13
point numbers. Note that the result should be bool type, i.e., 0 or 1. Jump instruction will be mentioned at section 2.6.
μGO Code:
Jasmin Code (for reference only):
1>2
2.0 < 3.1
ldc 1
ldc 2
isub
ifgt L_cmp_0
iconst_0
goto L_cmp_1
L_cmp_0:
iconst_1
L_cmp_1:
ldc 2.000000
ldc 3.100000
fcmpl
iflt L_cmp_2
iconst_0
goto L_cmp_3
L_cmp_2:
iconst_1
L_cmp_3:
2.3 Store/Load Variables
Relativeoperators: =, +=, -=, *=, /=, %=, ++, –. 2.3.1 Primitive Type
The following example shows how to load the constant at the top of the stack and store the value to the local variable ( x = 9 ). In addition, it then loads a constant to the Java stack, loads the content of the local variable, and adds the two values before the results are stored to the local variable ( ). Furthermore, the example code exhibits how to store a string to the local variable ( z = “Hello” ). The contents of local variables after the execution of the Jasmin code are shown as below.
y =4 + x
4 / 13
μGO Code:
x =9
y =4+ x
z = “Hello”
Jasmin Code (for reference only):
ldc 9 istore 0
ldc 4 iload 0 iadd istore 1
ldc "Hello" astore 2
; store 9 to x
; load x ; add 4 and x ; store the result to y
; store a string to z
2.4 Print
The following example shows how to print out the constants with the Jasmin code. Note that there is a little bit dierent for the actual parameters of the println functions invoked by the
instructions, i.e., int32 ( I ), oat32 ( F ), and string
( ). Note also that you need to treat bool type as string when encountering print statement, and the corresponding code segments are shown as below.
μGO Code:
Jasmin Code (for reference only):
invokevirtual
Ljava/lang/String;
println(30)
print("Hello")
print(true)
ldc 30 ; integer
getstatic java/lang/System/out Ljava/io/PrintStream; swap
invokevirtual java/io/PrintStream/println(I)V
ldc “Hello” ; string
getstatic java/lang/System/out Ljava/io/PrintStream;
swap
invokevirtual java/io/PrintStream/print(Ljava/lang/String;)V
5 / 13
6 / 13
2.5 Type Conversions (Type Casting)
The following example shows the usage of the casting instructions, i2f and f2i , where x is int32 local variable 0, y is oat32 local variable 1.
μGO Code:
Jasmin Code (for reference only):
x = x + int32(y)
iload 0 fload 1 f2i iadd istore 0
; x ; y ; convert y to int32 ; add them ; store to x
iconst_1 ; true
ifne L_cmp_0
ldc “false” ; we should load “false” and
goto L_cmp_1
L_cmp_0:
ldc "true" L_cmp_1:
; "true" as string literal for printing
getstatic java/lang/System/out Ljava/io/PrintStream;
swap
invokevirtual java/io/PrintStream/print(Ljava/lang/String;)V
2.6 Jump Instruction
The following example shows how to use jump instructions (both conditional and non-conditional branches). Jump instruction is used in if statement and for statement.
Jasmin Instruction
goto <label>
ifne <label>
ifle <label>
ifge <label>
Description
direct jump
jump if nonzero
jump if less than or equal to zero jump if greater than or equal to zero
ifeq <label> jump if zero
iflt <label> jump if less than zero
ifgt <label> jump if greater than zero
μGO Code (if statement, x is an int32 variable):
if x == 10 {
/* do something */
} else {
/* do the other thing */
}
Jasmin Code (for reference only):
iload 0
ldc 10
isub
ifeq L_cmp_0
iconst_0
goto L_cmp_1
L_cmp_0:
iconst_1
L_cmp_1:
ifeq L_if_false
goto L_if_exit
L_if_false: L_if_exit:
; load x ; load integer 10
; jump to L_cmp_0 if x == 0; ; if not, execute next line ; false (if x != 0) ; skip loading true to the stack ; by jumping to L_cmp_1
; if x == 0 jump to here ; true
; -> do something ; -> do the other thing
7 / 13
μGO Code (for statement, x is an oat32 variable):
var x float32 = 10.0 for x > 0.0 {
x–
println(x) }
Jasmin Code (for reference only):
ldc 10.000000 fstore 0 L_for_begin: fload 0
ldc 0.000000 fcmpl ifgt L_cmp_0 iconst_0 goto L_cmp_1
L_cmp_0:
iconst_1
L_cmp_1:
ifeq L_for_exit fload 0 ldc 1.0 fsub
fstore 0
fload 0
getstatic java/lang/System/out Ljava/io/PrintStream; swap
invokevirtual java/io/PrintStream/println(F)V
goto L_for_begin ; goto loop begin
L_for_exit:
; store 10.0 to x ; load x for comparison ; compare float32 numbers
; exit when the condition is false ;—+
; +— (x–)
;|
;---+ ; load x for println
8 / 13
μGO Code (switch statement, x is an int32 variable):
switch x { case 0: {
/* do something A */
}
case 1: {
/* do something B */
}
default: {
/* do something C */
} }
Jasmin Code (for reference only):
iload 0 ; x
goto L_switch_begin_0
L_case_0:
goto L_switch_end_0
L_case_1:
goto L_switch_end_0
L_case_2:
goto L_switch_end_0
L_switch_begin_0:
lookupswitch 0: L_case_0 1: L_case_1 default: L_case_2
L_switch_end_0:
return
; -> do something A ; exit switch statement
; -> do something B ; exit switch statement
; -> do something C ; exit switch statement
; a table with keys and labels
9 / 13
2.7 Method Invocation
There are several forms of method-calling instructions in the JVM. In this homework, methods are called using the instruction. The usage can be shown by following example. A function foo has signature that you have implemented in hw2, and this information is used during the code generation. The invokestatic Main/foo(II)I is used to invoke the method foo after two actual argumants ( 3 , 4 ) are loaded to the stack, and then the result of the function output will be pushed to the stack.
μGO Code:
invokestatic
package main
func foo(x int32, y int32) int32 {
return x + y }
func main() {
var z int32 = foo(3, 4) println(z)
return
}
Jasmin Code (for reference only):
(II)I
.method public static foo(II)I ; Define foo function .limit stack 20
.limit locals 20
iload 0 ; load the first argument iload 1 ; load the second argument iadd
ireturn
.end method
.method public static main([Ljava/lang/String;)V .limit stack 100
.limit locals 100
ldc 3 ; push argument to the stack
ldc 4 ; push argument to the stack
invokestatic Main/foo(II)I ; invoke `foo` method in `Main` class istore 2 ; store the result to z
iload 2 ; load z for println
getstatic java/lang/System/out Ljava/io/PrintStream;
swap
invokevirtual java/io/PrintStream/println(I)V
return
.end method
10 / 13
2.8 Setup Code
A valid Jasmin program should include the code segments for the execution environment setup. Your compiler should be able to generate the setup code, together with the translated Jasmin instructions (as shown in the previous paragraphs). The example code is listed as below.
Filename: hw3.j (generated by your compiler)
.source hw3.j
.class public Main .super java/lang/Object
; ... Your generated Jasmin code for the input μGO program ...
.method public static main([Ljava/lang/String;)V ; main function .limit stack 100 ; Define your storage size.
.limit locals 100 ; Define your local space number.
; ... Your generated Jasmin code for the input μGO program ...
return .end method
2.9 Workow Of The Assignment
You are required to build a μGO compiler based on the previous two assignments. The execution steps are described as follows.
Build your compiler by make command and you will get an executable named mycompiler .
Run your compiler using the command $ ./mycompiler < input.go , which is built by lex and yacc, with the given μGO code ( .go le) to generate the corresponding Java assembly code ( .j le).
The Java assembly code can be converted into the Java Bytecode ( le) through the Java assembler, Jasmin, i.e., use to generate
Main.class .
Run the Java program ( .class le) with Java Virtual Machine (JVM); the program should generate the execution results required by this assignment, i.e., use $ java Main to run the executable.
.class
$ java -jar jasmin.jar hw3.j
11 / 13
3. What Should Your Compiler Do?
In Assignment 3, the ex/bison le only need to print out the error messages, we score your assignment depending on the JVM execution result, i.e., the output of the command:
$ java Main .
When ERROR occurs during the parsing phase, we expect your compiler to print out ALL error messages (does not aect your score), as Assignment 2 did, and DO NOT generate the Java assembly code (.j le).
There are 11 test cases (each test case is 10pt and the total score is 110pt) in the Compiler hw3 le, and you can check the correctness by local-judge (type judge command in your terminal) as hw1 and hw2.
4. Submission
Hand in your homework with Moodle.
Only allow .zip format for compression.
The directory organization should be (change all StudentID to your student ID number):
Compiler_StudentID_HW3.zip/ └── Compiler_StudentID_HW3/
├── compiler_hw3.l
├── compiler_hw3.y
├── compiler_hw_common.h
├── jasmin.jar
└── Makefile
!!! Incorrect format will lose 10pt. !!!
5. Online Demonstration of Your Assignment 3
Demonstration will be held in virtual. The form and schedule of demonstration will be announced on Moodle later. During the demonstration, you will be asked to demonstrate your assignment downloaded from Moodle and you need to answer the questions about the logics of your codes in 5 ~ 10 minutes. The scores that you get for your Assignment 3 depend totally on how good your answers are. By default, the demonstration should be performed on TA’s PC.
12 / 13
6. References
Jasmin instructions: http://jasmin.sourceforge.net/instructions.html Java bytecode instruction listings:
https://en.wikipedia.org/wiki/Java_bytecode_instruction_listings
Java Language and Virtual Machine Specications: https://docs.oracle.com/javase/specs/ The Go (not μGo) Playground: https://go.dev/play/






