Rust, 116111 bytes
More of a comment on @Doorknob's answer, but I don't have any rep for comments as I just created an account.
One can shave 510 bytes off his Rust solution with the following:
fn r(s:&str)->u8{let mut n=0u8;for t in s.chars(){n=match t{'!'=>!n,'>'=>n>>1,'<'=>n<<1,'@'=>n>>4|(n&15)<<4'@'=>n>>4|n<<4,_=>n}}n}