def entry(self): self.write_file('entry:', tabbed=False) self.visit(cil.Call(dest = None, f = 'build_class_name_table')) self.visit(cil.Call(dest = None, f = 'allocate_prototypes_table')) self.visit(cil.Call(dest = None, f = 'build_prototypes')) self.visit(cil.Call(dest = None, f = 'build_dispatch_tables')) self.visit(cil.Call(dest = None, f = 'build_class_parents_table')) self.visit(cil.Allocate(dest = None, ttype = 'Main')) # Push main self self.write_file('sw $v0 0($sp)') self.write_file('addiu $sp $sp -4') self.visit(cil.Call(dest = None, f = f'Main_{INIT_CIL_SUFFIX}')) self.write_file('addiu $sp $sp 4') # Push main self self.write_file('sw $v0 0($sp)') self.write_file('addiu $sp $sp -4') self.visit(cil.Call(dest = None, f = 'Main_main')) self.write_file('addiu $sp $sp 4') self.write_file('li $v0 10') self.write_file('syscall')
def object_typename(self): self.write_file('function_Object_type_name:', tabbed=False) # Set up stack frame self.write_file(f'move $fp, $sp') # Box the string reference self.visit(cil.Allocate(dest = None, ttype = STRING_CLASS)) # Create new String object self.write_file('move $v1 $v0') # Box string's length self.visit(cil.Allocate(dest = None, ttype = INTEGER_CLASS) ) # Create new Int object self.write_file('lw $a1 12($fp)') # self self.write_file('lw $a1 0($a1)') self.write_file('mulu $a1 $a1 4') # self's class tag self.write_file('addu $a1 $a1 $s1') # class name table entry address self.write_file('lw $a1 0($a1)') # Get class name address self.write_file('move $a2 $0') # Compute string's length self.write_file('move $t2 $a1') self.write_file('_str_len_clsname_:', tabbed=False) self.write_file('lb $a0 0($t2)') self.write_file('beq $a0 $0 _end_clsname_len_') self.write_file('addiu $a2 $a2 1') self.write_file('addiu $t2 $t2 1') self.write_file('j _str_len_clsname_') self.write_file('_end_clsname_len_:', tabbed=False) self.write_file('sw $a2, 12($v0)') # Store string's length self.write_file('sw $v0, 12($v1)') # Fill String attributes self.write_file('sw $a1, 16($v1)') self.write_file('move $v0 $v1') self.write_file('jr $ra') self.write_file('')
def io_in_int(self): self.write_file('function_IO_in_int:', tabbed=False) # Set up stack frame self.write_file(f'move $fp, $sp') self.visit(cil.Allocate(dest = None, ttype = INTEGER_CLASS)) # Create new Int object self.write_file('move $t0 $v0') # Save Int object self.write_file('li $v0 5') # Read int self.write_file('syscall') self.write_file('sw $v0 12($t0)') # Store int self.write_file('move $v0 $t0') self.write_file('jr $ra') self.write_file('')
def isvoid(self): self.write_file(f'function_{ISVOID_FUNC}:', tabbed=False) # Set up stack frame self.write_file(f'move $fp, $sp') self.visit(cil.Allocate(dest = None, ttype = BOOLEAN_CLASS)) # $v0 contains new Bool object self.write_file(f'lw $t0 12($fp)') # 1st arg is an object address self.write_file(f'la $t1 {VOID_MIPS_NAME}') self.write_file(f'beq $t0 $t1 _is_void_true_') # arg == void type self.write_file(f'sw $0 12($v0)') # return False self.write_file(f'j _is_void_end_') self.write_file(f'_is_void_true_:', tabbed=False) self.write_file(f'li $t0 1') self.write_file(f'sw $t0 12($v0)') # return True self.write_file(f'_is_void_end_:', tabbed=False) # Return Bool object in $v0 self.write_file(f'jr $ra') self.write_file(f'')
def io_in_string(self): self.write_file('function_IO_in_string:', tabbed=False) # Set up stack frame self.write_file(f'move $fp, $sp') self.visit(cil.Allocate(dest = None, ttype = INTEGER_CLASS)) # Create new Int object for string's length self.write_file('move $v1 $v0') # $v1: Int pbject self.visit(cil.Allocate(dest = None, ttype = STRING_CLASS)) # Create new String object self.write_file('sw $v1 12($v0)') self.write_file('move $t5 $v0') # $t5: String object # Read String and store in a temp buffer self.write_file('la $a0 str_buffer') self.write_file('li $a1 1025') self.write_file('li $v0 8') # Read string self.write_file('syscall') # Compute string's length self.write_file('move $a0 $0') self.write_file('la $t2 str_buffer') self.write_file('_in_string_str_len_:', tabbed=False) self.write_file('lb $t0 0($t2)') self.write_file('beq $t0 $0 _end_in_string_str_len_') self.write_file('beq $t0 10 _end_in_string_str_len_') self.write_file('addiu $a0 $a0 1') self.write_file('addiu $t2 $t2 1') self.write_file('j _in_string_str_len_') self.write_file('_end_in_string_str_len_:', tabbed=False) # Store string's length into Integer class self.write_file('sw $a0 12($v1)') # Allocate size in $a0 ... string's length self.allocate_memory() # $a0: string's length $v0: string's new address $t5: String object # Copy string from buffer to new address self.write_file('la $t4 str_buffer') # Index for iterating the string buffer self.write_file('move $t1 $v0') # Index for iterating new string address self.write_file('_in_str_copy_:', tabbed=False) self.write_file('lb $t0 0($t4)') # Load a character self.write_file('beq $t0 $0 _end_in_str_copy_') # No more characters to copy self.write_file('beq $t0 10 _end_in_str_copy_') # No more characters to copy self.write_file('sb $t0 0($t1)') # Copy the character self.write_file('addiu $t4 $t4 1') # Advance indices self.write_file('addiu $t1 $t1 1') self.write_file('j _in_str_copy_') self.write_file('_end_in_str_copy_:', tabbed=False) # Store string self.write_file('sw $v0 16($t5)') # Clean string buffer self.write_file('la $t4 str_buffer') # Index for iterating the string buffer self.write_file('_in_str_clean_:', tabbed=False) self.write_file('lb $t0 0($t4)') # Load a character self.write_file('beq $t0 $0 _end_in_str_clean_') # No more characters to clean self.write_file('sb $0 0($t4)') # Clean the character self.write_file('addiu $t4 $t4 1') # Advance indices self.write_file('j _in_str_clean_') self.write_file('_end_in_str_clean_:', tabbed=False) # Return new string in $v0 self.write_file('move $v0 $t5') self.write_file('jr $ra') self.write_file('')
def string_substr(self): self.write_file('function_String_substr:', tabbed=False) # Set up stack frame self.write_file(f'move $fp, $sp') self.write_file(f'lw $t5 12($fp)') # self param self.write_file(f'lw $a1 16($fp)') # reference of object int that represent i self.write_file(f'lw $a1 12($a1)') # value of i self.write_file(f'lw $a2 20($fp)') # reference of object int that represent j self.write_file(f'lw $a2 12($a2)') # value of j that is length to copy self.write_file(f'blt $a1 $0 _index_negative') # index i is negative self.write_file(f'blt $a2 $0 _index_negative') # length j is negative self.write_file(f'add $a2 $a1 $a2') # finish index self.write_file(f'lw $a3 12($t5)') self.write_file(f'lw $a3 12($a3)') # length of string self.write_file(f'bgt $a2 $a3 _index_out') # j > lenght # not errors self.visit(cil.Allocate(dest = None, ttype = STRING_CLASS)) self.write_file(f'move $v1 $v0') # new string self.visit(cil.Allocate(dest = None, ttype = INTEGER_CLASS)) self.write_file(f'move $t0 $v0') # lenght of string self.write_file(f'move $t7 $a2') self.write_file(f'subu $t7 $t7 $a1') self.write_file(f'sw $t7 12($t0)') # save number that represent lenght of new string self.allocate_memory('$a2', register=True) # $v0 -> address of the string self.write_file(f'sw $t0 12($v1)') # store length self.write_file(f'sw $v0 16($v1)') # store address of new string to String object # generate substring self.write_file('move $t1 $v0') # Index for iterating the new string self.write_file('lw $t5 16($t5)') # Index for iterating the self string self.write_file('move $t4 $t5') self.write_file('addu $t4 $t4 $a1') # self's copy start self.write_file('addu $t5 $t5 $a2') # self's copy limit self.write_file('_substr_copy_:', tabbed=False) self.write_file('bge $t4 $t5 _end_substr_copy_') # No more characters to copy self.write_file('lb $a0 0($t4)') # Copy the character self.write_file('sb $a0 0($t1)') self.write_file('addiu $t1 $t1 1') # Advance indices self.write_file('addiu $t4 $t4 1') self.write_file('j _substr_copy_') # errors sections self.write_file(f'_index_negative:',tabbed=False) self.write_file(f'la $a0 _index_negative_msg') self.write_file(f'b _subst_abort') self.write_file(f'_index_out:',tabbed=False) self.write_file(f'la $a0 _index_out_msg') self.write_file(f'b _subst_abort') # abort execution self.write_file(f'_subst_abort:',tabbed=False) self.write_file(f'li $v0 4') self.write_file(f'syscall') self.write_file('la $a0 _abort_msg') self.write_file(f'li $v0 4') self.write_file(f'syscall') self.write_file(f'li $v0 10') self.write_file(f'syscall') # exit # successful execution self.write_file('_end_substr_copy_:', tabbed=False) self.write_file('move $v0 $v1') self.write_file('jr $ra') self.write_file('')
def string_concat(self): self.write_file('function_String_concat:', tabbed=False) # Set up stack frame self.write_file(f'move $fp, $sp') self.visit(cil.Allocate(dest = None, ttype = INTEGER_CLASS)) # Create new Int object self.write_file('move $v1 $v0') # Save new Int Object self.visit(cil.Allocate(dest = None, ttype = STRING_CLASS)) # Create new String object self.write_file('move $t3 $v0') # Store new String object self.write_file('lw $a1 12($fp)') # Self self.write_file('lw $a2 16($fp)') # Boxed String to concat self.write_file('lw $t1 12($a1)') # Self's length Int object self.write_file('lw $t1 12($t1)') # Self's length self.write_file('lw $t2 12($a2)') # strings to concat's length Int object self.write_file('lw $t2 12($t2)') # strings to concat's length self.write_file('addu $t0 $t2 $t1') # New string's length self.write_file('sw $t0 12($v1)') # Store new string's length into box self.write_file('lw $a1 16($a1)') # Unbox strings self.write_file('lw $a2 16($a2)') self.write_file('addiu $t0 $t0 1') # Add space for \0 self.allocate_memory('$t0', register=True) # Allocate memory for new string self.write_file('move $t5 $v0') # Keep the string's reference in v0 and use t7 # a1: self's string a2: 2nd string t1: length self t2: 2nd string length # v1: new string's int object self.write_file('move $t4 $a1') # Index for iterating the self string self.write_file('addu $a1 $a1 $t1') # self's copy limit self.write_file('_strcat_copy_:', tabbed=False) self.write_file('beq $t4 $a1 _end_strcat_copy_') # No more characters to copy self.write_file('lb $a0 0($t4)') # Copy the character self.write_file('sb $a0 0($t5)') self.write_file('addiu $t5 $t5 1') # Advance indices self.write_file('addiu $t4 $t4 1') self.write_file('j _strcat_copy_') self.write_file('_end_strcat_copy_:', tabbed=False) # Copy 2nd string self.write_file('move $t4 $a2') # Index for iterating the strings self.write_file('addu $a2 $a2 $t2') # self's copy limit self.write_file('_strcat_copy_snd_:', tabbed=False) self.write_file('beq $t4 $a2 _end_strcat_copy_snd_') # No more characters to copy self.write_file('lb $a0 0($t4)') # Copy the character self.write_file('sb $a0 0($t5)') self.write_file('addiu $t5 $t5 1') # Advance indices self.write_file('addiu $t4 $t4 1') self.write_file('j _strcat_copy_snd_') self.write_file('_end_strcat_copy_snd_:', tabbed=False) self.write_file('sb $0 0($t5)') # End string with \0 # $v0: reference to new string $v1: length int object # $t3: new string object # -> Create boxed string self.write_file('sw $v1 12($t3)') # New length self.write_file('sw $v0 16($t3)') # New string self.write_file('move $v0 $t3') # Return new String object in $v0 self.write_file('jr $ra') self.write_file('')