################################################################################
##
## LSU EE 3755 Fall 2013 Homework 5
##
##
 ## SOLUTION

 # See http://www.ece.lsu.edu/ee3755/2013f/hw05.pdf


################################################################################
## Main Routine

# This routine runs the test code for the first problem.  It does not
# have to be modified (other than comments), but it can be if it would
# help.  For example, you might comment out a test for one of the
# problems when working on the other.  If you're thinking of improving
# your grade by deleting the test cases which your code gets wrong
# you'll need to come up with a better plan.

        .data
SAMPLES:
        .asciiz "  sloppy,   whitespace ,  handling  ! "
        .asciiz "a"
        .asciiz "   "
        .asciiz "?  and "
        .asciiz "a, ,b"
        .byte 0

clean:
        .space 256

before_msg:
        .asciiz "Before : \"%/s0/s\"\n";
after_msg:
        .asciiz "After  : \"%/a1/s\"\n";

cat_table:
        .space 256
chars_no_ws_before:
        .asciiz ":;)]}.,!\"'";

        .text

        .globl __start
__start:
        la $a0, chars_no_ws_before
        la $a1, cat_table
        jal char_table_init
        addi $a2, $0, 1

        la $s0, SAMPLES
SAMPLOOP:
        la $a0, before_msg;
        addi $v0, $0, 11
        syscall

        la $a1, clean
        la $a2, cat_table
        jal wscleanup
        addi $a0, $s0, 0

        la $a0, after_msg;
        la $a1, clean
        addi $v0, $0, 11
        syscall

EOSLOOP:
        lb $t0, 0($s0)
        bne $t0, $0, EOSLOOP
        addi $s0, $s0, 1

        lb $t0, 0($s0)
        bne $t0, $0, SAMPLOOP
        nop

        addi $v0, $0, 10
        syscall


################################################################################
##
## Initialize Character Table


char_table_init:
        ## Register Usage
        #
        # Call:   $a0  String containing no-space-before characters.
        #         $a1  Location of character classification array.
        #         $a2  Value for element zero.

        addi $t0, $a1, 0
        addi $t1, $a1, 255

WV_LOOPI:
        sb $0, 0($t0)
        bne $t0, $t1, WV_LOOPI
        addi $t0, $t0, 1

        sb $a2, 0($a1)
        addi $t1, $0, 1
        addi $t2, $a0, 0
WV_LOOP:
        lbu $t0, 0($a0)
        beq $t0, $0, WV_DONE   # Exit the loop if at end of input string.
        add $t0, $t0, $a1
        sb $t1, 0($t0)
        j WV_LOOP
        addi $a0, $a0, 1
WV_DONE:
        jr $ra
        sub $v0, $a0, $t2


################################################################################
## Problem 1
##
## wscleanup: Clean up the whitespace in a string.

# Complete the routine below.


wscleanup:
        ## Register Usage
        #
        # Call:
        #   $a0: Address of first character of string.
        #   $a1: Address at which to put cleaned string.
        #   $a2: Address of no-whitespace-before table.
        #
        # Space: ' ' = 32

        # [x] Use character table to determine if all space should be skipped.
        # [x] Can modify registers $a0-$a3, $t0-$t9 and $v0 only.
        # [x] Do not modify $s0-$s7, $sp, $fp, or $ra
        # [x] Fill as many delay slots as possible.
        # [x] Code should be reasonably efficient.

        ## Put solution below.


        ## SOLUTION

        addi $t1, $0, 32       # Keep ASCII value of space handy.

PRELOOP:
        #  Skip past whitespace at the beginning of the string.
        #
        lbu $t0, 0($a0)
        beq $t0, $t1, PRELOOP
        addi $a0, $a0, 1

        #  Jump to place in code that copies until a space is found.
        j NWLOOP
        nop

LOOP:
        # Find next non-space character.
        #
        lbu $t0, 0($a0)
        beq $t0, $t1, LOOP
        addi $a0, $a0, 1

        # At this point $t0 has a non-space character.

        add $t3, $a2, $t0  # Compute address of table entry.
        lb $t4, 0($t3)     # Get classification of character.

        sb $t1, 0($a1)     # Store a space in the cleaned string.
        addi $a1, $a1, 1   # Advance the cleaned-string pointer.
        # If next character is a no-whitespace-before character then
        # un-advance the cleaned-string pointer.
        sub $a1, $a1, $t4

NWLOOP:
        # Copy non-space characters to cleaned string until a space is
        # found.
        #
        sb $t0, 0($a1)       # Store character in cleaned string.
        addi $a1, $a1, 1     # Advance cleaned-string pointer.
        beq $t0, $0 DONE     # Check for end.
        lb $t0, 0($a0)       # Load next character.
        bne $t0, $t1, NWLOOP # Continue if it's not a space.
        addi $a0, $a0, 1

        j LOOP
        nop

DONE:

        jr  $ra
        nop

####