| 
						
						
						
					 | 
					 | 
					@ -1,18 +1,18 @@
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					package chocopy.pa3;
 | 
					 | 
					 | 
					 | 
					package chocopy.pa3;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					import java.net.Socket;
 | 
					 | 
					 | 
					 | 
					import java.util.ArrayList;
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					import java.util.HashMap;
 | 
					 | 
					 | 
					 | 
					import java.util.HashMap;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					import java.util.List;
 | 
					 | 
					 | 
					 | 
					import java.util.List;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					import java.util.Map;
 | 
					 | 
					 | 
					 | 
					import java.util.Map;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					import java.util.Stack;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					import chocopy.common.analysis.AbstractNodeAnalyzer;
 | 
					 | 
					 | 
					 | 
					import chocopy.common.analysis.*;
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					import chocopy.common.analysis.SymbolTable;
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					import chocopy.common.astnodes.*;
 | 
					 | 
					 | 
					 | 
					import chocopy.common.astnodes.*;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					import chocopy.common.analysis.types.*;
 | 
					 | 
					 | 
					 | 
					import chocopy.common.analysis.types.*;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					import chocopy.common.codegen.*;
 | 
					 | 
					 | 
					 | 
					import chocopy.common.codegen.*;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					import static chocopy.common.codegen.RiscVBackend.Register.*;
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					import chocopy.common.codegen.RiscVBackend.Register;
 | 
					 | 
					 | 
					 | 
					import chocopy.common.codegen.RiscVBackend.Register;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					import static chocopy.common.codegen.RiscVBackend.Register.*;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					/**
 | 
					 | 
					 | 
					 | 
					/**
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -33,12 +33,12 @@ public class CodeGenImpl extends CodeGenBase
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					{
 | 
					 | 
					 | 
					 | 
					{
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    /** Label for built-in routines. */
 | 
					 | 
					 | 
					 | 
					    /** Label for built-in routines. */
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    protected final Label makeintLabel = new Label("makeint");
 | 
					 | 
					 | 
					 | 
					    protected final Label makeintLabel = new Label("makeint");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    protected final Label strneqlLablel = new Label("strneql");
 | 
					 | 
					 | 
					 | 
					    protected final Label strneqlLabel = new Label("strneql");
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    protected final Label streqlLablel = new Label("streql");
 | 
					 | 
					 | 
					 | 
					    protected final Label streqlLabel = new Label("streql");
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    protected final Label makeboolLabel = new Label("makebool");
 | 
					 | 
					 | 
					 | 
					    protected final Label makeboolLabel = new Label("makebool");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    protected final Label strcatLablel = new Label("strcat");
 | 
					 | 
					 | 
					 | 
					    protected final Label strcatLabel = new Label("strcat");
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    protected final Label concatLablel = new Label("concat");
 | 
					 | 
					 | 
					 | 
					    protected final Label concatLabel = new Label("concat");
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    protected final Label conslistLablel = new Label("conslist");
 | 
					 | 
					 | 
					 | 
					    protected final Label conslistLabel = new Label("conslist");
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    
 | 
					 | 
					 | 
					 | 
					    
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					 | 
					@ -91,6 +91,8 @@ public class CodeGenImpl extends CodeGenBase
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        {
 | 
					 | 
					 | 
					 | 
					        {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            stmt.dispatch(stmtAnalyzer);
 | 
					 | 
					 | 
					 | 
					            stmt.dispatch(stmtAnalyzer);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        }
 | 
					 | 
					 | 
					 | 
					        }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        stmtAnalyzer.emitSizeLabel();
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        backend.emitLI(A0, EXIT_ECALL, "Code for ecall: exit");
 | 
					 | 
					 | 
					 | 
					        backend.emitLI(A0, EXIT_ECALL, "Code for ecall: exit");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        backend.emitEcall(null);
 | 
					 | 
					 | 
					 | 
					        backend.emitEcall(null);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    }
 | 
					 | 
					 | 
					 | 
					    }
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					 | 
					@ -148,7 +150,6 @@ public class CodeGenImpl extends CodeGenBase
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    			varSlotMap.put(var.getVarName(), requiredStackSpace-emptySlotNum*wordSize);
 | 
					 | 
					 | 
					 | 
					    			varSlotMap.put(var.getVarName(), requiredStackSpace-emptySlotNum*wordSize);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    			emptySlotNum++;
 | 
					 | 
					 | 
					 | 
					    			emptySlotNum++;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        }
 | 
					 | 
					 | 
					 | 
					        }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        // --- Function Body ---
 | 
					 | 
					 | 
					 | 
					        // --- Function Body ---
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        // statements load all the variables that caller put on stack
 | 
					 | 
					 | 
					 | 
					        // statements load all the variables that caller put on stack
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        // statements use fp to load the variables
 | 
					 | 
					 | 
					 | 
					        // statements use fp to load the variables
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -157,10 +158,8 @@ public class CodeGenImpl extends CodeGenBase
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        for (Stmt stmt : funcInfo.getStatements()) {
 | 
					 | 
					 | 
					 | 
					        for (Stmt stmt : funcInfo.getStatements()) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            stmt.dispatch(stmtAnalyzer);
 | 
					 | 
					 | 
					 | 
					            stmt.dispatch(stmtAnalyzer);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        }
 | 
					 | 
					 | 
					 | 
					        }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        stmtAnalyzer.emitSizeLabel();
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        backend.emitJ(stmtAnalyzer.epilogue, "Jump to function epilogue");
 | 
					 | 
					 | 
					 | 
					        backend.emitJ(stmtAnalyzer.epilogue, "Jump to function epilogue");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        // --- Epilogue ---
 | 
					 | 
					 | 
					 | 
					        // --- Epilogue ---
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        backend.emitLocalLabel(stmtAnalyzer.epilogue, "Epilogue");
 | 
					 | 
					 | 
					 | 
					        backend.emitLocalLabel(stmtAnalyzer.epilogue, "Epilogue");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        backend.emitLW(RA, FP, -4, "Get return address");
 | 
					 | 
					 | 
					 | 
					        backend.emitLW(RA, FP, -4, "Get return address");
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					 | 
					@ -208,10 +207,7 @@ public class CodeGenImpl extends CodeGenBase
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        private final FuncInfo funcInfo;
 | 
					 | 
					 | 
					 | 
					        private final FuncInfo funcInfo;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        /** Label of code that exits from block. */
 | 
					 | 
					 | 
					 | 
					        /** Label of code that exits from block. */
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        protected Label elseBlock;
 | 
					 | 
					 | 
					 | 
					        protected Stack<Label> elseBlock = new Stack<Label>();
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        /** Variable to keep track of offsets of stored variables */
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        private Map<SymbolInfo, Integer> offsetMap = new HashMap<>();
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        /** Variable to keep track of slots of stored variables on stack */
 | 
					 | 
					 | 
					 | 
					        /** Variable to keep track of slots of stored variables on stack */
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        // example usage: backend.emitLW(A0, SP, varSlotMap.get(varName)) to load the variable using its name
 | 
					 | 
					 | 
					 | 
					        // example usage: backend.emitLW(A0, SP, varSlotMap.get(varName)) to load the variable using its name
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -223,6 +219,19 @@ public class CodeGenImpl extends CodeGenBase
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        private int sp_off;
 | 
					 | 
					 | 
					 | 
					        private int sp_off;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        /** Variable to store maximum possible offset depending on stack size.*/
 | 
					 | 
					 | 
					 | 
					        /** Variable to store maximum possible offset depending on stack size.*/
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        private int max_sp;
 | 
					 | 
					 | 
					 | 
					        private int max_sp;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        private final Register[] registerPool = {T2,T3, T4, T5, T6, A2, A3, A4, A5, A6};
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        private final boolean[] registerAvilMap = {true, true, true, true, true, true, true, true, true, true};
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        private int getRegister(){ //return a handle of a vacant register
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            for(int i = 0; i < 10; ++i)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                if(registerAvilMap[i])
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                    return i;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            for(int i = 0; i < 10; ++i)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                registerAvilMap[i] = true; //freeall;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            return 0;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        private void freeRegister(int handle){ //handle used to free the register
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            registerAvilMap[handle] = false;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        
 | 
					 | 
					 | 
					 | 
					        
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        /**
 | 
					 | 
					 | 
					 | 
					        /**
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					         * An analyzer for the function described by FUNCINFO0, which is null for the
 | 
					 | 
					 | 
					 | 
					         * An analyzer for the function described by FUNCINFO0, which is null for the
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -242,11 +251,13 @@ public class CodeGenImpl extends CodeGenBase
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            epilogue = generateLocalLabel();
 | 
					 | 
					 | 
					 | 
					            epilogue = generateLocalLabel();
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        }
 | 
					 | 
					 | 
					 | 
					        }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        private void incSp(int i){
 | 
					 | 
					 | 
					 | 
					        private void incSp(int i){
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            sp_off+=i+1;
 | 
					 | 
					 | 
					 | 
					            sp_off+=i;
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            max_sp = max_sp >= sp_off?max_sp:sp_off;
 | 
					 | 
					 | 
					 | 
					            max_sp = max_sp >= sp_off?max_sp:sp_off;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        }
 | 
					 | 
					 | 
					 | 
					        }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        
 | 
					 | 
					 | 
					 | 
					        
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        
 | 
					 | 
					 | 
					 | 
					        public void emitSizeLabel(){
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            backend.defineSym(size_label, max_sp*wordSize);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        
 | 
					 | 
					 | 
					 | 
					        
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        
 | 
					 | 
					 | 
					 | 
					        
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        // *********** functions start ***********
 | 
					 | 
					 | 
					 | 
					        // *********** functions start ***********
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -255,8 +266,7 @@ public class CodeGenImpl extends CodeGenBase
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        	    System.out.println("Inside CallExpr: " + node.function.name);
 | 
					 | 
					 | 
					 | 
					        	    System.out.println("Inside CallExpr: " + node.function.name);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        		backend.emitLW(T6, FP, 0, "Inside CallExpr: " + node.function.name);
 | 
					 | 
					 | 
					 | 
					        		backend.emitLW(T6, FP, 0, "Inside CallExpr: " + node.function.name);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        		
 | 
					 | 
					 | 
					 | 
					        		
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        		// FIXME: Why are we using globalSymbols here but not the sym???
 | 
					 | 
					 | 
					 | 
					            SymbolInfo Ty = sym.get(node.function.name);
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            SymbolInfo Ty = globalSymbols.get(node.function.name);
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            if(Ty instanceof ClassInfo){
 | 
					 | 
					 | 
					 | 
					            if(Ty instanceof ClassInfo){
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                //object create
 | 
					 | 
					 | 
					 | 
					                //object create
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                ClassInfo cls = (ClassInfo) Ty;
 | 
					 | 
					 | 
					 | 
					                ClassInfo cls = (ClassInfo) Ty;
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -276,7 +286,7 @@ public class CodeGenImpl extends CodeGenBase
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                    String.format("Load pointer to prototype of: %s", cls.getClassName()));
 | 
					 | 
					 | 
					 | 
					                    String.format("Load pointer to prototype of: %s", cls.getClassName()));
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                backend.emitJAL(objectAllocLabel, "Allocate new object in A0");
 | 
					 | 
					 | 
					 | 
					                backend.emitJAL(objectAllocLabel, "Allocate new object in A0");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                backend.emitSW(A0, FP, -sp_off*wordSize, String.format("Push on stack slot %d", sp_off));
 | 
					 | 
					 | 
					 | 
					                backend.emitSW(A0, FP, -sp_off*wordSize, String.format("Push on stack slot %d", sp_off));
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                incSp(0);
 | 
					 | 
					 | 
					 | 
					                incSp(1);
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                backend.emitSW(A0, FP, -sp_off*wordSize, "Push argument 0 from last.");
 | 
					 | 
					 | 
					 | 
					                backend.emitSW(A0, FP, -sp_off*wordSize, "Push argument 0 from last.");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                backend.emitADDI(SP, FP, sp_off, "Set SP to last argument.");
 | 
					 | 
					 | 
					 | 
					                backend.emitADDI(SP, FP, sp_off, "Set SP to last argument.");
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -293,6 +303,18 @@ public class CodeGenImpl extends CodeGenBase
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						        		
 | 
					 | 
					 | 
					 | 
						        		
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						        		List<Expr> args = node.args;
 | 
					 | 
					 | 
					 | 
						        		List<Expr> args = node.args;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						        		int spaceRequiredForArgs = (args.size() + 1)*4;
 | 
					 | 
					 | 
					 | 
						        		int spaceRequiredForArgs = (args.size() + 1)*4;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                    int depth = calleeFunctionInfo.getDepth();
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                    int tmpHandle = getRegister();
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                    Register tmp = registerPool[tmpHandle];
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                    FuncInfo currFuncInfo = calleeFunctionInfo;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                    backend.emitMV(tmp, FP, "Load FP");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                    while (depth > 0) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                        final FuncInfo parentFuncInfo = currFuncInfo.getParentFuncInfo();
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                        backend.emitLW(tmp, tmp, parentFuncInfo.getParams().size()*wordSize, "Load static link to " + parentFuncInfo.getFuncName());
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                        currFuncInfo = parentFuncInfo;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                        --depth;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                    }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                    freeRegister(tmpHandle);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						        		//backend.emitSW(A0, SP, -4, "Put static link");
 | 
					 | 
					 | 
					 | 
						        		//backend.emitSW(A0, SP, -4, "Put static link");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						        		for (int i = 0; i < args.size(); i++) {
 | 
					 | 
					 | 
					 | 
						        		for (int i = 0; i < args.size(); i++) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						        			int argNum = i + 1;
 | 
					 | 
					 | 
					 | 
						        			int argNum = i + 1;
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -304,13 +326,13 @@ public class CodeGenImpl extends CodeGenBase
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						        			StackVarInfo formalParamInfo = (StackVarInfo) calleeFunctionInfo.getSymbolTable().get(formalParamName);
 | 
					 | 
					 | 
					 | 
						        			StackVarInfo formalParamInfo = (StackVarInfo) calleeFunctionInfo.getSymbolTable().get(formalParamName);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						        			
 | 
					 | 
					 | 
					 | 
						        			
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						        			if (expr.getInferredType().equals(Type.INT_TYPE)) {
 | 
					 | 
					 | 
					 | 
						        			if (expr.getInferredType().equals(Type.INT_TYPE)) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						        				if (formalParamInfo.getVarType().equals(Type.OBJECT_TYPE) || formalParamInfo.getVarType().equals(Type.INT_TYPE)) {
 | 
					 | 
					 | 
					 | 
						        				if ((functionId.name.equals("print")) &&(formalParamInfo.getVarType().equals(Type.OBJECT_TYPE) || formalParamInfo.getVarType().equals(Type.INT_TYPE))) {
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						                        backend.emitJAL(makeintLabel, "Box integer");
 | 
					 | 
					 | 
					 | 
						                        backend.emitJAL(makeintLabel, "Box integer");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						        				} else  {
 | 
					 | 
					 | 
					 | 
						        				} else  {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						        					// FIXME: passed argument does not match formal parameter
 | 
					 | 
					 | 
					 | 
						        					// FIXME: passed argument does not match formal parameter
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						        				}
 | 
					 | 
					 | 
					 | 
						        				}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						                } else if (expr.getInferredType().equals(Type.BOOL_TYPE)) { 
 | 
					 | 
					 | 
					 | 
						                } else if (expr.getInferredType().equals(Type.BOOL_TYPE)) { 
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						                    	if (formalParamInfo.getVarType().equals(Type.OBJECT_TYPE) || formalParamInfo.getVarType().equals(Type.BOOL_TYPE)) {
 | 
					 | 
					 | 
					 | 
						                    	if ((functionId.name.equals("print"))&&(formalParamInfo.getVarType().equals(Type.OBJECT_TYPE) || formalParamInfo.getVarType().equals(Type.BOOL_TYPE))) {
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						                    		backend.emitJAL(makeboolLabel, "Box boolean");
 | 
					 | 
					 | 
					 | 
						                    		backend.emitJAL(makeboolLabel, "Box boolean");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						                    } else {
 | 
					 | 
					 | 
					 | 
						                    } else {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						                    		// FIXME: passed argument does not match formal parameter
 | 
					 | 
					 | 
					 | 
						                    		// FIXME: passed argument does not match formal parameter
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					 | 
					@ -347,8 +369,11 @@ public class CodeGenImpl extends CodeGenBase
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                    String.format("Push argument %d from last.", n_args - i - 1));
 | 
					 | 
					 | 
					 | 
					                    String.format("Push argument %d from last.", n_args - i - 1));
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            
 | 
					 | 
					 | 
					 | 
					            
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            backend.emitLW(A0, FP, (n_args- sp_off) * wordSize, String.format("Peek stack slot %d", sp_off - (n_args + 1)));
 | 
					 | 
					 | 
					 | 
					            backend.emitLW(A0, FP, (n_args- sp_off) * wordSize, String.format("Peek stack slot %d", sp_off - (n_args + 1)));
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            ClassInfo objectClass = (ClassInfo)sym.get(((Identifier)node.method.object).name);
 | 
					 | 
					 | 
					 | 
					            ClassInfo objectClass = null;
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					            if(node.method.object instanceof CallExpr)
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                objectClass = (ClassInfo)globalSymbols.get(((CallExpr)node.method.object).getInferredType().className());
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            else 
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                objectClass = (ClassInfo)globalSymbols.get(node.method.object.getInferredType().className());
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            backend.emitLW(A1, A0, getDispatchTableOffset(), "Load address of object's dispatch table");
 | 
					 | 
					 | 
					 | 
					            backend.emitLW(A1, A0, getDispatchTableOffset(), "Load address of object's dispatch table");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            backend.emitLW(A1, A1, getMethodOffset(objectClass, node.method.member.name), 
 | 
					 | 
					 | 
					 | 
					            backend.emitLW(A1, A1, getMethodOffset(objectClass, node.method.member.name), 
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                String.format("Load address of method: %s.%s", objectClass.getClassName(), node.method.member.name));
 | 
					 | 
					 | 
					 | 
					                String.format("Load address of method: %s.%s", objectClass.getClassName(), node.method.member.name));
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					 | 
					@ -411,46 +436,88 @@ public class CodeGenImpl extends CodeGenBase
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                backend.emitLI(Register.A0, 0, "Load boolean literal: false ");
 | 
					 | 
					 | 
					 | 
					                backend.emitLI(Register.A0, 0, "Load boolean literal: false ");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            return Register.A0;
 | 
					 | 
					 | 
					 | 
					            return Register.A0;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        }
 | 
					 | 
					 | 
					 | 
					        }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					        class StackVarRuntimeInfo {
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            public final int off;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            public final Register sl;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            public int regHandle;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            StackVarRuntimeInfo(Register sl, int off){
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                this.off = off;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                this.sl = sl;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                regHandle = -1;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            StackVarRuntimeInfo(Register sl, int off, int regHandle){
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                this.off = off;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                this.sl = sl;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                this.regHandle = regHandle;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            public void free(){
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                if(regHandle > 0){
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                    freeRegister(regHandle);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                    regHandle = -1;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        private Object getVar(Identifier id){
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            SymbolInfo info = sym.get(id.name);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            if(info instanceof StackVarInfo)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                return getStackVar((StackVarInfo)info);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            else
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                return ((GlobalVarInfo)info).getLabel();
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        private StackVarRuntimeInfo getStackVar(StackVarInfo info){
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            int curr_depth = funcInfo.getDepth();
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            int d_depth = curr_depth - info.getFuncInfo().getDepth();
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            if(d_depth == 0)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                return new StackVarRuntimeInfo(SP, varSlotMap.get(info.getVarName()));
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            else
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                FuncInfo curr = funcInfo;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                int tmpHandle = getRegister();
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                Register tmp = registerPool[tmpHandle];
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                backend.emitMV(tmp, FP, "tmp = FP");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                while(d_depth > 0){
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                    curr = curr.getParentFuncInfo();
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                    backend.emitLW(tmp, tmp, curr.getParams().size()*wordSize, "Get static link");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                    -- d_depth;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                // UNSAFE!!!!! PLEASE FREE THE TMP_HANDLE MANUALLY
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                return new StackVarRuntimeInfo(tmp, -wordSize*curr.getVarIndex(info.getVarName()), tmpHandle);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        
 | 
					 | 
					 | 
					 | 
					        
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        @Override
 | 
					 | 
					 | 
					 | 
					        @Override
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        public Register analyze(AssignStmt node) 
 | 
					 | 
					 | 
					 | 
					        public Register analyze(AssignStmt node) 
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        {
 | 
					 | 
					 | 
					 | 
					        {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        	System.out.println("Inside AssignStmt: ");
 | 
					 | 
					 | 
					 | 
					        	System.out.println("Inside AssignStmt: ");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            backend.emitLW(T6, FP, 0, "Inside AssignStmt: ");
 | 
					 | 
					 | 
					 | 
					            backend.emitLW(T6, FP, 0, "Inside AssignStmt: ");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            Type t = node.value.getInferredType();
 | 
					 | 
					 | 
					 | 
					            //Type t = node.value.getInferredType();
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            // if(t.isSpecialType() || t.isListType())
 | 
					 | 
					 | 
					 | 
					            // if(t.isSpecialType() || t.isListType())
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            {
 | 
					 | 
					 | 
					 | 
					            //{
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                Register reg = node.value.dispatch(this);
 | 
					 | 
					 | 
					 | 
					                Register reg = node.value.dispatch(this);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                if (reg == null)
 | 
					 | 
					 | 
					 | 
					                if (reg == null)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                    reg = A0;
 | 
					 | 
					 | 
					 | 
					                    reg = A0;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                if (sym.getParent() == null) 
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                {
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                for(Expr target: node.targets)
 | 
					 | 
					 | 
					 | 
					                for(Expr target: node.targets)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                {
 | 
					 | 
					 | 
					 | 
					                {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                    if(target instanceof Identifier)
 | 
					 | 
					 | 
					 | 
					                    if(target instanceof Identifier)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                    {
 | 
					 | 
					 | 
					 | 
					                    {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                            GlobalVarInfo gvi=(GlobalVarInfo)sym.get(((Identifier)target).name);
 | 
					 | 
					 | 
					 | 
					                        Identifier targetID = (Identifier)target;
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                            backend.emitSW(reg, gvi.getLabel(), Register.T0, "Assign global: "+gvi.getVarName()+"(using tmp register)");
 | 
					 | 
					 | 
					 | 
					                        Object var = getVar(targetID);
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                        if(var instanceof StackVarRuntimeInfo){
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                            StackVarRuntimeInfo rtinfo = (StackVarRuntimeInfo) var;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                            backend.emitSW(reg, rtinfo.sl, rtinfo.off ,"Store local variable: "+((Identifier)target).name);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                            rtinfo.free();
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                        } 
 | 
					 | 
					 | 
					 | 
					                        } 
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                        else
 | 
					 | 
					 | 
					 | 
					                        else
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                        {
 | 
					 | 
					 | 
					 | 
					                            backend.emitSW(reg, (Label)var, T0, "Store Global variable: " + ((Identifier)targetID).name);
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                            Register ret = target.dispatch(this);
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                            backend.emitSW(T1, ret, 0, "Set list element"); 
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                        }
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                    }
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                    }
 | 
					 | 
					 | 
					 | 
					                    }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                    else
 | 
					 | 
					 | 
					 | 
					                    else
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                    {
 | 
					 | 
					 | 
					 | 
					                    {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                    for(Expr target: node.targets)
 | 
					 | 
					 | 
					 | 
					                        Register ret = target.dispatch(this);
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                    {
 | 
					 | 
					 | 
					 | 
					                        backend.emitSW(T1, ret, 0, "Set list element"); 
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                        StackVarInfo svi = (StackVarInfo) sym.get(((Identifier)target).name);
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                        int loc = offsetMap.get(svi);
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                        backend.emitSW(reg, Register.FP, -loc*4, "Load local variable: "+svi.getVarName());
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                    }
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                    }
 | 
					 | 
					 | 
					 | 
					                    }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                }
 | 
					 | 
					 | 
					 | 
					                }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            return Register.A0;
 | 
					 | 
					 | 
					 | 
					            //}
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            return reg;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        }
 | 
					 | 
					 | 
					 | 
					        }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        
 | 
					 | 
					 | 
					 | 
					        
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        @Override
 | 
					 | 
					 | 
					 | 
					        @Override
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -469,11 +536,13 @@ public class CodeGenImpl extends CodeGenBase
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        	System.out.println("Inside IfExpr: ");
 | 
					 | 
					 | 
					 | 
					        	System.out.println("Inside IfExpr: ");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            Register result = node.condition.dispatch(this);
 | 
					 | 
					 | 
					 | 
					            Register result = node.condition.dispatch(this);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            Label ln = generateLocalLabel();
 | 
					 | 
					 | 
					 | 
					            Label ln = generateLocalLabel();
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            backend.emitBEQZ(result, ln,"Jump to beginning of loop");
 | 
					 | 
					 | 
					 | 
					            backend.emitBEQZ(result, ln,"Jump to end of loop");
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            node.thenExpr.dispatch(this);
 | 
					 | 
					 | 
					 | 
					            node.thenExpr.dispatch(this);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            backend.emitJ(ln, "Jump to end of if expression");
 | 
					 | 
					 | 
					 | 
					            backend.emitJ(ln, "Jump to end of if expression");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            backend.emitLocalLabel(elseBlock, "Else part of if expression");
 | 
					 | 
					 | 
					 | 
					            elseBlock.push(generateLocalLabel());
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            backend.emitLocalLabel(elseBlock.peek(), "Else part of if expression");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            node.elseExpr.dispatch(this);
 | 
					 | 
					 | 
					 | 
					            node.elseExpr.dispatch(this);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            elseBlock.pop();
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            backend.emitLocalLabel(ln, "End of if expression");
 | 
					 | 
					 | 
					 | 
					            backend.emitLocalLabel(ln, "End of if expression");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            return A0;
 | 
					 | 
					 | 
					 | 
					            return A0;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        }
 | 
					 | 
					 | 
					 | 
					        }
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -481,18 +550,19 @@ public class CodeGenImpl extends CodeGenBase
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        @Override
 | 
					 | 
					 | 
					 | 
					        @Override
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        public Register analyze(IfStmt node) 
 | 
					 | 
					 | 
					 | 
					        public Register analyze(IfStmt node) 
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        {
 | 
					 | 
					 | 
					 | 
					        {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        	
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        	System.out.println("Inside IfStmt: ");
 | 
					 | 
					 | 
					 | 
					        	System.out.println("Inside IfStmt: ");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            Register result = node.condition.dispatch(this);
 | 
					 | 
					 | 
					 | 
					            Register result = node.condition.dispatch(this);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            Label ln = generateLocalLabel();
 | 
					 | 
					 | 
					 | 
					            Label ln = generateLocalLabel();
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            backend.emitBEQZ(result, ln,"Jump to beginning of loop");
 | 
					 | 
					 | 
					 | 
					            backend.emitBEQZ(result, ln,"Jump to end of loop");
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            for(Stmt s:node.thenBody)
 | 
					 | 
					 | 
					 | 
					            for(Stmt s:node.thenBody)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                s.dispatch(this);
 | 
					 | 
					 | 
					 | 
					                s.dispatch(this);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            backend.emitJ(ln, "Jump to end of if statement");
 | 
					 | 
					 | 
					 | 
					            backend.emitJ(ln, "Jump to end of if statement");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            backend.emitLocalLabel(elseBlock, "Else part of if statement");
 | 
					 | 
					 | 
					 | 
					            elseBlock.push(generateLocalLabel());
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            backend.emitLocalLabel(elseBlock.peek(), "Else part of if statement");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            for(Stmt s:node.elseBody)
 | 
					 | 
					 | 
					 | 
					            for(Stmt s:node.elseBody)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                s.dispatch(this);
 | 
					 | 
					 | 
					 | 
					                s.dispatch(this);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            elseBlock.pop();
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            backend.emitLocalLabel(ln, "End of if statement");
 | 
					 | 
					 | 
					 | 
					            backend.emitLocalLabel(ln, "End of if statement");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            return null;
 | 
					 | 
					 | 
					 | 
					            return null;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        }
 | 
					 | 
					 | 
					 | 
					        }
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					 | 
					@ -526,11 +596,11 @@ public class CodeGenImpl extends CodeGenBase
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            
 | 
					 | 
					 | 
					 | 
					            
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            //Store address and length of lists on stack
 | 
					 | 
					 | 
					 | 
					            //Store address and length of lists on stack
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            backend.emitSW(Register.A0, Register.FP, -sp_off*wordSize, "Store address of first list");
 | 
					 | 
					 | 
					 | 
					            backend.emitSW(Register.A0, Register.FP, -sp_off*wordSize, "Store address of first list");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            sp_off++;
 | 
					 | 
					 | 
					 | 
					            incSp(1);
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            backend.emitSW(Register.T0, Register.FP, -sp_off*wordSize, "Store address of second list");
 | 
					 | 
					 | 
					 | 
					            backend.emitSW(Register.T0, Register.FP, -sp_off*wordSize, "Store address of second list");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            sp_off++;
 | 
					 | 
					 | 
					 | 
					            incSp(1);
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            backend.emitSW(Register.T3, Register.FP, -sp_off*wordSize, "Store length of combined list");
 | 
					 | 
					 | 
					 | 
					            backend.emitSW(Register.T3, Register.FP, -sp_off*wordSize, "Store length of combined list");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            sp_off++;
 | 
					 | 
					 | 
					 | 
					            incSp(1);
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            
 | 
					 | 
					 | 
					 | 
					            
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            //Allocate space on heap
 | 
					 | 
					 | 
					 | 
					            //Allocate space on heap
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            backend.emitLA(Register.A0, listClass.getPrototypeLabel(), "Load empty list");
 | 
					 | 
					 | 
					 | 
					            backend.emitLA(Register.A0, listClass.getPrototypeLabel(), "Load empty list");
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					 | 
					@ -571,7 +641,7 @@ public class CodeGenImpl extends CodeGenBase
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            {
 | 
					 | 
					 | 
					 | 
					            {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                node.right.dispatch(this);
 | 
					 | 
					 | 
					 | 
					                node.right.dispatch(this);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                backend.emitSW(Register.A0, Register.FP, -sp_off*wordSize, "Push on stack slot "+sp_off);
 | 
					 | 
					 | 
					 | 
					                backend.emitSW(Register.A0, Register.FP, -sp_off*wordSize, "Push on stack slot "+sp_off);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                sp_off++;
 | 
					 | 
					 | 
					 | 
					                incSp(1);
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                node.left.dispatch(this);
 | 
					 | 
					 | 
					 | 
					                node.left.dispatch(this);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                sp_off--;
 | 
					 | 
					 | 
					 | 
					                sp_off--;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                backend.emitLW(Register.T0, Register.FP, -sp_off*wordSize, "Pop stack slot "+sp_off);
 | 
					 | 
					 | 
					 | 
					                backend.emitLW(Register.T0, Register.FP, -sp_off*wordSize, "Pop stack slot "+sp_off);
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					 | 
					@ -626,11 +696,12 @@ public class CodeGenImpl extends CodeGenBase
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                        backend.emitADDI(Register.A0,Register.A0, 1, "Increment by 1");
 | 
					 | 
					 | 
					 | 
					                        backend.emitADDI(Register.A0,Register.A0, 1, "Increment by 1");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                        backend.emitSLT(Register.A0, Register.A0, Register.T0, comment);
 | 
					 | 
					 | 
					 | 
					                        backend.emitSLT(Register.A0, Register.A0, Register.T0, comment);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                    }
 | 
					 | 
					 | 
					 | 
					                    }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                    /* Maybe NA 
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                    else if(operator.equals("is"))
 | 
					 | 
					 | 
					 | 
					                    else if(operator.equals("is"))
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                    {
 | 
					 | 
					 | 
					 | 
					                    {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                        backend.emitXOR(Register.A0,  Register.A0, Register.T0, comment);
 | 
					 | 
					 | 
					 | 
					                        backend.emitXOR(Register.A0,  Register.A0, Register.T0, comment);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                        backend.emitSEQZ(Register.A0,  Register.A0, "Result is True if XOR equals 0");
 | 
					 | 
					 | 
					 | 
					                        backend.emitSEQZ(Register.A0,  Register.A0, "Result is True if XOR equals 0");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                    }
 | 
					 | 
					 | 
					 | 
					                    }*/
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                    else
 | 
					 | 
					 | 
					 | 
					                    else
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                    {
 | 
					 | 
					 | 
					 | 
					                    {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                        backend.emitJAL(errorNI, "Operator not implemented for integer operands");
 | 
					 | 
					 | 
					 | 
					                        backend.emitJAL(errorNI, "Operator not implemented for integer operands");
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -646,7 +717,7 @@ public class CodeGenImpl extends CodeGenBase
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                {
 | 
					 | 
					 | 
					 | 
					                {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                    node.right.dispatch(this);
 | 
					 | 
					 | 
					 | 
					                    node.right.dispatch(this);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                    backend.emitSW(Register.A0, Register.FP, -sp_off*wordSize, "Push on stack slot "+sp_off);
 | 
					 | 
					 | 
					 | 
					                    backend.emitSW(Register.A0, Register.FP, -sp_off*wordSize, "Push on stack slot "+sp_off);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                    sp_off++;
 | 
					 | 
					 | 
					 | 
					                    incSp(1);
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                    node.left.dispatch(this);
 | 
					 | 
					 | 
					 | 
					                    node.left.dispatch(this);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                    sp_off--;
 | 
					 | 
					 | 
					 | 
					                    sp_off--;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                    backend.emitLW(Register.T0, Register.FP, -sp_off*wordSize, "Pop stack slot "+sp_off);
 | 
					 | 
					 | 
					 | 
					                    backend.emitLW(Register.T0, Register.FP, -sp_off*wordSize, "Pop stack slot "+sp_off);
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -657,7 +728,7 @@ public class CodeGenImpl extends CodeGenBase
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                {
 | 
					 | 
					 | 
					 | 
					                {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                    node.right.dispatch(this);
 | 
					 | 
					 | 
					 | 
					                    node.right.dispatch(this);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                    backend.emitSW(Register.A0, Register.FP, -sp_off*wordSize, "Push on stack slot "+sp_off);
 | 
					 | 
					 | 
					 | 
					                    backend.emitSW(Register.A0, Register.FP, -sp_off*wordSize, "Push on stack slot "+sp_off);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                    sp_off++;
 | 
					 | 
					 | 
					 | 
					                    incSp(1);
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                    node.left.dispatch(this);
 | 
					 | 
					 | 
					 | 
					                    node.left.dispatch(this);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                    sp_off--;
 | 
					 | 
					 | 
					 | 
					                    sp_off--;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                    backend.emitLW(Register.T0, Register.FP, -sp_off*wordSize, "Pop stack slot "+sp_off);
 | 
					 | 
					 | 
					 | 
					                    backend.emitLW(Register.T0, Register.FP, -sp_off*wordSize, "Pop stack slot "+sp_off);
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -669,7 +740,7 @@ public class CodeGenImpl extends CodeGenBase
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                    Label label = generateLocalLabel();
 | 
					 | 
					 | 
					 | 
					                    Label label = generateLocalLabel();
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                    node.left.dispatch(this);
 | 
					 | 
					 | 
					 | 
					                    node.left.dispatch(this);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                    backend.emitSW(Register.A0, Register.FP, -sp_off*wordSize, "Push on stack slot "+sp_off);
 | 
					 | 
					 | 
					 | 
					                    backend.emitSW(Register.A0, Register.FP, -sp_off*wordSize, "Push on stack slot "+sp_off);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                    sp_off++;
 | 
					 | 
					 | 
					 | 
					                    incSp(1);
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                    backend.emitBEQZ(Register.A0, label, "If first operand is false, don't check second");
 | 
					 | 
					 | 
					 | 
					                    backend.emitBEQZ(Register.A0, label, "If first operand is false, don't check second");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                    node.right.dispatch(this);
 | 
					 | 
					 | 
					 | 
					                    node.right.dispatch(this);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                    sp_off--;
 | 
					 | 
					 | 
					 | 
					                    sp_off--;
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -682,7 +753,7 @@ public class CodeGenImpl extends CodeGenBase
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                    Label label = generateLocalLabel();
 | 
					 | 
					 | 
					 | 
					                    Label label = generateLocalLabel();
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                    node.left.dispatch(this);
 | 
					 | 
					 | 
					 | 
					                    node.left.dispatch(this);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                    backend.emitSW(Register.A0, Register.FP, -sp_off*wordSize, "Push on stack slot "+sp_off);
 | 
					 | 
					 | 
					 | 
					                    backend.emitSW(Register.A0, Register.FP, -sp_off*wordSize, "Push on stack slot "+sp_off);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                    sp_off++;
 | 
					 | 
					 | 
					 | 
					                    incSp(1);
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                    backend.emitBNEZ(Register.A0, label, "If first operand is true, don't check second");
 | 
					 | 
					 | 
					 | 
					                    backend.emitBNEZ(Register.A0, label, "If first operand is true, don't check second");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                    node.right.dispatch(this);
 | 
					 | 
					 | 
					 | 
					                    node.right.dispatch(this);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                    sp_off--;
 | 
					 | 
					 | 
					 | 
					                    sp_off--;
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -690,30 +761,82 @@ public class CodeGenImpl extends CodeGenBase
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                    backend.emitOR(Register.A0, Register.A0, Register.T0, "OR operation");
 | 
					 | 
					 | 
					 | 
					                    backend.emitOR(Register.A0, Register.A0, Register.T0, "OR operation");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                    backend.emitLocalLabel(label, "Next step after OR");
 | 
					 | 
					 | 
					 | 
					                    backend.emitLocalLabel(label, "Next step after OR");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                }
 | 
					 | 
					 | 
					 | 
					                }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                /*Maybe NA
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                else if(operator.equals("is"))
 | 
					 | 
					 | 
					 | 
					                else if(operator.equals("is"))
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                {
 | 
					 | 
					 | 
					 | 
					                {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                    backend.emitXOR(Register.A0,  Register.A0, Register.T0, comment);
 | 
					 | 
					 | 
					 | 
					                    backend.emitXOR(Register.A0,  Register.A0, Register.T0, comment);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                    backend.emitSEQZ(Register.A0,  Register.A0, "Result is True if XOR equals 0");
 | 
					 | 
					 | 
					 | 
					                    backend.emitSEQZ(Register.A0,  Register.A0, "Result is True if XOR equals 0");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                }
 | 
					 | 
					 | 
					 | 
					                }*/
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                else
 | 
					 | 
					 | 
					 | 
					                else
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                {
 | 
					 | 
					 | 
					 | 
					                {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                    backend.emitJAL(errorNI, "Operator not implemented for boolean operands");
 | 
					 | 
					 | 
					 | 
					                    backend.emitJAL(errorNI, "Operator not implemented for boolean operands");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                }
 | 
					 | 
					 | 
					 | 
					                }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            }
 | 
					 | 
					 | 
					 | 
					            }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            else if(node.left.getInferredType().isListType() && node.right.getInferredType().isListType())
 | 
					 | 
					 | 
					 | 
					            else if(node.left.getInferredType().isListType() && node.right.getInferredType().isListType())
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                if(operator.equals("+"))
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                    node.left.dispatch(this);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                    backend.emitSW(Register.A0, Register.FP, -sp_off*wordSize, "Push left operand on stack slot "+sp_off);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                    incSp(1);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                    node.right.dispatch(this);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                    backend.emitSW(Register.A0, Register.FP, -sp_off*wordSize, "Push right operand on stack slot "+sp_off);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                    incSp(1);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                    backend.emitADDI(Register.SP,Register.FP,-sp_off*wordSize,"Set SP to last argument");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                    backend.emitJAL(concatLabel, "Call concatenation routine");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                    backend.emitADDI(Register.SP, Register.FP, "-"+size_label, "Set SP to stack frame");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                    return Register.A0;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                    //addLists();
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                else
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                    backend.emitJAL(errorNI, "Operator not implemented for list operands");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                 
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            else if(node.left.getInferredType().equals(Type.STR_TYPE) && node.right.getInferredType().equals(Type.STR_TYPE))
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                if(operator.equals("=="))
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                incSp(2);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                backend.emitSW(node.left.dispatch(this), FP, (1 - sp_off) *wordSize, "Push argument 0 from last.");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                backend.emitSW(node.right.dispatch(this), FP, ( - sp_off) *wordSize, "Push argument 1 from last.");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                backend.emitADDI(SP, FP, -sp_off * wordSize, "Set SP to last argument.");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                backend.emitJAL(streqlLabel, "Invoke method:streql");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                sp_off -= 2;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                backend.emitADDI(SP, FP, -sp_off*wordSize, "restore sp");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                else if(operator.equals("!="))
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                incSp(2);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                backend.emitSW(node.left.dispatch(this), FP, (1 - sp_off) *wordSize, "Push argument 0 from last.");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                backend.emitSW(node.right.dispatch(this), FP, ( - sp_off) *wordSize, "Push argument 1 from last.");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                backend.emitADDI(SP, FP, -sp_off * wordSize, "Set SP to last argument.");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                backend.emitJAL(strneqlLabel, "Invoke method:strneql");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                sp_off -= 2;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                backend.emitADDI(SP, FP, -sp_off*wordSize, "restore sp");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                else if(operator.equals("+"))
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                    incSp(2);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                    backend.emitSW(node.left.dispatch(this), FP, (1 - sp_off) *wordSize, "Push argument 0 from last.");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                    backend.emitSW(node.right.dispatch(this), FP, ( - sp_off) *wordSize, "Push argument 1 from last.");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                    backend.emitADDI(SP, FP, -sp_off * wordSize, "Set SP to last argument.");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                    backend.emitJAL(strcatLabel, "Invoke method:strcat");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                    sp_off -= 2;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                    backend.emitADDI(SP, FP, -sp_off*wordSize, "restore sp");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                else
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                    backend.emitJAL(errorNI, "Operator not implemented for String operands");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            else if(operator.equals("is"))
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            {
 | 
					 | 
					 | 
					 | 
					            {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                node.right.dispatch(this);
 | 
					 | 
					 | 
					 | 
					                node.right.dispatch(this);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                backend.emitSW(Register.A0, Register.FP, -sp_off*wordSize, "Push on stack slot "+sp_off);
 | 
					 | 
					 | 
					 | 
					                backend.emitSW(Register.A0, Register.FP, -sp_off*wordSize, "Push on stack slot "+sp_off);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                sp_off++;
 | 
					 | 
					 | 
					 | 
					                incSp(1);
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                node.left.dispatch(this);
 | 
					 | 
					 | 
					 | 
					                node.left.dispatch(this);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                sp_off--;
 | 
					 | 
					 | 
					 | 
					                sp_off--;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                backend.emitLW(Register.T0, Register.FP, -sp_off*wordSize, "Pop stack slot "+sp_off);
 | 
					 | 
					 | 
					 | 
					                backend.emitLW(Register.T0, Register.FP, -sp_off*wordSize, "Pop stack slot "+sp_off);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                if(operator.equals("+"))
 | 
					 | 
					 | 
					 | 
					                backend.emitXOR(Register.A0,  Register.A0, Register.T0, "Operator: is");
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                    addLists();
 | 
					 | 
					 | 
					 | 
					                backend.emitSEQZ(Register.A0,  Register.A0, "Result is True if XOR equals 0");
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            }
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            else if(node.left.getInferredType().equals(Type.STR_TYPE) && node.right.getInferredType().equals(Type.STR_TYPE))
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            {
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            }
 | 
					 | 
					 | 
					 | 
					            }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            else
 | 
					 | 
					 | 
					 | 
					            else
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            {
 | 
					 | 
					 | 
					 | 
					            {
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -737,40 +860,40 @@ public class CodeGenImpl extends CodeGenBase
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                backend.emitSEQZ(Register.T0, Register.A0, "Not operation on Register A0");
 | 
					 | 
					 | 
					 | 
					                backend.emitSEQZ(Register.T0, Register.A0, "Not operation on Register A0");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            }
 | 
					 | 
					 | 
					 | 
					            }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            else
 | 
					 | 
					 | 
					 | 
					            else
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                return null;
 | 
					 | 
					 | 
					 | 
					                backend.emitJAL(errorNI, "Operator not implemented");
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            return Register.A0;
 | 
					 | 
					 | 
					 | 
					            return Register.A0;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        }
 | 
					 | 
					 | 
					 | 
					        }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        
 | 
					 | 
					 | 
					 | 
					        private SymbolInfo getSymbolInfo(Identifier id){
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            SymbolTable curr_sym = sym;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            SymbolInfo info = null;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            String id_name = id.name;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            while(curr_sym != null){
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                info = (SymbolInfo) curr_sym.get(id_name);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                if(info != null)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                    return info;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                curr_sym = curr_sym.getParent();
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            return info;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        @Override
 | 
					 | 
					 | 
					 | 
					        @Override
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        public Register analyze(Identifier node) 
 | 
					 | 
					 | 
					 | 
					        public Register analyze(Identifier node) 
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        {
 | 
					 | 
					 | 
					 | 
					        {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        	backend.emitLW(T6, FP, 0, "Inside Identifier: ");
 | 
					 | 
					 | 
					 | 
					        	backend.emitLW(T6, FP, 0, "Inside Identifier: ");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            if (sym.getParent() == null) 
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            {
 | 
					 | 
					 | 
					 | 
					            Identifier targetID = (Identifier)node;
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                GlobalVarInfo gvi=(GlobalVarInfo) sym.get(node.name);
 | 
					 | 
					 | 
					 | 
					            Object var = getVar(targetID);
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                backend.emitLW(Register.A0, gvi.getLabel(), "Load global: "+gvi.getVarName());
 | 
					 | 
					 | 
					 | 
					            if(var instanceof StackVarRuntimeInfo){
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                StackVarRuntimeInfo rtinfo = (StackVarRuntimeInfo) var;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                backend.emitLW(A0, rtinfo.sl, rtinfo.off,"Load local variable: "+node.name);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                rtinfo.free();
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            }
 | 
					 | 
					 | 
					 | 
					            }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            else 
 | 
					 | 
					 | 
					 | 
					            else 
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            {
 | 
					 | 
					 | 
					 | 
					                backend.emitLW(A0, (Label) var, "Load local variable: "+node.name);
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					// FIXME: This breaks, so had to comment it
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					//            	  VarInfo svi = (VarInfo) sym.get(node.name);
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					//                int loc = offsetMap.get(svi);
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					//                backend.emitLW(Register.A0, Register.FP, -loc*4, "Load local variable: "+svi.getVarName());
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            }
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            return null;
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        }
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        @Override
 | 
					 | 
					 | 
					 | 
					            return Register.A0;
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        public Register analyze(VarDef node) 
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        {
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            StackVarInfo svi = (StackVarInfo) sym.get(node.var.identifier.name);
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            node.value.dispatch(this);
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            backend.emitSW(Register.A0, Register.FP, -sp_off*wordSize, "Store variable "+node.var.identifier.name+" value in Stack");
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            offsetMap.put(svi, sp_off);
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            sp_off++;
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            return null;
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        }
 | 
					 | 
					 | 
					 | 
					        }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        
 | 
					 | 
					 | 
					 | 
					        
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					       
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        @Override
 | 
					 | 
					 | 
					 | 
					        @Override
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        public Register analyze(WhileStmt node) 
 | 
					 | 
					 | 
					 | 
					        public Register analyze(WhileStmt node) 
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        {
 | 
					 | 
					 | 
					 | 
					        {
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -778,7 +901,7 @@ public class CodeGenImpl extends CodeGenBase
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            Label startLoop = generateLocalLabel(); 
 | 
					 | 
					 | 
					 | 
					            Label startLoop = generateLocalLabel(); 
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            backend.emitLocalLabel(startLoop, "Beginning of while loop");
 | 
					 | 
					 | 
					 | 
					            backend.emitLocalLabel(startLoop, "Beginning of while loop");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            Register result = node.condition.dispatch(this);
 | 
					 | 
					 | 
					 | 
					            Register result = node.condition.dispatch(this);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            Label endLoop = elseBlock;
 | 
					 | 
					 | 
					 | 
					            Label endLoop = generateLocalLabel();
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            backend.emitBEQZ(result, endLoop,"Jump to end of the loop");
 | 
					 | 
					 | 
					 | 
					            backend.emitBEQZ(result, endLoop,"Jump to end of the loop");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            for(Stmt stmt:node.body) 
 | 
					 | 
					 | 
					 | 
					            for(Stmt stmt:node.body) 
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -792,25 +915,33 @@ public class CodeGenImpl extends CodeGenBase
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        @Override
 | 
					 | 
					 | 
					 | 
					        @Override
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        public Register analyze(ListExpr node) {
 | 
					 | 
					 | 
					 | 
					        public Register analyze(ListExpr node) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            int l = node.elements.size();
 | 
					 | 
					 | 
					 | 
					            int l = node.elements.size();
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            backend.emitLI(Register.A1, l+1, "Load length of list+1 in words");
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            backend.emitLA(Register.A0, listClass.getPrototypeLabel(), "Load empty list");
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            backend.emitJAL(objectAllocResizeLabel, "Allocate list");
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            backend.emitMV(Register.A1, Register.A0, "Store address of allocated space");
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            backend.emitMV(Register.T0, Register.A1, "Make a copy of address of allocated space");
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            int i=l;
 | 
					 | 
					 | 
					 | 
					            int i=l;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            backend.emitLI(Register.A0,l,"Load length of list in words");
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            backend.emitSW(Register.A0,Register.T0,0,"Store length of list: "+i);
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            backend.emitADDI(Register.T0,Register.T0,wordSize,"Increment address");
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            for(Expr exp:node.elements)
 | 
					 | 
					 | 
					 | 
					            for(Expr exp:node.elements)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            {
 | 
					 | 
					 | 
					 | 
					            {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                Register r = exp.dispatch(this);
 | 
					 | 
					 | 
					 | 
					                Register r = exp.dispatch(this);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                backend.emitSW(r,Register.T0,0,"Store element "+i+" from last.");
 | 
					 | 
					 | 
					 | 
					                if (exp.getInferredType().equals(Type.INT_TYPE) && !node.elements.get(0).getInferredType().equals(Type.INT_TYPE))
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                backend.emitADDI(Register.T0,Register.T0,wordSize,"Increment address");
 | 
					 | 
					 | 
					 | 
					                {
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                    if(r!=Register.A0)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                        backend.emitMV(r, Register.A0, "Copy to Register A0");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                    backend.emitJAL(makeintLabel, "Box integer");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                else if (exp.getInferredType().equals(Type.BOOL_TYPE) && !node.elements.get(0).getInferredType().equals(Type.BOOL_TYPE)) 
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                    if(r!=Register.A0)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                        backend.emitMV(r, Register.A0, "Copy to Register A0");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                    backend.emitJAL(makeboolLabel, "Box boolean");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                backend.emitSW(Register.A0, Register.FP, -sp_off*wordSize, "Push argument "+i+" from last");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                incSp(1);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                i--;
 | 
					 | 
					 | 
					 | 
					                i--;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            }
 | 
					 | 
					 | 
					 | 
					            }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            backend.emitMV(Register.A0,Register.A1,"Load address of list");
 | 
					 | 
					 | 
					 | 
					            backend.emitLI(Register.A0, l, "Pass list length");
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            backend.emitSW(Register.A0, Register.FP, -sp_off*wordSize, "Push length of list");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            incSp(1);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            backend.emitADDI(Register.SP, Register.FP, -(sp_off-1)*wordSize, "Set SP to last argument");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            backend.emitJAL(conslistLabel, "Move values to new list object");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            backend.emitADDI(Register.SP, Register.FP, "-"+size_label, "Set SP to stack frame");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            sp_off-=l;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            return Register.A0;
 | 
					 | 
					 | 
					 | 
					            return Register.A0;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        }
 | 
					 | 
					 | 
					 | 
					        }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -827,18 +958,104 @@ public class CodeGenImpl extends CodeGenBase
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        
 | 
					 | 
					 | 
					 | 
					        
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        @Override
 | 
					 | 
					 | 
					 | 
					        @Override
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					         public Register analyze(ForStmt node) {
 | 
					 | 
					 | 
					 | 
					        public Register analyze(ForStmt node) 
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            //System.out.println(node);
 | 
					 | 
					 | 
					 | 
					        {
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            /*
 | 
					 | 
					 | 
					 | 
					            int r;
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            node.
 | 
					 | 
					 | 
					 | 
					            List<Integer> regs= new ArrayList<Integer>();
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            if (node.iterable.getInferredType().isListType()) 
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                Label startLoop = generateLocalLabel();
 | 
					 | 
					 | 
					 | 
					                Label startLoop = generateLocalLabel();
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            backend.emitLocalLabel(startLoop, "Beginning of while loop");
 | 
					 | 
					 | 
					 | 
					                Label endLoop = generateLocalLabel();
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            node.condition.dispatch(this);
 | 
					 | 
					 | 
					 | 
					                r=getRegister();
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            Label endLoop = elseBlock;
 | 
					 | 
					 | 
					 | 
					                regs.add(r);
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                Register iden = registerPool[r];
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                node.iterable.dispatch(this);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                r=getRegister();
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                regs.add(r);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                Register l = registerPool[r];
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                r=getRegister();
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                regs.add(r);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                Register ln = registerPool[r];
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                backend.emitMV(l,Register.A0,"Location of list");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                r=getRegister();
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                regs.add(r);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                Register iter = registerPool[r];
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                backend.emitMV(iter, Register.ZERO, "Initialize index variable");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                backend.emitLocalLabel(startLoop, "Start for loop");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                backend.emitLW(ln, l, getAttrOffset(listClass, "__len__"), "Get attribute __len__");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                backend.emitBGE(iter, ln, endLoop, "Jump to end loop if counter exceeds length");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                backend.emitADDI(iden, iter, 4, "Compute list element offset in words");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                backend.emitLI(ln, wordSize, "Word size in bytes");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                backend.emitMUL(iden, iden, ln, "Compute list element offset in bytes");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                backend.emitADD(iden, l, iden, "Pointer to list element");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                backend.emitLW(iden, iden, 0, "Set list element");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                SymbolInfo info = sym.get(node.identifier.name);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                if(info instanceof GlobalVarInfo)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                    GlobalVarInfo gvi=(GlobalVarInfo) info;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                    backend.emitSW(iden, gvi.getLabel(), Register.T0, "Assign global: "+node.identifier.name+"(using tmp register)");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                else
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                    StackVarRuntimeInfo rtinfo = (StackVarRuntimeInfo) getVar(node.identifier);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                    backend.emitSW(iden, rtinfo.sl, rtinfo.off,"Store local variable: "+node.identifier.name);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                    rtinfo.free();
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                for(Stmt stmt:node.body)
 | 
					 | 
					 | 
					 | 
					                for(Stmt stmt:node.body)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                    stmt.dispatch(this);
 | 
					 | 
					 | 
					 | 
					                    stmt.dispatch(this);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                backend.emitADDI(iter, iter, 1, "Increment counter");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                backend.emitJ(startLoop, "Jump to beginning of loop");
 | 
					 | 
					 | 
					 | 
					                backend.emitJ(startLoop, "Jump to beginning of loop");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            backend.emitLocalLabel(endLoop, "End of while loop");*/
 | 
					 | 
					 | 
					 | 
					                backend.emitLocalLabel(endLoop, "End of for loop");
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            else if (node.iterable.getInferredType().equals(Type.STR_TYPE))
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                Label startLoop = generateLocalLabel();
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                Label endLoop = generateLocalLabel();
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                r=getRegister();
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                regs.add(r);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                Register iden = registerPool[r];
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                node.iterable.dispatch(this);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                r=getRegister();
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                regs.add(r);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                Register l = registerPool[r];
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                r=getRegister();
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                regs.add(r);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                Register ln = registerPool[r];
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                backend.emitMV(l,Register.A0,"Location of String");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                r=getRegister();
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                regs.add(r);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                Register iter = registerPool[r];
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                backend.emitMV(iter, Register.ZERO, "Initialize index variable");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                backend.emitLocalLabel(startLoop, "Start for loop");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                backend.emitLW(ln, l, getAttrOffset(strClass, "__len__"), "Get attribute __len__");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                backend.emitBGE(iter, ln, endLoop, "Jump to end loop if counter exceeds length");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                backend.emitADDI(iden, iter, 4 * wordSize, "Convert index to offset to char in bytes");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                backend.emitLBU(iden, iden, 0, "Load character");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                SymbolInfo info = sym.get(node.identifier.name);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                if(info instanceof GlobalVarInfo)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                    GlobalVarInfo gvi=(GlobalVarInfo) info;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                    backend.emitSW(iden, gvi.getLabel(), Register.T0, "Assign global: "+node.identifier.name+"(using tmp register)");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                else
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                    StackVarRuntimeInfo rtinfo = (StackVarRuntimeInfo) getVar(node.identifier);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                    backend.emitSW(iden, rtinfo.sl, rtinfo.off,"Store local variable: "+node.identifier.name);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                    rtinfo.free();
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                for(Stmt stmt:node.body)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                    stmt.dispatch(this);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                backend.emitADDI(iter, iter, 1, "Increment counter");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                backend.emitJ(startLoop, "Jump to beginning of loop");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                backend.emitLocalLabel(endLoop, "End of for loop");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            } 
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            else
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                System.out.println("Iterable not a list or a string");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            for(int n:regs)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                freeRegister(n);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            return null;
 | 
					 | 
					 | 
					 | 
					            return null;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            
 | 
					 | 
					 | 
					 | 
					            
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        }
 | 
					 | 
					 | 
					 | 
					        }
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -846,31 +1063,59 @@ public class CodeGenImpl extends CodeGenBase
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        @Override
 | 
					 | 
					 | 
					 | 
					        @Override
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        public Register analyze(IndexExpr node) 
 | 
					 | 
					 | 
					 | 
					        public Register analyze(IndexExpr node) 
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        {
 | 
					 | 
					 | 
					 | 
					        {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					//                incSp(1);
 | 
					 | 
					 | 
					 | 
					            incSp(1);
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					//                Register listObj = node.list.dispatch(this);
 | 
					 | 
					 | 
					 | 
					            Register listObj = node.list.dispatch(this);
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					//                backend.emitSW(listObj, FP, -sp_off * wordSize, String.format("Push on stack slot %d", sp_off));
 | 
					 | 
					 | 
					 | 
					            backend.emitSW(listObj, FP, -sp_off * wordSize, String.format("Push on stack slot %d", sp_off));
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					//                Register index = node.index.dispatch(this);
 | 
					 | 
					 | 
					 | 
					            Register index = node.index.dispatch(this);
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					//                Register vacantReg = (index != A0) ? A0 : A1;
 | 
					 | 
					 | 
					 | 
					            Register vacantReg = (index != A0) ? A0 : A1;
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					//
 | 
					 | 
					 | 
					 | 
					            int tmpHandle = getRegister();
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					//                if (node.list.getInferredType().isListType()) {
 | 
					 | 
					 | 
					 | 
					            Register temp= registerPool[tmpHandle];
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					//                    backend.emitLW(vacantReg, FP, -sp_off * wordSize, String.format("Pop stack slot %d", sp_off));
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					//
 | 
					 | 
					 | 
					 | 
					            if (node.list.getInferredType().isListType()) 
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					//                    this.d(vacantReg);
 | 
					 | 
					 | 
					 | 
					            {
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					//                    return this.a(vacantReg, index, A0, false);
 | 
					 | 
					 | 
					 | 
					                backend.emitLW(vacantReg, FP, -sp_off * wordSize, String.format("Pop stack slot %d", sp_off));
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					//                }else{
 | 
					 | 
					 | 
					 | 
					                final Label bp = generateLocalLabel();
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					//                    this.a(0, vacantReg);
 | 
					 | 
					 | 
					 | 
					                backend.emitBNEZ(listObj, bp, "Ensure not None");
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					//                    Register a = a(index);
 | 
					 | 
					 | 
					 | 
					                backend.emitJ(errorNone, "Go to error handler");
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					//                    Label ch = generateLocalLabel();
 | 
					 | 
					 | 
					 | 
					                backend.emitLocalLabel(bp, "Not None");
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					//                    backend.emitLW(a, vacantReg, getAttrOffset(strClass, "__len__"), "Load attribute: __len__");
 | 
					 | 
					 | 
					 | 
					                final Label bt = generateLocalLabel();
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					//                    backend.emitBLTU(index, a, ch, "Ensure 0 <= idx < len");
 | 
					 | 
					 | 
					 | 
					                backend.emitLW(temp, listObj, getAttrOffset(listClass, "__len__"), "Load attribute: __len__");
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					//                    backend.emitJ(f, "Go to error handler");
 | 
					 | 
					 | 
					 | 
					                backend.emitBLTU(index, temp, bt, "Ensure 0 <= index < len");
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					//                    backend.emitLocalLabel(ch, "Index within bounds");
 | 
					 | 
					 | 
					 | 
					                backend.emitJ(errorOob, "Go to error handler");
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					//                    this.c(index);
 | 
					 | 
					 | 
					 | 
					                backend.emitLocalLabel(bt, "Index within bounds");
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					//                    Register a2 = this.a(false);
 | 
					 | 
					 | 
					 | 
					                backend.emitADDI(index, index, 4, "Compute list element offset in words");
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					//                    this.a(1);
 | 
					 | 
					 | 
					 | 
					                backend.emitLI(temp, wordSize, "Word size in bytes");
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					//                    return a2;
 | 
					 | 
					 | 
					 | 
					                backend.emitMUL(index, index, temp, "Compute list element offset in bytes");
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					//                }
 | 
					 | 
					 | 
					 | 
					                backend.emitADD(index, listObj, index, "Pointer to list element");
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            		return null;
 | 
					 | 
					 | 
					 | 
					                backend.emitLW(vacantReg, index, 0, "Set list element");
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            } 
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            else 
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                backend.emitLW(vacantReg, FP, - sp_off * wordSize, String.format("Peek stack slot %d", sp_off-  1));
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                Label boundchk = generateLocalLabel();
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                backend.emitLW(temp, vacantReg, getAttrOffset(strClass, "__len__"), "Load attribute: __len__");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                backend.emitBLTU(index, temp, boundchk, "Ensure 0 <= idx < len");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                backend.emitJ(errorOob, "Go to error handler");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                backend.emitLocalLabel(boundchk, "Index within bounds");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                incSp(1);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                backend.emitSW(index, RiscVBackend.Register.FP, -sp_off * wordSize, String.format("Push on stack slot %d",sp_off));
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                getAttrOffset(strClass, "__len__");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                backend.emitLW(T0, FP, -sp_off * wordSize, String.format("Pop stack slot %d", sp_off));
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                --sp_off;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                backend.emitSW(A1, FP, -sp_off*wordSize, String.format("Push Argument %d", sp_off));
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                backend.emitADDI(T0, T0, 4 * wordSize, "Convert index to offset to char in bytes");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                backend.emitLBU(T0, T0, 0, "Load character");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                backend.emitLA(vacantReg, strClass.getPrototypeLabel(), "Create Str for char");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                backend.emitJAL(objectAllocLabel, "Alloc char");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                backend.emitLI(T1, 1, "str size");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                backend.emitSW(T1, vacantReg, 3*wordSize, "len");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                backend.emitSW(T0, vacantReg, 4*wordSize, "ch");  
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            freeRegister(tmpHandle);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            -- sp_off;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            return vacantReg;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        }
 | 
					 | 
					 | 
					 | 
					        }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  
 | 
					 | 
					 | 
					 | 
					  
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        public Register analyze(MemberExpr node) 
 | 
					 | 
					 | 
					 | 
					        public Register analyze(MemberExpr node) 
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
						
					 | 
					 | 
					
 
 |