Beispiel #1
0
	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')
Beispiel #2
0
	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('')
Beispiel #3
0
	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('')
Beispiel #4
0
	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'')
Beispiel #5
0
	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('')
Beispiel #6
0
	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('')
Beispiel #7
0
	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('')