                        ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Bool..vtable:           ;; virtual function table for Bool
                        constant string1
                        constant Bool..new
                        constant Object.abort
                        constant Object.copy
                        constant Object.type_name
                        ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
IO..vtable:             ;; virtual function table for IO
                        constant string2
                        constant IO..new
                        constant Object.abort
                        constant Object.copy
                        constant Object.type_name
                        constant IO.in_int
                        constant IO.in_string
                        constant IO.out_int
                        constant IO.out_string
                        ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Int..vtable:            ;; virtual function table for Int
                        constant string3
                        constant Int..new
                        constant Object.abort
                        constant Object.copy
                        constant Object.type_name
                        ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Main..vtable:           ;; virtual function table for Main
                        constant string4
                        constant Main..new
                        constant Object.abort
                        constant Object.copy
                        constant Object.type_name
                        constant IO.in_int
                        constant IO.in_string
                        constant IO.out_int
                        constant IO.out_string
                        constant Main.main
                        ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Object..vtable:         ;; virtual function table for Object
                        constant string5
                        constant Object..new
                        constant Object.abort
                        constant Object.copy
                        constant Object.type_name
                        ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
String..vtable:         ;; virtual function table for String
                        constant string6
                        constant String..new
                        constant Object.abort
                        constant Object.copy
                        constant Object.type_name
                        constant String.concat
                        constant String.length
                        constant String.substr
                        ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Bool..new:              ;; constructor for Bool
                        mov fp <- sp
                        ;; stack room for temporaries: 1
                        li r2 <- 1
                        sub sp <- sp r2
                        push ra
                        li r0 <- 4
                        alloc r0 r0
                        ;; store class tag, object size and vtable pointer
                        li r2 <- 0
                        st r0[0] <- r2
                        li r2 <- 4
                        st r0[1] <- r2
                        la r2 <- Bool..vtable
                        st r0[2] <- r2
                        ;; initialize attributes
                        ;; self[3] holds field (raw content) (Int)
                        li r1 <- 0
                        st r0[3] <- r1
                        ;; self[3] (raw content) initializer -- none 
                        mov r1 <- r0
                        pop ra
                        li r2 <- 1
                        add sp <- sp r2
                        return
                        ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
IO..new:                ;; constructor for IO
                        mov fp <- sp
                        ;; stack room for temporaries: 1
                        li r2 <- 1
                        sub sp <- sp r2
                        push ra
                        li r0 <- 3
                        alloc r0 r0
                        ;; store class tag, object size and vtable pointer
                        li r2 <- 10
                        st r0[0] <- r2
                        li r2 <- 3
                        st r0[1] <- r2
                        la r2 <- IO..vtable
                        st r0[2] <- r2
                        mov r1 <- r0
                        pop ra
                        li r2 <- 1
                        add sp <- sp r2
                        return
                        ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Int..new:               ;; constructor for Int
                        mov fp <- sp
                        ;; stack room for temporaries: 1
                        li r2 <- 1
                        sub sp <- sp r2
                        push ra
                        li r0 <- 4
                        alloc r0 r0
                        ;; store class tag, object size and vtable pointer
                        li r2 <- 1
                        st r0[0] <- r2
                        li r2 <- 4
                        st r0[1] <- r2
                        la r2 <- Int..vtable
                        st r0[2] <- r2
                        ;; initialize attributes
                        ;; self[3] holds field (raw content) (Int)
                        li r1 <- 0
                        st r0[3] <- r1
                        ;; self[3] (raw content) initializer -- none 
                        mov r1 <- r0
                        pop ra
                        li r2 <- 1
                        add sp <- sp r2
                        return
                        ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Main..new:              ;; constructor for Main
                        mov fp <- sp
                        ;; stack room for temporaries: 1
                        li r2 <- 1
                        sub sp <- sp r2
                        push ra
                        li r0 <- 4
                        alloc r0 r0
                        ;; store class tag, object size and vtable pointer
                        li r2 <- 11
                        st r0[0] <- r2
                        li r2 <- 4
                        st r0[1] <- r2
                        la r2 <- Main..vtable
                        st r0[2] <- r2
                        ;; initialize attributes
                        ;; self[3] holds field mystr (String)
                        ;; new String
                        push fp
                        push r0
                        la r2 <- String..new
                        call r2
                        pop r0
                        pop fp
                        st r0[3] <- r1
                        ;; self[3] mystr initializer -- none 
                        mov r1 <- r0
                        pop ra
                        li r2 <- 1
                        add sp <- sp r2
                        return
                        ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Object..new:            ;; constructor for Object
                        mov fp <- sp
                        ;; stack room for temporaries: 1
                        li r2 <- 1
                        sub sp <- sp r2
                        push ra
                        li r0 <- 3
                        alloc r0 r0
                        ;; store class tag, object size and vtable pointer
                        li r2 <- 12
                        st r0[0] <- r2
                        li r2 <- 3
                        st r0[1] <- r2
                        la r2 <- Object..vtable
                        st r0[2] <- r2
                        mov r1 <- r0
                        pop ra
                        li r2 <- 1
                        add sp <- sp r2
                        return
                        ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
String..new:            ;; constructor for String
                        mov fp <- sp
                        ;; stack room for temporaries: 1
                        li r2 <- 1
                        sub sp <- sp r2
                        push ra
                        li r0 <- 4
                        alloc r0 r0
                        ;; store class tag, object size and vtable pointer
                        li r2 <- 3
                        st r0[0] <- r2
                        li r2 <- 4
                        st r0[1] <- r2
                        la r2 <- String..vtable
                        st r0[2] <- r2
                        ;; initialize attributes
                        ;; self[3] holds field (raw content) (String)
                        la r1 <- the.empty.string
                        st r0[3] <- r1
                        ;; self[3] (raw content) initializer -- none 
                        mov r1 <- r0
                        pop ra
                        li r2 <- 1
                        add sp <- sp r2
                        return
                        ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Object.abort:           ;; method definition
                        mov fp <- sp
                        pop r0
                        ;; stack room for temporaries: 1
                        li r2 <- 1
                        sub sp <- sp r2
                        push ra
                        ;; method body begins
                        la r1 <- string7
                        syscall IO.out_string
                        syscall exit
Object.abort.end:       ;; method body ends
                        pop ra
                        li r2 <- 1
                        add sp <- sp r2
                        return
                        ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Object.copy:            ;; method definition
                        mov fp <- sp
                        pop r0
                        ;; stack room for temporaries: 1
                        li r2 <- 1
                        sub sp <- sp r2
                        push ra
                        ;; method body begins
                        ld r2 <- r0[1]
                        alloc r1 r2
                        push r1
l1:                     bz r2 l2
                        ld r3 <- r0[0]
                        st r1[0] <- r3
                        li r3 <- 1
                        add r0 <- r0 r3
                        add r1 <- r1 r3
                        li r3 <- 1
                        sub r2 <- r2 r3
                        jmp l1
l2:                     ;; done with Object.copy loop
                        pop r1
Object.copy.end:        ;; method body ends
                        pop ra
                        li r2 <- 1
                        add sp <- sp r2
                        return
                        ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Object.type_name:       ;; method definition
                        mov fp <- sp
                        pop r0
                        ;; stack room for temporaries: 1
                        li r2 <- 1
                        sub sp <- sp r2
                        push ra
                        ;; method body begins
                        ;; new String
                        push fp
                        push r0
                        la r2 <- String..new
                        call r2
                        pop r0
                        pop fp
                        ;; obtain vtable for self object
                        ld r2 <- r0[2]
                        ;; look up type name at offset 0 in vtable
                        ld r2 <- r2[0]
                        st r1[3] <- r2
Object.type_name.end:   ;; method body ends
                        pop ra
                        li r2 <- 1
                        add sp <- sp r2
                        return
                        ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
IO.in_int:              ;; method definition
                        mov fp <- sp
                        pop r0
                        ;; stack room for temporaries: 1
                        li r2 <- 1
                        sub sp <- sp r2
                        push ra
                        ;; method body begins
                        ;; new Int
                        push fp
                        push r0
                        la r2 <- Int..new
                        call r2
                        pop r0
                        pop fp
                        mov r2 <- r1
                        syscall IO.in_int
                        st r2[3] <- r1
                        mov r1 <- r2
IO.in_int.end:          ;; method body ends
                        pop ra
                        li r2 <- 1
                        add sp <- sp r2
                        return
                        ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
IO.in_string:           ;; method definition
                        mov fp <- sp
                        pop r0
                        ;; stack room for temporaries: 1
                        li r2 <- 1
                        sub sp <- sp r2
                        push ra
                        ;; method body begins
                        ;; new String
                        push fp
                        push r0
                        la r2 <- String..new
                        call r2
                        pop r0
                        pop fp
                        mov r2 <- r1
                        syscall IO.in_string
                        st r2[3] <- r1
                        mov r1 <- r2
IO.in_string.end:       ;; method body ends
                        pop ra
                        li r2 <- 1
                        add sp <- sp r2
                        return
                        ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
IO.out_int:             ;; method definition
                        mov fp <- sp
                        pop r0
                        ;; stack room for temporaries: 1
                        li r2 <- 1
                        sub sp <- sp r2
                        push ra
                        ;; fp[2] holds argument x (Int)
                        ;; method body begins
                        ld r2 <- fp[2]
                        ld r1 <- r2[3]
                        syscall IO.out_int
                        mov r1 <- r0
IO.out_int.end:         ;; method body ends
                        pop ra
                        li r2 <- 2
                        add sp <- sp r2
                        return
                        ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
IO.out_string:          ;; method definition
                        mov fp <- sp
                        pop r0
                        ;; stack room for temporaries: 1
                        li r2 <- 1
                        sub sp <- sp r2
                        push ra
                        ;; fp[2] holds argument x (String)
                        ;; method body begins
                        ld r2 <- fp[2]
                        ld r1 <- r2[3]
                        syscall IO.out_string
                        mov r1 <- r0
IO.out_string.end:      ;; method body ends
                        pop ra
                        li r2 <- 2
                        add sp <- sp r2
                        return
                        ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Main.main:              ;; method definition
                        mov fp <- sp
                        pop r0
                        ;; stack room for temporaries: 1
                        li r2 <- 1
                        sub sp <- sp r2
                        push ra
                        ;; self[3] holds field mystr (String)
                        ;; method body begins
                        ;; new String
                        push fp
                        push r0
                        la r2 <- String..new
                        call r2
                        pop r0
                        pop fp
                        st r0[3] <- r1
                        ;; mystr.concat(...)
                        push r0
                        push fp
                        ;; new String
                        push fp
                        push r0
                        la r2 <- String..new
                        call r2
                        pop r0
                        pop fp
                        ;; string8 holds "N"
                        la r2 <- string8
                        st r1[3] <- r2
                        push r1
                        ;; mystr
                        ld r1 <- r0[3]
                        bnz r1 l3
                        la r1 <- string9
                        syscall IO.out_string
                        syscall exit
l3:                     push r1
                        ;; obtain vtable from object in r1 with static type String
                        ld r2 <- r1[2]
                        ;; look up concat() at offset 5 in vtable
                        ld r2 <- r2[5]
                        call r2
                        pop fp
                        pop r0
                        st r0[3] <- r1
                        ;; mystr.concat(...)
                        push r0
                        push fp
                        ;; new String
                        push fp
                        push r0
                        la r2 <- String..new
                        call r2
                        pop r0
                        pop fp
                        ;; string10 holds "I"
                        la r2 <- string10
                        st r1[3] <- r2
                        push r1
                        ;; mystr
                        ld r1 <- r0[3]
                        bnz r1 l4
                        la r1 <- string11
                        syscall IO.out_string
                        syscall exit
l4:                     push r1
                        ;; obtain vtable from object in r1 with static type String
                        ld r2 <- r1[2]
                        ;; look up concat() at offset 5 in vtable
                        ld r2 <- r2[5]
                        call r2
                        pop fp
                        pop r0
                        st r0[3] <- r1
                        ;; mystr.concat(...)
                        push r0
                        push fp
                        ;; new String
                        push fp
                        push r0
                        la r2 <- String..new
                        call r2
                        pop r0
                        pop fp
                        ;; string12 holds "C"
                        la r2 <- string12
                        st r1[3] <- r2
                        push r1
                        ;; mystr
                        ld r1 <- r0[3]
                        bnz r1 l5
                        la r1 <- string13
                        syscall IO.out_string
                        syscall exit
l5:                     push r1
                        ;; obtain vtable from object in r1 with static type String
                        ld r2 <- r1[2]
                        ;; look up concat() at offset 5 in vtable
                        ld r2 <- r2[5]
                        call r2
                        pop fp
                        pop r0
                        st r0[3] <- r1
                        ;; mystr.concat(...)
                        push r0
                        push fp
                        ;; new String
                        push fp
                        push r0
                        la r2 <- String..new
                        call r2
                        pop r0
                        pop fp
                        ;; string12 holds "C"
                        la r2 <- string12
                        st r1[3] <- r2
                        push r1
                        ;; mystr
                        ld r1 <- r0[3]
                        bnz r1 l6
                        la r1 <- string14
                        syscall IO.out_string
                        syscall exit
l6:                     push r1
                        ;; obtain vtable from object in r1 with static type String
                        ld r2 <- r1[2]
                        ;; look up concat() at offset 5 in vtable
                        ld r2 <- r2[5]
                        call r2
                        pop fp
                        pop r0
                        st r0[3] <- r1
                        ;; mystr.concat(...)
                        push r0
                        push fp
                        ;; new String
                        push fp
                        push r0
                        la r2 <- String..new
                        call r2
                        pop r0
                        pop fp
                        ;; string15 holds "{"
                        la r2 <- string15
                        st r1[3] <- r2
                        push r1
                        ;; mystr
                        ld r1 <- r0[3]
                        bnz r1 l7
                        la r1 <- string16
                        syscall IO.out_string
                        syscall exit
l7:                     push r1
                        ;; obtain vtable from object in r1 with static type String
                        ld r2 <- r1[2]
                        ;; look up concat() at offset 5 in vtable
                        ld r2 <- r2[5]
                        call r2
                        pop fp
                        pop r0
                        st r0[3] <- r1
                        ;; mystr.concat(...)
                        push r0
                        push fp
                        ;; new String
                        push fp
                        push r0
                        la r2 <- String..new
                        call r2
                        pop r0
                        pop fp
                        ;; string17 holds "h"
                        la r2 <- string17
                        st r1[3] <- r2
                        push r1
                        ;; mystr
                        ld r1 <- r0[3]
                        bnz r1 l8
                        la r1 <- string18
                        syscall IO.out_string
                        syscall exit
l8:                     push r1
                        ;; obtain vtable from object in r1 with static type String
                        ld r2 <- r1[2]
                        ;; look up concat() at offset 5 in vtable
                        ld r2 <- r2[5]
                        call r2
                        pop fp
                        pop r0
                        st r0[3] <- r1
                        ;; mystr.concat(...)
                        push r0
                        push fp
                        ;; new String
                        push fp
                        push r0
                        la r2 <- String..new
                        call r2
                        pop r0
                        pop fp
                        ;; string19 holds "E"
                        la r2 <- string19
                        st r1[3] <- r2
                        push r1
                        ;; mystr
                        ld r1 <- r0[3]
                        bnz r1 l9
                        la r1 <- string20
                        syscall IO.out_string
                        syscall exit
l9:                     push r1
                        ;; obtain vtable from object in r1 with static type String
                        ld r2 <- r1[2]
                        ;; look up concat() at offset 5 in vtable
                        ld r2 <- r2[5]
                        call r2
                        pop fp
                        pop r0
                        st r0[3] <- r1
                        ;; mystr.concat(...)
                        push r0
                        push fp
                        ;; new String
                        push fp
                        push r0
                        la r2 <- String..new
                        call r2
                        pop r0
                        pop fp
                        ;; string21 holds "y"
                        la r2 <- string21
                        st r1[3] <- r2
                        push r1
                        ;; mystr
                        ld r1 <- r0[3]
                        bnz r1 l10
                        la r1 <- string22
                        syscall IO.out_string
                        syscall exit
l10:                    push r1
                        ;; obtain vtable from object in r1 with static type String
                        ld r2 <- r1[2]
                        ;; look up concat() at offset 5 in vtable
                        ld r2 <- r2[5]
                        call r2
                        pop fp
                        pop r0
                        st r0[3] <- r1
                        ;; mystr.concat(...)
                        push r0
                        push fp
                        ;; new String
                        push fp
                        push r0
                        la r2 <- String..new
                        call r2
                        pop r0
                        pop fp
                        ;; string23 holds "_"
                        la r2 <- string23
                        st r1[3] <- r2
                        push r1
                        ;; mystr
                        ld r1 <- r0[3]
                        bnz r1 l11
                        la r1 <- string24
                        syscall IO.out_string
                        syscall exit
l11:                    push r1
                        ;; obtain vtable from object in r1 with static type String
                        ld r2 <- r1[2]
                        ;; look up concat() at offset 5 in vtable
                        ld r2 <- r2[5]
                        call r2
                        pop fp
                        pop r0
                        st r0[3] <- r1
                        ;; mystr.concat(...)
                        push r0
                        push fp
                        ;; new String
                        push fp
                        push r0
                        la r2 <- String..new
                        call r2
                        pop r0
                        pop fp
                        ;; string25 holds "t"
                        la r2 <- string25
                        st r1[3] <- r2
                        push r1
                        ;; mystr
                        ld r1 <- r0[3]
                        bnz r1 l12
                        la r1 <- string26
                        syscall IO.out_string
                        syscall exit
l12:                    push r1
                        ;; obtain vtable from object in r1 with static type String
                        ld r2 <- r1[2]
                        ;; look up concat() at offset 5 in vtable
                        ld r2 <- r2[5]
                        call r2
                        pop fp
                        pop r0
                        st r0[3] <- r1
                        ;; mystr.concat(...)
                        push r0
                        push fp
                        ;; new String
                        push fp
                        push r0
                        la r2 <- String..new
                        call r2
                        pop r0
                        pop fp
                        ;; string17 holds "h"
                        la r2 <- string17
                        st r1[3] <- r2
                        push r1
                        ;; mystr
                        ld r1 <- r0[3]
                        bnz r1 l13
                        la r1 <- string27
                        syscall IO.out_string
                        syscall exit
l13:                    push r1
                        ;; obtain vtable from object in r1 with static type String
                        ld r2 <- r1[2]
                        ;; look up concat() at offset 5 in vtable
                        ld r2 <- r2[5]
                        call r2
                        pop fp
                        pop r0
                        st r0[3] <- r1
                        ;; mystr.concat(...)
                        push r0
                        push fp
                        ;; new String
                        push fp
                        push r0
                        la r2 <- String..new
                        call r2
                        pop r0
                        pop fp
                        ;; string28 holds "1"
                        la r2 <- string28
                        st r1[3] <- r2
                        push r1
                        ;; mystr
                        ld r1 <- r0[3]
                        bnz r1 l14
                        la r1 <- string29
                        syscall IO.out_string
                        syscall exit
l14:                    push r1
                        ;; obtain vtable from object in r1 with static type String
                        ld r2 <- r1[2]
                        ;; look up concat() at offset 5 in vtable
                        ld r2 <- r2[5]
                        call r2
                        pop fp
                        pop r0
                        st r0[3] <- r1
                        ;; mystr.concat(...)
                        push r0
                        push fp
                        ;; new String
                        push fp
                        push r0
                        la r2 <- String..new
                        call r2
                        pop r0
                        pop fp
                        ;; string30 holds "s"
                        la r2 <- string30
                        st r1[3] <- r2
                        push r1
                        ;; mystr
                        ld r1 <- r0[3]
                        bnz r1 l15
                        la r1 <- string31
                        syscall IO.out_string
                        syscall exit
l15:                    push r1
                        ;; obtain vtable from object in r1 with static type String
                        ld r2 <- r1[2]
                        ;; look up concat() at offset 5 in vtable
                        ld r2 <- r2[5]
                        call r2
                        pop fp
                        pop r0
                        st r0[3] <- r1
                        ;; mystr.concat(...)
                        push r0
                        push fp
                        ;; new String
                        push fp
                        push r0
                        la r2 <- String..new
                        call r2
                        pop r0
                        pop fp
                        ;; string32 holds "-"
                        la r2 <- string32
                        st r1[3] <- r2
                        push r1
                        ;; mystr
                        ld r1 <- r0[3]
                        bnz r1 l16
                        la r1 <- string33
                        syscall IO.out_string
                        syscall exit
l16:                    push r1
                        ;; obtain vtable from object in r1 with static type String
                        ld r2 <- r1[2]
                        ;; look up concat() at offset 5 in vtable
                        ld r2 <- r2[5]
                        call r2
                        pop fp
                        pop r0
                        st r0[3] <- r1
                        ;; mystr.concat(...)
                        push r0
                        push fp
                        ;; new String
                        push fp
                        push r0
                        la r2 <- String..new
                        call r2
                        pop r0
                        pop fp
                        ;; string34 holds "i"
                        la r2 <- string34
                        st r1[3] <- r2
                        push r1
                        ;; mystr
                        ld r1 <- r0[3]
                        bnz r1 l17
                        la r1 <- string35
                        syscall IO.out_string
                        syscall exit
l17:                    push r1
                        ;; obtain vtable from object in r1 with static type String
                        ld r2 <- r1[2]
                        ;; look up concat() at offset 5 in vtable
                        ld r2 <- r2[5]
                        call r2
                        pop fp
                        pop r0
                        st r0[3] <- r1
                        ;; mystr.concat(...)
                        push r0
                        push fp
                        ;; new String
                        push fp
                        push r0
                        la r2 <- String..new
                        call r2
                        pop r0
                        pop fp
                        ;; string30 holds "s"
                        la r2 <- string30
                        st r1[3] <- r2
                        push r1
                        ;; mystr
                        ld r1 <- r0[3]
                        bnz r1 l18
                        la r1 <- string36
                        syscall IO.out_string
                        syscall exit
l18:                    push r1
                        ;; obtain vtable from object in r1 with static type String
                        ld r2 <- r1[2]
                        ;; look up concat() at offset 5 in vtable
                        ld r2 <- r2[5]
                        call r2
                        pop fp
                        pop r0
                        st r0[3] <- r1
                        ;; mystr.concat(...)
                        push r0
                        push fp
                        ;; new String
                        push fp
                        push r0
                        la r2 <- String..new
                        call r2
                        pop r0
                        pop fp
                        ;; string23 holds "_"
                        la r2 <- string23
                        st r1[3] <- r2
                        push r1
                        ;; mystr
                        ld r1 <- r0[3]
                        bnz r1 l19
                        la r1 <- string37
                        syscall IO.out_string
                        syscall exit
l19:                    push r1
                        ;; obtain vtable from object in r1 with static type String
                        ld r2 <- r1[2]
                        ;; look up concat() at offset 5 in vtable
                        ld r2 <- r2[5]
                        call r2
                        pop fp
                        pop r0
                        st r0[3] <- r1
                        ;; mystr.concat(...)
                        push r0
                        push fp
                        ;; new String
                        push fp
                        push r0
                        la r2 <- String..new
                        call r2
                        pop r0
                        pop fp
                        ;; string12 holds "C"
                        la r2 <- string12
                        st r1[3] <- r2
                        push r1
                        ;; mystr
                        ld r1 <- r0[3]
                        bnz r1 l20
                        la r1 <- string38
                        syscall IO.out_string
                        syscall exit
l20:                    push r1
                        ;; obtain vtable from object in r1 with static type String
                        ld r2 <- r1[2]
                        ;; look up concat() at offset 5 in vtable
                        ld r2 <- r2[5]
                        call r2
                        pop fp
                        pop r0
                        st r0[3] <- r1
                        ;; mystr.concat(...)
                        push r0
                        push fp
                        ;; new String
                        push fp
                        push r0
                        la r2 <- String..new
                        call r2
                        pop r0
                        pop fp
                        ;; string39 holds "o"
                        la r2 <- string39
                        st r1[3] <- r2
                        push r1
                        ;; mystr
                        ld r1 <- r0[3]
                        bnz r1 l21
                        la r1 <- string40
                        syscall IO.out_string
                        syscall exit
l21:                    push r1
                        ;; obtain vtable from object in r1 with static type String
                        ld r2 <- r1[2]
                        ;; look up concat() at offset 5 in vtable
                        ld r2 <- r2[5]
                        call r2
                        pop fp
                        pop r0
                        st r0[3] <- r1
                        ;; mystr.concat(...)
                        push r0
                        push fp
                        ;; new String
                        push fp
                        push r0
                        la r2 <- String..new
                        call r2
                        pop r0
                        pop fp
                        ;; string41 holds "0"
                        la r2 <- string41
                        st r1[3] <- r2
                        push r1
                        ;; mystr
                        ld r1 <- r0[3]
                        bnz r1 l22
                        la r1 <- string42
                        syscall IO.out_string
                        syscall exit
l22:                    push r1
                        ;; obtain vtable from object in r1 with static type String
                        ld r2 <- r1[2]
                        ;; look up concat() at offset 5 in vtable
                        ld r2 <- r2[5]
                        call r2
                        pop fp
                        pop r0
                        st r0[3] <- r1
                        ;; mystr.concat(...)
                        push r0
                        push fp
                        ;; new String
                        push fp
                        push r0
                        la r2 <- String..new
                        call r2
                        pop r0
                        pop fp
                        ;; string43 holds "L"
                        la r2 <- string43
                        st r1[3] <- r2
                        push r1
                        ;; mystr
                        ld r1 <- r0[3]
                        bnz r1 l23
                        la r1 <- string44
                        syscall IO.out_string
                        syscall exit
l23:                    push r1
                        ;; obtain vtable from object in r1 with static type String
                        ld r2 <- r1[2]
                        ;; look up concat() at offset 5 in vtable
                        ld r2 <- r2[5]
                        call r2
                        pop fp
                        pop r0
                        st r0[3] <- r1
                        ;; mystr.concat(...)
                        push r0
                        push fp
                        ;; new String
                        push fp
                        push r0
                        la r2 <- String..new
                        call r2
                        pop r0
                        pop fp
                        ;; string45 holds "}"
                        la r2 <- string45
                        st r1[3] <- r2
                        push r1
                        ;; mystr
                        ld r1 <- r0[3]
                        bnz r1 l24
                        la r1 <- string46
                        syscall IO.out_string
                        syscall exit
l24:                    push r1
                        ;; obtain vtable from object in r1 with static type String
                        ld r2 <- r1[2]
                        ;; look up concat() at offset 5 in vtable
                        ld r2 <- r2[5]
                        call r2
                        pop fp
                        pop r0
                        st r0[3] <- r1
                        ;; out_string(...)
                        push r0
                        push fp
                        ;; mystr
                        ld r1 <- r0[3]
                        push r1
                        push r0
                        ;; obtain vtable for self object of type Main
                        ld r2 <- r0[2]
                        ;; look up out_string() at offset 8 in vtable
                        ld r2 <- r2[8]
                        call r2
                        pop fp
                        pop r0
Main.main.end:          ;; method body ends
                        pop ra
                        li r2 <- 1
                        add sp <- sp r2
                        return
                        ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
String.concat:          ;; method definition
                        mov fp <- sp
                        pop r0
                        ;; stack room for temporaries: 1
                        li r2 <- 1
                        sub sp <- sp r2
                        push ra
                        ;; fp[2] holds argument s (String)
                        ;; method body begins
                        ;; new String
                        push fp
                        push r0
                        la r2 <- String..new
                        call r2
                        pop r0
                        pop fp
                        mov r3 <- r1
                        ld r2 <- fp[2]
                        ld r2 <- r2[3]
                        ld r1 <- r0[3]
                        syscall String.concat
                        st r3[3] <- r1
                        mov r1 <- r3
String.concat.end:      ;; method body ends
                        pop ra
                        li r2 <- 2
                        add sp <- sp r2
                        return
                        ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
String.length:          ;; method definition
                        mov fp <- sp
                        pop r0
                        ;; stack room for temporaries: 1
                        li r2 <- 1
                        sub sp <- sp r2
                        push ra
                        ;; method body begins
                        ;; new Int
                        push fp
                        push r0
                        la r2 <- Int..new
                        call r2
                        pop r0
                        pop fp
                        mov r2 <- r1
                        ld r1 <- r0[3]
                        syscall String.length
                        st r2[3] <- r1
                        mov r1 <- r2
String.length.end:      ;; method body ends
                        pop ra
                        li r2 <- 1
                        add sp <- sp r2
                        return
                        ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
String.substr:          ;; method definition
                        mov fp <- sp
                        pop r0
                        ;; stack room for temporaries: 1
                        li r2 <- 1
                        sub sp <- sp r2
                        push ra
                        ;; fp[3] holds argument i (Int)
                        ;; fp[2] holds argument l (Int)
                        ;; method body begins
                        ;; new String
                        push fp
                        push r0
                        la r2 <- String..new
                        call r2
                        pop r0
                        pop fp
                        mov r3 <- r1
                        ld r2 <- fp[2]
                        ld r2 <- r2[3]
                        ld r1 <- fp[3]
                        ld r1 <- r1[3]
                        ld r0 <- r0[3]
                        syscall String.substr
                        bnz r1 l25
                        la r1 <- string47
                        syscall IO.out_string
                        syscall exit
l25:                    st r3[3] <- r1
                        mov r1 <- r3
String.substr.end:      ;; method body ends
                        pop ra
                        li r2 <- 3
                        add sp <- sp r2
                        return
                        ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
                        ;; global string constants
			;; ERROR
                        ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
eq_handler:             ;; helper function for =
                        mov fp <- sp
                        pop r0
                        push ra
                        ld r1 <- fp[3]
                        ld r2 <- fp[2]
                        beq r1 r2 eq_true
                        li r3 <- 0
                        beq r1 r3 eq_false
                        beq r2 r3 eq_false
                        ld r1 <- r1[0]
                        ld r2 <- r2[0]
                        ;; place the sum of the type tags in r1
                        add r1 <- r1 r2
                        li r2 <- 0
                        beq r1 r2 eq_bool
                        li r2 <- 2
                        beq r1 r2 eq_int
                        li r2 <- 6
                        beq r1 r2 eq_string
                        ;; otherwise, use pointer comparison
                        ld r1 <- fp[3]
                        ld r2 <- fp[2]
                        beq r1 r2 eq_true
eq_false:               ;; not equal
                        ;; new Bool
                        push fp
                        push r0
                        la r2 <- Bool..new
                        call r2
                        pop r0
                        pop fp
                        jmp eq_end
eq_true:                ;; equal
                        ;; new Bool
                        push fp
                        push r0
                        la r2 <- Bool..new
                        call r2
                        pop r0
                        pop fp
                        li r2 <- 1
                        st r1[3] <- r2
                        jmp eq_end
eq_bool:                ;; two Bools
eq_int:                 ;; two Ints
                        ld r1 <- fp[3]
                        ld r2 <- fp[2]
                        ld r1 <- r1[3]
                        ld r2 <- r2[3]
                        beq r1 r2 eq_true
                        jmp eq_false
eq_string:              ;; two Strings
                        ld r1 <- fp[3]
                        ld r2 <- fp[2]
                        ld r1 <- r1[3]
                        ld r2 <- r2[3]
                        ld r1 <- r1[0]
                        ld r2 <- r2[0]
                        beq r1 r2 eq_true
                        jmp eq_false
eq_end:                 pop ra
                        li r2 <- 2
                        add sp <- sp r2
                        return
                        ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
le_handler:             ;; helper function for <=
                        mov fp <- sp
                        pop r0
                        push ra
                        ld r1 <- fp[3]
                        ld r2 <- fp[2]
                        beq r1 r2 le_true
                        li r3 <- 0
                        beq r1 r3 le_false
                        beq r2 r3 le_false
                        ld r1 <- r1[0]
                        ld r2 <- r2[0]
                        ;; place the sum of the type tags in r1
                        add r1 <- r1 r2
                        li r2 <- 0
                        beq r1 r2 le_bool
                        li r2 <- 2
                        beq r1 r2 le_int
                        li r2 <- 6
                        beq r1 r2 le_string
                        ;; for non-primitives, equality is our only hope
                        ld r1 <- fp[3]
                        ld r2 <- fp[2]
                        beq r1 r2 le_true
le_false:               ;; not less-than-or-equal
                        ;; new Bool
                        push fp
                        push r0
                        la r2 <- Bool..new
                        call r2
                        pop r0
                        pop fp
                        jmp le_end
le_true:                ;; less-than-or-equal
                        ;; new Bool
                        push fp
                        push r0
                        la r2 <- Bool..new
                        call r2
                        pop r0
                        pop fp
                        li r2 <- 1
                        st r1[3] <- r2
                        jmp le_end
le_bool:                ;; two Bools
le_int:                 ;; two Ints
                        ld r1 <- fp[3]
                        ld r2 <- fp[2]
                        ld r1 <- r1[3]
                        ld r2 <- r2[3]
                        ble r1 r2 le_true
                        jmp le_false
le_string:              ;; two Strings
                        ld r1 <- fp[3]
                        ld r2 <- fp[2]
                        ld r1 <- r1[3]
                        ld r2 <- r2[3]
                        ld r1 <- r1[0]
                        ld r2 <- r2[0]
                        ble r1 r2 le_true
                        jmp le_false
le_end:                 pop ra
                        li r2 <- 2
                        add sp <- sp r2
                        return
                        ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
lt_handler:             ;; helper function for <
                        mov fp <- sp
                        pop r0
                        push ra
                        ld r1 <- fp[3]
                        ld r2 <- fp[2]
                        li r3 <- 0
                        beq r1 r3 lt_false
                        beq r2 r3 lt_false
                        ld r1 <- r1[0]
                        ld r2 <- r2[0]
                        ;; place the sum of the type tags in r1
                        add r1 <- r1 r2
                        li r2 <- 0
                        beq r1 r2 lt_bool
                        li r2 <- 2
                        beq r1 r2 lt_int
                        li r2 <- 6
                        beq r1 r2 lt_string
                        ;; for non-primitives, < is always false
lt_false:               ;; not less than
                        ;; new Bool
                        push fp
                        push r0
                        la r2 <- Bool..new
                        call r2
                        pop r0
                        pop fp
                        jmp lt_end
lt_true:                ;; less than
                        ;; new Bool
                        push fp
                        push r0
                        la r2 <- Bool..new
                        call r2
                        pop r0
                        pop fp
                        li r2 <- 1
                        st r1[3] <- r2
                        jmp lt_end
lt_bool:                ;; two Bools
lt_int:                 ;; two Ints
                        ld r1 <- fp[3]
                        ld r2 <- fp[2]
                        ld r1 <- r1[3]
                        ld r2 <- r2[3]
                        blt r1 r2 lt_true
                        jmp lt_false
lt_string:              ;; two Strings
                        ld r1 <- fp[3]
                        ld r2 <- fp[2]
                        ld r1 <- r1[3]
                        ld r2 <- r2[3]
                        ld r1 <- r1[0]
                        ld r2 <- r2[0]
                        blt r1 r2 lt_true
                        jmp lt_false
lt_end:                 pop ra
                        li r2 <- 2
                        add sp <- sp r2
                        return
                        ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
start:                  ;; program begins here
                        la r2 <- Main..new
                        push fp
                        call r2
                        push fp
                        push r1
                        la r2 <- Main.main
                        call r2
                        syscall exit
