# Function print
  lw a0, 4(sp)                             # Load arg
  beq a0, zero, print_6                    # None is an illegal argument
  lw t0, 0(a0)                             # Get type tag of arg
  li t1, 1                                 # Load type tag of `int`
  beq t0, t1, print_7                      # Go to print(int)
  li t1, 3                                 # Load type tag of `str`
  beq t0, t1, print_8                      # Go to print(str)
  li t1, 2                                 # Load type tag of `bool`
  beq t0, t1, print_9                      # Go to print(bool)
print_6:                                   # Invalid argument
  li a0, 1                                 # Exit code for: Invalid argument
  la a1, STRING["Invalid argument"]        # Load error message as str
  addi a1, a1, 16                          # Load address of attribute __str__
  j abort                                  # Abort
	
# Printing bools
print_9:                                   # Print bool object in A0
  lw a0, 12(a0)                            # Load attribute __bool__
  beq a0, zero, print_10                   # Go to: print(False)
  la a0, STRING["True"]                    # String representation: True
  j print_8                                # Go to: print(str)
print_10:                                  # Print False object in A0
  la a0, STRING["False"]                   # String representation: False
  j print_8                                # Go to: print(str)

# Printing strs.        
print_8:                                   # Print str object in A0
  addi a1, a0, 16                          # Load address of attribute __str__
  j print_11                               # Print the null-terminated string is now in A1
  mv a0, zero                              # Load None
  j print_5                                # Go to return
print_11:                                  # Print null-terminated string in A1
  li a0, 4                                 # Code for ecall: print_string
  ecall                                    # Print string
  li a1, 10                                # Load newline character
  li a0, 11                                # Code for ecall: print_char
  ecall                                    # Print character
  j print_5                                # Go to return
	
# Printing ints.
print_7:                                   # Print int object in A0
  lw a1, 12(a0)                            # Load attribute __int__
  li a0, 1                                 # Code for ecall: print_int
  ecall                                    # Print integer
  li a1, 10                                # Load newline character
  li a0, 11                                # Code for ecall: print_char
  ecall                                    # Print character
  mv a0, zero                              # Load None
  mv a0, zero                              # Load None
	
print_5:                                   # End of function
  jr ra                                    # Return to caller
