diff --git a/AST.py b/AST.py
index 2f451c7851b650df4c95dd099e81977a6376b849..1f2940f38d2da1303657c71159a99bfcb64c073b 100644
--- a/AST.py
+++ b/AST.py
@@ -17,6 +17,8 @@ class ASTNode():
         # reachability: None = not set, True = maybe, False = no
         self.outMaybe = None # either None or True/False
 
+    def getConstant(self):
+        return None
 
     # Do certains actions on every node of the AST tree
     #   call the same method in each class and its children recursively
diff --git a/AstBuilding.py b/AstBuilding.py
index b195fa3ce293a5e24503d18da203a6454e7db782..3c872478b01a49e1c4019c3878daab46139d6c44 100644
--- a/AstBuilding.py
+++ b/AstBuilding.py
@@ -1,6 +1,7 @@
 from CompNode import CompNode
 from pprint import pprint
 from Environment import GlobalEnv
+from TypeNodes import getSupers
 from CodeGenUtils import p, genProcedure, used_labels, local_labels, pLabel, genericHelperFunctions, globalImport
 
 # tree: (filename, parseTree)
@@ -62,23 +63,38 @@ def reachabilityChecking(ASTs):
 # Returns a dictionary (type e.g. "boolean") -> str (the assembly code generated)
 def arrayClassMemory(types):
     # All method labels from java.lang.Object
-    # TODO: add subtype testing table
     methods = ["M_Object_Object_", "M_Object_equals_Object", "M_Object_toString_", "M_Object_hashCode_", "M_Object_clone_", "M_Object_getClass_"]
-    typeDict = {}
     primTypes = ['boolean', 'byte', 'char', 'int', 'short'] # All possible types
-    for t in types:
+    typeDict = {}
+    # assignable = dict({"java.lang.Object" : 0,
+    # "java.lang.Cloneable" : 4,
+    # "java.io.Serializable" : 8
+    # })
+
+    for tt in types:
         # Class memory layout
         # Label: "A_type"
         # Label for SIT pointer: "I_SIT_spot_typeName_array"
         # Label for method pointers: "V_typeName_methodName_param_array"
+        if tt.__class__.__name__ == "ClassNode":
+            t = tt.name
+        else:
+            t = tt
+
         code = "section .data\n"
         code += "; Start of class memory layout\n"
         code += pLabel(name=t, type="array") + \
                 pLabel("SIT_spot_"+ t + "_array", "inter") + \
                 p(instruction="dd", arg1=64)
+
+        # point to subtype table
+        code += pLabel("subT_spot_" + t, "inter")
+        code += p("dd", "42")
+
         for m in methods:
             code += pLabel(name=t+"_"+m+"_array", type="vtable") + \
                     p(instruction="dd", arg1=64)
+
         code += "; End of class memory layout\n"
 
         # Creating a function to initialize class memory layout
@@ -94,6 +110,12 @@ def arrayClassMemory(types):
             code += p(instruction="extern", arg1=m) + \
                     p(instruction="mov", arg1="eax", arg2="dword V_"+t+"_"+m+"_array") + \
                     p(instruction="mov", arg1="[eax]", arg2="dword "+m, comment="points to method implementation")
+
+        if tt.__class__.__name__ == "ClassNode":
+            code += p("extern", "A_subT_" + tt.name)
+            code += p("mov", "eax", "I_subT_spot_" + t)
+            code += p("mov", "[eax]", "dword A_subT_" + tt.name)
+
         code += p(instruction="ret", arg1="")
         code += "; End of function to initialize class memory layout\n"
         if t in primTypes:
@@ -113,21 +135,23 @@ def codeGenPrep(ASTs):
     interM = []
     types = ['boolean', 'byte', 'char', 'int', 'short'] # All possible types
     classNodes = []
+    j = 0
 
     for t in ASTs:
         classInterNode = t[1].typeDcl
         if classInterNode.__class__.__name__ == "ClassNode":
-
-            types.append(classInterNode.name)
+            types.append(classInterNode)
             classNodes.append(classInterNode)
         else: # interfaceNode, get their methods to prep for SIT
             interM += classInterNode.methods
 
+        classInterNode.subTypeOffset = j * 4 # assign each type a position in the subtype testing table
+        j += 1
+
     # store SIT and subtype table size
-    for i in range(len(classNodes)):
-        classNodes[i].SITsize = len(interM)
-        classNodes[i].subTypeSize = len(types) - 5 # no primitive types in subtype table
-        classNodes[i].subTypeOffset = i * 4 # assign each type a position in the subtype testing table
+    for c in classNodes:
+        c.SITsize = len(interM)
+        c.subTypeSize = j  # no primitive types in subtype table
 
     # prep SIT
     for i in range(len(interM)):
diff --git a/CodeGenUtils.py b/CodeGenUtils.py
index c953da3cd38254b328dbf339a5ac04b05e86f372..270f9a21af893614b205682528d3b5ede62f73ad 100644
--- a/CodeGenUtils.py
+++ b/CodeGenUtils.py
@@ -96,6 +96,7 @@ def genMethodInvoke(method):
 
 # generates shorter code for constant value conditionals and comparison conditionals
 # cond is either literalNode or ExprNode or NameNode
+# cond could also be methodInvNode, arrayAccessNode or fieldAccessNode
 def iffalse(cond, label):
     result = ""
     if cond.__class__.__name__ == "NameNode":
diff --git a/ExprPrimaryNodes.py b/ExprPrimaryNodes.py
index da0eca1b286a4bcec3ace7274b5e971996a23bb9..043b18beea79d0ac1acf87da0b4b14f1e44ca281 100644
--- a/ExprPrimaryNodes.py
+++ b/ExprPrimaryNodes.py
@@ -163,6 +163,10 @@ class ArrayAccessNode(ASTNode):
         if not self.index.myType.isNum():
             raise Exception("ERROR: Array index must be a number.")
         self.myType = TypeStruct(self.array.myType.name, self.array.myType.typePointer)
+    
+    def getIfFalse(self, label):
+        self.codeGen()
+        return self.code + p("cmp", "eax", "[G__Zero]") + p("je", label)
 
     def addr(self):
         result = "; Start of calculating address for array access\n" + \
@@ -327,6 +331,21 @@ class AssignNode(ASTNode):
         self.code = self.right.code
         self.code += p("push", "eax")
 
+        # array assign check
+        if self.left.__class__.__name__ == "ArrayAccessNode" and (not self.left.myType.isPrimitive):
+            self.code += "; array assign subtype check\n"
+            self.left.array.codeGen()
+            self.code += self.left.array.code
+
+            offset = self.right.myType.typePointer.subTypeOffset
+            self.code += p("mov", "ebx", "[eax]", "start subtype test") # access class tag of left object
+            self.code += p("mov", "ebx", "[ebx + 4]") # access subtype testing column
+            self.code += p("mov", "ebx", "[ebx + " + str(offset) + "]") # ebx has isSubtype
+
+            # exception if not subtype, else do nothing (object is already in eax)
+            self.code += p("cmp", "[G__Zero]", "ebx")
+            self.code += p("je", "H__Throw_Exception")
+
         self.code +=("; Evaluate left of assignment\n")
         self.code += self.left.addr()
 
@@ -387,8 +406,9 @@ class CastNode(ASTNode):
         self.code += self.right.code
 
         # subtype test:
-        if not self.left.myType.isPrimitive:
-            # only test if right is not primitive (primitive types would be correctly static tested already)
+        if (not self.left.myType.isPrimitive) and self.right.myType.isArray ==  self.left.myType.isArray:
+            # only test if not primitive,  both are array or both non array
+            # cast would've exception if array is casting to non-array and not Object
             offset = self.left.myType.typePointer.subTypeOffset
             self.code += p("mov", "ebx", "[eax]", "start subtype test") # access class tag of left object
             self.code += p("mov", "ebx", "[ebx + 4]") # access subtype testing column
@@ -578,8 +598,8 @@ class ExprNode(ASTNode):
             self.left.codeGen()
             self.code += self.left.code
 
-            # only test if non-primitive
-            if not self.right.myType.isPrimitive:
+            # only test if non-primitive, both arrays or both non arrays
+            if (not self.right.myType.isPrimitive) and self.right.myType.isArray == self.left.myType.isArray:
                 offset = self.right.myType.typePointer.subTypeOffset
                 self.code += p("mov", "eax", "[eax]") # access class tag of left object
                 self.code += p("mov", "eax", "[eax + 4]") # access subtype testing column
@@ -856,6 +876,10 @@ class FieldAccessNode(ASTNode):
                 checkProtected(self.ID.prefixLink, self)
         except: # where there are no mods
             return
+    
+    def getIfFalse(self, label):
+        self.codeGen()
+        return self.code + p("cmp", "eax", "[G__Zero]") + p("je", label)
 
     # generates code that evaluates the address of field access
     # result stored in eax (address)
@@ -886,8 +910,7 @@ class FieldAccessNode(ASTNode):
             return
 
         fieldNode = self.ID.prefixLink
-        label = fieldNode.typeName + "_" + fieldNode.name
-        self.code = "; Accessing a field :" + label + "\n"
+        self.code = "; Accessing a field \n"
         # Evaluating the address of the field we're trying to access
         if self.primary:
             self.code += self.addr()
@@ -989,6 +1012,10 @@ class MethodInvNode(ASTNode):
                 self.args.codeGen()
             self.code += self.args.code
 
+    def getIfFalse(self, label):
+        self.codeGen()
+        return self.code + p("cmp", "eax", "[G__Zero]") + p("je", label)
+
     def codeGen(self):
         if hasattr(self, "code"):
             return
diff --git a/TypeNodes.py b/TypeNodes.py
index 99fab645db712e1729f483ba14d6633671a8cda5..28b222c58dec73c4435f72bad8c0cc78a404ce47 100644
--- a/TypeNodes.py
+++ b/TypeNodes.py
@@ -19,7 +19,7 @@ class ClassInterNode(ASTNode):
         self.SITsize = 0
         self.subTypeSize = 0
         self.subTypeOffset = 0
-
+        
         # sets
         self.inherits = []
         self.super = []
@@ -331,7 +331,7 @@ class ClassNode(ClassInterNode):
 
         ####### ADDING METHODS TO CLASS MEMORY LAYOUT AND FIELDS TO FIELD OFFSET TABLE #########
         # Copying over the offsets of methods from superclass and DECLARING memory segment for the methods
-        lastMethodOffset = 0  # stores the largest method offset in the superCalss
+        lastMethodOffset = 4  # stores the largest method offset in the superCalss
                         # TODO: set this to 4 after the implemntation of both the SIT and subtype testing table
                         # Note: This is 4 less than the offset of where the next method would be located
                         #       This is to accomodate for the addition of 4 to lastMethodOffset in EVERY (including the first) iteration in the
@@ -384,7 +384,7 @@ class ClassNode(ClassInterNode):
             self.data += p("dd", "42")
 
         # Layout subtype testing column
-        self.data += pLabel("subT_" + self.name, "inter")
+        self.data += pLabel("subT_" + self.name, "array")
         for i in range(self.subTypeSize):
             self.data += pLabel("subT_" + str(i), "inter")
             self.data += p("dd", "0") # 0 for False, 1 for True
@@ -443,7 +443,7 @@ class ClassNode(ClassInterNode):
         # fill in subtype testing column
         self.code += "\n; Filling in subtype testing\n"
         self.code += p("mov", "eax", "I_subT_spot_" + self.name)
-        self.code += p("mov", "[eax]", "dword I_subT_" + self.name)
+        self.code += p("mov", "[eax]", "dword A_subT_" + self.name)
 
         for t in getSupers(self): # getSupers includes self
             dlabel = "I_subT_" + str(t.subTypeOffset // 4)