   [s]
   (commutes (second (first s)) (second (second s))))
 
-(defn canon
-  "Converts a Seq to linear IR form."
-  [s]
-	    (cond 
-			 (matches-eseq-left? s) (remove-eseq-left s)
-			 (matches-double-eseq? s) (remove-double-eseq s)
-			 (matches-eseq-commute? s)
+;;Whether or not any change whatsoever was made to the structure of the tree during the most recent round of canon-localoicalization
+;;If so, we should set this to false and run canon-local again.
+(def *global-change* (atom true))
+
+(defn canon-local
+  "Converts a Statement or Expression to linear IR form."
+  [s]
+	(let [*local-change* (atom false)
+				newS 
+    (cond 
+			 (matches-eseq-left-binop? s) (do (println "match left binop")	(reset! *local-change* true)	(raise-eseq-left-binop s))
+		 	 (matches-eseq-left-cond? s) (do (println "match left cond")	(reset! *local-change* true)	 (raise-eseq-left-cond s))
+			 (matches-double-eseq? s) (do (println "match double eseq")	(reset! *local-change* true)	 (raise-double-eseq s)	)
+			 (matches-eseq-commute-binop? s)
+					(do(println "match commute binop") (reset! *local-change* true)						
 			       (if (commutes? s)
-			         (remove-eseq-commute s)
-			         (remove-eseq-no-commute s))
-						;;If s contains Call as an argument, and s is NOT a move, then construct a new ESeq node moving the result of the call into the return value register.
-						;;Then recurse on the newly created node.
-					 (contains-call? s)
-							(reorganize-call s)
+			         (raise-eseq-commute-binop s)
+			         (raise-eseq-no-commute-binop s))						
+					)
+			 (matches-eseq-commute-cond? s)
+			      (do(println "match commute cond") (reset! *local-change* true)	
+								(if (commutes? s)
+						         (raise-eseq-commute-cond s)
+						         (raise-eseq-no-commute-cond s))				
+							)
+			;;If s contains Call as an argument, and s is NOT a move, then construct a new ESeq node moving the result of the call into the return value register.
+			;;Then recurse on the newly created node.
+	;;		(contains-call? s) ;;this wont work with the current approach; have to remove calls in a separate procedure
+	;;				(do (reset! *local-change* true) (reorganize-call s))
 		(= :minijava.ir/Seq (type s))
-				(flatten;;run canon on each element of the sequence
-					  (for [s (:seqs s)] (canon s)))
+		(do	(println "match seq")	(Seq (flatten;;run canon-local on each element of the sequence
+					  (for [s (:seqs s)] (canon-local s)))))
 		(= :minijava.ir/ExpSeq (type s)) ;;is this right?
-			   (list (canon (:seqs s)) (canon (:exp s)))
+			 (do	(println "match expseq")  (ExpSeq (canon-local (:seqs s)) (canon-local (:exp s))) )
 		(= :minijava.ir/BinaryOp (type s))
-				(BinaryOp (:op s) (canon (:exp1 s))  (canon (:exp2 s)))
+				(do	(println "match binop") (BinaryOp (:op s) (canon-local (:exp1 s))  (canon-local (:exp2 s))))
 		(= :minijava.ir/Conditional (type s))
-				(Conditional (:op s) (canon (:exp1 s))  (canon (:exp2 s)) (:t s) (:f s))
+				(do	(println "match cond")(Conditional (:op s) (canon-local (:exp1 s))  (canon-local (:exp2 s)) (:t s) (:f s)))
 		(= :minijava.ir/Call (type s))
-				(Call (:lbl s) (canon (:args s)))
+				(Call (:lbl s) (canon-local (:args s)))
 		(= :minijava.ir/Statement (type s))
-				(Statement (canon (:exp s)))
+				(Statement (canon-local (:exp s)))
 		:else
-				s;;no changes or recursion needed for Consts, Jmps, NoOps,Temp, Name, etc
-))
+			s;;no changes or recursion needed for Consts, Jmps, NoOps,Temp, Name, etc
+		)]
+		(if @*local-change* (reset! *global-change* true))
+		newS))
+
+(defn canon-raise [t] 
+ (do
+	(reset! *global-change* true)
+	(let [*current-tree* (atom t)]
+ 	(while @*global-change*
+	(do	(reset! *global-change* false)
+		(swap! *current-tree* canon-local)))
+	@*current-tree*)
+	)
+)
+
+(defn remove-seqs[t]
+		(cond
+				(= :minijava.ir/Seq (type t))
+						(flatten (for [t (:seqs t)] (remove-seqs t)))
+				:else t;;All seqs are guaranteed to be top level (not contained in anything but a seq), so we dont need to explore other nodes.
+	)
+)
+
+
+(defn canon [t]
+	(let [raised (canon-raise t)]
+	;;now remove all the top level sequences, and return a vector of statements, with no seqs (or expseqs, but those were already removed)
+	(remove-seqs t)	
+))
+
+
 
 ;; BASIC BLOCKS
 

								arg2 (if (not (= :minijava.ir/Call (type (:exp2 s)))) (:exp2 s)
											;;;exp2 is a call, so wrap it in an eseq  
											(let [t (tm/temp)] (ExpSeq (Move (:exp2 s) t) t)))]
								(canon (Conditional (:op s) arg1 arg2 (:t s) (:f s))));;ok; now create a new binop with these arguments, and run canon on it		
			(= :minijava.ir/Mem (type s))
					;;s is an Mem, and its adress is a call	
					(canon (Mem (let [t (tm/temp)] (ExpSeq (Move (:exp s) t) t))))

				:else s
))

								arg2 (if (not (= :minijava.ir/Call (type (:exp2 s)))) (:exp2 s)
											;;;exp2 is a call, so wrap it in an eseq  
											(let [t (tm/temp)] (ExpSeq (Move (:exp2 s) t) t)))]
								(canon-local (BinaryOp (:op s) arg1 arg2)));;ok; now create a new binop with these arguments, and run canon-local on it		
				(= :minijava.ir/ExpSeq (type s))
					;;s is an expseq, and its expression is a call	
					(canon-local (ExpSeq (:seqs s) 	
								 (let [t (tm/temp)] (ExpSeq (Move (:exp s) t) t))))
			(= :minijava.ir/Conditional (type s))
							;;s is an conditional, and one or both arguments are calls
