# 3827 Homework 3, problem 2, "eval"
#
# <your name here>, <your uni here>
#
# Invoke with, e.g., spim -file eval.s
#	
	.text
	# $a0 : pointer to an expression
eval:
	# REPLACE WITH YOUR CODE
	li	$v0, 999	# Just a placeholder
	jr $ra

######################################################################
#
# Test harness: extend to add tests
#		      
	.data

# Expression nodes take two forms:
# .word 0, 42   	# Leaf: integer
# .word '+', e42, e17	# Branch: operator is +, left is e42, right is e17

e42:	.word 0, 42
e17:	.word 0, 17
e25:	.word 0, 25
eadd:	.word '+', e17, e25
e2:	.word 0, 2
e3:	.word 0, 3
eadd3:	.word '+', e2, e3
e5:	.word 0, 5
emult1:	.word '*', e5, eadd3
esub:	.word '-', e42, e17
eadd2:	.word '+', emult1, esub

	# Add more test expressions here
	
nl:	.asciiz "\n"
lparen:	.asciiz "("
onechar: .asciiz " "
rparen:	.asciiz ")"
equals:	.asciiz " = "	
	
	.text

	# Print an expression tree
	# $a0 : address of the root of the expression tree
print:
	lb	$t0, 0($a0)
	bne	$t0, $0, prbranch

	lw	$a0, 4($a0)	# leaf: print its value
	li	$v0, 1
	syscall
	jr	$ra

prbranch:
	addiu	$sp, $sp, -8	# Save $ra and $s0 on the stack
	sw	$ra, 0($sp)
	sw	$s0, 4($sp)

	move 	$s0, $a0	# Remember the tree node

	la	$a0, lparen	# print (
	li	$v0, 4
	syscall
	
	lw	$a0, 4($s0)	# print(left)
	jal	print

	lb	$t0, 0($s0)	# print(op)
	la	$a0, onechar
	sb	$t0, 0($a0)
	li	$v0, 4
	syscall

	lw	$a0, 8($s0)	# print(right)
	jal	print

	la	$a0, rparen	# print )
	li	$v0, 4
	syscall
	
	lw	$ra, 0($sp)	# Restore $ra and $s0
	lw	$s0, 4($sp)
	addiu	$sp, $sp, 8
	jr	$ra

	# Print an expression tree, evaluate it, and print the result
	# $a0 : address of the root of the expression tree
preval:
	addiu	$sp, $sp, -8	# Save $ra and $s0
	sw	$ra, 0($sp)
	sw	$s0, 4($sp)

	move	$s0, $a0

	jal	print		# Print the expression

	la	$a0, equals	# Print " = "
	li	$v0, 4
	syscall

	move	$a0, $s0	# Call eval on the expression
	jal	eval

	move	$a0, $v0	# Print the (integer) result
	li	$v0, 1
	syscall

	la	$a0, nl		# Print a newline
	li	$v0, 4
	syscall
	
	lw	$ra, 0($sp)	# Restore $ra and $s0
	lw	$s0, 4($sp)
	addiu	$sp, $sp, 8
	jr	$ra
	
	.globl main

	# Run a number of tests
main:
	move	$s0, $ra

	la	$a0, e42	# preval(e42)
	jal	preval

	la	$a0, e17	# preval(e17)
	jal	preval

	la	$a0, e25	# preval(e25)
	jal	preval

	la	$a0, eadd	# preval(eadd)
	jal	preval

	la	$a0, emult1	# preval(emult1)
	jal 	preval

	la	$a0, eadd2	# preval(eadd2)
	jal	preval

	# Add your own tests here

	move	$ra, $s0
	jr	$ra
